This commit is contained in:
t3chn0m4g3 2020-03-03 12:30:57 +00:00
parent 5d7a6f3270
commit 3b8c959c66
3 changed files with 152 additions and 21 deletions

View file

@ -49,23 +49,25 @@ services:
- tanner_redis - tanner_redis
# Tanner WEB Service # Tanner WEB Service
# tanner_web: tanner_web:
# build: ./tanner build: ./tanner
# container_name: tanner_web container_name: tanner_web
# restart: always restart: always
# stop_signal: SIGKILL stop_signal: SIGKILL
# tmpfs: tmpfs:
# - /tmp/tanner:uid=2000,gid=2000 - /tmp/tanner:uid=2000,gid=2000
# tty: true tty: true
# networks: networks:
# - tanner_local - tanner_local
# image: "dtagdevsec/tanner:2006" # ports:
# command: tannerweb # - "127.0.0.1:8091:8091"
# read_only: true image: "dtagdevsec/tanner:2006"
# volumes: command: tannerweb
# - /data/tanner/log:/var/log/tanner read_only: true
# depends_on: volumes:
# - tanner_redis - /data/tanner/log:/var/log/tanner
depends_on:
- tanner_redis
# Tanner Service # Tanner Service
tanner: tanner:
@ -86,7 +88,7 @@ services:
- /data/tanner/files:/opt/tanner/files - /data/tanner/files:/opt/tanner/files
depends_on: depends_on:
- tanner_api - tanner_api
# - tanner_web - tanner_web
- tanner_phpox - tanner_phpox
# Snare Service # Snare Service

View file

@ -23,12 +23,16 @@ import json
import asyncio import asyncio
import hashlib import hashlib
import argparse import argparse
import functools
from aiohttp import web from aiohttp import web
from asyncio.subprocess import PIPE from asyncio.subprocess import PIPE
from pprint import pprint from pprint import pprint
_pretty_dumps = functools.partial(json.dumps, sort_keys=True, indent=4)
class PHPSandbox(object): class PHPSandbox(object):
@classmethod @classmethod
def php_tag_check(cls, script): def php_tag_check(cls, script):
@ -51,7 +55,7 @@ class PHPSandbox(object):
self.stdout_value += line + b'\n' self.stdout_value += line + b'\n'
@asyncio.coroutine @asyncio.coroutine
def sandbox(self, script, phpbin="php7.0"): def sandbox(self, script, phpbin="php7"):
if not os.path.isfile(script): if not os.path.isfile(script):
raise Exception("Sample not found: {0}".format(script)) raise Exception("Sample not found: {0}".format(script))
@ -96,12 +100,12 @@ def api(request):
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
ret['file_md5'] = file_md5 ret['file_md5'] = file_md5
return web.Response(body=json.dumps(ret, sort_keys=True, indent=4).encode('utf-8')) return web.json_response(ret, dumps=_pretty_dumps)
if __name__ == '__main__': if __name__ == '__main__':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--phpbin", help="PHP binary, ex: php7.0", default="php7.0") parser.add_argument("--phpbin", help="PHP binary, ex: php7", default="php7")
args = parser.parse_args() args = parser.parse_args()
phpbin = args.phpbin phpbin = args.phpbin

125
docker/tanner/phpox/dist/sandbox.py.old vendored Normal file
View file

@ -0,0 +1,125 @@
#!/usr/bin/env python3
# Copyright (C) 2016 Lukas Rist
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os
import tempfile
import json
import asyncio
import hashlib
import argparse
from aiohttp import web
from asyncio.subprocess import PIPE
from pprint import pprint
class PHPSandbox(object):
@classmethod
def php_tag_check(cls, script):
with open(script, "r+") as check_file:
file_content = check_file.read()
if "<?" not in file_content:
file_content = "<?php" + file_content
if "?>" not in file_content:
file_content += "?>"
check_file.write(file_content)
return script
@asyncio.coroutine
def read_process(self):
while True:
line = yield from self.proc.stdout.readline()
if not line:
break
else:
self.stdout_value += line + b'\n'
@asyncio.coroutine
def sandbox(self, script, phpbin="php7.0"):
if not os.path.isfile(script):
raise Exception("Sample not found: {0}".format(script))
try:
cmd = [phpbin, "sandbox.php", script]
self.proc = yield from asyncio.create_subprocess_exec(*cmd, stdout=PIPE)
self.stdout_value = b''
yield from asyncio.wait_for(self.read_process(), timeout=3)
except Exception as e:
try:
self.proc.kill()
except Exception:
pass
print("Error executing the sandbox: {}".format(e))
# raise e
return {'stdout': self.stdout_value.decode('utf-8')}
class EchoServer(asyncio.Protocol):
def connection_made(self, transport):
# peername = transport.get_extra_info('peername')
# print('connection from {}'.format(peername))
self.transport = transport
def data_received(self, data):
# print('data received: {}'.format(data.decode()))
self.transport.write(data)
@asyncio.coroutine
def api(request):
data = yield from request.read()
file_md5 = hashlib.md5(data).hexdigest()
with tempfile.NamedTemporaryFile(suffix='.php') as f:
f.write(data)
f.seek(0)
sb = PHPSandbox()
try:
server = yield from loop.create_server(EchoServer, '127.0.0.1', 1234)
ret = yield from asyncio.wait_for(sb.sandbox(f.name, phpbin), timeout=10)
server.close()
except KeyboardInterrupt:
pass
ret['file_md5'] = file_md5
return web.Response(body=json.dumps(ret, sort_keys=True, indent=4).encode('utf-8'))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--phpbin", help="PHP binary, ex: php7.0", default="php7.0")
args = parser.parse_args()
phpbin = args.phpbin
app = web.Application()
app.router.add_route('POST', '/', api)
loop = asyncio.get_event_loop()
handler = app.make_handler()
f = loop.create_server(handler, '0.0.0.0', 8088)
srv = loop.run_until_complete(f)
print('serving on', srv.sockets[0].getsockname())
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(handler.finish_connections(1.0))
srv.close()
loop.run_until_complete(srv.wait_closed())
loop.run_until_complete(app.finish())
loop.close()