Skip to content

Instantly share code, notes, and snippets.

@integeruser
Last active July 6, 2019 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save integeruser/0c87f46f82d40a36e6a9901059f09ffd to your computer and use it in GitHub Desktop.
Save integeruser/0c87f46f82d40a36e6a9901059f09ffd to your computer and use it in GitHub Desktop.
A shellcoding helper
#!/usr/bin/env python3
import argparse
import os
import re
import subprocess
import tempfile
BAD_BYTES = {0x00, 0x0a, 0x0d}
def exec(cmd, capture_stdout=True):
if capture_stdout:
p = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
return p.returncode, p.stdout.decode('ascii').strip()
else:
p = subprocess.run(cmd, shell=True)
return p.returncode, ''
parser = argparse.ArgumentParser()
parser.add_argument('infile', help='the shellcode file')
parser.add_argument('action', nargs='?', choices=['d', 'o', 'p', 'r'], default='p')
parser.add_argument('-m64', action='store_true', help='if present, assemble and link for x86-64')
args = parser.parse_args()
outfile, _ = os.path.splitext(os.path.basename(args.infile))
outfile = os.path.join(tempfile.gettempdir(), outfile)
outfile_bin = '{outfile}.bin'.format(outfile=outfile)
outfile_o = '{outfile}.o'.format(outfile=outfile)
nasm_fmt = 'elf64' if args.m64 else 'elf32'
ld_emu = 'elf_x86_64' if args.m64 else 'elf_i386'
if args.action == 'p':
returncode, _ = exec('nasm -f bin -o {} {}'.format(outfile_bin, args.infile))
if returncode == 0:
print(outfile_bin, os.path.getsize(outfile_bin))
with open(outfile_bin, 'rb') as f:
shellcode = f.read()
print(''.join(('%.2x' if c not in BAD_BYTES else '\x1B[31m%.2x\x1B[0m') % c for c in shellcode))
print(''.join(('\\x%.2x' if c not in BAD_BYTES else '\x1B[31m\\x%.2x\x1B[0m') % c for c in shellcode))
elif args.action == 'o':
returncode, stdout = exec(
'nasm -f {0} -o {1} {2} && objdump -D -M intel {1}'.format(nasm_fmt, outfile_o, args.infile))
if returncode == 0:
dump = stdout[stdout.index('00000000 <_start>:'):]
bad_bytes_re = '(\s)(' + '|'.join('%.2x' % b for b in BAD_BYTES) + ')'
print(re.sub(bad_bytes_re, '\\1\x1B[31m\\2\x1B[0m', dump))
elif args.action == 'd' or args.action == 'r':
returncode, stdout = exec(
'nasm -f {0} -o {1} {2} && ld -N -m {3} -o {4} {1}'.format(nasm_fmt, outfile_o, args.infile, ld_emu, outfile))
if returncode == 0:
if args.action == 'd':
exec('gdb -q {0} -ex=start'.format(outfile), capture_stdout=False)
elif args.action == 'r':
exec('{0}'.format(outfile), capture_stdout=False)
bits 32
section .text
global _start
_start:
push 0
push 0
push 0
push 0
mov edi, esp
push 0
push '//sh'
push '/bin'
mov [edi], esp
push 0
push '-c'
mov [edi+4], esp
push 0
push 'mi'
push 'whoa'
mov [edi+8], esp
;;;;; call execve(filename, argv, envp)
mov ebx, [edi]
mov ecx, edi
xor edx, edx
xor eax, eax
mov al, 0xb
int 0x80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment