Grüße!
Bevor ich zum eigentlichen Problem komme zuerst die Ausgangslage in Sachen Software:
- OS: Microsoft Windows 2000
- FTP Server: Serv-U 6 FTP Server
- Webserver: Apache 2.2.4 Win32
- Credentials für die Tests: User=testuser, PWD=testuser.
- PWD Verschlüsselungen: Angeblich bei FTP- und Webserver MD5.
Das sollte auch schon alles wichtige sein. Nun zum Problem...
WAS soll eigentlich getan werden? Nun, am Webserver soll eine Seite geschützt werden, die FTP Statistiken zeigt. Nicht weiter schwer, ließe sich per htpasswd/.htaccess machen. Nur sollen die User vom FTP auch zum Webserver portiert werden, ohne die Klartextpasswörter zu kennen, damit sich FTP User mit bestehenden Credentials am Webserver einloggen können. Das geht nur mittels gleicher Hashalgorithmen. Die scheinen sich aber sowohl in ihrer Verschlüsselung, als auch Repräsentation (Encoding) zu unterscheiden. Zuerst zum FTP:
Der Serv-U 6 FTP Server hat bei mir ca. 30 User, und bis auf die Passwörter ist alles im Configfile als Klartext abgelegt. Die Passwörter, also das eigentlich interessante ist MD5 hashed.
Die Hashes sind mit 2-Byte Salts versehen. Im Configfile des FTP Servers sieht die entsprechende Zeile z.B. so aus:
Password=qi481F86E841C9D742BA6CC4261CF8EACF"qi" ist also der Salt, der Rest der MD5 Hash, der aus Salt+PWD generiert wurde, also in unserem Falle aus "qitestuser". Daß der Hash wirklich Standard MD5 ist, läßt sich mittels des Tools mdcrack verifizieren. Wenn man selbiges mit stark limitiertem Alphabet auf den Hash losläßt, ist er innerhalb weniger Sekunden zu cracken. Der Salt muß natürlich als Prefix für den Challenge mit übergeben werden. Die Verifikation erfolgte so:
mdcrack-12.exe -s testuser -v -b qi -M MD5 481F86E841C9D742BA6CC4261CF8EACF"-s" spezifiziert das Alphabet, "-b" den Salt als Prefix für die Challenge. Cracked nach nur 11 Sekunden auf C2D 3.16GHz mit reduziertem Alphabet.Gut, nun wußte ich, Serv-U 6 setzt ganz normale salted MD5 Hashes ein. Soviel also zum FTP Server, hier liegt der Fall klar. Nun aber zum Apachen...
Wenn man am Apachen ebenfalls einen User "testuser" mit PWD "testuser" anlegt (mit default PWD encryption, bei Win32 laut htpasswd.exe "MD5"), sieht die entsprechende Zeile im htpasswd File (oder wie man sein Userfile halt nennen möchte) so aus:
testuser:$apr1$oo1.....$7Qr1pbvQE4uKH8gpveF.h/Nach kurzer Google-Befragung wurde die Syntax einigermaßen klar, sieht so aus:
<username>:$apr1$<salt>$<md5 password hash>Nun ist das ein MD5 Hash, wie ich ihn noch nie zuvor gesehen habe. Ein Kollege informierte mich dann, daß es verschiedene, gängige Codierungen/Repräsentationen für MD5 Hashes gibt. Eine davon ist hexadezimal, wie z.B. vom Serv-U FTP Server verwendet. Es gibt aber noch weitere, wie z.B. 8-Bit ASCII, binär, 6-Bit base64, 5-Bit base32 usw.
Base64 wäre noch ok gewesen, aber scheinbar verwendet Apache nicht das [
standard base64 Alphabet] um den Hash darzustellen, sondern ein 6-Bit custom Alphabet, auch wenn ich nicht begreife, wieso?!
Auszug aus htpasswd.c (Apache 2.2.4 Win32 Sourcecode):
static void to64(char *s, unsigned long v, int n)
{
static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
}
}
Das base64 Alphabet würde "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ =" lauten, dies ist mit dem 6-Bit Alphabet des Apache htpasswd Tools wie man sieht nicht identisch. Warum ein custom Encoding gewählt wurde, verschließt sich mir völlig. Wieso nicht das bestehende Standard base64, für das es fertige Converter zu ASCII oder HEX gibt?! Ich weiß es nicht. Aber das war nicht das einzige Problem...
Hier ein Auszug aus der Apache Dokumentation, der mich erst recht aus allen Wolken fallen ließ:
MD5
"$apr1$" + the result of an Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random 32-bit salt and the password. See the APR source file apr_md5.c for the details of the algorithm.
Der Salt in jedem der 1000 Hashschritte ist Random 32-Bit steht hier. Meiner Meinung nach ist der Salt aber 8-32 Bit, also auch in Länge variabel (man siehe ein htpasswd Ergebnis mit unterschiedlichen PWDs)!
Ich habe mir den Qellcode der apr_md5.c natürlich angesehen, aber das ist mir einfach zu hoch, da ich kein C beherrsche, und das nur sehr begrenzt verstehen kann, habe auch von Kryptographie null Ahnung. Aber der Zeichensatz (das bestätigt sich durch 6-Bit Rightshifts in apr_md5.c würde ich meinen) ist wohl definitiv besagter custom base64, da eben auch die Funktion "to64(char *s, unsigned long v, int n)" eingesetzt wird.
Nun die Primefrage an alle, die den Quellcode verstehen (ist als ZIP angehängt, htpasswd.c und apr_md5.c): Wie kann ich Standard MD5 Hashes so portieren, daß daraus von Apache lesbare MD5 Hashes werden (sprich: Reproduktion des Apache Hashalgos, ohne alle PWDs vorher zu Plaintext cracken zu müssen)?
Ist es überhaupt möglich, den Standardhash von Serv-U zu so einem Customhash zu machen? Das Encoding im custom base64 Alphabet ist wohl noch das geringere Problem, aber ich verstehe diese 1000 MD5-Runs mit Random Salts leider nicht ausreichend.
Ein cracken oder erfragen aller FTP Userpasswörter wäre zu mühsam oder im Crackfall schlichtweg gröber bedenklich.
Vielen Dank für eure Hilfe!
Anhänge (Apache Sourcecode):
htpasswd.c als ZIPapr_md5.c als ZIPDieser Fall wurde auch bei [
DevShed] gepostet.