Sicherheit in Onlinespielen – Wichtige Grundregeln

Egal ob Browsergame oder Multiplayer PvP, Onlinespiele sind in der heutigen Zeit sehr gefragt. Es macht einfach mehr Spass, gemeinsam mit Freunden zu Spielen, statt sich mit einer pseudoklugen KI an der Seite herrum zu schlagen. Der Trend geht klar Richtung Onlinespiele, was wiederrum auch Gamehacker anlockt. In dem heutigen Artikel werden Grundlagen besprochen, auf die man beim Programmieren achten sollte. Anschaulich wird das ganze durch Beispiele erklärt.

Das Spektrum von Hacks, über Bots und Exploits ist zu groß, als dass man es alles in einem Artikel abdecken könnte. Daher werden primär nur Echtzeit-Onlinespiele betrachtet. Diese Techniken lassen sich aber beliebig auf andere Multiplayer-Spiele übertragen. Und noch kurz zu den verwendeten Begriffen in diesem Artikel:

  • Server: Dabei handelt es sich um einen zentralen (!) Server, der das eigentliche Spiel hostet. Er nimmt Daten von anderen Spielern entgegen und verteilt die „Änderungen“ im Spiel an alle verbundenen Clients. In machen Spielen wird der Server auch als „Host“ bezeichnet, was im Prinzip nichts anderes bedeutet.
  • Client: Ein Spieler, der mit dem Server verbunden ist und aktiv Stati (Schießen, Laufen) an den Server sendet

Der wohl bedeutenste Grundsatz dürfte sein: Traue nie den vom Client empfangenden Daten. Der Client schickt, wie schon oben erwähnt, in regelmäsigen Abständen Daten wie seine eigene Position und seine Attribute an den Server. Wenn ein Gamehacker die Welt-Position des Clients verändert, wird diese auch zum Server gesendet. Wenn der Server diese Daten nun ungeprüft übernimmt, haben wir einen sog. Teleport-Hack. Solche Teleport-Hacks befanden sich u.a. in großen Onlinespielen wie Metin 2.

Während sich der entstehende Vorteil durch Teleportierungen noch in Grenzen hält, hört der Spass bei sog. Masskill-Hacks auf. Dabei sendet der Client die Nachricht „Ich habe XX Schaden am Gegner Y gemacht“. Der Server übernimmt dieses ungeprüft und tötet den Gegner Y. In Battlefield 3 ist dieser Hack inzwischen gefixxt, die Kollisionserkennung ist allerdings immernoch Clientseitig. So sind „Instant Kills“ möglich, indem man einfach den Schaden, den eine Waffe verursacht, ins unendliche erhöht. Daher die Regel Nummer 2: Auf Plausibilität prüfen! Im Falle einer clientbasierten Kollisionserkennung kann man durch Wände schießen. Wenn der Server nun einmalig prüft, ob Spieler X den Spieler Y überhaupt treffen kann, wären solche Hacks schon verhindert. Warum das nicht gemacht wird? Weil solche Checks relativ viel Rechenleistung brauchen und einen Server mit 64 Spielern überfordern würde.

Continue Reading

0

Stämme Bot – Timing ist alles

Heute geht es um präzise tickende Maschienen und ein Projekt, das nun doch ziemlich komplex geworden ist. Ein Stämme Bot!

Doch zunächst etwas in eigener Sache: Vielleicht bist Du hier, weil Du mehr oder weniger freiwillig von Keller-Elite auf diese Seite weitergeleitet wurdest. Hoschi111 war so nett, nach der Schließung von Keller-Elite die User hier her zu leiten. Ist eine große Ehre für mich und ich hoffe es gibt hier den ein oder anderen Artikel der Dich interessiert.

Ich weis nicht, ob Du schon Erfahrung im Browsergame „Die Stämme“ gemacht hast. Wenn nein, hier eine kurze Einführung: Um ein anderes Dorf zu erobern (im Stämmejargon auch „adeln“) muss man zwischen 3 und 5 erfolgreiche Angriffe mit einem Adelsgeschlecht auf das Dorf führen. Jedes Adelsgeschlecht (kurz AG) senkt die Zustimmung der Bevölkerung um 20-35 Prozent. Nach und nach sind die Dorfbewohner gewillt zum Angreifer überzulaufen. Dies möchte der Verteidiger natürlich verhindern und schickt allerei Defensive Einheiten in den Kampf um das Dorf zu verteidigen. Manchmal ist die Übermacht aber so groß, dass die eigene Verteidigung nicht standhält. Und dann tritt Plan B in der Kraft: Das „raustimen“. Da die große Offensive vor den AGs angreifen muss, um das Dorf von jeglicher Verteidigung zu befreien, laufen verschiedene Angriffswellen auf ein Dorf. Zumeist sind das ein bis zwei große Offensiven und direkt dahinter die AGs. Die AGs greifen meist mit nur geringem „Begleitschutz“ an, denn eigentlich ist das Dorf ja leer. Und meist werden alle verfügbaren Einheiten bei der großen Offensive gebraucht.

Der Clou ist nun das „Timen“ dieser Angriffe. Man möchte dem Verteidiger möglichst wenig Chancen geben, zwischen den beiden Angriffswellen (Offensive und AGs) Unterstützung im Dorf zu plazieren. Also folgen die Angriffe im Optimalfall wenige Zehntelsekunden aufeinander. Da man 4 Angriffe für die AGs möglichst Zeitnahe aufeinander losschicken muss, wird die Sache spannend. Es gibt extra Tools im Internet zum üben des „Timens“ dieser Angriffe. Doch in was in der Computer uns weit vorraus? Richtig, Timing!

Aus einem Tool, das lediglich Planngszwecke erfüllen sollte, ist so ein mehr oder weniger komplexer Bot geworden. Ein paar Bilder sagen wie immer mehr als Worte:

DSBot_1

Continue Reading

0

World Conqueror 2 – IAP Purchase Hack

Gab schon lange nichts mehr zu Android RE, das muss sich ändern 😉 Ein guter Freund fragte mich nach einem Hack für das Androidspiel World Conqueror 2. Über das Spiel selbst kann ich euch nichts erzählen, dann ich hab es bisher nicht gespielt. Wichtig ist nur, dass es Medallien gibt die man per „In App Purchase“ (IAP) kaufen kann. Mit diesen Medallien kann man sich Abzeichen kaufen, welche wiederrum Boni auf Rohstoffe und Kampfeinheiten geben. Ohne diese Boni ist das Spiel irgendwann nicht mehr zu schaffen, das typische Free-To-Play and Pay-To-Win Prinzip. Aber wir schaffen uns heute Abhilfe.

Screenshot_2015-01-01-18-59-12

Wir decompilen die App gewohnt mit Apktool und Dex2Jar und stellen fest, dass das eigentliche Spiel in nativem Code vorliegt. Für uns heißt das mehr Arbeit, natives Debugging und stundenlange Suche in ARM-Opcodes. Aber zum Glück gibt es eine Schnittstelle des nativen Programmes zu dem einfach zu analysierenden Java-Code. Denn die Google-Käufe werden natürlich über normales Java abgewickelt und müssen dann ihren Weg in die native Bibliothek finden. Dazu finden sich folgende Funktionen im Java-Code:

private static native void AddMedal(int paramInt);
private static native void CallNativeError();
private static native void CallNativeExit();
public static void DeviceNotMatch();
// *Snip*
public static native void PurchaseSuccess(int paramInt);

Das „native“-Schlüsselwort sagt dabei, dass sich die Funktion nicht im Java-Code befindet, sondern in einer nativen Bibliothek zu finden ist. Wenn wir diese mit IDA Pro öffnen, finden wir u.a. folgenden Code:

Continue Reading

0

Brute Force mal anders – Stämme Cracker

Eines meiner ersten Programme, damals noch mit C++.CLI, war ein Stämme Cracker. Als Grünschnabel habe ich mir damals Sourcecode zusammengesucht und so 10 Webbrowser-Controls gleichzeitig kontrolliert. Aus Nostalgiegründen, aber auch um zu zeigen dass sich in der Browsergame-Welt nicht vieles geändert hat, wurde nun ein neuer Cracker geschrieben. Um diesen wird sich der heutige Artikel drehen.

Fangen wir chronologisch an. Das Browsergame Die Stämme gibt es seid 2003 und hat seitdem massiven Zuwachs erfahren. Inzwischen wurde die 112te Welt gestartet mit mehreren Millionen aktiven Spielern auf allen Servern zusammen. In einem Thread auf Free-Hack ist damals ein Username-Grabber und Cracker erschienen, welcher mein Interesse geweckt hat. Stämme hatte damals, wohl mehr aus Debugzwecken, eine Liste von allen Usernamen auf der aktiven Welt in einer Liste gespeichert, welche per WebAccess zugänglich war. Dieser besagte User von Free-Hack stieß wohl auf diese Liste und schrieb prompt einen Cracker dafür, höchstwarscheinlich den ersten Stämme-Cracker überhaupt. Wie komme ich zu dieser Vermutung? Nunja, die Stämme Server waren auf solche massiven Zugangsanfragen nicht vorbereitet: Anstatt nach ein paar Versuchen die IP zu bannen, konnte man munter fröhlich so viele Username-Kombinationen ausprobieren wie man wollte. Und nachdem einige User von Free-Hack dieses Tool massiv nutzten, waren die Stämme Server komplett down-ge“DDosed“. Das Tool selbst war simple: Es grabbte die Username Liste und probierte dann pro Username ein paar Standartpasswörter wie „qwertz“ und „passwort“ durch. Die Erfolgsquote damals war erschreckend hoch. Bei 1000 Usernamen fand man locker 50 Accounts die man für seine Zwecke nutzen konnte. Mein damaliges Tool war natürlich weit unperformanter wie der Cracker von Free-Hack, aber das Erfolgserlebtnis dass man wirklich einen Account durch ein eigenes Tool gebrutet hatte wird mir immer in Erinnerung bleiben.

Ca. 7 Jahre später ist sowohl Stämme, als auch meine Programmierkentnisse weiter gereift. Aus Spass fing ich mit ein paar Leuten an wieder Stämme zu spielen. Und da kommen solche alten Gedanken wieder hoch 🙂 „Wird es immernoch möglich sein, auf diesem Wege an Accounts zu kommen?“. Prompt wurde programmiert und prompt war auch schon das erste Problem vorhanden: Wie kam man an die Usernamen? Stämme bietet glücklicherweise eine Rangliste an, in der 25 Accounts pro Seite aufgelistet sind. Also wurde ein Login sowie ein Grabber geschrieben, um an die besagten Benutzernamen zu kommen.  Da ich nur an Spielern interessiert war, welche besser wie ich sind, wurden die obersten 15000 Plazierungen ausgelesen.

temp

Continue Reading

0

Form Grabbing in Firefox – PoC

Form Grabbing in Firefox. Das ist nichts neues und es gibt zuhauf Beispiele mit dokumentierem Sourcecode. Warum also ein Artikel drüber verfassen? Ein guter Bekannter zeige mir ein Video von einem Form-Grabber in Firefox und fragte mich wie das geht. Ich hatte mich nie damit beschäftigt und nur ein paar Ansätze im Kopf, doch das interesse war geweckt. Wie schaffen es Bots, Daten aus Website-Formularen so gezielt auszulesen?

In dem folgenden Artikel wird ein Proof of Concept von einem Form-Grabber mit injecteter DLL erstellt. Das besondere im Vergleich zu den 100 anderen Proof of Concepts  ist hierbei, dass die injectete DLL Managed ist und somit erst ein CLRHost für das Ausführen von .NET Code reingeladen werden muss. Das Konzept sollte aus den vorherigen Artikeln wie diesem und diesem bekannt sein.

Fangen wir mit etwas Theorie an: Es gibt zwei Wege Daten aus Webformularen auszulesen. Diese Formulare sind intern auch nur Textfelder, die man markieren und kopieren kann wie man es aus Windows gewohnt ist. Das heißt im Umkehrschluss auch, dass diese Felder ein Handle und eine Windows-Klasse besitzen müssen. Mit diesem Handle können wir von externen Programmen Firefox dazu auffordern, uns den Textinhalt dieses Handles zurückzugeben. Der große Nachteil ist, dass man sich erstmal zu diesem Handle „Vorzuhangeln“ muss. Hier muss man über mehrere UI Elemente und Knoten mit Unterknoten laufen, bis man am gewünschten Ziel angekommen ist. Sehr elegant ist das nicht und für jede Seite müsste dieser Pfad eingeprogrammiert werden! Wer weiteres über diesen Ansatz lesen möchte, dem sei die WM_GETTEXT Message und dieser Stackoverflowpost ans Herz gelegt. Eleganter, und vor allem universal für jede Seite ist das Abfangen von der GET/POST Request bevor diese über SSL unkenntlich gemacht wird. Und genau dieser Ansatz ist verblüffend einfach und zielführend!

Die später geschriebene DLL hängt sich an die sog. PR_Write Funktion der nss3.dll von Firefox. Diese wird verwendet, um Streams jeder Art zu beschreiben. Sei es ein Filestream welcher auf die Festplatte schreibt, oder ein Netstream welcher an eine TCP Verbindung gerichtet ist. Wie unschwer zu erkennen ist, nimmt diese Funktion drei Parameter entgegen. Der erste ist das Stream-Handle, was nicht weiter besprochen wird. Das zweite Argument enthält einen Zeiger auf einen Buffer (Zwischenspeicher), in welchem sich die zu schreibenden Daten befinden. Das  dritte Argument gibt schließlich an, wieviele Daten aus dem Zwischenspeicher in den Stream geschrieben werden sollen.

Setzt man mit OllyDBG einen Breakpoint an der PR_Write Funktion, so lassen sich alle drei Argumente schön im Stack anschauen. Das deutet daraufhin, dass es sich bei der PR_Write Funktion um eine cdecl-Calling-Convention handelt. Die später für uns wichtige Calling Convention gibt an, wie die Parameter der Funktion übergeben werden. Dabei gibt es viel Möglichkeiten: Parameter können sich in Registern befinden oder auch der Reihe nach auf den Stack geladen werden. Letzeres ist wohl hier der Fall.

PR_Write

 

Schön zu sehen sind die 3 Stackargumente in umgekehrter Reinfolge. Die Return-Adresse befinder sich ganz Oben auf dem Stack, danach folgt der Zeiger auf den Stream und der Zeiger auf den Buffer. Als drittes Argument kann man die Länge des Buffers, in diesem Fall 0x221 Bytes sehen. Links im Stack Window ist die Buffer-Adresse geöffnet. Hier sieht man klar die POST Request die gesendet wird, mit allen GET und POST Parametern. (GetParam=NotSoSecret, PostParam=VeryS3cret).

Continue Reading

0

HackEx – How to not code an API

Es musste ja so kommen: Der Hacker hacked mal wieder das Hackerspiel. Dieser Artikel ist schon lange geplant, aber erst jetzt habe ich es geschafft ihre neuste API anzusprechen.

Aber ganz Langsam: HackEx ist ein Online-Spiel für Android Handys. Es geht darum, andere Spieler zu Hacken, ihnen ihr Guthaben zu stehen und die eigene Software für besser Verteidigung/Angriffe aufzurüsten. Das Spiel wurde von den Entwicklern ein „wenig“ vernachlässigt, so dass bald Bots und Scripter die Leaderboards übernahmen. Allerdings ist die Punkteverteilung für diese Leaderboards auch nicht durchdacht: Ein Angriff auf ein Spieler Level 1, welcher nur 4 Sekunden dauert, bringt genau so viele Punkte wie ein Angriff auf einen Spieler viel höheren Levels.

Die JSon-API ist einfach gestrickt: Man bekommt beim Login ein Token zugewiesen, was man in folgenden Requests als „X-API-KEY“ im Header mitschickt. Weitere Befehle, wie z.B. das abrufen von aktuellen Prozessen (/v5/user_processes) geschieht über GET Requests. Zum Senden von bestimmten Angriffen werden meist Argumente als POST Request übergeben.

Bisher hört sich die API doch ganz vernüftig an. Bis auf, dass sie bis vor kurzem Unverschlüsselt war und somit Leuten das Botten ermöglichte. Aber welches Browsergame kennt das nicht? Nein, ich möchte auf viel schlimmere Sachen herraus:

Continue Reading

0

Keygen Me 1 – Lösungshinweise

Annährend 3 Monate ist es her, dass ich mich an einem Keygen Me versucht habe. Ziel war es ein „Algorithmus“ zu entwickeln, den man nicht durch simples Rückrechnen der Rechenoperationen brechen kann. Blogpartner tr4ceflow hat einen Artikel dazu gewidmet, der schon gute Ansätze beinhaltet. In der Zukunft werden Keygen Mes mit einem nicht so überladenen Compiler wie Visual Studio kompiliert, da viel zu viel verwirrender Mist reinkommt. Das habe ich auch dadurch gelernt 😉

Alle 3-4 Tage werden hier neue Lösungshinweise erscheinen. Wieviele es insgesammt werden weiß ich nocht nicht.

13.09.2014:

Alle Infos von tr4ceflows Blogpost zusammengefasst: Per GetDlgItem und GetWindowTextA wird der Text aus den Textboxen Name, Serial1 und Serial2 ausgelesen. Diese werden an eine Funktion, die den eigentlichen Keycheck vornimmt übergeben (0x1E1C60). Nun muss gelten: usernameLength – 1 == strlen(key1)/4). Der Key wird nun in 4er Blöcke zerlegt und in shorts (2 byte) gespeichert. Aus 01234567 wird 0x0123 und 0x4567 . Dieses wird zu einem Float umgewandelt (0x0123 = 291d => 291.0f) und im Anschluss durch 100 geteilt. Nun wird gerechnet, und zwar mit Floats. Es werden nun alle Buchstaben durchlaufen. Dabei wird jeweils die Summe aus einer „Rechnung“ gebildet und diese vom aktuellen Buchstaben abgezogen. Nun wird vergleichen, ob die Differenz in einem „Bereich“ liegt, der durch die e-Funktion mit einem statischen Exponenten aus einem Array begrenzt wird. Wenn die Differenz kleiner als die expotentierte Zahl ist, so wird die Schleife Fortgesetzt. Wenn nein, so wird aus der Funktion rausgesprungen und der Key ist nicht gültig.

Ich möchte nochmal einen kleinen zusätzlichen Tipp geben: tr4ceflow hat eine Rechung aufgestellt, wie die Sache im ersten, zweiten und dritten Durchgang aussieht.

- berechne    - hex(e) / 100.0
              - hex(f) / 100.0
              - hex(g) / 100.0
- berechne die Summe
	1. Durchgang :  hex(e) / 100.0 + hex(f) / 100.0 + hex(g) / 100.0
	2. Durchgang :  4*hex(e) / 100.0 + 2*hex(f) / 100.0 + hex(g) / 100.0
	3. Durchgang :  9*hex(e) / 100.0 + 3*hex(f) / 100.0 + hex(g) / 100.0
- hole einzelnen Buchstaben "a" aus Namen und berechne die Differenz

Schaut euch dabei mal die Vorfakoren der hex(e/f/g) an. Beim ersten Durchlauf ist dieser stets 1, beim zweiten durchlauf ist er 1,2,4, …, beim dritten Durchlauf 1,3,9,… . Kommen euch diese Folgen bekannt vor? Wenn ja, wo finden sie Anwendung? Vorallem im Zusammenhang mit einer Addition ! Dieser (relativ) große Tipp hilft hoffentlich, auf die richtige Spur zu kommen. Denn tra4ceflow hat bereits alle vorarbeit geleistet, jetzt gilt es nur noch 1+1 zusammenzuzählen.

16.09.2014:

save(2)

Entspricht dem Polynom: f(x) = -0.054166*x^6 + 1.02083*x^5  -6.3125*x^4 + 10.0625*x^3 + 32.866*x^2 -106.583*x^1 + 138

Entspricht auch dem Usernamen: EASYSURF

Schaut euch mal den Y-Wert des Polynoms an den ganzen Zahlen an, also: f(1), f(2), … Vergleicht es mit EASYSURF!

18.09.2014:

Mit den obigen Zeilen ist der Hauptteil des Keygens, nämlich Key1 bereits errechnet. Das sind also einfach die Koeffizienten des Polynoms was den Usernamen bzw die ASCII Characters des Usernamens abzüglich dem letzten Buchstaben annährt. Hier der Beispielkey für EASYSURF.

Key1: fffb0066fd8903ee0cd6d65e35e7

Doch was ist mit Key 2? Dort wird ebenfalls ein Polynom verwendet. Doch welchen Wert muss es haben? Es ist ganz ähnlich. Doch das hebe ich mir für den nächsten und finalen Tipp auf 😉

22.09.2014:

Abschliesend gibt es die volle Auflösung und auch den Sourcecode zum Keygen. Fangen wir mit dem zweiten Key an. Auch hierbei handelt es sich um encodierte Koeffizienten des Polynoms des „strlen(username) – 1“-Grades. Allerdings geht es hier auch noch um Grenzwertberechnung. Der Grenzwert Polynom2/Polynom1 gegen Unendlich muss gegen den letzten Buchstaben/10 gehen. Dabei ist bekanntlich nur größte Exponent entscheidend, welcher im Nenner, als auch im Zähler ausgeklammert wird. Beim oben genannten Key ist der größte Exponent 0xfffb, was nach umrechnen -0,0541 ergibt. Der Grenzwert, also der letzte Buchstabe, muss F = 70d sein. Die Gleichung umzustellen müsste jeder hinbekommen: x/-0,0541=7.0 => x = -0,0541*7.0 = -0.3787. Encodieren wir das wieder in unsere Short-Schreibweise, so erhalten wir: ffdb. Da die restlichen Exponenten egal sind, können wir da einfach die restlichen Koeffizenten von Key1 ranhängen. Damit erhalten wir als gültige Keykombination:
Key1 = fffb0066fd8903ee0cd6d65e35e7
Key2 = ffdb0066fd8903ee0cd6d65e35e7

Continue Reading

0

Stadt Land Fluss Multiplayer – Pwned

Hallo zusammen! Der Ausdruck „Pwned“ findet in meinem Vokabular eigentlich keine Verwendung, doch hier ist er wirklich angebracht. Heute geht es um eine (noch) relativ unbekannte App „Stadt Land Fluss Multiplayer„, welche mit ca. 25000 Downloads nicht so bekannt wie Quizduell ist. Das Prinzip des Spiels ist einfach: Man hat 60 Sekunden Zeit, in den verschiedesten Kategorien Begriffe mit dem gleichen Anfangsbuchstaben einzutragen. Wer also die meisten Wörter weis und dabei auch noch ohne Schreibfehler tippt, schlägt den Gegner.

Screenshot_2014-07-13-18-23-33

Eine normale Modifikation könnte uns die Zeit zum Eintippen der Begriffe auf unendlich hochsetzen. Ein solcher Hack ist innerhalb von 3 Minuten geschrieben, denn die GameActivity bekommt als Parameter 60 ( = Sekunden) übergeben. Ein kleiner Smali-Patch schafft hier Abhilfe. Doch das ist kein Pwn, bei Begriffen die wir nicht wissen hilft uns auch keine längere Zeit zum überlegen. Ein anderer Ansatz muss her!

Diesen Ansatz finden wir in der API, die glücklicherweiße die Daten unverschlüsselt und per JSon überträgt. Zum Abrufen von Spieldaten senden wir folgende Request an den Server:

postData={"auth":{"password":"PASSWORDMD5Hashed","userId":"66XXX"},"clientInfo":{"appVersion":"1.0","bundleId":"de.lochmann.stadtlandfluss","os":"android"},"requests":{"getGameData":{"gameId":"1945415","userId":"X61XX","type":"getGameData"}}}

Die Antwort, welche zu Lang zum pasten ist, liefert uns diverse Strukturen mit Daten zum Spiel, dem Spieler, seiner Punktezahl und natürlich den bisher eingegeben Antworten. Ihr ahnt, worauf es hinausläuft? Daten aller Spiele grabben, eine riesige Datenbank aufbauen und pwnen! Das wäre ein Ansatz, doch bei bisher 1945415 gespielten Spielen wäre das komplette Grabben sinnlos. Zwar habe ich hier nun eine 2 GB Datenbank mit den ersten paar tausend Einträgen rumliegen, doch das filtern von richtigen Antworten macht auch nicht wirklich Spass. Man könnte daraus eine informative Statistik über Antworten und Punktezahlen erstellen, doch das nur als Randgedanke.

Continue Reading

0

Apex = Defeated?

Anderthalb Monate ist es her, seid der erste Post über Apex entstanden ist. Nun bin ich an dem Punkt angelangt, Apex als besiegt zu bezeichnen. Zwar weis ich noch lange nicht, wie all die unzähligen Apex Module arbeiten, aber es reicht für uns einen Hack zu schreiben ohne das Apex (frei nach Archimedes) unsere Kreise stört , Mir ist klar dass dieser Post vielleicht von anderen Kopiert wird und als Vorlage für andere Hacks benutzt wird, daher werde ich keinen kompletten Source posten.

Im letzten Post wurde erwähnt dass Apex uns nach dem Hook von End2DOptimized und RenderString Kicks verteilt. Auch sollte im Hinterkopf behalten werden, dass Apex uns nicht selbst kickt, sondern nur Daten an den zentralen Server weiterleitet. Des weiteren sollten wir uns in das Gedächnis rufen, dass die Detour-Library die ersten 6 Bytes einer Funktion mit einem JMP ersetzt. Das alles deutet darauf hin, dass Apex irgendwie den Funktionsanfang prüft, ob dort Hooks gesetzt sind oder nicht. Prompt wurde CheatEngine gezückt und der Debugger attached, welcher in auf Lesezugriffe am Anfang der gehookten End2DOptimized Funktion achtet. Das selbe wäre auch mit OllyDbg möglich gewesen, aber CheatEngine ist in diesem Fall bequemer zu bedienen.

ApexHashing

Mit allein diesem Resultat fangen wir wenig an. Wichtig ist zu wissen, dass generell 0x7XXXXXXX Adressen in den Kernelspace zeigen. Mit dem Debugger finden wir, dass 0x760575B2 in der Funktion IsBadReadPointer liegt und diese wohl unseren Funktionsanfang prüft. Der Call dazu erfolgt allerdings auf dem 0x0CCXXXXX Adressbereich. Wir wissen ja inzwischen, das Apex zwei große Module in den Speicher mapped, allerdings ist keines davon annährend in diesem Bereich. Ein Glück, dass VirtualAlloc gehooked ist und wir somit die dynamischen Speicherreservierungen mitbekommen. Darin finden wir:

14:08:20 Virtual Alloc! Size: 7d90, Addr: 0xcce0000, allocType: 1000, flProtect: 40

Continue Reading

0

Keygen-Me 1

Wie bereits in dem News-Post angekündigt habe ich mich an einem Keygen-Me versucht. Ziel dabei war es ein Keygen-Me zu erstellen, welches nicht durch stumpes Rückrechnen zu knacken ist, sondern vielmehr Verständnis für den Algorithmus erfordert. Die Idee zu diesem Keygen-Me ist in einer Mathevorlesung entstanden, aber das sollte euch nicht abschrecken, die hier verwendete Mathematik sollte jederman bekannt sein.

Die Schwierigkeit dieser Herrausforderung ist schwer einzuschätzen, aber ich behaupte das jeder fortgeschrittene Reverser der genug Zeit hat diese Challange schafft.

Zum Abschluss noch wichtige Informationen: Da es gewollt zu einem Präzisionsverlust des Keys kommt, findet man bei längeren Usernamen weniger Keys. Hier eine Tabelle für, an der ihr Euch orientieren könnt, entstanden aus 1000 random Keys:

LENGTH | VALID RATIO
4       | 100%
5       | 100%
6       | ~93%
7       | ~20%
8       | ~8%
9       | ~5%
10      | ~1.7%

Screenshot: (wer sich über die hässlige GUI beschwert sollte mir lieber danken, dass ich die Save/Restore Values Buttons eingebaut habe 😛 )
KeygenMe1

Download: [Download nicht gefunden.]

Viel Erfolg!

P.S. Inzwischen ist ein Writeup erschienen

0

Seiten:1234567...13