Wij zijn |
Verschil NT, LM, NTLM, NTLMv1, NTLMv2, NET-NTLMv2
Ondanks dat de benamingen erg op elkaar lijken en het vaker dan eens verkeerd gebruikt wordt, zijn het verschillende dingen. Zo is NTLM de benaming van het authenticatieprotocol waaronder NTLMv1 en NTLMv2 vallen, en wordt de NT-hash door heel veel mensen een NTLM-hash genoemd. In deze blogpost zetten we uiteen wat de verschillen en overeenkomsten zijn en leggen we uit hoe het NTLM protocol werkt.
Hoe werkt NTLM, NTLMv1, NTLMv2, LM?
LM / LMv1 en de LM-hash
LM (LAN Manager) is een verouderd authenticatieprotocol dat oorspronkelijk werd gebruikt in oudere versies van het Windows-besturingssysteem. Het werd geïntroduceerd in de jaren ’80 en ’90 en wordt nu als onveilig beschouwd vanwege de zwakke versleutelingstechnieken die het gebruikt. LM slaat wachtwoorden op in een zwak gehashte vorm, bekend als een LM-hash, wat het kwetsbaar maakt voor aanvallen. Sinds Windows Vista/Server 2008 staat LM ondersteuning standaard uitgeschakeld. Als er in een netwerk oudere systemen staan, of de optie specifiek is ingeschakeld dan kunnen er nog LM-hashes rondzwerven.
LM-hash maken
De LM-hash wordt als volgt geconstrueerd:
- Het wachtwoord van de gebruiker wordt omgezet naar hoofdletters.
- Het wachtwoord wordt opgevuld met nullbytes tot een lengte van 14 bytes.
- Het wachtwoord wordt in twee helften van 7 bytes verdeeld.
- Uit elke helft van 7 bytes worden DES-sleutels gecreëerd (de parity bits worden toegevoegd).
- Met deze sleutels wordt de constante ASCII-string
KGS!@#$%
versleuteld, wat resulteert in twee 8-byte versleutelde waarden. - Deze twee versleutelde waarden worden samengevoegd tot een 16-byte LM-hash.
LMv1-response maken
Het LAN Manager protocol is een challenge-response protocol, waarbij de server een challenge stuurt. Dit werkt als volgt:
- De client geeft aan te willen verbinden en de server stuurt een server challenge.
- De client zet het wachtwoord om in de LM-hash.
- Deze LM-hash wordt aangevuld met nullbytes tot 21 bytes (vanaf 16 bytes).
- Deze string wordt gesplitst in drie delen van 7 bytes.
- Uit elk deel van 7 bytes worden DES-sleutels gecreëerd.
- Met deze sleutels wordt de server challenge versleuteld, wat resulteert in drie 8-byte versleutelde waarden.
- Deze drie versleutelde waarden worden samengevoegd tot een 24-byte LMv1-response.
Op beveiligingsgebied zitten hier diverse pijnpunten in. Een aantal punten die meteen opvallen, het wachtwoord is niet hoofdlettergevoelig, dus de set met mogelijke wachtwoorden is significant kleiner. Daarnaast, als het wachtwoord gelijk aan of korter dan zeven karakters is, is het tweede deel van de hash altijd hetzelfde. Immers, het lege wachtwoord wordt aangevuld met nullbytes, vervolgens wordt hier een deskey van gemaakt en wordt de string KGS!@#$%
versleuteld. Hieruit komt altijd 0xaad3b435b51404ee
.
Het is belangrijk om te weten hoe LM werkt omdat het de basis is van de nieuwere authenticatieprotocollen, maar omdat LMv1 tegenwoordig (hopelijk) nergens meer gebruikt wordt gaan we niet nog dieper in op LM.
NTLMv1 en de NT-hash
De NT-hash is een wachtwoordhash die wordt gebruikt in het NTLM-authenticatieprotocol van Windows-besturingssystemen. De NT-hash staat, eigenlijk onterecht, ook wel bekend als de NTLM-hash. In oudere versies van Windows werd binnen het LM-authenticatieprotocol de LM-hash gebruikt. De NT-hash is ten opzichte van de LM-hash een stukje veiliger. In plaats van de DES functies wordt er hier gebruik gemaakt van het MD4 hashingalgoritme. De mogelijke wachtwoorden worden daardoor niet meer beperkt tot de DOS karakterset maar alle UTF-16 karakters mogen worden gebruikt, er zit geen limiet meer op van 14 karakters en het wachtwoord wordt niet meer naar een bepaalde lengte opgevuld met nullbytes.
Het maken van een NT-hash
De NT-hash wordt als volgt geconstrueerd:
- Het unicode (UTF16-LE) wachtwoord wordt omgezet naar hex.
- Het MD4-algortime wordt toegepast. Dit is de NT-hash.
-
Welkom01!
wordt0x570065006c006b006f006d00300031002100
-
0x570065006c006b006f006d00300031002100
wordt0xa958a3e244a682c7be90850c7a4e69eb
De NT-hash kan gebruikt worden om middels het NTLM-protocol te authenticeren. Het is in principe niet nodig om de hash te kraken en om te zetten naar een plaintext wachtwoord. Deze methode heet pass-the-hash.
Het berekenen van een NTLMv1-response
NTLMv1 is net als LMv1 een challenge-response protocol. Sterker nog, het NTLM-response wordt op exact dezelfde wijze berekend. Het verschil zit hem in de startwaarde, waar bij LMv1 de LM-hash het beginpunt is, is dat bij NTLMv1 de NT-hash.
- De client geeft aan te willen verbinden en de server stuurt een server challenge.
- De client zet het wachtwoord om in de NT-hash.
- Deze NT-hash wordt aangevuld met nullbytes tot 21 bytes (vanaf 16 bytes).
- Deze string wordt gesplitst in drie delen van 7 bytes.
- Uit elk deel van 7 bytes worden DES-sleutels gecreëerd (de parity bits worden toegevoegd).
- Met deze sleutels wordt de server challenge versleuteld, wat resulteert in drie 8-byte versleutelde waarden.
- Deze drie versleutelde waarden worden samengevoegd tot een 24-byte NTLMv1-response.
- De server geeft een challenge met de waarde
0x1122334455667788
. -
Welkom01!
wordt0xa958a3e244a682c7be90850c7a4e69eb
. -
0xa958a3e244a682c7be90850c7a4e69eb
wordt0xa958a3e244a682c7be90850c7a4e69eb0000000000
-
0xa958a3e244a682c7be90850c7a4e69eb0000000000
wordt0xa958a3e244a682
,0xc7be90850c7a4e
en0x69eb0000000000
. -
0xa958a3e244a682
wordt0xA8AD297C25259B04
,0xc7be90850c7a4e
wordt0xC7DFA4105162E99D
,0x69eb0000000000
wordt0x68F4C10101010101
. - Bij een server challenge van
0x1122334455667788
wordt dit0xc8d035ab2a6bff25
,0x736d9a5749216e0a
en0x1179943b75b8f05b
. - Samengevoegd is dit het NTLMv1-response,
0xc8d035ab2a6bff25736d9a5749216e0a1179943b75b8f05b
.
NTLMv2 / Net-NTLMv2
Tot slot behandelen we het NTLMv2 protocol, wat ook onder de overkoepelende noemer NTLM valt. Dit protocol is een iteratie op het NTLMv1 protocol en heeft een aantal extra beveiligingsmechanismes toegevoegd. Er wordt gebruik gemaakt van HMAC-MD5 en naast de server challenge is er ook een client challenge (ook wel client nonce). In de authenticatie-uitwisseling verschilt de client nonce, de timestamp en de server challenge iedere authenticatie-uitwisseling. Hierdoor zijn ze allemaal uniek. Het herhalen van een oude NTLMv2-response is hierdoor niet mogelijk. NTLMv2 wordt van de bovenstaande genoemde protocollen als het meest veilig beschouwd, maar kent ook zijn gebreken. Moderne authenticatieprotocollen zoals Kerberos zijn een stuk veiliger.
Het hergebruiken van een NTLMv2-response is dus niet mogelijk, maar wat wel mogelijk is, is het onderscheppen van een authenticatieverzoek van een client en deze doorsturen naar een andere server. Vervolgens de server challenge terugsturen naar de client en tot slot het NTLMv2-response van de client doorsturen naar de server. Dit wordt een relay attack genoemd. In een andere blogpost zullen we hier dieper op in gaan.
NTLMv2 proces
De NT-hash wordt op dezelfde manier geconstrueerd als bij NTLMv1, daar is niets aan veranderd. De verandering zit hem in het proces omtrent het construeren van het NTLMv2-response.
- De client geeft aan te willen verbinden en de server stuurt een server challenge.
- De client zet het wachtwoord om in de NT-hash.
- De unicode gebruikersnaam in hoofdletters wordt omgezet naar hex.
- De unicode target wordt (hoofdlettergevoelig) omgezet naar hex.
- De hex-waardes van de gebruikersnaam en target worden samengevoegd.
- Deze samengevoegde string wordt versleuteld met het HMAC-MD5-algoritme, waarbij de NT-hash als sleutel wordt gebruikt. De 16-byte uitkomst is de NTLMv2-hash.
- Er wordt een blob met gegevens gemaakt, waarin verschillende dingen staan, zoals de timestamp, de client nonce, en de targetinformatie.
- De server challenge wordt samengevoegd met de zojuist gemaakte blob.
- Deze samengevoegde string wordt versleuteld met het HMAC-MD5-algoritme, waarbij de NTLMv2-hash (uit stap 6) als sleutel wordt gebruikt. Hieruit komt een 16-byte waarde.
- Deze 16-byte waarde wordt samengevoegd met de blob. Dit is het NTLMv2-response.
Blob
Dit kunnen we weer met een voorbeeld verduidelijken, maar eerst moeten we weten wat er precies in de genoemde blob moet komen te staan.
De blob met gegevens bestaat uit de volgende waardes:
Targetinformatie
De targetinformatie bestaat uit een domain name subblock (0x0200
), server name subblock (0x0100
), DNS domain name subblock (0x0400
), DNS server name subblock (0x0300
) en een Terminator subblock (0x00000000
). Na de specificatie van het subblock staat de lengte van de data. Vervolgens komt de data (met de zojuist opgegeven lengte).
Naam van subblock | Hex-waarde | Lengte in hex | Data | Data in hex (UTF-16LE) |
---|---|---|---|---|
Domain name subblock | 0x0200 |
0x1400 |
NETWORKIFY |
0x4e004500540057004f0052004b00490046005900 |
Server name subblock | 0x0100 |
0x0800 |
DC01 |
0x4400430030003100 |
DNS domain name subblock | 0x0400 |
0x2000 |
NETWORKIFY.local |
0x4e004500540057004f0052004b004900460059002e006c006f00630061006c00 |
DNS server name subblock | 0x0300 |
0x2a00 |
DC01.NETWORKIFY.local |
0x44004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c00 |
Terminator subblock | 0x0000 |
0x0000 |
Deze waardes worden achter elkaar geplakt, wat resulteert in de volgende targetinformatie: 0x020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c0000000000
.
Voorbeeld
Om het NTLMv2-response te berekenen hebben we nog wat meer informatie nodig, we gaan van het onderstaande uit.
- De server geeft een challenge met de waarde
0x1122334455667788
. -
Welkom01!
wordt0xa958a3e244a682c7be90850c7a4e69eb
. -
JAN
wordt0x4a0041004e00
. -
NETWORKIFY.local
wordt0x4e004500540057004f0052004b004900460059002e006c006f00630061006c00
. - Samengevoegd wordt dat
0x4a0041004e004e004500540057004f0052004b004900460059002e006c006f00630061006c00
. - Die string wordt gehasht middels HMAC-MD5, met de NT-hash als sleutel, dat wordt
0x2d231c43cbe51fc97bcb4de5e664633a
. - In de tabel is te zien hoe de blob wordt opgebouwd, de timestamp op het moment van schrijven is
133354454190000000
, in hex is dat0x01e4b1c23c09ec00
. De blob wordt dan0x010100000000000001e4b1c23c09ec00887766554433221100000000020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c000000000000000000
- De server challenge wordt samengevoegd met de blob, dat geeft
0x1122334455667788010100000000000001e4b1c23c09ec00887766554433221100000000020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c000000000000000000
- Deze samengevoegde string wordt versleuteld middels HMAC-MD5, met de NTLMv2-hash van stap 6 als sleutel. Dit geeft
0xd724cf06040dfdde5bae09dd32fa51d6
. - Deze waarde wordt samengevoegd met de blob, dit is het NTLMv2-response.
0xd724cf06040dfdde5bae09dd32fa51d6010100000000000001e4b1c23c09ec00887766554433221100000000020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c000000000000000000
Controleren / kraken
Hashen is altijd eenrichtingsverkeer. Om te controleren of we het NTLMv2-response juist hebben samengesteld moeten we de hash proberen te kraken. Het makkelijkst is om dit via Hashcat te doen.
Hashcat kan met ontzettend veel verschillende algortimes overweg. De mode die we nodig hebben voor NTLMv2 is mode 5600. Het benodigde formaat wijkt iets af van ons gemaakte NTLMv2-response, het ziet er zo uit:
username::domain:server_challenge:NTLMv2-hash:blob
Als we de waardes invullen wordt de Net-NTLMv2-hash dus als volgt:
Jan::NETWORKIFY.local:1122334455667788:d724cf06040dfdde5bae09dd32fa51d6:010100000000000001e4b1c23c09ec00887766554433221100000000020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c000000000000000000
Het plaintext wachtwoord is bekend, dus het opgeven van een woordenlijst is niet nodig. Met onderstaand commando wordt de hash gekraakt. De berekening van het NTLMv2-response is dus correct uitgevoerd.
./hashcat -m 5600 "Jan::NETWORKIFY.local:1122334455667788:d724cf06040dfdde5bae09dd32fa51d6:010100000000000001e4b1c23c09ec00887766554433221100000000020014004e004500540057004f0052004b00490046005900010008004400430030003100040020004e004500540057004f0052004b004900460059002e006c006f00630061006c0003002a0044004300300031002e004e004500540057004f0052004b004900460059002e006c006f00630061006c000000000000000000" -a 3 "Welkom01!"
LMv2
Naast NTLMv2 is er ook LMv2, ontwikkeld voor compatibiliteit met oude servers. Oudere servers sturen alleen het LM-response en verwachten dat de grootte hiervan exact 24 bytes is. LMv2 is eigenlijk een soort mini-implementatie van NTLMv2.
LMv2 proces
Er wordt gestart met een NT-hash en niet met een LM-hash. De NT-hash wordt op dezelfde manier geconstrueerd als bij NTLM.
- De client geeft aan te willen verbinden en de server stuurt een server challenge.
- De client zet het wachtwoord om in de NT-hash.
- De unicode gebruikersnaam in hoofdletters wordt omgezet naar hex.
- De unicode target wordt (hoofdlettergevoelig) omgezet naar hex.
- De hex-waardes van de gebruikersnaam en target worden samengevoegd.
- Deze samengevoegde string wordt versleuteld met het HMAC-MD5-algoritme, waarbij de NT-hash als sleutel wordt gebruikt. De 16-byte uitkomst is de NTLMv2-hash.
- De server challenge wordt samengevoegd met een random client nonce..
- Deze samengevoegde string wordt versleuteld met het HMAC-MD5-algoritme, waarbij de NTLMv2-hash (uit stap 6) als sleutel wordt gebruikt. Hieruit komt een 16-byte waarde.
- Deze 16-byte waarde wordt samengevoegd met de client nonce. Dit is het LMv2-response.
Hoe kunnen wij u helpen?
QR Codes: Het onverwachte wapen in Device Code Phishing
Device code phishing, net als aanvallen via Adversary-in-the-middle (AiTM), vertegenwoordigt een geavanceerde vorm van cyberdreiging die zich onderscheidt van traditionele phishing. Device code phishing exploiteert de ‘OAuth2 Device Authorization Grant flow‘ van Microsoft Azure, die gebruikers in staat stelt zich aan te melden bij apparaten met beperkte invoermogelijkheden.
Cross-Site Scripting (XSS): wat is het en hoe te voorkomen
In deze blogpost lees je alles over Cross-Site Scripting (XSS). Welke vormen van XSS er zijn. Wat de impact van een XSS-aanval kan zijn en hoe je het kan voorkomen.
CORS: het belang van Cross-Origin Resource Sharing
Bij onze klanten zien we een toenemende implementatie van Cross-Origin Resource Sharing (CORS). Helaas constateren we ook een stijging in het aantal onveilig geconfigureerde CORS-implementaties. In deze blog duiken we dieper in wat CORS is, de meest voorkomende misconfiguraties en hun potentiële risico’s, en hoe je sterke CORS-regels kunt instellen om je webapplicaties te beschermen.