Compare commits

...

4 Commits

Author SHA1 Message Date
JoYo 9aca501928 SIGSEGV safe generation with mutation control 2019-02-19 03:25:00 +00:00
JoYo 01d309f81f flippin dangerous 2019-02-19 00:28:34 +00:00
JoYo 908248905a minor doc 2019-02-19 00:15:48 +00:00
JoYo 001641dfb9 cleaning up code a bit 2019-02-18 23:40:19 +00:00
3 changed files with 66 additions and 46 deletions

View File

@ -1,16 +1,11 @@
version: '3'
services:
sins_build:
sins_run:
image: sins
build:
context: .
volumes:
- ${PWD}:/app
working_dir: /app
command: yasm seed.asm -o seed
sins_run:
image: sins
volumes:
- ${PWD}:/app
working_dir: /app
command: python3 -m sins
# command: yasm seed.asm -o seed

View File

@ -1,3 +1,3 @@
#! /usr/bin/env python3
from .run import sins, shell_func
from .run import sins, generation
# from .orm import SeedNode

View File

@ -3,29 +3,56 @@ from argparse import ArgumentParser
from datetime import datetime
from pathlib import Path
from random import randint
from multiprocessing import Process, Queue
from queue import Empty
import binascii
import ctypes
import logging
import subprocess
import mmap
whoami_shell = b"\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53\x48\x89\xe7\x68\x2d\x63\x00\x00\x48\x89\xe6\x52\xe8\x10\x00\x00\x00\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x77\x68\x6f\x61\x6d\x69\x00\x56\x57\x48\x89\xe6\x0f\x05"
seed_shell = b'U\x90H\x89\xe5\x90H\x89}\xf8\x90H\x8bE\xf8\x90]\x90\xc3'
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
def shell_func(shellcode: bytes):
exec_mem = mmap.mmap(
-1, len(shellcode),
prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
flags=mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)
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'])
def flip(shellcode: bytes):
shellcode = bytearray(shellcode)
offset = randint(0, len(shellcode) -1)
flip = randint(0, 255)
shellcode[offset] ^= flip
return bytes(shellcode)
def generation(queue: Queue, shellcode: bytes):
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)
exec_mem.write(shellcode)
ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)(
ctypes.addressof(ctypes_buffer))
addr = ctypes.addressof(ctypes_buffer)
function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)(addr)
function._avoid_gc_for_mmap = exec_mem
return function
shellcode_len = ctypes.c_uint(len(shellcode))
result = function(shellcode_len)
queue.put(result)
def sins():
@ -35,6 +62,8 @@ def sins():
parser.add_argument('-v', '--verbose', action='count')
parser.add_argument('-s', '--seed', help='path to PIC image.')
parser.add_argument('-o', '--output', help='path to results directory.')
parser.add_argument('-l', '--lineage', default=10,
help='max count of unsuccessful generation.')
args = parser.parse_args()
log_level = logging.INFO
@ -70,35 +99,31 @@ def sins():
with seed.open('rb') as seed_file:
seed_data = seed_file.read()
logger.info(f'seed_data\n{seed_data}')
logger.info(f'seed_len: {len(seed_data)}')
logger.info(f'seed:\n{seed_data}')
seed = shell_func(seed_shell)
ret_val = seed(ctypes.c_uint(len(seed_data)))
queue = Queue()
logger.info(f'ret_val: {ret_val}')
while True:
lineage = 0
seed_flipped = flip(seed_data)
def func_void(shellcode: bytes):
exec_mem = mmap.mmap(
-1, len(shellcode),
prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
flags=mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)
while lineage < args.lineage:
logger.info(f'lineage: {lineage}')
result = None
exec_mem.write(shellcode)
proc = Process(target=generation, args=(queue, seed_flipped))
proc.start()
try:
result = queue.get(timeout=1)
except Empty:
lineage += 1
continue
ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
function = ctypes.CFUNCTYPE(ctypes.c_int64)(
ctypes.addressof(ctypes_buffer))
function._avoid_gc_for_mmap = exec_mem
if not result:
lineage += 1
continue
return function
def example():
logging.basicConfig(level=logging.DEBUG)
logging.info(whoami_shell)
logging.info('wtfm8')
whoami = func_void(whoami_shell)
ret_val = whoami()
# whoami doesn't ret
logging.info(ret_val)
logger.info(f'scrap:\n{seed_flipped}')
logger.info(f'result: {result}')
lineage = 0
seed_flipped = flip(seed_flipped)