题目质量很好,后边慢慢复现。
Web
Sourceless Guessy Web (Baby Flag)
目录遍历,flag在根目录下的etc/passwd。payload:?page=../../../etc/passwd,这里如果不确定往回退几个目录可以多加几层../,最终会到根目录底下。SEE{2nd_fl4g_n33ds_RCE_g00d_luck_h4x0r}
Misc
Regex101
有很多个txt文件,flag是其中一个txt的内容;给了flag格式,所以读出每个txt的内容然后正则过滤就行。
1 | import re |
FORENSICS
Sniffed Traffic
首先分析http流量,可以看到传输了zip文件;导出http对象即可获取zip。
追踪tcp流,在32组发现zip密码:
hey!
what the? who is this
someone who stole your thingamajig. now whats the password?
im really not sure why i would willingly give you the password. but for the sake of story telling, here it is 49949ec89a41ed9bdd18c4ce74f37ae4
解开是stuff.stuff,winhex分析发现有压缩包的痕迹,所以binwalk再把最后一层zip分出来。需要密码而并非伪加密,于是爆破,得到解压密码john,解开就是flag。SEE{w1r35haRk_d0dod0_4c87be4cd5e37eb1e9a676e110fe59e3}
CRYPTO
Close Enough
p,q取的太接近了,费马分解n就行。
Lost Modulus
服务端对提交的m1和m2有限制:
1 | assert m1.bit_length() >= 1600 and long_to_bytes(m1).startswith(b"SEE{") |
需要在绕过这两个限制的条件下构造特定的m1和m2求n。得到n以后对n开$2^i$得到flag。通常构造明文关系是让m1和m2有倍数关系,但这题不知道e,不可行;于是想到幂次关系:
服务端加密之后有:
故c2^3 - c1为关于n的多项式。由于每次e都是随机的,所以同一组数据可以向服务器请求两次得到两个不同的多项式;两组数据做gcd可得到n。完整exp:
1 | from Crypto.Util.number import * |
UniveRSAlity
也是交互类题目,首先对上传的p和q有限制,p和q的高位固定,并且都为128bit:
1 | p = int(input('p=')) |
其次需要上传d进行解密,并且明文json可通过token验证:
1 | print('We will use e=65537 because it is good practice.') |
最后,若js中有”flag”,才会打印flag:
1 | if 'flag' in js: |
关于p和q的取值,只需要爆破低位取得prime即可;解密若直接传入真实的私钥d,则解出的json数据虽然可以通过验证并不会包含”flag”;所以需要伪造一个d,让解密出的json数据既有token键值对又有”flag”;那么问题转化为:伪造一个明文$fakem$,$fake_m=c^d\mod n$,已知$fake{m}$和c、n,求d。
为了能快速求离散对数,我们需要找到光滑的p和q,最后用ph算法和crt求解即可。exp:
1 | from Crypto.Util.number import * |
The True ECC
本质上是paper题,可参考m0leCon CTF 2020 Teaser — King Exchange,相关论文点击这里。只需要参考paper建立同构关系即可,exp:
1 | from random import randint |