Free the Peter Lustig [gelöst]

Ich habe mich auch mal an ein Crackme gemacht. Dabei habe ich mich ein wenig von Free the ELF inspirieren lassen.
Es ist eine Mischung aus Programmieraufgabe und Crackme.
Der erste Teil (Programmieraufgabe) sollte sich mit jeder Betriebssystem/Programiiersprache Kombination lösen lassen. Da die Lösung des erste Teils eine ELF-Datei ist, empfiehlt sich (sofern ihr nicht zu "Ich-brauche-keinen-Debugger-und-löse-Crackmes-nur-durch-Disassembler-Dump-lesen-Leuten" gehört) das Ganze mit Linux anzugehen. (Nicht das die Windows Nutzer am Ende ganz geschockt vor einer ELF sitzen und nicht wissen was sie damit anfangen sollen)

Ich denke die Programmieraufgabe sollte sich von jedem der ein wenig Programmiererfahrung hat, (und ?Underground-Crackseiten? wie z.B. http://www.google.de kennt ;) ) lösen lassen. Das Crackme erfordet (wie jedes Crackme) einige Assemblerkenntnisse, und natürlich logisches Denken.
Sollten irgendwelche Fragen/Probleme auftauchen, könnt ihr sie hier posten.

mfg, loose
 
Was sind die Regeln für das Crackme?
Patchen wird wohl nicht erlaubt sein? (Ich hab zumindets nen keygen gemacht)
Und was willst du als Lösung haben?

War recht interessant das ganze rumgepacke und -codiere.
Das Crackme an sich hat einen einfachen Algo, der aber trickreich verpackt ist.
Um mal nen Key zu nennen "(;" (also ohne die anführungszeichen)
 
Wow, hätte ja nicht gedacht, das mir jemand so schnell ne Lösung präsentiert (6h 13min nach meinem Post), andere Crackmes liegen ja oft Monate brach...
Daher: 100 Gummipunkte und ein grüner Leuchtkeks für lagalopex!
Patchen ist bei dieser Art von Crackme erfordert bei dieser Art Crackme natürlich so gut wie keine Denkleistung, daher habe ich es für selbstverständlich gehaöten, dass Patchen keine Lösung ist...

Und was willst du als Lösung haben?
Natürlich ein gültiges PW, bzw Keygen.

Freut mich auf jeden Fall, dass es dir gefallen hat.

mfg, loose
 
Original von loose
Daher: 100 Gummipunkte und ein grüner Leuchtkeks für lagalopex!
:]

Dann liefer ich mal den keygen nach ;)
Erstmal ist aufgefallen, dass das Bild viel größer ist als es sein müsste. Also erstmal die "überflüssigen" Bytes am Ende der Datei in eine neue Datei geschrieben. Die Daten sehen noch recht zufällig aus und es fällt auf, dass es gerade 52 byte kleiner ist als das bereinigte erste Bild. 52 Bytes sind BMP-Header und Infos. Also den Header davor und Bild angeguckt... da ist ja der Peter ;)
Jetzt sind in den Datenbytes jeweils das letzte bit von interesse, es ist eine 32bit Zahl (= die Größe) sowie die eigentliche ELF-Datei, das Programm zum extrahieren dürfte nicht das Problem sein :)

Das Crackme ist dann relativ einfach (bis auf einen Punkt, dazu später). Es wird ein String eingelesen und dann Zeichen für Zeichen betrachtet.
Erstmal wird das Zeichen mit 0xcf maskiert (also bit 5 und 4 gelöscht), dann wird, sofern das Ergebnis größer als das vorherige oder gleich null ist folgendes berechnet:
endergebnis += f(ergebnis)*indexInSerial+ergebnis
Das Endergebnis muss am Ende 20 sein.
Die Funktion f wiederum wendet xor auf einen Speicherbereich an, führt ihn danach aus und führt das xor nochmal aus. Es wird also Programmcode entschlüsselt, ausgeführt und wieder verschlüsselt.
Also gdb angeschmissen, breakpoint kurz vor dem call gesetzt und dann den entschlüsselten Bereich angezeigt, in Assembler. Mit etwas Übung sieht man recht schnell, dass es nichts weiter macht als zu prüfen, ob das Argument eine Primzahl ist.

Achtung, es werden MB-weise Keys generiert. Ob sie alle stimmen, weiß ich nicht, aber stichprobenweise haben sie funktioniert.
Code:
#include <stdio.h>

int isprime(int x)
{
	int i;
	if (x <= 1)
		return 0;
	if (x == 2)
		return 1;
	for (i = 2; i * i <= x; ++i)
		if (x % i == 0)
			return 0;
	return 1;
}

int calc_num(const char *c)
{
	int i, t, o = 0, s = 0;
	for (i = 0; c[i]; ++i) {
		t = c[i]&0xcf;
		if (t > o || t == 0) {
			o = t;
			s += isprime(t)*i+t;
		}
	}
	return s;
}

void inc(char *s)
{
	if (s[0] == 0x3f) {
		s[0] = ' ';
		inc(s+1);
	} if (s[0] == 0) {
		s[0] = ' ';
		s[1] = 0;
	} else
		s[0]++;
}

int main(int argc, char *argv[])
{
	char serial[100] = " ";
	for (;;) {
		if (calc_num(serial) == 20)
			printf("\"%s\"\n", serial);
		inc(serial);
	}
	return 1;
}
 
Zurück
Oben