2019 中关村网络与信息安全领域专项赛
中关村网络与信息安全领域专项赛,i春秋主办。最后一道python字节码混淆挺牛逼的,比赛是没解出来,赛后好好学习了一下这方面的知识,成功复现了。
打这场比赛的时候正在xman,桂电的师傅也一起在打,师傅们牛逼。
比赛时间:8月15日
题目下载地址
Crypto
sm4
使用pysm4库。不知道为什么字符串的解密解不出结果,用整形加解密可以
1 | from pysm4 import decrypt |
dp
dp = d%(p-1)
知道dp很容易求得p
1 | import gmpy2 |
Reverse
flat
使用ollvm使控制流程平坦化 。不过由于内容不复杂,调试一下很容易知道加密过程。
前4步都是校验flag格式,flag{},中间包裹一串数+字母
但是由于校验的原因出现了多解:
1 | res = "J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB" |
这里的到
1 | 9bbfa2fc-c8b8-464d-8122-84da0e8e5d71 |
如果换一下if的顺序,会得到:
1 | zbbfasfc-cyby-uwud-yrss-yudaqeyevdxr |
由于数字的加密在两个范围中间有重复,因此数字解回去会有多解的境况。
每一位不同的互相组合,能得到2**17种解。
都是符合条件的解,输入都能得到正确结果
猜测是uuid,第一条正确。
src_leak
给出了c++的源码,是一系列的模板元编程,分析一下每个函数的作用,以及给出的结果,按照注释中说的求出每部分的值
x1-x5进行如下运算:
- func2求参数的二进制数中1的个数,func3求参数的奇偶。全部返回1说明他们的二进制数应该有奇数个1。
- _func1求参数的平方根,向下取整,使用了牛顿法求根。
- flag是满足这样的数最小的,因为最终加起来要最小
于是只需要从结果的平方爆到结果+1的平方,找到第一个二进制数有奇数个1的数。
最后x6计算了func4<1>到func4<10000>中返回1的个数
func4为判断是否为素数,是返回1
1 | from math import * |
py
这题比较难,先贴脚本,有空慢慢写。
pyc去混淆:
1 | # python2 disasm_anti.py py.pyc |
得到去了混淆的python字节码,然后静态分析。没办法直接拿到py脚本。这里是ollvm,不知道怎么实现的,出题人牛逼。
稍微看一下不难发现是要解一元二次方程。
1 | from math import sqrt |
Misc
yasaxi
010 editor打开,压缩包结尾能看到密码为loli
解压出图片,末尾多了一串字符串。
1 | ..... ..... ..... ..... !?!!. ?.... ..... ..... ..... .?.?! .?... .!... |
查找发现是Ook!编码
http://tool.bugku.com/brainfuck/?wafcloud=3
解码一下得到flag
1 | flag{f71d6bca-3210-4a31-9feb-1768a65a33db} |