#数据库知识:
1、数据库名,表名,列名,数据
2、自带数据库,数据库用户及权限
3、数据库敏感函数,默认端口及应用
4、数据库查询方法(增加删除修改更新)
#SQL注入产生原理:
代码中执行的SQL语句存在可控变量导致
#影响SQL注入的主要因素:
1、数据库类型(权限操作)
2、数据操作方法(增删改查)
3、参数数据类型(符号干扰)
4、参数数据格式(加密编码等)
5、提交数据方式(数据包部分)
6、有无数据处理(无回显逻辑等)
#常见SQL注入的利用过程:
1、判断数据库类型
2、判断参数类型及格式
3、判断数据格式及提交
4、判断数据回显及防护
5、获取数据库名,表名,列名
5、获取对应数据及尝试其他利用
#黑盒/白盒如何发现SQL注入
1、盲对所有参数进行测试
2、整合功能点脑补进行测试
白盒参考后期代码审计课程
利用过程:
获取数据库名->表名->列名->数据(一般是关键数据,如管理员)
案例说明:
在应用中,存在增删改查数据的操作,其中SQL语句结构不一导致注入语句也要针对应用达到兼容执行,另外也需要明白黑盒中功能对应的操作方法;除此之外部分业务应用功能也要做到了解(如接受IP,UA,COOKIE,Referer等头部),并且通过功能分析出对应SQL操作方法。
UA(User-Agent):
场景1:对UA设备指定显示方案
漏洞成因:应用将 UA 头直接拼接到 SQL 语句中(如用户行为日志记录、用户身份验证等场景),且未使用参数化查询
接收UA头信息,然后联合sql语句去数据库中直接查询,没有做任何防护,就会造成漏洞
//错误示例:直接拼接UA头到SQL
ua = _SERVER['HTTP_USER_AGENT'];
sql = "INSERT INTO user_agent_log (user_id, ua) VALUES ('user_id', 'ua')";
mysqli_query(conn, $sql);
黑盒时就看有没有显示内容,没有显示就直接盲测,对有可能接收的数据进行测试
白盒就直接查看源代码即可,查sql语句等,
测试场景:
这个是接收ua头到数据库中查询,所以是用的select语句

开去burp抓包,因为burp抓包时会忽略本地(127.0.0.1) 这个地址的,所以改成本机IP即可,或者换成burp中打开的浏览器也行
抓到数据包后

修改ua头的值,看显示部分是否变化

这里前面还有两步一步是判断是否有注入点,一步是判断列数的; 这里是判断数据回显位置的

先使用' 闭合前面的查询语句,然后写自己的查询语句,最后加个# 将后面的查询语句注释掉
s
场景2:对UA设备进行信息记录
网站对访问者的IP等信息进行存储,写到数据库中 ;对ua信息进行接收和存储
这里就要用到insert语句中的注入语句了,再用select的注入语句是行不通的,会报错,导致即使有漏洞也没有用
XFF(X-Forwarded-For):
场景1:限制IP访问功能
网站中某个网页限制IP访问,只允许特定的IP访问;如果它是接收xff头来确定IP的话,那么就有可能产生安全问题;可以防止非指定IP访问,是要用xff头接收IP时,会造成这个注入
这是一个登录页面,它会交给xff.php 去处理数据

提交数据后页面提示 没有权限访问页面

打开burp 抓包

这个是接收xff头来判断是否是允许访问的IP,如果没有xff头就会用到下面的获取方式,而下面的获取方式是直接获取当前的IP地址,就不能在burp中修改了,就无法造成注入;所以要看是否是xff头验证;黑盒中的话就直接加一个xff头进行测试,有就有,没有就换下一个测试地方
//获取 X-Forwarded-For头信息
xff = _SERVER['HTTP_X_FORWARDED_FOR']?? null;
//如果 X-Forwarded-For头存在,取第一个 IP**地址
if ($xff) {
client_ip = xff;
} else {
//如果 X-Forwarded-For头不存在,使用客户端的 IP**地址
client_ip = _SERVER['REMOTE_ADDR'];
}
加一个xff头测试,这里还是不给访问,因为是测试,所以知道哪些IP 可以访问;

修改IP为指定IP 后可以正常进行访问页面了,测试sql注入时,不需要知道指定的IP是什么,只要它查询的是数据库的里面的内容,那么随便写一个IP即可,后面接上测试语句即可;测试指定IP是什么是为了其他漏洞测试,这里如果想知道指定IP是什么就可以先重可能的IP段进行测试,比如服务器的IP,不行之后就用工具进行爆破,C段爆破

随便写一个IP测试,判断回显位置

查看数据库名;后面就是查表名,数据了

场景2:记录IP访问日志
这个和ua头记录一样是用的insert语句;后面会有实验
Cookie:
场景:开发人员在编写一个根据用户 ID(存储在Cookie中)来查询信息的功能
接收cookie中的某个数据来确定访问的用户是登录状态,是否是VIP等,如果接收的数据在查询时是在数据库进行查询,那么就可能会造成sql注入
访问页面时 提示 未发现用户 要么是没登陆;或者是权限不够

判断用户语句
//从 Cookie中获取用户 ID
if (isset($_COOKIE['user_id'])) {
user_id = _COOKIE['user_id'];
} else {
die("未发现存在用户访问。");
}
//构建存在 SQL注入风险的查询语句
sql = "SELECT \* FROM users WHERE id = user_id";
*//*执行查询
result = conn->query($sql);
if (result \&\& result->num_rows > 0) {
row = result->fetch_assoc();
echo "用户名: ". $row['username']. "<br>";
echo "邮箱: ". $row['email'];
} else {
echo "未找到用户信息。";
}
开burp抓包

黑盒中就测试时可以先注册一个账号,然后开启抓包,查看接收的变量是什么,这里是user_id ;或者直接对变量名进行爆破
判断列数

查看回显位置

查看当前数据库名

测试思路:
黑盒:
注册一个账号,查看数据包;fuzz字典爆破;findsomething 获取参数
Referer: 和这个 csrf 漏洞相似
网站期望登录请求来自于本站页面,如果Referer是其他来源,则拒绝登录。
数据库中写了一个表,里面的值是网址;后端代码来判断数据来源是否是来自数据库里面的网址,是就放行,不是就拒绝;如果应用不是通过查询数据库中的网址是否符合,而是写一个表或者一个文件存储的话,就没有sql注入了
//获取 Referer头信息
referer = _SERVER['HTTP_REFERER']?? '';
//构建存在 SQL注入风险的查询语句,检查 Referer**是否允许
referer_sql = "SELECT \* FROM allowed_referers WHERE referer_url = 'referer'";
referer_result = conn->query($referer_sql);
if ($referer_result->num_rows === 0) {
die("登录请求来源不合法,拒绝登录。");
}else{
row = referer_result->fetch_assoc();
echo "来源 ". $row['referer_url']. "<br>";
}

来到登录页面,随便输入账号密码测试

页面显示 来源不合法

开burp抓包,看到有referer 记录来源

修改为正确网址,查看情况

网址随便输入什么都行,然后在后面输入测试语句即可;这个是测试有几列的

输入3就报错,说明是两列

查询数据库名

实战中就看有么有referer ,如果有就修改来源,测试网页是否正常,不正常,则说明可能有sql注入;因为如果它只是接收后去文件里面比对或者和某个列表进行对比的话,就不会有sql注入
增删改查大致功能应用:
MySQL三种报错注入方式下的insert,update,delete命令注入示例 - impulse- - 博客园
select查询:用户查询,新闻查询
delete删除:用户删除,新闻删除
update修改:用户修改,新闻修改
insert增加:用户注册,新闻添加
下面是用php代码写了一个数据库增删改查的功能的网页

select语句 在查询功能中注入
先输入 'and 1=1# 测试可以查询到数据
输入 'and 1=2 # 时 查询不到,说明有注入点

输入 zhangsan' order by 3 # 时能正常显示数据,说明原查询的sql语句的字段大于等于3;加大字段数测试

输入字段数为4 时错误,所以字段数为3

输入 'union select 1,2,3# 查看数据回显位置

查看当前数据库,后面操作和第53天的一样,下面就是查表名,然后根据表名查数据,查用户的数据(admin) ,查到后就用admin登录网页

insert语句 插入数据
用select一样的语句 执行时,会报错,所以要判断当前输入框中可能是用的什么方法,是增,删,改,查 中的哪一种

insert 语句的写法就和select完全不一样了,要用 ' or updatexml(1,concat(0x7e,(database())),0) or ' 这种

update语句 更新数据

delete 语句


显示和其他三个不同,主要是因为显示的内容不一样,写的语句也不一样;因为查询的数据内容要显示出来,而其他三个只需要显示成功或者失败即可,不需要将删除了什么或者修改了什么的内容显示出来,它们没有回显;但是增删改 的语句也是不一样的 ;
为什么不能用查询语句来进行其他语句的注入?主要是其他方法不支持,其他方法的数据不回显等;比如说,就是查询语句里面的union select 这个是联合查询,那其他方法没有这个,所以用了这个就会报错
#实例应用:
HTTP头-XFF注入
https://mp.w eixin.qq.com/s/CiCxpHbW4IArB2nYSH-12w
https://mp.weixin.qq.com/s/_jj0o7BKm8CGEcn77gvdOg
加密还原+JSON注入
https://mp.weixin.qq.com/s/c3wji_LL_nuiskAKpg89pA
HTTP头-403绕过