2018-03-05 12:33:14 +00:00
|
|
|
#!/usr/bin/env python2
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import subprocess
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import errno
|
2018-09-05 06:46:41 +00:00
|
|
|
import urllib2
|
2018-09-05 05:57:11 +00:00
|
|
|
import time
|
2018-03-05 12:33:14 +00:00
|
|
|
|
|
|
|
default_local_bin_location = os.path.expanduser('~/.local/bin/')
|
|
|
|
ROOT = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(prog="create-workspace.py")
|
|
|
|
parser.add_argument('-P', '--pupy-git-folder', default=ROOT, help='Path to pupy git')
|
|
|
|
parser.add_argument('-NC', '--do-not-compile-templates',
|
|
|
|
action='store_true', default=False, help='Do not compile payload templates')
|
2018-09-05 05:57:11 +00:00
|
|
|
parser.add_argument('-DG', '--download-templates-from-github-releases',
|
|
|
|
action='store_true', default=False, help='Do not compile payload templates and download latest templates from travis-ci automatic build')
|
2018-03-05 12:33:14 +00:00
|
|
|
parser.add_argument('-R', '--docker-repo',
|
|
|
|
help='Use non-default toolchains repo (Use "local" to build all the things on your PC')
|
|
|
|
parser.add_argument('-B', '--bin-path', default=default_local_bin_location,
|
|
|
|
help='Store pupy launch wrapper to this folder (default={})'.format(
|
|
|
|
default_local_bin_location))
|
|
|
|
parser.add_argument('-NI', '--no-pip-install-deps', action='store_true', default=False,
|
|
|
|
help='Do not install missing python deps (virtualenv, python-docker) using pip')
|
|
|
|
parser.add_argument('workdir', help='Location of workdir')
|
|
|
|
|
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
def main():
|
|
|
|
args = parser.parse_args()
|
2018-03-05 12:33:14 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
with open('/dev/null', 'w') as devnull:
|
2018-08-17 16:37:40 +00:00
|
|
|
subprocess.check_call(['git', '--help'], stdout=devnull)
|
2018-03-05 12:33:14 +00:00
|
|
|
except:
|
2018-08-17 16:37:40 +00:00
|
|
|
sys.exit("Install git (example: sudo apt-get install git)")
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-09-05 05:57:11 +00:00
|
|
|
if args.download_templates_from_github_releases:
|
|
|
|
args.do_not_compile_templates=True
|
|
|
|
elif not args.do_not_compile_templates:
|
2018-08-17 16:37:40 +00:00
|
|
|
try:
|
|
|
|
with open('/dev/null', 'w') as devnull:
|
|
|
|
subprocess.check_call(['docker', '--help'], stdout=devnull)
|
|
|
|
except:
|
|
|
|
sys.exit("Install docker: https://docs.docker.com/install/")
|
|
|
|
|
|
|
|
vsc = '/proc/sys/abi/vsyscall32'
|
|
|
|
if os.path.isfile(vsc):
|
|
|
|
vsyscall = int(open(vsc).read())
|
|
|
|
if not vsyscall:
|
|
|
|
sys.exit('You need to have vsyscall enabled:\n~> sudo sysctl -w abi.vsyscall32=1\n~> sudo reboot')
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
try:
|
|
|
|
import virtualenv
|
|
|
|
except:
|
|
|
|
if args.no_pip_install_deps:
|
|
|
|
sys.exit('virtualenv missing: pip install --user virtualenv')
|
|
|
|
else:
|
2018-09-04 12:34:51 +00:00
|
|
|
subprocess.check_output('pip install --user virtualenv', shell=True)
|
2018-07-08 09:36:15 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
import virtualenv
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
workdir = os.path.abspath(args.workdir)
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
if not os.path.isfile(os.path.join(args.pupy_git_folder, 'create-workspace.py')):
|
|
|
|
sys.exit('{} is not pupy project folder'.format(args.pupy_git_folder))
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
if os.path.isdir(workdir) and os.listdir(workdir):
|
|
|
|
sys.exit('{} is not empty'.format(workdir))
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
pupy = os.path.abspath(args.pupy_git_folder)
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
print "[+] Pupy at {}".format(pupy)
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
if not args.do_not_compile_templates:
|
|
|
|
print "[+] Compile common templates"
|
|
|
|
env = os.environ.copy()
|
|
|
|
if args.docker_repo:
|
|
|
|
env['REPO'] = args.docker_repo
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
subprocess.check_call([
|
2018-08-21 08:36:17 +00:00
|
|
|
os.path.join(args.pupy_git_folder, 'client', 'build-docker.sh')
|
|
|
|
], env=env, cwd=os.path.join(args.pupy_git_folder, 'client'))
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
print "[+] Create VirtualEnv environment"
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
try:
|
|
|
|
os.makedirs(args.workdir)
|
|
|
|
except OSError, e:
|
|
|
|
if e.errno == errno.EEXIST:
|
|
|
|
pass
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
virtualenv.create_environment(workdir)
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
print "[+] Install dependencies"
|
|
|
|
subprocess.check_call([
|
|
|
|
os.path.join(workdir, 'bin', 'pip'),
|
|
|
|
'install',
|
|
|
|
'-r', 'requirements.txt'
|
|
|
|
], cwd=os.path.join(pupy, 'pupy'))
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
subprocess.check_call([
|
|
|
|
os.path.abspath(os.path.join(workdir, 'bin', 'pip')),
|
|
|
|
'install', '--upgrade', '--force-reinstall',
|
|
|
|
'pycryptodome'
|
|
|
|
], cwd=os.path.join(pupy, 'pupy'))
|
|
|
|
|
2018-09-05 05:57:11 +00:00
|
|
|
if args.download_templates_from_github_releases:
|
2018-09-05 06:46:41 +00:00
|
|
|
download_link="https://github.com/n1nj4sec/pupy/releases/download/latest/payload_templates.txz"
|
|
|
|
print "downloading payload_templates from {}".format(download_link)
|
2018-09-06 06:36:00 +00:00
|
|
|
subprocess.check_call(["wget", "-O", "payload_templates.txz", download_link], cwd=os.path.join(pupy))
|
2018-09-05 06:46:41 +00:00
|
|
|
print "extracting payloads ..."
|
|
|
|
subprocess.check_call(["tar", "xf", "payload_templates.txz", "-C", "pupy/"], cwd=os.path.join(pupy))
|
2018-09-05 05:57:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
wrappers=["pupysh", "pupygen"]
|
|
|
|
print "[+] Create {} wrappers".format(','.join(wrappers))
|
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
pupysh_update_path = os.path.join(workdir, 'bin', 'pupysh-update')
|
2018-09-05 05:57:11 +00:00
|
|
|
pupysh_paths=[]
|
|
|
|
for script in wrappers:
|
|
|
|
pupysh_path = os.path.join(workdir, 'bin', script)
|
|
|
|
pupysh_paths.append(pupysh_path)
|
2018-08-17 16:37:40 +00:00
|
|
|
|
2018-09-05 05:57:11 +00:00
|
|
|
with open(pupysh_path, 'w') as pupysh:
|
|
|
|
wa = os.path.abspath(workdir)
|
|
|
|
print >>pupysh, '#!/bin/sh'
|
|
|
|
print >>pupysh, 'cd {}'.format(wa)
|
|
|
|
print >>pupysh, 'exec bin/python -B {} "$@"'.format(
|
|
|
|
os.path.join(pupy, 'pupy', script+'.py'))
|
2018-08-17 16:37:40 +00:00
|
|
|
|
2018-09-05 05:57:11 +00:00
|
|
|
os.chmod(pupysh_path, 0755)
|
2018-08-17 16:37:40 +00:00
|
|
|
|
|
|
|
with open(pupysh_update_path, 'w') as pupysh_update:
|
|
|
|
wa = os.path.abspath(workdir)
|
|
|
|
print >>pupysh_update, '#!/bin/sh'
|
|
|
|
print >>pupysh_update, 'set -e'
|
|
|
|
print >>pupysh_update, 'echo "[+] Update pupy repo"'
|
|
|
|
print >>pupysh_update, 'cd {}; git pull --recurse-submodules'.format(pupy)
|
|
|
|
print >>pupysh_update, 'echo "[+] Update python dependencies"'
|
|
|
|
print >>pupysh_update, 'source {}/bin/activate; cd pupy; pip install --upgrade -r requirements.txt'.format(
|
|
|
|
workdir)
|
|
|
|
if not args.do_not_compile_templates:
|
|
|
|
print >>pupysh_update, 'echo "[+] Recompile templates"'
|
|
|
|
for target in ('windows', 'linux32', 'linux64'):
|
|
|
|
print >>pupysh_update, 'echo "[+] Build {}"'.format(target)
|
|
|
|
print >>pupysh_update, 'docker start -a build-pupy-{}'.format(target)
|
|
|
|
print >>pupysh_update, 'echo "[+] Update completed"'
|
|
|
|
|
|
|
|
os.chmod(pupysh_update_path, 0755)
|
2018-09-05 05:57:11 +00:00
|
|
|
|
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
|
|
|
|
if args.bin_path:
|
|
|
|
bin_path = os.path.abspath(args.bin_path)
|
|
|
|
print "[+] Store symlink to pupysh to {}".format(bin_path)
|
|
|
|
|
|
|
|
if not os.path.isdir(bin_path):
|
|
|
|
os.makedirs(bin_path)
|
|
|
|
|
2018-09-05 05:57:11 +00:00
|
|
|
for src, sympath in [(x, os.path.splitext(os.path.basename(x))[0]) for x in pupysh_paths]+[(pupysh_update_path, 'pupysh-update')]:
|
2018-08-17 16:37:40 +00:00
|
|
|
sympath = os.path.join(bin_path, sympath)
|
|
|
|
|
|
|
|
if os.path.islink(sympath):
|
|
|
|
os.unlink(sympath)
|
|
|
|
|
|
|
|
elif os.path.exists(sympath):
|
|
|
|
sys.exit("[-] File at {} already exists and not symlink".format(sympath))
|
|
|
|
|
|
|
|
os.symlink(src, sympath)
|
|
|
|
|
|
|
|
if bin_path not in os.environ['PATH']:
|
|
|
|
print "[-] {} is not in your PATH!".format(bin_path)
|
|
|
|
else:
|
|
|
|
print "[I] To execute pupysh:"
|
|
|
|
print "~ > pupysh"
|
|
|
|
print "[I] To update:"
|
|
|
|
print "~ > pupysh-update"
|
2018-03-05 12:33:14 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
print "[I] To execute pupysh:"
|
2018-09-05 05:57:11 +00:00
|
|
|
print "~ > {}".format(pupysh_paths[0])
|
2018-03-05 12:33:14 +00:00
|
|
|
print "[I] To update:"
|
2018-08-17 16:37:40 +00:00
|
|
|
print "~ > {}".format(pupysh_update_path)
|
|
|
|
|
2018-03-05 12:33:14 +00:00
|
|
|
|
2018-08-17 16:37:40 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|