scrap-is-not-scrap/sins/run.py

101 lines
2.8 KiB
Python
Raw Normal View History

#! /usr/bin/env python3
from argparse import ArgumentParser
from datetime import datetime
from pathlib import Path
from random import randint
import binascii
import ctypes
import logging
import mmap
2019-02-19 00:15:48 +00:00
template_shell = b''.join([
b'\x55', # push rbp
b'\x48\x89\xe5', # mov rbp,rsp
b'\x48\x89\x7d\xf8', # mov QWORD [rbp-0x8],rdi
b'\x48\x8b\x45\xf8', # mov rax,QWORD [rbp-0x8]
b'\x5d', # pop rbp
b'\xc3']) # ret
seed_shell = b''.join([
b'\x55',
b'\x48\x89\xe5',
b'\x90' * randint(8, 64),
b'\x48\x89\x7d\xf8',
b'\x90' * randint(8, 64),
b'\x48\x8b\x45\xf8',
b'\x5d',
b'\xc3'])
2019-02-18 23:16:25 +00:00
def shell_func(shellcode: bytes):
2019-02-18 23:40:19 +00:00
prot = mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC
flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE
exec_mem = mmap.mmap(-1, len(shellcode), prot=prot, flags=flags)
2019-02-18 23:16:25 +00:00
exec_mem.write(shellcode)
ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
2019-02-18 23:40:19 +00:00
addr = ctypes.addressof(ctypes_buffer)
function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)(addr)
2019-02-18 23:16:25 +00:00
function._avoid_gc_for_mmap = exec_mem
return function
def sins():
now = '{0:%Y%m%dT%H%M%S}'.format(datetime.utcnow())
parser = ArgumentParser(
description='position independent code (PIC) mutation experiment.')
parser.add_argument('-v', '--verbose', action='count')
2019-02-18 23:16:25 +00:00
parser.add_argument('-s', '--seed', help='path to PIC image.')
parser.add_argument('-o', '--output', help='path to results directory.')
args = parser.parse_args()
log_level = logging.INFO
log_format = logging.Formatter('%(message)s')
if args.verbose:
log_level = logging.DEBUG
log_format = logging.Formatter(
'%(levelname)s %(filename)s:%(lineno)d\n%(message)s\n')
logger = logging.getLogger('sins')
logger.setLevel(log_level)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(log_level)
stream_handler.setFormatter(log_format)
logger.addHandler(stream_handler)
if args.output:
log_path = f'{args.output}/sins-{now}.log'
file_handler = logging.FileHandler(log_path)
file_handler.setLevel(log_level)
file_handler.setFormatter(log_format)
logger.addHandler(file_handler)
2019-02-18 23:16:25 +00:00
logger.info(now)
seed_data = seed_shell
if args.seed:
seed = Path(args.seed)
with seed.open('rb') as seed_file:
seed_data = seed_file.read()
2019-02-19 00:28:34 +00:00
seed_data = bytearray(seed_data)
offset = randint(0, len(seed_data))
flip = randint(0, 255)
seed_data[offset] ^= flip
2019-02-19 00:15:48 +00:00
seed_len = ctypes.c_uint(len(seed_data))
logger.info(f'seed_data\n{binascii.b2a_hex(seed_data)}')
logger.info(f'seed_len: {seed_len}')
2019-02-18 23:16:25 +00:00
seed = shell_func(seed_shell)
2019-02-19 00:15:48 +00:00
ret_val = seed(seed_len)
2019-02-18 23:16:25 +00:00
logger.info(f'ret_val: {ret_val}')