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");

}
-------------------