Confuser String Decrypter über mDbg
Der Confuser ist nach wie vor ein aktuelles Thema. Und dabei ist die String-Decryption soweit ich weiß nicht geknackt! Confuser stellt für fast alle Strings eine eigene Decrypterfunktion mit eigener Ressource sowie eigenen Verschlüsselungsparametern bereit. Der reine Horror für jeden, der einen statischen Unpacker schreiben will.
Dieses mal ging es um einen anderen, dynamischen Ansatz: Warum nicht die Strings auslesen, nachdem sie sich entschlüsselt im Speicher befinden? Und da ich bei dem Proxy System von Confuser Erfolg mit WinDbg hatte, ist auch hier zum Debugger gegriffen worden. Microsoft stellt uns eine .NET Debugging API bereit, auch wenn sich kaum etwas darüber im Internet finden lässt. Und genau mit dieser API in Kombination mit ein wenig Confuserwissen, Speicherlayout und .NET ist es möglich, einen Debugger und Unpacker für die Strings zu schreiben. Dabei laufen folgende Schritte ab:
- Debugger Instanz erstellen + die Executable laden
- Nach dem Laden vom “mscorlib.dll”-Modul ein Breakpoint auf System.Reflection.Module.ResolveMethod setzen (wird von .cctor gecalled, siehe Proxy-System)
- Sobald dieser Breakpoint erreicht ist, werden Breakpoints auf alle String-Decrypter Funktionen gesetzt. Der ResolveMethod BP wird entfernt.
- Wenn ein Decrypt-BP erreicht ist, so wird aus der Funktion raus gesprungen und der Wert in EAX ausgelesen. Dabei wird der Parameter (Token) von dem Decrypt-Call zusammen mit dem entschlüsselten String abgespeichert.
- Alle Decrypt-Funkionen, die ein Token (+ entschlüsselten String) haben, werden mit dem echten String ersetzt.
Kingt nach viel Arbeit und Source? Nicht wirklich. Fangen wir bei Punkt 1 an:
Engine = new MDbgEngine(); Proc = Engine.CreateProcess(@"C:\Users\AL\Downloads\li0nsar3c00l enhanceviews.net bot_patched.exe", "", DebugModeFlag.Debug, null); Proc.PostDebugEvent += Proc_PostDebugEvent; // Jedes Event wird hierhin weitergereicht Engine.Processes.Active.CorProcess.OnBreakpoint += CorProcess_OnBreakpoint; // ein BP wird als Event gecalled Proc.Go().WaitOne(); // Wir lassen laufen, bis ein BP erreicht ist. Console.ReadLine(); |