Hallo,
beim lesen von diesem Thread kam mir die Idee ein HackMe zu schreiben.
Mission zu HackMe.exe (Mission Impossible Musik im Hintergrund)
1.) Durch die Passwortkontrolle kommen.
2.) Im Code der den geheimen Text ausgibt, wird eine Variable deklariert welche
wichtige Informationen enthält. Besorgen Sie sich den Inhalt dieser Variable.*Regeln**
+Jeder Weg der zum Ziel führt ist erlaubt. Sei kreativ!
*Hinweise*
+Bei eingabe des richtigen Passworts gibt das Programm eine Meldung auf der Konsole
aus und schließt sich sofort wieder.
+Bei falschem Passwort schließt sich dass Programm sofort wieder.
+Bruteforce ist zum lösen der Aufgabe nicht erforderlich.Viel Erfolg!
Gruss
tscherno
PS: Wer es schafft soll die Lösung und seine Vorgehensweise bitte hier posten!
HackMe if you can - wäre doch ein cooler Titel 🙂
Lg XXX
Hallo,
hab die Lösung: (ROT13 verschlüsselt um keinen Spoiler zu erstellen)
1.) Vz Ersyrpgbe qrpbzcvyvrera
2.) Fbhepr nacnffra hz Pbzcvyrsäuvt mh znpura
3.) Qra Purpx nhfonhra bo qre ibz Cnffjbeg orerpuargr Unfu zvg qrz üorervafgvzzg qre vz Pbqr Uneqtrpbqrg vfg. -> Nffrzoyl xnaa trynqra jreqra
4.) Zvg Zbab.prpvy qvr Nffrzoyl va rva Svyr qhzcra
5.) Zvg qrz Ersyrpgbe qvr Nffrzoyl nanylfvrera => Trurvzre fgevat = "JJJ.ZLPFUNEC.QR"
Grüsse,
Egon
/edit: ROT13 Dekoder: http://www.retards.org/projects/rot13/
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Da die Lösung ja schon vorliegt.... sag mal was zu deinen Protection Settings (Reactor nehme ich an). Vor allem: Library oder Application Mode und NecroBit.
MfG gurgell
Hallo,
für mich hat das Ding nicht Obfuscated ausgesehen. Ich nehme mal an, dass gar keiner drübergelassen wurde.
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo egrath,
saubere Arbeit, jetzt kannst du ja mal eins schreiben. =)
Hallo gurgell,
egrath hat recht, dass ding ist nicht Obfuscated, ich habe nur komische Variablennamen verwendet.
Gruss
tscherno
Achso, es war also praktisch komplett ungeschützt (also die reine .net Assembly)?
MfG gurgell
Hallo,
ich find die Idee echt nicht schlecht solche kleinen Aufgaben zu erstellen -> Werd mich mal dransetzen und versuchen was zu basteln 😉
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Ach Mensch, jetzt wollte ich mich gerade dran machen, habe dann aber in gurgells Beitrag gelesen, dass es obfuscated sei (was ja nicht stimmt). Hab es deswegen gelassen weil ich dachte, bei obfuscated kann ich nichts machen, und mir gleich die Lösung angeschaut.. naja dann halt beim nächsten mal 😁
Hi alpi,
ich habe nicht gesagt, dass es Obfuscated ist. In Wahrheit habe ich es mir nichtmal angesehen.
Da es im verlinkten Thread um .net Reactor ging war ich davon ausgegangen, dass die Assembly eben damit geschützt wurde und wollte bloß ein paar Details der Protection-Settings erfahren.
Obfuscation ist übrigens != nicht zu knacken. Hier kommt es ganz stark auf die Art der Obfuscation an und grundsätzlich reicht Obfuscation allein nicht aus um ein .net Programm ausreichend zu schützen.
Hier eine etwas ältere aber gute Einführung in die Materie:
http://www.howtoselectguides.com/dotnet/obfuscators/
Edit: Was ich noch sagen wollte: Ohne irgend eine Art von Obfuscation, VMs etc. lassen sich .net Assemblies kaum schützen. Natürlich kann man bspw. eine sichere Shareware-Freischaltung mit Hilfe von asymmetrischen Verfahren konstruieren. In einem solchen Fall würde ein Cracker dann aber eben einfach die ungeschützte Assembly zu seinen gunsten Patchen. Und dank MSIL ist dies wesentlich einfacher als in nativem Code.
MfG gurgell
Hallo,
so jungs hier mal ne aufgabe zum reinbeissen: Ziel ist es den Inhalt einer Variable im Programm zu bestimmen (den Int32 mit dem Variablennamen "geheim" - ist eh die einzige lokal deklarierte Variable).
Viel vergnügen.
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo egrath,
ich bekomme eine "InvalidProgramException" 0_o ? Hast du dass etwa in IL geschriebe ? 😜
Gruss
tscherno
Hallo tscherno,
also ausführen lässt es sich bei mir (Nur mit der .NET Runtime, Mono nicht) . Aber du gehst recht in der annahme dass es in IL geschrieben ist.
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Selbiges hier, schmiert nach dem starten leider ab 🙁
ich verwende auch die .NET Runtime. Möglicherweise ist die .zip korrupt?
Gruss
tscherno
Habe es nicht ausgeführt, tippe aber auch auf korruptes Archiv oder ist es beabsichtigt, dass die exe 8,8 Mb groß ist und fast keine Daten enthält?
Hallo,
sorry, ich habe einen Befehl vergessen beim Code, drum schmierte er ab (Interessanterweise nur bei 32-Bit VM's, die 64 Bit CLR hat den Code gefressen)
ZIP File im originalen Post wurde aktualisiert.
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo zusammen,
es wurde relativ ruhig um diesen Thread 😁
Entweder liegt es an der Tageszeit oder daran, dass bis jetzt alle an dem von Egarth geposteten Test gescheitert sind. 👅
PS: Auch ich bin daran gescheitert, ich habe zwar so ein paar Kleinigkeiten herausgefunden. Habe aber keine Lösung zu deinem Problem gefunden.
Morgen wenn die ganzen Profis wieder aktiv sind, dann wird das bestimmmt einer lösen können. 🙂
mfg
michlG
Hallo,
nein die Assembly ist:* Nicht signiert
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hi!
Ich tippe auf die 7. 😉
Mfg NeuroCoder
Hallo,
der Kandidat erhält 100 Punkte.
Hier die auflösung:* Das ganze ist in IL geschrieben
Für die interessierten anbei der Source.
Grüsse,
Egon
/edit: So NeuroCoder, du bist an der Reihe was zu basteln 🙂
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Oh mein Gott, und ich habe versucht ein Programm zu schreiben welches den IL-Code aus dem MethodBody herauskopiert, die NOPs entfernt und dann per AssemblyBuilder ein neues Assembly erzeugt. Mir ist es aber nicht gelungen den EntryPoint richtig zu setzen.
Naja, dafür habe ich sehr viel über AssemblyBuilder gelernt 😁
ldc.i4.7 <- ist dass die Zeile?
Gute Nacht
tscherno
Es gibt noch ne andere Lösung das rauszufinden, wobei aber zu gute kommt dass du sonst nicht viel machst. Einfach dein Programm mit dem Debugger ausführen und anhalten. Dann einfach Diassembly anschauen vom unmanaged Code der durch den Jitter erzeugt wird(sind ja nur nen paar Zeilen da der die ganzen Nops rauswirft) und da ist nur eine Zeile bei wo eine Konstante geladen wird -> das muss also die gesuchte Zahl sein.
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 xor eax,eax
00000006 mov dword ptr [ebp-4],eax
00000009 mov dword ptr [ebp-4],7
00000010 jmp 00000038
00000012 jmp 00000038
00000014 jmp 00000038
00000016 jmp 00000038
00000018 jmp 00000038
0000001a jmp 00000038
0000001c jmp 00000038
0000001e jmp 00000038
00000020 jmp 00000038
00000022 jmp 00000038
00000024 jmp 00000038
00000026 jmp 00000038
00000028 jmp 00000038
0000002a jmp 00000038
0000002c jmp 00000038
0000002e jmp 00000038
00000030 jmp 00000038
00000032 jmp 00000038
00000034 jmp 00000038
00000036 jmp 00000038
00000038 mov ecx,dword ptr ds:[02D1303Ch]
0000003e call 77CF9CE4
00000043 mov esp,ebp
00000045 pop ebp
00000046 ret
6.Zeile
Wie gesagt, es kommt entgegen dass du sonst nicht viel machst 🙂 Bei mehreren Zuweisungen wäre es schon nicht mehr möglich gewesen genau zu sagen welche jetzt die gesuchte ist.
Baka wa shinanakya naoranai.
Mein XING Profil.
Hi!
So, ich habe mal was gebastelt.
Als Eingabe wird eine positive, ganze Zahl (0 ist auch möglich) verlangt.
Bei korrekter Zahl wird die zu ermittelnde Zielzahl mit einer "besonderen Formatierung" ausgegeben.
Bitte komplette Ausgabe, Eingabezahl und den Lösungsweg posten. 🙂
Viel Spaß und viel Erfolg!
NeuroCoder
Hallo zusammen,
wenn die "besondere Formatierung" eine gesuchte Zahl in eckigen Klammern sein soll, dann ist die gesuchte Zahl die 23. Der dazu eingegebene Offset ist die 13. (siehe angehängtes Bild)
Zur Lösung:
Ich bin pragmatisch herangegangen:
static void Main(string[] args)
{
VM vm = new VM();
//Console.WriteLine("HackMe");
//Console.Write("Enter Offset: ");
//int offset = int.Parse(Console.ReadLine());
Console.WriteLine("=== BEGIN ===");
//vm.Execute(offset);
//Console.WriteLine("\n=== END ===");
for (int i = 0; i < 30; i++)
{
try
{
Console.Write("Versuch " + i + " ");
vm.Execute(i);
}
catch
{
Console.WriteLine();
continue;
}
Console.WriteLine();
Console.WriteLine("Erfolgreich: " + i);
break;
}
Console.ReadLine();
}
Worauf ich ziemlich schnell dann zum Ergebnis gekommen bin. So hab ich mir das "mühselige" Analysieren, was diese oder die andere hexadezimale Anweisung genau macht und bin auch das mühselige "Rotate" umgangen.
Vielleicht nicht das gewünschte Verfahren zum Knacken, aber ein effizientes 😉
Ich schau mal, ob ich auch so etwas zeitnah basteln kann.
Viele Grüße
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
Hallo nochmal,
falls das oben genannte wirklich die Lösung war, dann hab ich hier noch etwas:
Habe ein Programm angehängt, das zu modifizieren ist. Es gibt im .NET Programm eine boolsche Variable "cracked", die konstant auf "false" steht. Wer es schafft mein Programm so zu modifizieren, dass die Variable konstant auf "true" steht, der hat die Aufgabe erfüllt.
Zu sehen ist es daran, dass bei der Ausführung des Programms je nach dem, wie die boolsche Variable gesetzt ist ein anderer Text in der Konsole erscheint.
Ich hab mir hier etwas mühe gegeben, ist aber für Hacker relativ leicht zu cracken.
Viel Glück dabei,
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
Hallo norman_timo,
Deine Lösung stimmt! 🙂
Ich hatte mir schon gedacht, dass Bruteforce die leichteste Methode sein würde (bei so wenig Möglichkeiten).
Bei der Konstruktion hab ich mich ein bißchen an Malbolge orientiert ( http://de.wikipedia.org/wiki/Malbolge ). Daher die mit der Laufzeit rotierenden OpCodes.
Mfg NeuroCoder
output:
"Du hast es geschafft, herzlichen Glückwunsch!"
weg:
es ist gekapselt von einem vb6 programm.
diese exe enthält die eigendliche .net exe und extrahiert sie in documente und einst...<username>\local...\temp und ruft dann die .net exe auf.
diese habe ich mir geschnappt und mit ildasm angeschaut und den ilcode extrahiert. dann habe ich eine kleine änderung vorgenommen, anschließend wieder mit ilasm zusammengesetzt.
Hallo,
während ich mir grad die nächste Schweinerei überlegt bin ich auf was nettes gestossen:* mscoree.tlb referenzieren
using System;
using System.Runtime.InteropServices;
namespace egrath.test.hackme
{
public class HackMe
{
public static void Main( string[] args )
{
// Proceed only if we are not running inside the Debugger
if( IsDebuggerAttached() )
return;
Console.Out.WriteLine( "Hier" );
}
private static bool IsDebuggerAttached()
{
int attached = 0;
new mscoree.CorRuntimeHostClass().IsDebuggerAttached( out attached );
return attached == 0 ? false : true;
}
}
}
... und schon lässt sich das Programm nicht mehr debuggen 😉
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo,
genau das mein ich - beim starten der Applikation und bei anderen häufigen Aktionen wird gecheckt ob ein Debugger dran ist. Ist dem so, beendet sich die Applikation ohne eine Meldung.
Ist zwar nicht grade massiver Stopper, aber ärgern kann er jemanden trotzdem.
Grüsse,
Egon
egrath's Blog: http://egonrath.eg.funpic.de/wordpress
Hallo zusammen,
ja ich hab hier einen vb6 Launcher gebastelt. Ich hab das Programm a) wegen der Einfachheit halber in eine temporäre Datei geschrieben, und b) weil ich es ja nicht zu kompliziert machen wollte 😉)
dann habe ich eine kleine änderung vorgenommen, anschließend wieder mit ilasm zusammengesetzt.
Hast Du das auch in der Originalexe abändern können (Hexcode)? Oder hast Du nur die temporäre Datei verändert um an den Ergebnisstring zu kommen?
Wenn in der Original-Exe, dann kannst Du ja noch dazu angeben welche Hex-Stelle hier wie verändert wurde. (Auch mal interessant, von Hex-Maschinencode zu IL-Code und dann zur Ausführung 😉 -> Hacking eben.
Grüße und Gratulation
Norman-Timo
A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”
Hallo,
während ich mir grad die nächste Schweinerei überlegt bin ich auf was nettes gestossen:
mscoree.tlb referenzieren
using System; using System.Runtime.InteropServices; namespace egrath.test.hackme { public class HackMe { public static void Main( string[] args ) { // Proceed only if we are not running inside the Debugger if( IsDebuggerAttached() ) return; Console.Out.WriteLine( "Hier" ); } private static bool IsDebuggerAttached() { int attached = 0; new mscoree.CorRuntimeHostClass().IsDebuggerAttached( out attached ); return attached == 0 ? false : true; } } }
... und schon lässt sich das Programm nicht mehr debuggen 😉
Grüsse,
Egon
Das kann man bestimmt umgehen (wenn man OllyDbg verwendet kann man es zumindest vor IsDebuggerPresent aus der Windows API verstecken)
Hallo JAck30lena
bis man auf die idee kommt, das jemand tatsächlich so einen hunbug in seine anwendung reinbringt, kann es sein , das die meisten daran schon scheitern bzw aufgeben.
Wir sollten im Auge bahlten vor wem wir unsere Anwendung schützen müssen. Ganz sicher nicht vor dem Anwender (welcher Anwender debuggt schon seine Applications?) und auch nicht unbedingt vor skrippt kiddies.
Wir sollten aber nicht davon ausgehen, dass IsDebuggerAttached irgend eine Hürde für einen Cracker darstellen kann. Der Aufruf geht auf eine Systemfunktion aus WinNT Zeiten zurück und ist wohl bekannt. Viele kommerzielle Protektoren (besonders für nativen Code) bringen solch eine Erkennung von Hause aus mit wobei man annehmen darf, dass ihre Methoden schon die zuverlässigsten von den möglichen sind. Gebracht hat's wohl eher wenig.
MfG gurgell
es geht wohl eher darum den anwender bzw den programmierer erstmal eine hürde hinzuwerfen. bis man auf die idee kommt, das jemand tatsächlich so einen hunbug in seine anwendung reinbringt, kann es sein , das die meisten daran schon scheitern bzw aufgeben.
Ist natürlich eine (kleine) Hürde, obwohl ich natürlich gurgell recht geben muss, einen Cracker kann man so natürlich noch lange nicht vom debuggen abhalten 😁
@gurgell
Ich glaube hier geht es auch eher um den Spaß selbst einen kleinen Schutz zu schreiben, auch wenn der natürlich nicht vergleichbar ist mit mächtigen Packern, die z.B. Code-morphing nutzen.
Du bist wohl auch als Programmierer eher interessiert an den Interner als ein durschnittlicher Anwender 😉
servus,
abgesehen davon das es glaub ich ein sehr interessanten thema ist grade für mich als relativer neuling ^^ aber mich würde viel mehr interessieren objemand schon für das letzte programm schon eine lösung hat oder ansätze weil man ja mim reflector da nicht weit kommt 😁
bin da schon ziemlich gespannt drauf denn dann weiß auch ich als anfänger wie man seine programme möglicherweise schützen kann wenn ich irgendwann mal ein interessanten programm schreib hehe
private int Main()
{
string programmingSkills = getMySkills("programming")
return = 1;
}
So jetzt hab ich die nächste Gemeinheit fertig. Wenn ihr es geschafft habt, erscheint ein netter Text. (Nein, es ist wirklich ein TEXT!) .
Erlaubt ist alles.
Tipps: vor ausführen kopieren; Reflector o.ä.; Es wird wenn ihr alles richtig macht und das richtige Passwort eingebt eine weitere Datei erstellt;
[EDIT] Sorry für den Fehler. Hoffe keine Weiteren vorhanden. Es ist jetzt korrigiert.
[edit=Jack30lena]Anhang entfernt weil mein Virenscanner darauf andauernd angesprungen ist[/edit]
hmmm bin vllt jetzt theoretisch nicht der schnellst gewesen 😁 aber habs hinbekommen nur fehlt mir der text ^^.... er erstellt mir zwar eine datei aber einen text bekomm ich nicht ausgegeben oO
naja gemacht hab ich es so....
ist mit sicherheit nicht die schönste variante aber irgendwie hast ja geklappt und für meinen skill hast gereicht ^^
public static void Main()
{
try
{
string location = Assembly.GetExecutingAssembly().Location;
string tempFileName = Path.GetTempFileName();
Console.WriteLine("Passwort?");
File.Delete(tempFileName);
File.Move(location, tempFileName);
FileStream self = new FileStream(tempFileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None);
byte[] buffer = new byte[0x7fff8];
self.Read(buffer, 0, buffer.Length);
FileStream stream2 = new FileStream(location, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
stream2.SetLength(0L);
stream2.Write(buffer, 0, buffer.Length);
string eingabe = Console.ReadLine();
if (eingabe.Length <= 10)
{
ulong key = Base64(eingabe);
ulong num2 = 0L;
ulong num3 = 0L;
// Hier hab ich das Bool eingefügt. Wollte den Teil nicht auskommentieren
Boolean codieren = false;
if (codieren == true)
{
for (int i = 0; (key != num2) && (num3 != 12528034086997679287L); i++)
{
if (i > 0xf4240)
{
return;
}
ulong num5 = 1L;
while (num5 != 0L)
{
if ((key & num5) != (num2 & num5))
{
num3 ^= num5;
break;
}
num5 = num5 << 1;
}
num2 = 0L;
if ((num3 & 9223372036854775808L) != (num3 & ((ulong)1L)))
{
num2 += (ulong)1L;
}
for (num5 = 2L; num5 != 0L; num5 = num5 << 1)
{
if ((((num5 >> 1) & num3) == 0L) == (0L == (num5 & num3)))
{
num2 += num5;
}
}
}
}
EntschlüsseleUndExtrahiere(key, self);
}
}
catch
{
}
}
Gruß
private int Main()
{
string programmingSkills = getMySkills("programming")
return = 1;
}
Hi
- 1 eingabe und die hackMe 0.5.exe war da
Ich weiss nicht wieso, aber ich bekomme dieses File auch. Ohne dass ich irgendetwas geändert hätte. Ich kann auch eingeben was ich will. Diese Datei wird immer erstellt. Aber Text bekomme ich auch keinen.
Deshalb behaupte ich mal, dass das Entfernen der For-Schleife nicht der Grund dafür ist. Denn floste hat es sicher absichtlich so gemacht, dass dieses File jedesmal erstellt wird.
mfg
michlG
Du Hast das, was die Prüfung, ob der Key stimmt sein sollte ausgeschaltet und höchstwahrscheinlich noch Daten gelöscht...
Also nicht gelöst.
aber da ist tatsächlich noch ein fehler drin:
es muss
(key != num2) || (num3 != 12528034086997679287L)
statt
(key != num2) && (num3 != 12528034086997679287L)
heißen.
Deshalb behaupte ich mal, dass das Entfernen der For-Schleife nicht der Grund dafür ist. Denn floste hat es sicher absichtlich so gemacht, dass dieses File jedesmal erstellt wird.
hmm also ich hab vorher getestet und da is bei eingabe einfach das fenster wieder zugegangen und ncihts ist passiert.....
Du Hast das, was die Prüfung, ob der Key stimmt sein sollte ausgeschaltet und höchstwahrscheinlich noch Daten gelöscht...
Also nicht gelöst.
dann neuer versuch neues glück ^^
private int Main()
{
string programmingSkills = getMySkills("programming")
return = 1;
}
hmm also ich hab vorher getestet und da is bei eingabe einfach das fenster wieder zugegangen und ncihts ist passiert.....
wenn ich das Programm öffne (Orginale Version - frisch entpackt) und als Passwort 1 eingebe, dann schliesst sich das Programm und die zweite Datei wird erzeugt.
das Ganze wird aber wahrscheinlich damit zusammenhängen
aber da ist tatsächlich noch ein fehler drin:
es muss(key != num2) || (num3 != 12528034086997679287L)
statt
(key != num2) && (num3 != 12528034086997679287L)
heißen.
mfg
michlG
Tipps: vor ausführen kopieren; Reflector o.ä.;
Noch auf Reflector hinweisen dass die User auf die Idee kommen das Programm neu zu kompilieren und sich die Chance auf Lösung des Problems verbauen 😉
Dann irgendwelche Operationen in der Main die eh nichts machen um von der eigentlichen Entschlüsselung des versteckten Programms abzulenken.
Nicht schlecht, bin grad nur zu Müde um mich mit dem Byteschubsen für die XOR Verschlüsselung zu beschäftigen. Aber vielleicht hat ja jemand anderes dadurch ne Idee erhalten 🙂
Deine neue Version des Programms macht auch mehr Sinn als die vorher - blöd wenn man sich vernavigiert und keine Daten mehr an der Position sind wo man lesen möchte 😉
Baka wa shinanakya naoranai.
Mein XING Profil.