Assembly AT&T on BSD + Making shellc0de for FreeBSD System
by cr0security
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 <stdio.h>
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 above freebsd asm code inlinely?? here they come:
#include <stdio.h>
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 <stdio.h>
int main()
{
asm volatile("mov $0x1,%al\t\n"
"push $0x1\t\n"
"push %eax\t\n"
"int $0x80");
}
-------------------