seeseekey.net - Invictus Deus Ex Machina

Unter .NET gibt es an jedem Objekt die Methode „GetHash­Code“ wel­che einen Hash­Code zurück­lie­fert. Das Pro­blem an die­ser Methode ist jedoch das sie vom Objekt selbst imple­men­tiert wer­den muss. Möchte man nun eine Methode mit der man jedes Objekt gene­risch has­hen kann, so ist diese Funk­tion hilfreich:

public string GetSHA1HashFromObject(object obj)
{
	SHA1CryptoServiceProvider sha1Provider=new SHA1CryptoServiceProvider();
	DataContractSerializer serializer=new DataContractSerializer(obj.GetType());

	using(MemoryStream memoryStream=new MemoryStream())
	{
		serializer.WriteObject(memoryStream, obj);
		sha1Provider.ComputeHash(memoryStream.ToArray());
		return Convert.ToBase64String(sha1Provider.Hash);
	}
}

Die Funk­tion seria­li­siert dabei das Objekt und hasht anschlie­ßend das seria­li­sierte Objekt. Damit ist es egal, wel­ches Objekt in die Funk­tion gege­ben wird.

Möchte man die lokale Revi­sion eines Git Repo­si­to­ries ermit­teln so reicht es in der Konsole:

git log -n 1

ein­zu­ge­ben. Das ganze sieht auf dem Ter­mi­nal dann so aus:

commit 1c40074d28676ec996ec91f1719cff43077f15f6
Author: Example 
Date:   Tue Jan 3 09:52:23 2013 +0800

    Bugfixes in example function.

Soll nur der Hash aus­ge­ben wer­den so muss die Kom­man­do­zeile wie folgt aussehen:

git log -n 1 --pretty=format:"%H"

Damit bekommt man dann nur den ent­spre­chen­den Hashwert ausgegeben.

In den letz­ten Tagen kur­sier­ten die Pass­wort­hashs der Com­mu­nities Last.fm, eHar­mony und Lin­ke­dIn durch das Netz. Bei Last.fm waren dies unge­sal­zene MD5 Hashs die man per Brute Force in rela­tiv kur­zer Zeit zurück­rech­nen kann.

Das Pro­blem ist das sobald man dies „zurück­rech­nen“ kann, kann man die Pass­wör­ter bei ande­ren Diens­ten (Mail, Ama­zon, usw.) aus­pro­bie­ren und damit Schind­lu­der trei­ben. In einer per­fek­ten Welt würde zwar jeder für jeden Dienst ein extra Pass­wort benut­zen, aber es ist nun mal keine per­fekte Welt.

Noch pro­ble­ma­ti­scher wird das ganze wenn man die Pass­wör­ter im Klar­text (siehe Update) spei­chert (was man defi­ni­tiv nicht tun sollte). So gibt es im Nor­den Deutsch­lands eine erfolg­rei­che Com­mu­nity mit knapp 140000 Mit­glie­dern wel­che auf den Namen NB-Town hört und unter www.nb-town.de zu fin­den ist.

Das Pro­blem offen­bart sich sobald man ein­mal die „Pass­wort ver­ges­sen?“ Funk­tio­na­li­tät benutzt. Dar­auf­hin bekommt man fol­gende Mail:

Die Pass­wort ver­ges­sen? Mail

Wie man sieht wird das Pass­wort im Klar­text gespei­chert (sonst könnte es die „Pass­wort ver­ges­sen?“ Funk­tio­na­li­tät nicht zurück­sen­den), was bei einer sol­chen Com­mu­nity fahr­läs­sig ist. Sobald jemand an die Daten­bank her­an­kom­men so hat er 140000 Pass­wör­ter + die pas­sen­den Iden­ti­tä­ten dazu. Ein ande­res Pro­blem bei Pass­wör­tern wel­che im Klar­text gespei­chert wer­den, ist immer das die Betrei­ber Zugriff auf diese haben und damit (theo­re­tisch) Schind­lu­der betrei­ben können.

Des­halb gilt, Pass­wör­ter immer gehasht (aber nicht mit MD5 ;)) und gesal­zen spei­chern. Einene schö­nen Arti­kel dazu gibt es bei Heise unter http://www.heise.de/security/artikel/Passwoerter-unknackbar-speichern-1253931.html.

Update:
Die Pass­wör­ter wer­den in der Daten­bank nicht im Klar­text gespei­chert, son­dern AES ver­schlüs­selt. Bei der „Pass­wort ver­ges­sen?“ Funk­tion wird der Schlüs­sel in der Query über­ge­ben, so das das Pass­wort ent­schlüs­selt wer­den kann. Man müsste als böser Mensch also an den Web­ser­ver und den Daten­bank­ser­ver her­an­kom­men und um Zugriff auf die Pass­wör­ter zu bekommen.