|
1 | 1 | #!/usr/bin/env python3
|
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +# File name : shellcode_parser.py |
| 4 | +# Author : Ooggle (@Ooggle_) |
| 5 | +# Date created : 21 Jun 2022 |
2 | 6 |
|
| 7 | +import os |
| 8 | +import sys |
3 | 9 | from lib.shellcode_parser import asm_parse, asm_build
|
4 | 10 | from binascii import unhexlify
|
5 | 11 | import argparse
|
|
22 | 28 |
|
23 | 29 | print(banner)
|
24 | 30 |
|
| 31 | + |
25 | 32 | def parse_args():
|
26 | 33 | parser = argparse.ArgumentParser(
|
27 |
| - prog='shellcoding-companion.py', |
28 |
| - formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
29 |
| - parser.add_argument('-o', '--output', nargs=1, help='output file for the shellcode') |
30 |
| - parser.add_argument('-p', '--python', action=argparse.BooleanOptionalAction, help='output python command to generate the shellcode from command line', metavar='') |
31 |
| - parser.add_argument('source', nargs='+', help='nasm source(s) file(s) (Example: shellcode.s)') |
| 34 | + prog=sys.argv[0], |
| 35 | + formatter_class=argparse.ArgumentDefaultsHelpFormatter |
| 36 | + ) |
| 37 | + parser.add_argument("-o", "--output", default=None, help="Output file for the shellcode.") |
| 38 | + |
| 39 | + group = parser.add_argument_group(description="Output languages") |
| 40 | + group.add_argument("-p2", "--python2", default=False, action="store_true", help='Output python2 command to generate the shellcode from command line.') |
| 41 | + group.add_argument("-p3", "--python3", default=False, action="store_true", help='Output python3 command to generate the shellcode from command line.') |
| 42 | + group.add_argument("-P", "--perl", default=False, action="store_true", help='Output perl command to generate the shellcode from command line.') |
| 43 | + |
| 44 | + parser.add_argument("source", nargs="+", help="NASM source(s) file(s) (Example: shellcode.s)") |
32 | 45 | args = parser.parse_args()
|
33 |
| - #parser.print_help() |
34 | 46 | return args
|
35 | 47 |
|
| 48 | + |
36 | 49 | if __name__ == '__main__':
|
37 | 50 | args = parse_args()
|
38 |
| - |
| 51 | + |
| 52 | + if len(os.popen("which nasm").read()) == 0: |
| 53 | + print("\x1b[1;31m[!] Missing requirement: nasm\x1b[0m") |
| 54 | + exit(0) |
| 55 | + |
| 56 | + if len(os.popen("which objdump").read()) == 0: |
| 57 | + print("\x1b[1;31m[!] Missing requirement: objdump\x1b[0m") |
| 58 | + exit(0) |
| 59 | + |
39 | 60 | # building shellcode(s)
|
40 |
| - print(f'\x1b[1;32m[+] building shellcode(s): {args.source}\x1b[0m') |
| 61 | + print(f'\x1b[1;32m[+] Building shellcode(s): {args.source}\x1b[0m') |
41 | 62 | for source in args.source:
|
42 |
| - print(f'\x1b[0;32m[+] {source}...\x1b[0m', end='') |
| 63 | + print(f'\x1b[0;32m[+] {source} ...\x1b[0m', end='') |
43 | 64 | if asm_build(source) != 0:
|
44 |
| - print(f'\x1b[1;31m[-] ERROR: build failed for "{source}"\x1b[0m') |
45 |
| - quit(1) |
46 |
| - print(f'\x1b[1;32m success\x1b[0m') |
47 |
| - |
| 65 | + print(f'\x1b[1;31m[!] ERROR: build failed for "{source}"\x1b[0m') |
| 66 | + exit(1) |
| 67 | + print(f'\x1b[1;32m Success!\x1b[0m') |
48 | 68 |
|
49 | 69 | # parsing shellcode(s)
|
50 |
| - print('\n\x1b[1;32m[+] parsing shellcode(s)\x1b[0m') |
| 70 | + print('\n\x1b[1;32m[+] Parsing shellcode(s)\x1b[0m') |
51 | 71 | bytecodes = []
|
52 | 72 | for source in args.source:
|
53 |
| - print(f'\x1b[0;32m[+] {source}.bin...\x1b[0m') |
| 73 | + print(f'\x1b[0;32m[+] {source}.bin ...\x1b[0m') |
54 | 74 | (tmpbytes, _) = asm_parse(f'{source}.bin', '<.text>')
|
55 | 75 | bytecodes.append([unhexlify(b) for b in tmpbytes.split(' ') if b != ''])
|
56 | 76 |
|
57 |
| - |
58 | 77 | # saving final shellcode to file
|
59 | 78 | if args.output:
|
60 |
| - print(f'\n\x1b[1;32m[+] saving shellcode to "{args.output[0]}"\x1b[0m') |
61 |
| - |
62 |
| - with open(args.output[0], 'wb') as f: |
| 79 | + print(f'\n\x1b[1;32m[+] Saving shellcode to "{args.output}"\x1b[0m') |
| 80 | + |
| 81 | + with open(args.output, 'wb') as f: |
63 | 82 | for bytecode in bytecodes:
|
64 | 83 | for b in bytecode:
|
65 | 84 | f.write(b)
|
66 |
| - print(f'\x1b[0;32m[+] done\x1b[0m') |
67 | 85 |
|
68 |
| - if args.python: |
69 |
| - print(f'\n\x1b[1;32m[+] generating python command\x1b[0m') |
| 86 | + print(f'\x1b[0;32m[+] Done! {sum([len(b) for b in bytecodes])} bytes written to {args.output}\x1b[0m') |
| 87 | + |
| 88 | + if args.python2: |
| 89 | + print(f'\n\x1b[1;32m[+] Generating python command\x1b[0m') |
| 90 | + |
| 91 | + hex_bytecodes = "" |
| 92 | + for bytecode in bytecodes: |
| 93 | + hex_bytecode = ''.join([ |
| 94 | + '\\x' + hex(int.from_bytes(c, 'big'))[2:].rjust(2, '0') |
| 95 | + for c in bytecode |
| 96 | + ]) |
| 97 | + hex_bytecodes += hex_bytecode |
| 98 | + |
| 99 | + print(f'python2 -c \'print "{hex_bytecodes}"\'') |
| 100 | + |
| 101 | + if args.python3: |
| 102 | + print(f'\n\x1b[1;32m[+] Generating python command\x1b[0m') |
| 103 | + |
| 104 | + hex_bytecodes = "" |
| 105 | + for bytecode in bytecodes: |
| 106 | + hex_bytecode = ''.join([ |
| 107 | + '\\x' + hex(int.from_bytes(c, 'big'))[2:].rjust(2, '0') |
| 108 | + for c in bytecode |
| 109 | + ]) |
| 110 | + hex_bytecodes += hex_bytecode |
| 111 | + |
| 112 | + print(f'python3 -c \'print "{hex_bytecodes}"\'') |
| 113 | + |
| 114 | + if args.perl: |
| 115 | + print(f'\n\x1b[1;32m[+] Generating perl command\x1b[0m') |
70 | 116 |
|
71 |
| - print('python2 -c \'print "', end='') |
| 117 | + hex_bytecodes = "" |
72 | 118 | for bytecode in bytecodes:
|
73 |
| - for c in bytecode: |
74 |
| - print('\\x' + hex(int.from_bytes(c, 'big'))[2:].rjust(2, '0'), end='') |
| 119 | + hex_bytecode = ''.join([ |
| 120 | + '\\x' + hex(int.from_bytes(c, 'big'))[2:].rjust(2, '0') |
| 121 | + for c in bytecode |
| 122 | + ]) |
| 123 | + hex_bytecodes += hex_bytecode |
75 | 124 |
|
76 |
| - print('"\'') |
| 125 | + print(f'perl -e \'print "{hex_bytecodes}"\'') |
77 | 126 |
|
78 |
| - print('\n\x1b[1;32m[+] done\x1b[0m\n') |
| 127 | + print('\n\x1b[1;32m[+] Done!\x1b[0m\n') |
0 commit comments