Skip to content

Commit 062ffc1

Browse files
committed
Added python2, python3, perl output options
1 parent 18cfeca commit 062ffc1

File tree

3 files changed

+132
-48
lines changed

3 files changed

+132
-48
lines changed

README.md

+41-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
[![img release](https://img.shields.io/github/commit-activity/m/Ooggle/shellcoding-companion.svg?sanitize=true&color=blue)](#)
2-
[![img last commit](https://img.shields.io/github/last-commit/Ooggle/shellcoding-companion.svg)](#)
3-
[![img last release](https://img.shields.io/github/release/Ooggle/shellcoding-companion.svg?color=red)](#)
4-
[![img last release](https://img.shields.io/twitter/follow/Ooggle_.svg?style=social)](https://twitter.com/Ooggle_)
1+
![](./.github/banner.png)
52

6-
# shellcoding-companion
3+
<p align="center">
4+
A python script to automatically generate shellcode payload from assembly files.
5+
<br>
6+
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Ooggle/shellcoding-companion">
7+
<img alt="img release" src="https://img.shields.io/github/commit-activity/m/Ooggle/shellcoding-companion.svg?sanitize=true&color=blue">
8+
<img alt="img last commit" src="https://img.shields.io/github/last-commit/Ooggle/shellcoding-companion.svg">
9+
<img alt="img last release" src="https://img.shields.io/github/release/Ooggle/shellcoding-companion.svg?color=red">
10+
<a href="https://twitter.com/intent/follow?screen_name=Ooggle_" title="Follow"><img src="https://img.shields.io/twitter/follow/Ooggle_?label=Ooggle_&style=social"></a>
11+
<br>
12+
</p>
713

8-
## Dependancies
14+
## Requirements
915

10-
- nasm
11-
- objdump
12-
- python3
13-
14-
## Setup
16+
To use this tool, you first need to install `nasm`, `objdump` and `python3`. You can install them with:
1517

1618
```sh
1719
sudo apt install nasm
@@ -20,5 +22,32 @@ sudo apt install nasm
2022
## Usage
2123

2224
```sh
23-
python3 shellcoding-companion.py -h
25+
$ ./shellcoding-companion.py -h
26+
27+
__ _ _ _ _ _
28+
/ _\ |__ ___| | | ___ ___ __| (_)_ __ __ _
29+
\ \| '_ \ / _ \ | |/ __/ _ \ / _` | | '_ \ / _` |
30+
_\ \ | | | __/ | | (_| (_) | (_| | | | | | (_| |
31+
\__/_| |_|\___|_|_|\___\___/ \__,_|_|_| |_|\__, |_v0.2.0
32+
/ __\___ _ __ ___ _ __ __ _ |___/(_) ___ _ __
33+
/ / / _ \| '_ ` _ \| '_ \ / _` | '_ \| |/ _ \| '_ \
34+
/ /__| (_) | | | | | | |_) | (_| | | | | | (_) | | | |
35+
\____/\___/|_| |_| |_| .__/ \__,_|_| |_|_|\___/|_| |_|
36+
By Ooggle |_| https://twitter.com/Ooggle_
37+
38+
39+
usage: ./shellcoding-companion.py [-h] [-o OUTPUT] [-p] source [source ...]
40+
41+
positional arguments:
42+
source NASM source(s) file(s) (Example: shellcode.s)
43+
44+
optional arguments:
45+
-h, --help show this help message and exit
46+
-o OUTPUT, --output OUTPUT
47+
Output file for the shellcode. (default: None)
48+
-p, --python Output python command to generate the shellcode from command line. (default: False)
2449
```
50+
51+
## Contributing
52+
53+
Pull requests are welcome. Feel free to open an issue if you want to add other features.

lib/shellcode_parser.py

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,42 @@
11
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
# File name : shellcode_parser.py
4+
# Author : Ooggle (@Ooggle_)
5+
# Date created : 21 Jun 2022
6+
7+
import os
28

3-
from os import popen, system
49

510
def asm_parse(pathname, label_start, opcode_end=False, debug=False):
6-
objdump = popen(f' objdump -d {pathname}').read().split('\n')
11+
objdump = os.popen(f'objdump -d {pathname}').read().split('\n')
712

813
# skip to start of shellcode
914
i = 0
1015
for i in range(len(objdump)):
1116
if label_start in objdump[i]:
1217
break
13-
i+= 1
18+
i += 1
1419

1520
shellcode = ''
1621
# start parsing
1722
while i < len(objdump):
1823
if objdump[i][10:32].rstrip() != '':
19-
shellcode+= objdump[i][10:32].rstrip() + ' '
24+
shellcode += objdump[i][10:32].rstrip() + ' '
2025
if opcode_end:
2126
if opcode_end in objdump[i]:
2227
break
23-
i+= 1
28+
i += 1
2429
else:
2530
break
26-
31+
2732
shellcode_len = len(shellcode.split(' ')) - 1
2833
if debug:
29-
print(f'Shellcode length: {(shellcode_len)}')
34+
print(f'Shellcode length: {(shellcode_len)}')
3035
print(shellcode)
3136
return shellcode, shellcode_len
3237

38+
3339
def asm_build(program_name):
34-
ret = system(f'nasm -f elf64 {program_name} -o {program_name}.o && ld -s ./{program_name}.o -o ./{program_name}.bin')
35-
system(f'rm -rf {program_name}.o')
40+
ret = os.system(f'nasm -f elf64 {program_name} -o {program_name}.o && ld -s ./{program_name}.o -o ./{program_name}.bin')
41+
os.system(f'rm -rf {program_name}.o')
3642
return ret

shellcoding-companion.py

100644100755
+76-27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
# File name : shellcode_parser.py
4+
# Author : Ooggle (@Ooggle_)
5+
# Date created : 21 Jun 2022
26

7+
import os
8+
import sys
39
from lib.shellcode_parser import asm_parse, asm_build
410
from binascii import unhexlify
511
import argparse
@@ -22,57 +28,100 @@
2228

2329
print(banner)
2430

31+
2532
def parse_args():
2633
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)")
3245
args = parser.parse_args()
33-
#parser.print_help()
3446
return args
3547

48+
3649
if __name__ == '__main__':
3750
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+
3960
# 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')
4162
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='')
4364
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')
4868

4969
# 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')
5171
bytecodes = []
5272
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')
5474
(tmpbytes, _) = asm_parse(f'{source}.bin', '<.text>')
5575
bytecodes.append([unhexlify(b) for b in tmpbytes.split(' ') if b != ''])
5676

57-
5877
# saving final shellcode to file
5978
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:
6382
for bytecode in bytecodes:
6483
for b in bytecode:
6584
f.write(b)
66-
print(f'\x1b[0;32m[+] done\x1b[0m')
6785

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')
70116

71-
print('python2 -c \'print "', end='')
117+
hex_bytecodes = ""
72118
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
75124

76-
print('"\'')
125+
print(f'perl -e \'print "{hex_bytecodes}"\'')
77126

78-
print('\n\x1b[1;32m[+] done\x1b[0m\n')
127+
print('\n\x1b[1;32m[+] Done!\x1b[0m\n')

0 commit comments

Comments
 (0)