In juli 2021 stuitten we op de Lorenz ransomware. Lorenz is een ransomware-familie (“strain”) die organisaties aanvalt en waarmee honderdduizenden euro’s aan losgeld wordt geëist. Bij onze analyse in 2021 merkten we dat de ransomware enkele bugs bevatte en dat het mogelijk was om er een decryptor voor te bouwen. Dit betekende dat we, in het kader van het NoMoreRansom initiatief, een gratis decryptor voor Lorenz konden publiceren.
Begin maart 2022 dook er plotseling een nieuwe variant van Lorenz op. Het fragment dat wij analyseerden dateert van 2 maart 2022. Bestanden die met deze variant zijn versleuteld, verschillen van de eerdere. In dit blog beschrijven we onze bevindingen over de nieuwe variant. Bovendien wijzen we op een ernstige bug in de ransomware die het voor de hacker feitelijk onmogelijk maakt om de versleutelde bestanden nog te herstellen. En ten slotte kunnen we aankondigen dat het nog steeds mogelijk is om de bestanden te ontsleutelen, ook zonder losgeld te betalen. Of beter: alléén zonder losgeld te betalen.
Overzicht
Er zijn nogal wat verschillen tussen deze Lorenz-variant en de eerdere. Zo bestond het eerdere losgeldbriefje bijvoorbeeld uit een HTML-document met de naam ‘HELP_SECURITY_EVENT.html’. Het losgeldbriefje van de nieuwe variant is een plat tekstdocument genaamd ‘HELP.TXT’.
Net als de vorige variant legt deze nieuwe Lorenz-variant contact met een command & control-server. Het contact wordt via HTTP op poort 80 geïnitieerd middels het verzenden van een kleine POST-request die gegevens over het geïnfecteerde systeem bevat: de computernaam, het interne IP-adres en de Windows-versie (bijv. 6.1 voor Windows 7). Mogelijk wordt deze command & control-communicatie gebruikt om de hackers van basale gebruiksstatistieken te voorzien.
Een ander verschil is de string-encryptie. In de eerste variant van Lorenz die we analyseerden, waren strings ingebed in de binary, in de vorm van platte tekst. Dit keer zijn ze versleuteld met behulp van een eenvoudig algoritme: ze zijn XOR-encrypted met behulp van de single-byte sleutel 0x6B en vervolgens Base64-gecodeerd.
Helaas bevat deze Lorenz-variant enkele ernstige bugs en fouten. In tegenstelling tot zijn voorganger zorgt deze variant bij het opstarten niet voor de aanmaak van – en controle op – een mutex. Bovendien wordt de encryptiesleutel die nodig is voor het ontsleutelen van een geïnfecteerd bestand niet weggeschreven. Dit betekent dat decryptie nagenoeg onmogelijk is.
Mogelijk dubbele encryptie
Het is gebruikelijk dat ransomware bij het opstarten een mutex aanmaakt en zichzelf beëindigt als er al een mutex aanwezig is. Dit is een heel belangrijke stap, want hiermee wordt voorkomen dat er meerdere instances van de ransomware tegelijkertijd actief zijn. De eerste variant van Lorenz die we analyseerden, maakte een mutex genaamd ‘wolf’ aan en controleerde daar ook op, zoals het hoort. Het proces werd automatisch beëindigd als er al een mutex aanwezig was, zoals te zien is in het onderstaande screenshot.
De recente variant van Lorenz die we analyseerden, maakt geen mutex aan en controleert ook niet op de aanwezigheid daarvan. Er kunnen dus meerdere instances tegelijkertijd actief zijn, waardoor het risico bestaat dat de verschillende instances elkaars versleutelde bestanden beschadigen, zodanig dat ontsleuteling later erg moeilijk of zelfs onmogelijk wordt.
Bestandsencryptie
In de kern is het bestandsencryptieschema hetzelfde gebleven. Bestanden worden versleuteld met behulp van een combinatie van RSA- en AES-encryptie in CBC-modus. Er wordt een random wachtwoord gegenereerd en dit wordt gebruikt om de feitelijke encryptiesleutel af te leiden met behulp van de functie CryptDeriveKey.
De manier waarop bestanden worden versleuteld is echter wél veranderd. Met de vorige variant werd elk bestand in zijn geheel versleuteld, in blocks van 48 bytes. De marker ‘.sz40’ voor versleutelde bestanden en het RSA-encrypted wachtwoord werden vervolgens in de kop van het bestand geplaatst. Met de recente variant worden de bestanden onderverdeeld in twee categorieën: bestanden kleiner dan 64.368.875 bytes (~ 61MiB), en bestanden die groter zijn dan dat. Kleine bestanden worden in hun geheel versleuteld, maar nu in blocks van 160 bytes. Grotere bestanden krijgen een andere behandeling. Alleen de eerste 4.000.000.000 bytes (~3.7GB) van deze bestanden worden versleuteld. Kleine bestanden worden naast elkaar (“side-by-side”) versleuteld, want de marker van het versleutelde bestand en de encryptiesleutel worden in de kop van het bestand geplaatst. Dat betekent dat het versleutelde bestand wordt gemaakt en dat het oorspronkelijke bestand na de versleuteling wordt gewist. Grote bestanden worden “in-place” versleuteld, wat betekent dat de blocks stuk voor stuk worden gelezen, versleuteld, en teruggeschreven in het bestand. Na de encryptie krijgt het bestand de naam van zijn versleutelde tegenhanger.
Zoals gezegd werden bestanden in de vorige variant versleuteld in blocks van 48 bytes. Het algoritme voor het versleutelen van kleine bestanden in de nieuwe variant doet datzelfde, maar dan in blocks van 160 bytes. Mogelijk hebben de auteurs het oorspronkelijke encryptiealgoritme aangepast om nu alleen kleine bestanden te versleutelen en hebben ze een nieuw algoritme geschreven voor het versleutelen van de grote bestanden. Zoals te zien is in het onderstaande screenshot zijn de auteurs één keer vergeten om 48 te veranderen in 160. In de praktijk is ‘is_final_block’ altijd TRUE zodra het einde van het bestand is bereikt, tenzij het restant gelijk is aan 48 bytes. Is het resterende aantal bytes (het laatste block dat kleiner is dan of gelijk is aan 160 bytes) géén veelvoud van 8, dan kunnen de laatste bytes van het versleutelde bestand ongeldige data bevatten.
Een ernstige fout
Wil ransomware succesvol zijn, dan moet hij in staat zijn om de versleutelde bestanden op de juiste manier te herstellen. Lukt dat de hackers niet, dan verliezen ze een flink deel van hun druk op het slachtoffer. De auteurs van Lorenz hebben in de recente variant een ernstige fout gemaakt. Een fout die ervoor zorgt dat de versleutelde bestanden niet meer ontsleuteld kunnen worden.
Voor het herstellen van een versleuteld bestand hebben we de sleutel nodig die gebruikt is voor het versleutelen ervan. Vergeet niet dat Lorenz een random wachtwoord genereert voor het afleiden van de feitelijke AES-encryptiesleutel. Deze sleutel wordt vervolgens versleuteld met RSA, waarbij de openbare sleutel door de hackers wordt ingebed in de ransomware. Dit is heel gebruikelijk. Daarnaast wordt deze RSA-encrypted sleutel weggeschreven naar de kop of staart van het versleutelde bestand. We hebben die sleutel immers nodig om de oorspronkelijke inhoud van het bestand later weer te kunnen herstellen.
Hier is nu de grootste fout gemaakt. Het wachtwoord is 40 tekens lang, maar alle met RSA-1024 versleutelde data heeft 128 bytes (1024 / 8 bits) geheugenruimte nodig. De ransomware creëert echter geen buffer die groot genoeg is voor deze 128 bytes. Zoals in het onderstaande screenshot te zien is, zouden de marker van het versleutelde bestand en de RSA-encrypted sleutel naar het versleutelde bestand weggeschreven moeten worden met behulp van de functie WriteFile. Aangezien WriteFile buiten de 40 bytes grote buffer ‘encrypted_file_key’ zou lezen, faalt deze functie en wordt de fout ‘ERROR_INVALID_USER_BUFFER’ geretourneerd. Er wordt echter niet gecontroleerd op de geretourneerde fout en het versleutelen van het bestand wordt voortgezet.
Het bovenstaande screenshot is afkomstig uit het encryptiealgoritme voor kleine bestanden, maar het algoritme voor grote bestanden heeft precies hetzelfde probleem. Het gevolg van deze fout is dat versleutelde bestanden alleen de marker en de versleutelde inhoud bevatten, niet de sleutel. Zonder die sleutel is het nagenoeg onmogelijk om het bestand te herstellen.
Conclusie
Bij de vorige Lorenz-variant die we analyseerden, kwamen we tot de conclusie dat ontsleuteling mogelijk was zonder het losgeld te hoeven betalen. Bovendien vestigden we de aandacht op een bug die de laatste 48 bytes van bepaalde bestanden kon vernietigen. Deze nieuwe variant van Lorenz kent echter problemen die een stuk ernstiger zijn, zoals de vernietiging van complete bestanden. Ook al is de “48-byte bug” opgelost, we kunnen veilig concluderen dat deze nieuwe variant ronduit destructief is.
Gelukkig is decryptie nog steeds mogelijk zonder het losgeld te hoeven betalen. Bent u getroffen door Lorenz? Betaal het losgeld dan niet, want in bepaalde gevallen krijgt u uw bestanden niet terug. Neem contact met ons op om te bespreken hoe we u wellicht kunnen helpen met het herstellen van uw data. Zonder dat u losgeld betaalt!
Indicators of Compromise
Indicator | Description |
427713275e7c4515e3c577684a7c5f96e45771fee54f1c3162a2d6a2cc4cd76e
|
SHA-256 of new Lorenz variant sample |
172[.]86[.]75[.]81 | Command & control server |