通过数据库的插入延迟造成条件竞争下的命令执行

好久没发博客了,补上之前学的一些东西

文章本人首发于t00ls

0x01

初学代码审计,前年找了一个小众cms挖了个命令执行,这次看见它更新后又审了一下之前出现漏洞的地方尝试绕过。 上次出现问题的地方在于:

用户提交配置信息,后台把网站的配置信息存入数据库,写入配置文件的时候从数据库中取出配置信息,以"$变量=值"的方式粘贴成字符串后写入到php文件中作为配置文件。 配置文件形式如下:

漏洞被修复后,代码如下,第6行-第11行:

 1 function WriteConfig() { global $dosql, $config_cache, $gourl;
 2 
 3 $str = '<?php    if(!defined(\'IN_PHPMYWIND\')) exit(\'Request Error!\');'."\r\n\r\n";
 4 $dosql->Execute("SELECT `varname`,`vartype`,`varvalue`,`vargroup` FROM `#@__webconfig` ORDER BY orderid ASC");
 5 while($row = $dosql->GetArray())
 6 {
 7     //强制去掉 '
 8     //强制去掉最后一位 /
 9     $vartmp = str_replace("'",'',$row['varvalue']);
10 
11     if(substr($vartmp, -1) == '\\')
12     {
13         $vartmp = substr($vartmp,1,-1);
14     }
15 
16     if($row['vartype'] == 'number')
17     {
18         if($row['varvalue'] == '')
19         {
20             $vartmp = 0;
21         }
22 
23         $str .= "\${$row['varname']} = ".$vartmp.";\r\n";
24     }
25     else
26     {
27         $str .= "\${$row['varname']} = '".$vartmp."';\r\n";
28     }
29 }
30 $str .= '?>';
31 
32 if(!Writef($config_cache,$str))
33 {
34     ShowMsg("变量成功保存,但由于 config.cache.php 无法写入,因此不能更新配置!", $gourl);
35     exit();
36 }
37 
38 RewriteURL();

可以看到,它在写入配置文件前对单引号进行了循环过滤和 \ 的单次过滤,那绕过的思路就来了,我可以通过注释掉变量值中的后一个单引号,使配置文件变为如下形式:

$key1='xxx\';$key2='; phpinfo();\';

$key1='xxx\';$key2='; phpinfo();\';

但是这种利用需要同时对两个变量的值进行修改才可以完成整个攻击过程,不然只修改了一处,整个配置文件就出现语法错误从而导致整个网站出错无法正常访问,第二个更新变量的请求就无法正常被处理。 幸运的是,程序里刚好有同时对两处变量进行修改的代码逻辑。

0x02

完成整个攻击过程后我就开始想了,如果同时只可以更新一个变量呢?有什么方法可以继续整个攻击过程吗?

回到上面提到的,再来看看后台的整个数据处理过程:

用户提交配置信息-》存入数据库-》从数据库取出数据-》粘贴成字符串-》写入配置文件

存入数据库-》从数据库取出数据 ,如果我们提交第一个更新配置文件变量的请求,在它被存入数据库还没被取出写成配置文件之前再提交第二个更新下一个变量的请求,那不就可以了吗?

如何让数据库在存入时产生延迟?当存入的数据足够大的时候

所以目前的思路是,提交第一个可以对数据库存取产生足够延迟的更新请求-》在错误配置文件生成前提交第二个更新请求-》第一个请求导致的错误配置文件被生成-》第二个请求生成的合法配置文件被生成,错误的配置文件被覆盖-》攻击完成

在尝试的过程中,发现第一个请求的字符达到3w个以上时才可以产生可利用的延迟 最后攻击成功

cms是phpmywind,漏洞点在/admin/web_config.php文件,感兴趣的朋友可以自行尝试~

转载于:https://www.cnblogs.com/iceli/p/10393680.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值