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

144 lines
4.3 KiB
Python
Raw Normal View History

#! /usr/bin/env python3
from argparse import ArgumentParser
from datetime import datetime
from multiprocessing import Process, Queue
2019-02-19 03:33:56 +00:00
from pathlib import Path
from queue import Empty
2019-02-19 04:40:35 +00:00
from sqlalchemy import exists, desc
from tempfile import TemporaryDirectory
import logging
from .mutation import generation, mutate, seed_shell, growth
2019-02-19 04:40:35 +00:00
from .orm import db_config, ScrapNode
from .disassemble import objdump
2019-02-18 23:16:25 +00:00
2019-03-07 02:17:42 +00:00
def export():
now = '{0:%Y%m%dT%H%M%S}'.format(datetime.utcnow())
parser = ArgumentParser(
description='export recent scrap shellcode.')
parser.add_argument('-v', '--verbose', action='count')
parser.add_argument('-db', '--database', default='/out/sins.sqlite',
help='path to scrap database.')
parser.add_argument('-o', '--out_path',
help='path to export scrap shellcode.')
args = parser.parse_args()
level = logging.DEBUG if args.verbose else logging.INFO
logging.basicConfig(level=level, format='%(message)s')
logging.info(now)
db_path = Path(args.database)
session = db_config(db_path)
logging.info(f'db_path: {db_path}')
recent = session.query(ScrapNode).order_by(desc('ctime')).first()
logging.info(f'recent: {recent}')
out_path = Path(f'{args.out_path}/scrap-{recent.checksum[:8]}.bin')
with out_path.open('wb') as file:
file.write(recent.image)
2019-02-18 23:16:25 +00:00
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.')
2019-03-07 02:17:42 +00:00
parser.add_argument('-o', '--out_path', help='path to results directory.')
parser.add_argument('-l', '--lineage', default=10,
2019-02-19 03:33:56 +00:00
help='max count of unsuccessful generation.')
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)
2019-02-18 23:16:25 +00:00
logger.info(now)
2019-03-07 02:17:42 +00:00
if args.out_path:
db_path = Path(f'{args.out_path}/sins.sqlite')
2019-02-19 04:40:35 +00:00
else:
temp_dir = TemporaryDirectory()
db_path = Path(f'{temp_dir.name}/sins.sqlite')
session = db_config(db_path)
logger.info(f'db_path: {db_path}')
recent = session.query(ScrapNode).order_by(desc('ctime')).first()
2019-02-19 04:40:35 +00:00
if args.seed:
seed_path = Path(args.seed)
with seed_path.open('rb') as seed_file:
seed_data = seed_file.read()
seed = ScrapNode(child=seed_data)
logger.debug(f'args.seed:\n{seed}')
elif recent:
seed = recent
logger.debug(f'recent:\n{seed}')
2019-02-19 04:40:35 +00:00
else:
seed = ScrapNode(child=seed_shell)
2019-02-21 00:26:47 +00:00
logger.debug(f'seed_shell:\n{seed}')
2019-03-07 02:17:42 +00:00
exists = session.query(ScrapNode).filter(
ScrapNode.checksum == seed.checksum).all()
2019-02-21 00:26:47 +00:00
if exists:
seed = exists[0]
else:
session.add(seed)
session.commit()
2019-02-19 04:40:35 +00:00
parent = seed
queue = Queue()
while True:
lineage = 0
while lineage < args.lineage:
scrap = mutate(parent.image)
logger.debug(f'lineage: {lineage}')
result = None
2019-02-19 00:28:34 +00:00
2019-02-19 04:40:35 +00:00
proc = Process(target=generation, args=(queue, scrap))
proc.start()
try:
result = queue.get(timeout=1)
except Empty:
lineage += 1
continue
if result != len(scrap):
lineage += 1
continue
2019-02-18 23:16:25 +00:00
opcodes = objdump(scrap)
2019-02-24 07:50:51 +00:00
ops_count = opcodes.count('\n')
logger.debug({'result': result, 'ops': ops_count})
scrap = growth(shellcode=scrap, objdump=opcodes)
2019-02-19 04:40:35 +00:00
parent = ScrapNode(child=scrap, parent_id=parent.id)
parent.objdump = opcodes
session.add(parent)
2019-02-19 04:40:35 +00:00
session.commit()
2019-02-24 07:50:51 +00:00
logger.info(parent)
lineage = 0