Sec, blogmal! - rev-eng

Categories:

Everything

Februar '17

SoSoSoSoSoSoSo
303112345
6789101112
13141516171819
20212223242526
272812345

Archive:

Mon, 14 Mar 2011

Patching Android Apps

How to patch an Android application:

First off, some basics. Android applications are delivered in a single .apk file. This is simply a differently-named .zip file, so any common zip tool should be able to unpack it. Inside you will usually find all the resources (images, sounds) and (among other things) a file called classes.dex which contains the code for that application. This is bytecode for the dalvik VM. You can disassemble this bytecode into something you could call android assembler. Compared to real assembler code, this is pretty high-level, but still nothing like a high-level language like java. As method and member names are preserved, it is usually fairly easy to understand unless the author used an obfuscator before release (In that case, all your methods will be named a, b, c...).

To follow this example along, you need a few tools:

  • Your favourite editor
  • A simple zip/unzip utility (commandline or 7zip or similar gui tool)
  • An android assembler/disassembler
  • A way to sign your zip file.
    • For a quick&dirty hack, SignApk is easy to use, but you can also use jarsigner if you're already familiar with it.
  • Not to forget a working java installation. Smali/baksmali and signapk/jarsigner both require it.

As a simple example, we'll be removing the focus sound from the android camera. – As we'll be replacing a builtin app, you will need root access to your phone.

  1. First, get a copy of the .apk you intend to change. In our case, we grab it from our phone with:

    adb pull /system/app/Camera.apk
    

  2. Then, we need to get the classes.dex file from it

    unzip Camera.apk classes.dex
    

  3. Now we run the disassembler. The output will be in the out/ subdirectory.

    java -jar baksmali-1.2.6.jar classes.dex
    

    You can peek around the out/ subdir where all the code is. Change whatever you want.

  4. In our case, the file we need to edit is: com/android/camera/Camera$AutoFocusCallback.smali

    To remove the focus sound, look for a line containing invoke-virtual and ->startTone. In my version it looks like this:

    invoke-virtual {v0, v1}, Landroid/media/ToneGenerator;->startTone(I)Z"
    

    Just delete that line.

  5. After you're done, we need to put it all back together into an .apk. First we re-assemble the code into a classes.dex:

    java -jar smali-1.2.6.jar out -o classes.dex
    

  6. Put that file back into the .apk with

    zip Camera.apk classes.dex
    

  7. Because we changed the contents, we now need to re-sign it. If you're using signapk, do this:

    java -jar signapk.jar testkey.x509.pem testkey.pk8 Camera.apk Camera_signed.apk
    

  8. Last but not least, we need to install our new .apk. Because it's a system app, we need to actually replace the file like this:

    adb remount
    adb push Camera_signed.apk /system/app/Camera.apk
    

    If it were a normal app, you would simply uninstall the original, and then install the .apk like any other app. (e.g. with adb install foo.apk)

After you reboot your phone, your Camera should now be less noisy. Yay!

– Sec

P.S.: If you want to remove the shutter sound instead, check this thread on xda-developers.com. Basically it boils down to:

adb remount
adb shell rm /system/media/audio/ui/camera_click.ogg 

posted at: 14:46 | Category: /rev-eng | permanent link to this entry | 5 comments (trackback)

Thu, 19 Jan 2006

Probleme mit Cryptoloop und Suse

Eigentlich gehört das in die Kategorie Das glaubt mir doch eh keiner.

Gestern hat ein Kollege hier seinen Laptop unvorsichtigerweise lang genug ohne Strom stehen lassen, und plötzlich war er aus. Nunja, ärgerlich weil vermeidbar, aber an sich kein Problem, man hat ja schliesslich ein journaling Filesystem.

Denkste.

Beim Booten weigert sich das Teil hartnäckig die Filesysteme wieder zu mounten. Die erste Befürchtung, daß er die Passphrase vergessen hat, läßt sich noch recht einfach zerstreuen:

 kiste:~# losetup -e twofish256 /dev/loop0 /data/crypt5
 Password:
 kiste:~# file -s /dev/loop0
 /dev/sda2: Linux rev 1.0 ext3 filesystem data (needs journal recovery)

Lang hält die Freude nicht an, denn mounten lässt es sich nicht. Das Journal hat irgendwelche interessanten Fehler…

 kiste:~# fsck /dev/loop0
 fsck 1.34 (25-Jul-2003)
 e2fsck 1.34 (25-Jul-2003)
 Superblock has a bad ext3 journal (inode 8).
 Clear<y>? yes
*** ext3 journal has been deleted - filesystem is now ext2 only ***

 Superblock doesn't have has_journal flag, but has ext3 journal inode.
 Clear<y>? yes

Und fährt dann dann fort, das FS komplett zu schreddern. Nicht gut.

Und wenn man es als ext2fs mounten will, bekommt man das im syslog:

 Jan 17 15:13:30 kiste kernel: EXT2-fs: loop(7,0): \
 couldn't mount because of unsupported optional features (4).

(Was ist denn das für eine Schizophrenie? Entweder optional, oder nicht!)

Unter FreeBSD hab ich dem ext2fs-kernelmodul mal zum Testen so gepatcht, daß es das Mounten trotzdem erlaubt, und siehe da, man sah einen Grossteil der Files. Leider konnte man aber nur einen kleinen Teil davon lesen…

Nun, mit debugfs kann man das journal zwar löschen, aber mounten kann mans nachher immer noch nicht. Damn. - Schauen wir uns nochmal genauer an, was fsck noch so alles sagt:

 Inode count in superblock is 640002, should be 640000.
 Fix<y>? yes

Hm. Strange. Ein Offset von 2 Inodes? Keine Ahnung wie sowas passieren kann…

 /dev/loop0 was not cleanly unmounted, check forced.
 Pass 1: Checking inodes, blocks, and sizes
 Group 0's block bitmap at 10 conflicts with some other fs block.
 Relocate<y>? 

Irgendwie klingt das ungesund. Was ist da wohl passiert?

Naja, nachdem auch schon der inode count kaputt ist, habe ich mir mal den Superblock-Inhalt angeschaut:

 kiste:~# debugfs /dev/loop0
 debugfs 1.34 (25-Jul-2003)
 debugfs: stats
 [...]

Die Werte sahen eigentlich alle gut aus… bis auf das da:

 Group  0: block bitmap at 10, inode bitmap at 3, inode table at 4
           4 free blocks, 15959 free inodes, 2 used directories

Die block bitmap (ja, die über die der fsck meckert) ist at 10. In den anderen Groups siehts so aus:

 Group  1: block bitmap at 32770, inode bitmap at 32771, inode table at 32772
           0 free blocks, 15793 free inodes, 85 used directories
 Group  2: block bitmap at 65536, inode bitmap at 65537, inode table at 65538
           0 free blocks, 15323 free inodes, 92 used directories

Da ist sie also genau immer eins vor der inode bitmap.

Da mir so langsam die Ideen ausgegangen sind, hab' ich mal ein bisschen in einem Hexdump des Filesystems rumgesucht:

 kiste:~# dd if=/dev/loop0 bs=512 count=20 of=t
 kiste:~# xxd <t >t.xxd
 kiste:~# vim t.xxd

<such such, fündig bei 0×1000>

 0001000: 0a00 0000 0300 0000 0400 0000 0400 573e  ...........…W>

genau die 3 Zahlen der Group 0 von oben. Machen wir also aus dem 0a ein 02, und schreiben es zurück:

 kiste:~# xxd -r <t.xxd >t.neu
 kiste:~# dd if=t.neu bs=512 of=/dev/loop0 conv=notrunc

und schmeissen den fsck nochmal an. Der sagt jetzt:

 Group 16's block bitmap at 524297 conflicts with some other fs block.
 Relocate<y>?

Hm. debugfs sagt uns wieder:

 Group 16: block bitmap at 524297, inode bitmap at 524289, inode table at 524290
           10275 free blocks, 15858 free inodes, 6 used directories

dumpe2fs hat die gleiche Information, nur für unseren Fall schöner aufbereitet:

 Group 16: (Blocks 524288-557055)
   Block bitmap at 524297 (+9), Inode bitmap at 524289 (+1)
   Inode table at 524290-524789 (+2)

beim Durchsehen, fällt einem nochmal das gleiche Problem in Group 32 auf:

 Group 32: (Blocks 1048576-1081343)
   Block bitmap at 1048586 (+10), Inode bitmap at 1048577 (+1)
   Inode table at 1048578-1049077 (+2)

Ok, gleich nochmal in t.xxd rumspielen.

 0001200: 0900 0800 0100 0800 0200 0800 2328 f23d  ............#(.=

machen wir aus dem 09 ein 00 und

 0001400: 0a00 1000 0100 1000 0200 1000 0000 363e  ...........…6>

ändern wir das 0a in ein 00. Dann schreiben wir es (wie oben) zurück:

 kiste:~# xxd -r <t.xxd >t.neu
 kiste:~# dd if=t.neu bs=512 of=/dev/loop0 conv=notrunc

Aber leider selbst jetzt ist das Filesystem noch recht kaputt. Der Versuch mit debugfs rdump Daten rauszukopieren erzeugt immernoch recht viele Fehler ;-/

Aber!

Ist euch was aufgefallen? Ja?

Die drei Stellen an denen wir was editiert haben sind 0×1000, 0×1200, 0×1400 - verdammt regelmässig, oder?

Schauen wir nochmal genauer auf die Änderungen:

         War   Soll
 0×1000  0A     02
 0×1200  09     00
 0×1400  0A     00

Hm. Der Unterschied ist in allen drei Fällen ungefähr gleich groß. Schauen wir uns das binär an:

         War    Soll  War XOR Soll
 0×1000  1010b  0010b   1000b
 0×1200  1001b  0000b   1001b
 0×1400  1010b  0000b   1010b

He. Das sieht aus wie ein Zähler. Und 0×200 (512) ist genau eine übliche Blockgröße.

Ein paar prüfende Blicke in den Hexdump zeigen, daß in allen Blöcken die nur aus 0-Bytes bestehen, am Anfang genau die Blocknummer drinsteht. Dieser Verdacht reicht für einen Test. Schnell ein C-Programm zusammengehackt, das ein File in 512-Byte-Blöcken kopiert, und immer vorne die Blocknummer reinXORt.

Gut, ein kurzer Dämpfer, weil fread() auf dem Linux hier coredumpt weil das File größer als 2G ist, aber das läßt sich mit den passenden #defines hinbiegen.

Schnell den Ursprungszustand wieder herstellen:

 kiste:~# dd if=t bs=512 of=/dev/loop0 conv=notrunc
 kiste:~# losetup -d /dev/loop0

Das Programm mal drüberlaufen lassen:

 kiste:~# gcc -o xorme -Wall xorme.c
 kiste:~# ./xorme crypt5 crypt5.out
 sector: 9c4000: err(eof?) while reading

Und sehen was rauskommt:

 kiste:~# losetup /dev/loop0 crypt5.out
 kiste:~# fsck /dev/loop0
 fsck 1.34 (25-Jul-2003)
 e2fsck 1.34 (25-Jul-2003)
 /dev/loop0: recovering journal
 /dev/loop0: clean, 18990/640000 files, 1205770/1280000 blocks

Yay!

Ein Test mit mount liefert auch das befriedigende Ergebniss, daß alle Dateien wieder vorhanden, und auch lesbar sind. Das macht einen glücklichen Kollegen, ein paar Tafeln Schokolade für mich, und wieder was über die Interna von ext2fs/ext3fs gelernt.

Bleibt eigentlich nur noch die Frage, wie das passieren konnte. Der aktuelle Verdacht ist, daß durch irgendein SuSe-Update sich was an dem crypto-loop Treiber geändert hat und das erst durch den Reboot (und damit verbundene reattach/remount) aufgefallen ist. Wenn irgendeiner der Leser da mehr Ahnung hat, wäre ich für einen Hinweis natürlich dankbar.

– Sec

Update: Das Problem ist SuSE bekannt und dort beschrieben. (Dank an Nick)

Seufz


posted at: 10:48 | Category: /rev-eng | permanent link to this entry | 1 comment (trackback)

Tue, 20 Dec 2005

Auslesen des BIOS-Passworts

Ein gerade mal 2 Wochen altes Posting auf bugtraq diskutiert neben diversen anderen (wenig überraschenden) Erkenntnissen zum BIOS-Passwort auch eine verblüffende Tatsache. Das BIOS benutzt einen Bereich im RAM als Tastaturpuffer, den es – selbst wenn man ein Passwort eingibt – nicht löscht. Nun kommt hinzu, daß der so günstig am Anfang des physikalischen Speichers liegt, das kein traditionelles OS (Windows, Linux, *BSD) den Bereich überschreibt.

Zum Ausprobieren schaut man einfach im RAM ab 0x041e jedes zweite Byte an. Auf einem unixoiden System z.B. so:

 dd if=/dev/mem bs=512 skip=2 count=1 | hexdump -C | head

Voila, da steht es. (Und nein, mein Passwort poste ich hier jetzt nicht ;)

– Sec


posted at: 23:28 | Category: /rev-eng | permanent link to this entry | 6 comments (trackback)

Wed, 07 Dec 2005

Installing unsigned drivers in Windows

If you install a Driver on Windows XP which is not blessed by Microsoft, you get a nasty Dialog box with a warning. - Microsoft tries to tell people this is for stability reasons - See this blog entry at The Old New Thing for someone arguing for it, and read the comments for reasons why this idea only sounds good in writing.

About a year ago this had also come up on the OpenVPN mailinglist (see here). Someone in that thread pointed out, that Microsoft says you can't change it in your program which tiggered my hacker gene to see how this could be done anyways.

Liberal usage of regmon revealed that the value is indeed stored in the Policy key of HKLM\Software\Microsoft\Driver Signing, but there was also a write to the PrivateHash key of HKLM\Software\Microsoft\Windows\CurrentVersion\Setup.

With the help of apispy it was easily found out that the PrivateHash is an MD5 hash of the 4-byte-extended value of the Policy Key and some seed. The Seed is the 4-byte value of the seed key from HKLM\System\WPA\PnP).

This was quickly written down in a small proof of concept program. - And please, don't even think about ugly things like automating a mouse click to acknowledge such a dialog box again. :)

– Sec


posted at: 17:53 | Category: /rev-eng | permanent link to this entry | 4 comments (trackback)

Wed, 21 Sep 2005

The author is displeased

Vereinfacht ausgedrückt ist reverse engineering (womit sich Einträge in der Kategorie /rev-eng beschäftigen) nur nötig wenn Mangel an Dokumentation herrscht. Manchmal ist keine Dokumentation da, weil die Leute zu faul waren, oder einfach garnicht daran gedacht haben, daß jemand diesen oder jenen Aspekt dokumentiert haben möchte.

Meistens allerdings handelt es sich eigentlich nur um Security by Obscurity. Seien es die in einer Konfigurationsdatei versteckten Paßwörter, selbsterfundene Fileformate die niemand anders lesen soll oder auch hardgecodete Paßwörter.

Das Problem dabei ist: Wenn man solche Dokumentationsmängel behebt, fühlt sich der Autor der Software oft auf den Schlips getreten.

Aus diesem Grund bekam ich vor kurzem eine Mail von einem Herrn Bippes, dem dieser Eintrag zum Paßwort von AfuP mißfiel.

Obwohl mich die Drohung der Mail, das Paßwort in der nächsten Version besser zu verstecken, eher dazu verleitet es darauf ankommen zu lassen (Es geht doch nichts über einen kleinen Wettkampf :-), habe ich mich trotzdem entschlossen, das Paßwort von der Seite zu entfernen.

Um es aber nochmal klar zu machen: Das Paßwort steht in o.g. Fall im Klartext im Binary. Wer es trotzdem nicht rausfindet, kann bei mir auch freundlich per E-Mail nachfragen.

Achja, das gilt auch für alle zukünftigen Einträge. Sollte, aus welchen Gründen auch immer, irgendeine Information auf diesen Seiten verschwinden, kann diese immer bei mir erfragt werden.

– Sec


posted at: 13:30 | Category: /rev-eng | permanent link to this entry | 1 comment (trackback)

Thu, 11 Aug 2005

Random ramblings about PSI, the jabber client

This is Blog-Repost: I did this earlier than the above Date suggests :)

PSI is a nice jabber client which I use mostly for work and also for some private contacts.

I had forgotten my jabber password, which was saved in PSI. I needed it to test another jabber client, so I wanted it back. But no, they had to make it unnecessarily hard. There is a commercial program to recover it, it is called AIMPR (Advanced IM Password Recovery) - But I dislike paying money for this.

So had to spend quite some time until i found the solution. I present it here, so others don't have to spend their time.

How to recover your jabber password from PSI.

  1. Search for your config.xml
  2. Extract the <jid> and <password> part from within your <account> group
  3. Decrypt by interpreting the password as hex 16bit-unicode, and XORing it to the jid.

If you have only Ascii characters in your password, you can try this line of perl:

perl -le '($jid,$pw)=@ARGV;$pw=~s/..(..)/chr hex$1/ge; \
          print substr($pw^$jid,0,length$pw)'  \
          user@jabber.server 000100020003007e

This information is relevant for PSI 0.92 - The author seemed displeased with me disclosing this information, so expect the algorithm to change.

Have fun.

Sec

P.S.: (added 2005-08-02)
WARNING: As it stands, PSI 0.10 and newer versions will remove saving of PGP passphrases completely. This means they will delete your PGP passphrase from the config file without notice!

The jabber password is still obfuscated the same way last time I checked.

P.P.S.: (added 2007-03-20)
There are of course other ways to recover the password. But I have to say, my method is much simpler and quicker :-)

P.P.P.S.: (added 2010-09-01)
This still works with PSI 0.13, although the config file name has changed to accounts.xml


posted at: 18:28 | Category: /rev-eng | permanent link to this entry | 32 comments (trackback)

Wed, 10 Aug 2005

Yet another Password

Blog-Repost. Original vom 2005-08-02

Ein paar Worte zu AfuP, also genauer gesagt, zur Offlineversion davon.

Ich persönlich habe ja garnichts mit Amateurfunken zu tun, aber ich kenne natürlich den einen oder anderen.

Nun wurde mir vor ein paar Tagen zugetragen, daß die Fragen die dem Programm beiliegen in einem verschlüsseltem ZIP sind.

Häh? Warum denn das?

Nun, derjenige wollte gerne eine Palm-Version schreiben, und fragte mich, ob ich nicht das Passwort herausfinden könnte.

Ich sah schon einen Abend mit einem Disassembler vor meinem geistigen Auge – die Praxis war aber dann doch bequemer.

strings *exe *DLL > DICT
zipcrack -d DICT Fragen/K23Fragen.qst

Voila:

Password recovered: xxxxxxxx

das war ja einfach. Alle sind glücklich, und ich kann AfuP wieder
deinstallieren.

P.S.: Einen Versuch habe ich mir dann doch noch gegönnt…

Technische Kenntnisse mit 55% und
Betriebliche Kenntnisse mit 50%.

naja, zum Afu tauge ich noch nicht ganz, aber ein bißchen Grundwissen scheine ich doch zu haben ;)

This information is relevant for AfuP150 - The author may be displeased with me disclosing this information and change the Password in later versions.

Have fun.

  –Sec

posted at: 17:23 | Category: /rev-eng | permanent link to this entry | 1 comment (trackback)

powered by blosxom
in 0.00 s