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' version: '3'
services: services:
sins_build: sins_run:
image: sins image: sins
build: build:
context: . context: .
volumes: volumes:
- ${PWD}:/app - ${PWD}:/app
working_dir: /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: python3 -m sins
# command: yasm seed.asm -o seed

View File

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

View File

@ -3,29 +3,56 @@ from argparse import ArgumentParser
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from random import randint from random import randint
from multiprocessing import Process, Queue
from queue import Empty
import binascii import binascii
import ctypes import ctypes
import logging import logging
import subprocess
import mmap 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" template_shell = b''.join([
seed_shell = b'U\x90H\x89\xe5\x90H\x89}\xf8\x90H\x8bE\xf8\x90]\x90\xc3' 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): seed_shell = b''.join([
exec_mem = mmap.mmap( b'\x55',
-1, len(shellcode), b'\x48\x89\xe5',
prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC, b'\x90' * randint(8, 64),
flags=mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE) 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) exec_mem.write(shellcode)
ctypes_buffer = ctypes.c_int.from_buffer(exec_mem) ctypes_buffer = ctypes.c_int.from_buffer(exec_mem)
function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)( addr = ctypes.addressof(ctypes_buffer)
ctypes.addressof(ctypes_buffer))
function = ctypes.CFUNCTYPE(ctypes.c_uint, ctypes.c_uint)(addr)
function._avoid_gc_for_mmap = exec_mem 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(): def sins():
@ -35,6 +62,8 @@ def sins():
parser.add_argument('-v', '--verbose', action='count') parser.add_argument('-v', '--verbose', action='count')
parser.add_argument('-s', '--seed', help='path to PIC image.') parser.add_argument('-s', '--seed', help='path to PIC image.')
parser.add_argument('-o', '--output', help='path to results directory.') 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() args = parser.parse_args()
log_level = logging.INFO log_level = logging.INFO
@ -70,35 +99,31 @@ def sins():
with seed.open('rb') as seed_file: with seed.open('rb') as seed_file:
seed_data = seed_file.read() seed_data = seed_file.read()
logger.info(f'seed_data\n{seed_data}') logger.info(f'seed:\n{seed_data}')
logger.info(f'seed_len: {len(seed_data)}')
seed = shell_func(seed_shell) queue = Queue()
ret_val = seed(ctypes.c_uint(len(seed_data)))
logger.info(f'ret_val: {ret_val}') while True:
lineage = 0
seed_flipped = flip(seed_data)
def func_void(shellcode: bytes): while lineage < args.lineage:
exec_mem = mmap.mmap( logger.info(f'lineage: {lineage}')
-1, len(shellcode), result = None
prot=mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC,
flags=mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE)
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) if not result:
function = ctypes.CFUNCTYPE(ctypes.c_int64)( lineage += 1
ctypes.addressof(ctypes_buffer)) continue
function._avoid_gc_for_mmap = exec_mem
return function logger.info(f'scrap:\n{seed_flipped}')
logger.info(f'result: {result}')
lineage = 0
def example(): seed_flipped = flip(seed_flipped)
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)