Skip to content

Commit

Permalink
ver 1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
pinksawtooth committed Sep 28, 2018
1 parent 687028a commit cdc3cf3
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 65 deletions.
36 changes: 16 additions & 20 deletions manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,6 @@ def start_analyze():
with open('config.json', 'w') as outfile:
json.dump(json_data, outfile)

cmd=[("virsh snapshot-revert " + VM_NAME + " --current")]

p = (subprocess.Popen(cmd, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True))
output = p.stderr.read().decode('utf-8')
print(output)

if "busy" in output:
state={"state":0}
with open("state.json", 'w') as f:
json.dump(state, f)
return make_response(jsonify(status_code=2, message="failed to initialize KVM: Device or resource busy"), 500)

elif "Domain" in output:
state={"state":0}
with open("state.json", 'w') as f:
json.dump(state, f)
return make_response(jsonify(status_code=2, message="Domain snapshot not found: the domain does not have a current snapshot"), 500)

cmd = [("./xmlrpc_client.py "+ uid)]
subprocess.Popen(cmd, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)

Expand Down Expand Up @@ -87,7 +69,6 @@ def file_upload():

@app.route('/results/<uuid>')
def show_result(uuid=None):
print(uuid)

result = list(collection.find({u"UUID":uuid}))[0]
result.pop('_id')
Expand All @@ -97,7 +78,22 @@ def show_result(uuid=None):
else:
return make_response(jsonify(status_code=1, message='Analysing.'), 206)


@app.route('/yara/<rule_name>')
def get_yara_file(rule_name=None):

rule_name_check = rule_name.replace("_", "")
if rule_name_check.isalnum() == False:
return make_response(jsonify(status_code=2, message="Invalid rule_name"), 400)

cmd=[("find yara/ -type f | xargs grep -l -x -E -e " + "\"rule "+ rule_name +" .*{\" -e \"rule "+ rule_name +"{\" -e \"rule " + rule_name + "\"")]
print(cmd)
p = (subprocess.Popen(cmd, shell=True, stdin=None, stdout=subprocess.PIPE, close_fds=True))
output = p.stdout.read().decode('utf-8')

with open(output.strip(), 'r') as f:
yara_file=f.read()

return jsonify(status_code=0, result=yara_file)

@app.errorhandler(404)
def not_found(error):
Expand Down
7 changes: 0 additions & 7 deletions mouse_emu.py

This file was deleted.

6 changes: 3 additions & 3 deletions setup/setup.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

mkdir target result tools yara
mkdir target result yara
chmod 777 target result
sudo apt install python3 python3-magic kvm virt-manager libvirt-bin bridge-utils mongodb npm nginx
sudo pip3 install -r requirements.txt
sudo apt install python3 python3-pip python3-magic qemu-kvm virt-manager libvirt-bin bridge-utils mongodb npm nginx autoconf
sudo pip3 install -r setup/requirements.txt
21 changes: 21 additions & 0 deletions tools/mouse_emu.pyw
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import ctypes.wintypes
import random, time

User32 = ctypes.WinDLL('User32.dll')
GetSystemMetrics = User32.GetSystemMetrics

RESOLUTION = {
"x": User32.GetSystemMetrics(0),
"y": User32.GetSystemMetrics(1)
}

def move_mouse():
x = random.randint(0, RESOLUTION["x"])
y = random.randint(0, RESOLUTION["y"])

User32.SetCursorPos(x, y)

while(1):
move_mouse()
time.sleep(0.1)

93 changes: 59 additions & 34 deletions xmlrpc_client.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env python3

import xmlrpc.client
import os, sys, shutil, json, subprocess, time, yara, glob, hashlib, datetime, requests
import os, sys, shutil, json, subprocess, time, yara, hashlib, datetime, requests
from pathlib import Path
from pymongo import MongoClient
from pprint import pprint

with open("tknk.conf", 'r') as f:
tknk_conf = json.load(f)
Expand All @@ -12,10 +12,7 @@
VM_URL=tknk_conf['vm_url']

def change_state():
with open("state.json", 'r') as f:
state = json.load(f)

state['state'] = 0
state={"state":0}

with open("state.json", 'w') as f:
json.dump(state, f)
Expand Down Expand Up @@ -54,18 +51,6 @@ def vm_down():

if __name__ == '__main__':
args = sys.argv
c=0

while(1):
vm_state = subprocess.check_output(["virsh", "domstate", VM_NAME])
time.sleep(1)
c+=1
#print (vm_state.decode('utf-8'))
if "running" in str(vm_state.decode('utf-8')):
break
if c == 60:
change_state()
exit()

#db connect
client = MongoClient('localhost', 27017)
Expand Down Expand Up @@ -96,35 +81,67 @@ def vm_down():

result['scans'].append({"sha256":file_sha256, "detect_rule":list(map(str,matches)), "file_name":config['target_file']})

os.mkdir("result/" + str(now.strftime("%Y-%m-%d_%H:%M:%S")))
cmd=[("virsh snapshot-revert " + VM_NAME + " --current")]
p = (subprocess.Popen(cmd, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True))
output = p.stderr.read().decode('utf-8')
print(output)

if "busy" in output:
print("failed to initialize KVM: Device or resource busy")
result["result"]["is_success"] = False
result["result"]["detail"] = "failed to initialize KVM: Device or resource busy"
change_state()
collection.update({u'UUID':uid},result)
exit()

elif "Domain" in output:
print("Domain snapshot not found: the domain does not have a current snapshot")
result["result"]["is_success"] = False
result["result"]["detail"] = "Domain snapshot not found: the domain does not have a current snapshot"
change_state()
collection.update({u'UUID':uid},result)
exit()

c=0

while(1):
vm_state = subprocess.check_output(["virsh", "domstate", VM_NAME])
time.sleep(1)
c+=1
#print (vm_state.decode('utf-8'))
if "running" in str(vm_state.decode('utf-8')):
break
if c == 60:
change_state()
exit()

upload("config.json")
tools = ["tools/hollows_hunter.exe", "tools/pe-sieve.dll", "tools/procdump.exe", "tools/pssuspend.exe", "tools/mouse_emu.exe"]
tools = ["tools/hollows_hunter.exe", "tools/pe-sieve.dll", "tools/procdump.exe", "tools/pssuspend.exe", "tools/mouse_emu.pyw"]

for tool_name in tools:
upload(tool_name)

upload("target/" + config['target_file'])

ret = dump()
print("ret===============================")
pprint(ret)

if ret == False:
print("Connection error\n")
is_success == False
is_success = False
result["result"]["detail"] = "Connection error"
else:
ret = download()

if ret == True:
shutil.move("dump.zip", "result/")
print("dump finish")
is_success = True

else:
is_success = False
result["result"]["detail"] = "dump file does not exist"
if result["mode"] == "procdump":
result["result"]["detail"] = "Process does not exist"
else:
result["result"]["detail"] = "Dump file does not exist"

vm_down()

Expand All @@ -134,8 +151,8 @@ def vm_down():
result["result"]["is_success"] = True
result["result"]["detail"] = "Detected with yara rule!"
break

with open("result/"+ str(now.strftime("%Y-%m-%d_%H:%M:%S")) + "/" +file_sha256+'.json', 'w') as outfile:
os.mkdir("result/" + str(uid))
with open("result/"+ str(uid) + "/" +file_sha256+'.json', 'w') as outfile:
json.dump(result, outfile, indent=4)

print (json.dumps(result, indent=4))
Expand All @@ -145,15 +162,23 @@ def vm_down():
exit()

elif is_success == True:
p = Path("result/dump.zip")
if p.exists():
p.unlink()
print("remove")
shutil.move("dump.zip", "result/")
subprocess.run(['unzip', "dump.zip"], cwd="result")

files = glob.glob("result/dump/**", recursive=True)
p = Path("result/dump/")

for f in files:
if "exe" in f.rsplit(".", 1) or "dll" in f.rsplit(".", 1) or "dmp" in f.rsplit(".", 1):
sha256_hash = str(hashlib.sha256(open(f,'rb').read()).hexdigest())
matches = rules.match(f)
result['scans'].append({"sha256":sha256_hash, "detect_rule":list(map(str,matches)), "file_name":f.rsplit("/", 1)[1]})
for f in p.glob("**/*"):
print(f.suffix)
print(f.resolve())
print(f.name)
if (".exe" == f.suffix) or (".dll" == f.suffix) or (".dmp" == f.suffix):
sha256_hash = str(hashlib.sha256(open(str(f.resolve()),'rb').read()).hexdigest())
matches = rules.match(str(f.resolve()))
result['scans'].append({"sha256":sha256_hash, "detect_rule":list(map(str,matches)), "file_name":f.name})

for scan in result["scans"]:
if scan["detect_rule"] != []:
Expand All @@ -166,7 +191,7 @@ def vm_down():
with open("result/dump/"+file_sha256+'.json', 'w') as outfile:
json.dump(result, outfile, indent=4)

os.rename("result/dump/", "result/"+str(now.strftime("%Y-%m-%d_%H:%M:%S")))
os.rename("result/dump/", "result/"+str(uid))
os.remove("result/dump.zip")
os.remove("config.json")

Expand Down
4 changes: 3 additions & 1 deletion xmlrpc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def dump():
with open('config.json', 'r') as outfile:
config = json.load(outfile)

subprocess.call(['cmd.exe', "/c", "start", "pythonw", "mouse_emu.pyw"])

if config["mode"] == "diff":
Psapi = ctypes.WinDLL('Psapi.dll')
EnumProcesses = Psapi.EnumProcesses
Expand All @@ -36,7 +38,7 @@ def dump():
src_set = set(ProcessIds)

subprocess.call(['cmd.exe', "/c", "start", config['target_file']])
subprocess.call(['cmd.exe', "/c", "start", 'mouse_emu.exe'])


print(("wait for unpack %d seconds\n") % config["time"])

Expand Down

0 comments on commit cdc3cf3

Please sign in to comment.