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' 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,6 +3,8 @@ 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
@ -27,7 +29,15 @@ seed_shell = b''.join([
b'\xc3']) 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 prot = mmap.PROT_READ | mmap.PROT_WRITE | mmap.PROT_EXEC
flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE flags = mmap.MAP_ANONYMOUS | mmap.MAP_PRIVATE
exec_mem = mmap.mmap(-1, len(shellcode), prot=prot, flags=flags) 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 = 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():
@ -49,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
@ -84,17 +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()
seed_data = bytearray(seed_data) logger.info(f'seed:\n{seed_data}')
offset = randint(0, len(seed_data)) queue = Queue()
flip = randint(0, 255)
seed_data[offset] ^= flip
seed_len = ctypes.c_uint(len(seed_data)) while True:
logger.info(f'seed_data\n{binascii.b2a_hex(seed_data)}') lineage = 0
logger.info(f'seed_len: {seed_len}') seed_flipped = flip(seed_data)
seed = shell_func(seed_shell) while lineage < args.lineage:
ret_val = seed(seed_len) 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)