Assembly AT&T on BSD + Making shellc0de for FreeBSD System - by myw1sd0m this article was written by : myw1sd0m a.k.a wisdomc0de greets: peneter,gunslinger, flyf666, superman,ketek,chaer,we nkhairu,wahyu,n0te,blackn0te,kumbang and all devilzc0de crew and members I'm getting dizzy while modifying worm into botnet, so let's play before we start develop again. Today We're gonna play on a toy : Assembly Toys on BSD + Making shellc0de on FreeBSD i386 Machine ------------------------------ * uname -a we'll be using freebsd 6.3 here: %uname -a FreeBSD whereisthehostnameasshole 6.3-PRERELEASE FreeBSD 6.3-PRERELEASE #1 whereisthedateasshole we're goin to use gnu asm as our compiler today * Syscalls syscall lists at freebsd located at :/usr/src/sys/sys/syscall.h at first we're goin to write a little program that display this string: devilzc0de as always it will invoke these syscalls: 1. sys_write the c declaration is : ssize_t write(int fd, const void *buf, size_t count); %cat /usr/src/sys/sys/syscall.h | grep write #define SYS_write 4 /* 68 is obsolete vwrite */ #define SYS_writev 121 #define SYS_pwrite 174 #define SYS_pwritev 290 #define SYS_aio_write 319 -------------- yeah we're goin to use this: #define SYS_write 4 %eax will be $4 (sys_write) %ebx goes our fd number , 0=stdin 1=stdout and 2=stderr (http://en.wikipedia.org/wiki/File_descriptor) %ebx goes for buffer %edx goest for string length %ebx (fd) ---------- %ecx (buf)---------------%edx (size, i meant length of devilzc0de string)----------------------%esi-------------------%edi where %eax will be our retval. this scheme always happen on every syscall below 6 arg(s), so if it's 4 args the next arg will be on %esi and if it's 5 args the next will be at %edi ------------------ %pico devilzc0de.s UW PICO(tm) 4.10 File: devilzc0de.s so to make these sys_write with string devilzc0de, here is our code sys_write and it ends with a sys_exit: ------------------------- .section .rodata evilbuf: .ascii "devilzc0de" len = . - evilbuf .globl _start _start: pushl $len pushl $evilbuf pushl $1 movl $4,%eax pushl %eax int $0x80 _out: movl $1, %eax pushl $0 pushl %eax int $0x80 -------------------- to assemble just type these: %as -o devilzc0de.o devilzc0de.s then we can linker: %ld -o devilzc0de devilzc0de.o %./devilzc0de devilzc0de% we may see the arguments from each syscalls that we've executed above using strace: ----------------------- %strace ./devilzc0de execve(0xbfbfe760, [0xbfbfec48], [/* 0 vars */]) = 0 write(1, "devilzc0de", 10devilzc0de) = 10 exit(0) = ? % ------------------------- write(1, "devilzc0de", 10devilzc0de) = 10 fs=1 -> stdout next is content of buffer: devilzc0de string length=10 exit(0) -> we exit with 0 as our return value as we may see here: --------------- %echo $? 0 % --------------- we may exit with other retval: %cat keluar.s .globl _start _start: movl $1, %eax pushl $1 pushl %eax int $0x80 %as -o keluar.o keluar.s %ld -o keluar keluar.o %./keluar %echo $? 1 % * Making exit shellcode ok let's try to make an exit shellcode example from this asm code: %cat keluar.s .globl _start _start: movl $1, %eax pushl $1 pushl %eax int $0x80 %objdump -d keluar keluar: file format elf32-i386-freebsd Disassembly of section .text: 08048074 <_start>: 8048074: b8 01 00 00 00 mov $0x1,%eax 8048079: 6a 01 push $0x1 804807b: 50 push %eax 804807c: cd 80 int $0x80 here's the freebsd shellc0de: \xb8\x01\x00\x00\x00\x6a\x01\x50\xcd\x80 then we must avoid null byte by changing $eax to %al (we must switch movl to mov because movl means mov long), we've made our new shellcode: %objdump -d keluar keluar: file format elf32-i386-freebsd Disassembly of section .text: 08048074 <_start>: 8048074: b0 01 mov $0x1,%al 8048076: 6a 01 push $0x1 8048078: 50 push %eax 8048079: cd 80 int $0x80 % so our final shellcode is: \xb0\x01\x6a\x01\x50\xcd\x80 let's using in our c: /**freebsd exit shellcode with return value : 1 made by: mywisdom**/ #include char shellcode[] = "\xb0\x01\x6a\x01\x50\xcd\x80"; int main() { fprintf(stdout,"Length: %d\n",strlen(shellcode)); (*(void(*)()) shellcode)(); } %gcc -o x x.c %./x Length: 7 % length=7 ??? have a look below: \xb0 \ x01 \ x6a \ x01 \ x50 \ xcd \ x80 1 2 3 4 5 6 7 each hex split represent 1 decimal Length: %d\n",strlen(shellcode) * the inline asm for inline asm we may use: __asm__(" asm code here") or we may use: asm(" asm code here ") how to insert aboce freebsd asm code inlinely?? here they come: #include int main() { __asm__("mov $0x1,%al\t\n" "push $0x1\t\n" "push %eax\t\n" "int $0x80"); } * asm volatile technic this asm volatile tehcnic will force gcc not to optimize our asm code until this asm finish here if we're gonna use asm volatile: ---------------- #include int main() { asm volatile("mov $0x1,%al\t\n" "push $0x1\t\n" "push %eax\t\n" "int $0x80"); } -------------------