myGully.com

myGully.com (https://mygully.com/index.php)
-   Tutorials/Howtos (https://mygully.com/forumdisplay.php?f=429)
-   -   [Tutorial] Votes manipulieren am Beispiel vom Axe Adventskalender 2011 (https://mygully.com/showthread.php?t=2512753)

LeguanFreund 09.12.11 22:03

[Tutorial] Votes manipulieren am Beispiel vom Axe Adventskalender 2011
 
1. Analyse mit wireshark

Ich denke es ist klar, dass der AXE Adventskalender in Flash geschrieben ist.
Da Flash ja Client-seitig läuft muss das Flash Applet irgendwann mal mit einem Server kommunizieren. Deshalb ist der offensichtliche erste Ansatz, mal den Netzwerktraffic anzuschauen, der entsteht während man abstimmt.
Starten wir also [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] und stimmen für irgendwas ab. Vorher löschen wir am besten die (Flash-)Cookies oder gehen ins private Browsing um zu verhindern, dass das Flash Applet irgendwelche Daten gespeichert hat.

Ist das geschafft, sieht es erstmal so aus: (brotip: filter auf http stellen)


Bisher nichts besonders spannendes, am Anfang läd der Browser erstmal die Webseite inkl Flash Applet, javas*****s etc herunter.
Schauen wir also, ob wir weiter unten etwas interesannteres entdecken.
Und tatsächlich entdecken wir einige Aufrufe, die json Daten zurückgeben. Wieso das sofort auffallen sollte, könnt ihr hier nachlesen: [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...], [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]

Wir stellen also folgende Vermutung auf (und genaueres Anschauen der Pakete in wireshark bestätigt das):
Das Flash Applet ist ein front-end für einen "RESTful Web Service".

Schauen wir uns also den Teil mit den json Daten genauer an (brotip: nach ip.addr filtern):


Wir sehen also dass nacheinander folgende URLs aufgerufen werden:
1. [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]
2. [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]
3. [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]
4. [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]
5. [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]{langer string}

Es sind alles GET Requests, dh die einzigen Parameter, die übergeben werden sind Cookies und im Fall von Vote.json der Parameter c.
Da sich Vote.json wichtig anhört, kopieren wir uns mal den ganzen Aufruf raus für später:
Code:

http://api.excite-advent.axe.de/Idea/Vote.json?c=MzNlZTc0ZmUxZGE1ZjRmNTQ1MjY4NWE0NDU1MzA0ZTQ3NTUzZDRlNDc1OTc5NGU0NzUxNzg1OTU0NmIzMDRmNTc1NjZjNWE0NDZiMzU0ZDdhNjMzMTRlNDgxYWZlNWJjYzRlZmNkOGMzMGM2YzhjMGNhZjAwNzc3MDQwYTk5NTMyMWE0OTg0OTg2MzY0NmViNmYwYjNmYjBhNzY4Mjk3Njg2MmNhMzg3ZjM1ZWM0NmMxYjhiZGY3NmY4YjI4M2M0YWY0ZTBjNTE5YjMxZjNiNGNmYjY0NGIyZjAzNDQwMjhhZTgwMjY2ZjcyZjY5OGM4ZmM2MjQ5MmM3ZWJlNWZkM2E4NzYwYmIyYjliYWQyOThlOTRiY2Q1NTZiMGYzYjlkNDg0ODkwYWY2M2M3NDQyNGIxNWJmOWZjYTBmNDk4Y2VjNTVlNTczNmQw
Das schöne hieran ist jetzt, dass wir die ganzen Aufrufe einfach im Browser testen können, der uns dann selbstständig Cookies setzt, was das ganze sehr bequem macht.

2. Analyse des json Interfaces

Wir nehmen jetzt einen Browser und versuchen die Aufrufe, die das Flash Applet macht, nachzuvollziehen.
Als erstes Fällt auf, dass als /Idea/Check.json aufgerufen wurde, noch kein Cookie von Flash aus gesendet wurde.
Gehen wir also ins private Browsing und rufen die URL einfachmal selbst auf. Zurück kommt
Code:

{"data":[],"error":[],"type":"Success","session_name":"PHPSESSID-AxeExciteAdventskalenderApi-1_0_4","session_id":"deb83594950056ad821662117943ebd0","ttl":60}
Wir vermuten, die Attribute session_name und session_id sind die Cookies, die gesetzt werden, nochmal in Form von JSON Daten und ein Blick in die Browser Cookies bestätigt das.

Wenn wir uns dann /Idea/Calendar.json und /Idea/List.json im Browser anschauen, erkennen wir, dass hier die vergangenen Abstimmungen und die aktuelle Rangliste übertragen wird. Bemerken kann man hier, dass das gleiche JSON Objekt wie bei /Idea/Check.json zurückkommt, mit dem Attribut "data" entsprechend verändert. Außerdem kommt eine leere session_id zurück, was uns aber nicht weiter stören sollte.

/Captcha.png gibt uns wie zu erwarten das Captcha, welches zur entsprechenden session_id gehört zurück.

Mysteriös ist jetzt der Parameter, der /Idea/Vote.json übergeben wird. Wir können sicher sein, dass dieser einerseits das Captcha und andererseits den Begriff für den abgestimmt werden soll beinhalten muss.

Auf den ersten Blick sieht das aus als wäre es [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...], und tatsächlich, wenn wir [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] draufwerfen erhalten wir
Code:

33ee74fe1da5f4f5452685a4455304e47553d4e4759794e47517859546b304f57566c5a446b354d7a63314e481afe5bcc4efcd8c30c6c8c0caf00777040a995321a49849863646eb6f0b3fb0a7682976862ca387f35ec46c1b8bdf76f8b283c4af4e0c519b31f3b4cfb644b2f0344028ae80266f72f698c8fc62492c7ebe5fd3a8760bb2b9bad298e94bcd556b0f3b9d484890af63c74424b15bf9fca0f498cec55e5736d0
Also irgendwelche (binär) Daten in Form von [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] (je zwei Ziffern entsprechen einem Byte).
Wenn wir versuchen, das einfach als [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...], kommt leider nichts sinnvolles dabei raus. Dasselbe gilt für UTF-* und sonstige gängige Zeichencodierungen.

Wir wollen also rausfinden, wie das Flash Applet auf diese Zeichenfolge kommt. Glücklicher Weise ist das reversen von Flash relativ einfach, da Flash in einen Zwischencode compiliert. Nehmen wir also die 30 Tage Trial vom [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] und schauen uns die [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] darin an.

3. Analyse der Main.swf

Wir suchen erstmal den Actions*****-Teil der swf Datei, denn dort steht der Code drin, der uns interessiert.
Nach einigem herumsuchen fällt eine Klasse mit dem Namen [Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...] auf:


Leider funktioniert der Decompiler nicht so 100%ig richtig, daher müssen wir in den nächsten Schritten sehr viel raten.

Ganz am Ende der Klasse sehen wir eine Methode getURLVariables. Klingt nach dem, was wir suchen.
[Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]

Wir erraten, dass hier zunächst ein Objekt in JSON kodiert und dann mit der Methode encrypt verschlüsselt wird.

Schauen wir uns also encrypt genauer an, diese nimmt einen String als Parameter:
[Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]

Wir erraten wieder, was hier passiert:
1. Parameter wird base64 codiert. (Z. 74)
2. Es wird ein zufälliger 8 Zeichen langer String "iv" erzeugt (Z. 88)
3. Es wird ein zufälliger 25 Zeichen langer String "key" erzeugt (Z. 94)
4. Es wird ein Cipher mithilfe der Methode _getCipher und aus den Strings "iv" und "key" erzeugt (Z. 97)
Wer Wikipedia zu Blowfish befragt hat, weiß was das bedeuten könnte.
5. Mit dieser Cipher wird der Text aus 1. verschlüsselt (Z. 100)
6. Das Ergebnis (irgendwelche binär Daten) wird hexadezimal kodiert (Z. 105)
7. Dieses wiederrum wird in zwei Teile "encr1" und "encr2" zerhackt, wobei "encr1" die ersten 13 Zeichen und "encr2" der Rest ist. (Z. 107, 109)
8. (hier muss man kurz in die "P-Code" Ansicht wechseln, da der Decompiler in Zeile 111 offenbar Mist gebaut hat) Es wird "iv" in base64 und dann zeichenweise hexadezimal codiert, "key" wird zeichenweise hexadezimal codiert, anschließend wird ein String encr1.iv.key.encr2 erzeugt (Z. 111), der dann Base64 codiert (Z. 115) und als Ergebnis zurückgegeben wird.

Werfen wir noch einen Blick in _getCipher:
[Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...]

[Link nur für registrierte und freigeschaltete Mitglieder sichtbar. Jetzt registrieren...], und stellen fest:
Es handelt sich um Blowfish Verschlüsselung im CBC Modus, wobei der Schlüssel der MD5-Hash von "key" und "iv" der IV Parameter für den CBC Modus ist.


Wir lernen: Der Mysteriöse Parameter in /Idea/Vote.json ist Blowfish Verschlüsselt, mehrmals hexadezimal und base64 codiert und enthält den Schlüssel und IV Parameter.
Wir können uns jetzt also ein S***** schreiben, was den vorher mitgelesenen Parameter entschlüsselt.

4. Wir bauen das Flash Applet als S***** nach

Man kann jetzt die S***** Sprache seiner Wahl verwenden, ich habe mich für PHP mit mcrypt und curl entschieden.
Nach konsultieren der php dokumentation über die Funktion pack und mcrypt_cbc überlegt man sich folgende Funktion zur Entschlüsselung:
PHP-Code:

    function axe_decrypt($param) {
        
$param base64_decode($param);

        
$encr1 substr($param013);
        
$iv    substr($param1324);
        
$key   substr($param3750);
        
$encr2 substr($param87);

        
$encrypted pack("H*"$encr1.$encr2);
        
$key pack("H*"$key);
        
$iv base64_decode(pack("H*"$iv));
        
$dec mcrypt_cbc(MCRYPT_BLOWFISHMD5($key), $encryptedMCRYPT_DECRYPT$iv);
        
$dec base64_decode($dec);

        return array(
$key$iv$dec);
    } 

Die Funktion nimmt den Parameter von /Idea/Vote.json und gibt ein Tripel (key, iv, text) zurück. Sie kehrt gerade die Schritte, die wir bei der Main.swf erraten haben, um.

Schauen wir also, ob wir richtig geraten haben, und wenden die Funktion auf die mitgelesenen Daten an:
Code:

{"axedtid":"29b4f99c9fb9eda5232536044743149c","idea":"Isomorphismus","captcha":"23s583"}
Das sieht schonmal ganz gut aus und ist sogar relativ selbsterklärend. Wir stellen fest, dass der Parameter "axetid" gerade unserer session_id entspricht.

Analog erhalten wir eine Funktion, die solche Daten wieder verschlüsselt:
PHP-Code:

    function axe_encrypt($key$iv$data) {
        
$data base64_encode($data);        
        
$enc  mcrypt_cbc(MCRYPT_BLOWFISHMD5($key), $dataMCRYPT_ENCRYPT$iv);

        
$iv  implode(unpack("H*"base64_encode($iv)));
        
$key implode(unpack("H*"$key));

        
$enc   implode(unpack("H*",$enc));
        
$encr1 substr($enc013);
        
$encr2 substr($enc13);

        return 
$encr1.$iv.$key.$encr2;
    } 

Wir testen kurz, ob wir mit der Ausgabe von axe_decrypt als Parameter von axe_encrypt wieder den gleichen String erhalten. (dies ist der Fall)

Unser S***** soll also wie folgt arbeiten:
1. /Idea/Check.json aufrufen (ohne Cookie) und session_id holen.
2. /Captcha.png mit session_id aus 1. als Cookie herunterladen
3. Der User tippt das Captcha ab
4. Wir bauen uns aus diesen Daten den Parameter für /Idea/Vote.json.

Dank PHP können wir das bequem mithilfe von zB Apache über einen lokalen Webserver machen. Jetzt können wir also schonmal ohne das Flash Applet unbegrenzt oft (wie sich herausstellt) voten.

Nachdem wir dann 1000 Captchas von Hand abgetippt haben, merken wir, dass es immer wieder die gleichen sind.

5. Voten ohne Captchas abtippen

Wir modifizieren das S***** und speichern die Captchas, die akzeptiert wurden, als {Captcha}.png ab.
Sobald wir zwei gleiche Captchas haben, vergleichen wir die Dateien und sehen, dass es exakt dieselben Bilder sind.
Wir können das Voten also folgendermaßen automatisieren:
1. Speichere alle Captchas in Form von {Captcha}.png (*)
2. Erzeuge Liste mit Tupeln von MD5-Hash der Datei und entsprechendem Captcha als Text
3. Nachdem wir jetzt ein Captcha heruntergeladen haben, nehmen wir den MD5 Hash davon, suchen in unserer Liste danach und können so direkt den Text herausfinden, ohne dass der User das abtippen muss.
4. ?
5. profit

Hurrdurr42 10.12.11 12:17

Sieht interessant aus.
Hast du damit ganz oft für Lasertag von Barney gestimmt? :D

LeguanFreund 11.12.11 16:37

ich nutz das gar nicht, ist mir zu blöd. Allerdings benutzt ein Blog namens Trendspektor dieses Skript, um damit seine eigenen Begriffe gewinnen zu lassen. (schon seit 4-5 Tage, sind alle Begriffe die gewonnen haben durch das Skript zu stande gekommen von dem Blog Trendspektor)

Joker1486 06.05.14 12:56

Hey kann mir wer helfen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 Uhr.

Powered by vBulletin® (Deutsch)
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.