Mission Calculator

第十六届极客大挑战missioncalculator (1).png

main函数:第十六届极客大挑战missioncalculator (2).png​​

banner函数:

第十六届极客大挑战missioncalculator (3).png

​math函数:

第十六届极客大挑战missioncalculator (4).png

我们开始分析代码,首先我们发现有后门函数即win函数,然后发现math函数中调用win函数,那我们看math函数中调用win函数的条件

第十六届极客大挑战missioncalculator (5).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
作者
ZenDuk
发布于
2025年10月30日
许可协议