shellforge 0.2.0pre6 review
DownloadShellForge is a python program that builds shellcodes from C
|
|
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).
#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!
x55x89xe5x83xecx24x53xe8x00x00x00x00x5bx83xc3xf4x8bx83x67x00
x00x00x89x45xf0x8bx83x6bx00x00x00x89x45xf4x8bx83x6fx00x00x00
x89x45xf8x0fxb7x83x73x00x00x00x66x89x45xfcx8dx4dxf0xbax0ex00
x00x00xb8x04x00x00x00xc7x45xecx01x00x00x00x53x8bx59xfcxcdx80
x5bxb8x01x00x00x00xc7x45xecx00x00x00x00x53x8bx59xfcxcdx80x5b
x5bxc9xc3x48x65x6cx6cx6fx20x77x6fx72x6cx64x21x0ax00
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[] =
"x55x89xe5x83xecx24x53xe8x00x00x00x00x5bx83xc3xf4x8bx83x67"
"x00x00x00x89x45xf0x8bx83x6bx00x00x00x89x45xf4x8bx83x6fx00"
"x00x00x89x45xf8x0fxb7x83x73x00x00x00x66x89x45xfcx8dx4dxf0"
"xbax0ex00x00x00xb8x04x00x00x00xc7x45xecx01x00x00x00x53x8b"
"x59xfcxcdx80x5bxb8x01x00x00x00xc7x45xecx00x00x00x00x53x8b"
"x59xfcxcdx80x5bx5bxc9xc3x48x65x6cx6cx6fx20x77x6fx72x6cx64"
"x21x0ax00";
int main(void) { ((void (*)())shellcode)(); }
We can use an xor loader to avoid x00 bytes in the shellcode
$ ./shellforge.py -v0 -x hello.c
xebx0dx5ex31xc9xb1x75x80x36x02x46xe2xfaxebx05xe8xeexffxffxff
x57x8bxe7x81xeex26x51xeax02x02x02x02x59x81xc1xf6x89x81x65x02
x02x02x8bx47xf2x89x81x69x02x02x02x8bx47xf6x89x81x6dx02x02x02
x8bx47xfax0dxb5x81x71x02x02x02x64x8bx47xfex8fx4fxf2xb8x0cx02
x02x02xbax06x02x02x02xc5x47xeex03x02x02x02x51x89x5bxfexcfx82
x59xbax03x02x02x02xc5x47xeex02x02x02x02x51x89x5bxfexcfx82x59
x59xcbxc1x4ax67x6ex6ex6dx22x75x6dx70x6ex66x23x08x02
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
hAAAAX5AAAAHPPPPPPPPah0B20X5Tc80Ph0504X5GZBXPh445AX5XXZaPhAD00X5wxx
UPTYII19hA000X5sOkkPTYII19h0000X5cDi3PTY19I19I19I19h0000X50000Ph0A0AX50yu
RPTY19I19I19I19h0000X5w100PTYIII19h0A00X53sOkPTYI19h0000X50cDiPTYI19I19hA000X5
R100PTYIII19h00A0X500yuPTYI19I19h0000X50w40PTYII19I19h0600X5u800PTYIII19h0046X53
By9PTY19I19I19h0000X50VFuPTYI19I19h0000X5LC00PTYIII19h0060X5u79xPTY19I19I19I19h
0000X5000FPTY19I19h2005X59DLZPTYI19h0000X500FuPTYI19I19h0010X5DLZ0PTYII19h0006
X50Fu9PTY19I19I19I19h0000X5LW00PTYIII19h0D20X5Lx9DPTY19h0000X5000kPhA0A0X5ec
V0PTYI19I19h0B0AX5FXLRPTY19h5550X5ZZZePTYI19??
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,"erreurn",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);
}
Requirements:
Add features/limitations/changes here
shellforge 0.2.0pre6 keywords