SIGSEGV safe generation with mutation control

master
JoYo 2019-02-19 03:25:00 +00:00
parent 01d309f81f
commit 9aca501928
3 changed files with 44 additions and 20 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,6 +3,8 @@ 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
@ -27,7 +29,15 @@ seed_shell = b''.join([
b'\xc3'])
def shell_func(shellcode: bytes):
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)
@ -39,7 +49,10 @@ def shell_func(shellcode: bytes):
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():
@ -49,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
@ -84,17 +99,31 @@ def sins():
with seed.open('rb') as seed_file:
seed_data = seed_file.read()
seed_data = bytearray(seed_data)
logger.info(f'seed:\n{seed_data}')
offset = randint(0, len(seed_data))
flip = randint(0, 255)
seed_data[offset] ^= flip
queue = Queue()
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}')
while True:
lineage = 0
seed_flipped = flip(seed_data)
seed = shell_func(seed_shell)
ret_val = seed(seed_len)
while lineage < args.lineage:
logger.info(f'lineage: {lineage}')
result = None
logger.info(f'ret_val: {ret_val}')
proc = Process(target=generation, args=(queue, seed_flipped))
proc.start()
try:
result = queue.get(timeout=1)
except Empty:
lineage += 1
continue
if not result:
lineage += 1
continue
logger.info(f'scrap:\n{seed_flipped}')
logger.info(f'result: {result}')
lineage = 0
seed_flipped = flip(seed_flipped)