[DASCTF八月挑战赛]easymath题解

    DASCTF八月赛的Crypto方向,拿下其他两道题很简单,但是这道最多人解出来的题反而解不出来。打完比赛回来看其他师傅写的wp,说是这是TSGCTF原题,所以直接放弃思考,上大佬的wp,我看看大佬这个wp,感觉这题还是有点东西的,里面涉及的基础的一些数学知识还是值得总结总结。

题目

assert(len(open('flag.txt', 'rb').read()) < 50)
assert(str(int.from_bytes(open('flag.txt', 'rb').read(), byteorder='big') << 10000).endswith('1862790884563160582365888530869690397667546628710795031544304378154769559410473276482265448754388655981091313419549689169381115573539422545933044902527020209259938095466283008')

题目就两行,意思大概就是有个长度不超过50的flag,让它右移10000个二进制位,然后截下来最后175个十进制位,让我们通过截下来的175个十进制位还原flag。

分析

本题最大的障碍就是没有用数学的方式来分析这道题,我之前在想最后这些十进制位和原来的flag之间有怎样的关联,比如flag的最后一个二进制位怎么影响最后剩下来的这些尾数,然后还想一位一位往上推,总之路子走错了。

题目也有提示,ezmath嘛,跟数学有关,这里最好的解决方案还是用数学式子来表示其中的关系。

(flag*2^{10000})%10^{175} = r %10^{175}

其中r为告诉我们的那个尾数。

分析到这里其实就很容易想到2**10000的逆元了,通过逆元消掉其他项,剩下一个flag。

求解

但是消掉2**10000存在一个问题,2**10000与10**175并不互质,很明显,两者有2的公因数,按照逆元的定义,这是不行的。因此要做一些变换。

我们先将上面式子的模拆开:

(flag*2^{10000}) = r + 10^{175}*x

把公因数2给去了得到:

(flag*2^{9825}) = r//2^{175} + 5^{175}*x

 (r可以整除2**175)

式子现在可以变化为:

(flag*2^{9825}) %5^{175}= r//2^{175} %5^{175}

此时2**9825与5**175互质,可以求出逆元d:

import gmpy2
d = gmpy2.invert(2**9825,5**175)

两边同时乘上d,由逆元性质得到:

flag % 5^{175}= (r//2^{175}*d )%5^{175}

由于题目提到flag长度小于50,一个字符占8个二进制位,即可计算:

 由此可以消去左边的模运算

由于r已知,右边可以直接计算出来,结果即为flag

最后long_to_bytes()得:

flag{90ee7e8df270bf5133a95ff904a059b8}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值