最近攻防世界尝试自学逆向题,作为操作系统总评才七十五六分的小渣渣,而且没学过汇编语言,我这几天学的可谓起起落落落落落落。。。连新手区的一大半题目都解不出来,于是我就寻思有没有更简单的练习题可以做。上网好一顿搜索,又找到了好多CTF平台,比如说bugku、WhaleCTF、国钧CTF等等。其中有一个叫中学生CTF的,我一看这名字就决定先做这里的试试,再怎么说,中学生做的题目也不会难道哪里去吧,不过也不要看不起高中生哦,人家高中就开始打CTF了,而我高中再打LOL.....
由于进去的时候是晚上十一点多,web题目服务器并没开放(今天十点起来就可以得到web环境了),所以当时做了些MISC的编码题和Crypto的题目。Crypto题目就一道,题型就是简单的给出加密源码,要自己找出解密逻辑,只不过难度没有3DES那么高,也不是分组密码模式漏洞问题,比较直白。
题目是下图的代码,就这么几行: 可以看出,要求的17位输入才是真正的flag,输入经过10、11行的加密运算之后,得到的密文则是题目所给列表内容。
先研究加密逻辑,是把输入的内容按字处理,找出这个字符对应ACSII码数值,然后左移3位或上它右移五位,得到的结果异或123后与上255。
这个加密运算算是比较简单了,首先它是单纯的按字运算,不涉及前后明文关联加密,也没有CBC模式那种密文作为IV加密的方法,其次,它给的运算是纯二进制,只有移位运算和与或非。
当时思考就是一步步拿出加密各步骤的逆运算,就是加密的逆运算——解密。加密最后一步是与运算,那么我当时就想,与的逆运算是什么呢?以下为当时思考,最后没能成功得出有用结论,可以跳过阅读。
假设A&B=C,那么如果B和C已知,能求出A的运算就是与的逆运算。与都是按位与,0&1=0,0&0=0,1&1=1,只有全1才得1,否则都是0,还有a&1=a,a&0=0.利用这些规则我们能否找到与的逆运算呢?
就单拿a&0=0这一条,就无法逆推,不过乘法里也有a*0=0,但还是有逆运算除法,只是没有除以0罢了,因为这个是特殊情况。那么排除这个a&0=0特殊情况,能不能找到与的逆呢?
其实没有这个特殊情况,就只剩1情况了,这时a&b=c,b!=0,就有a=b&c。emmm。。。。好像得出的结论是一句废话。。。
看来思路有点偏,既然不能找到&的逆算通解,那么对于&某个特定的数,找出特解应该也可,于是我回头一看——255?!!!
a与上一个255不就是a吗?!亏我花那么多时间去瞎鼓捣,原来这里就只是个障眼法的作用。。。
不过对于倒数第二步的异或运算,就可以通过再次异或同一个数得到原数:已知A,A^B=C,有B^B=0000...,那么就有A^B^B=C^B,即A^000...=A=C^B。所以解密时我们再次异或123就可以
接下来是两个移位运算的或运算,我们可以手画一下,发现对于flag列表里的数,都是8位以内的二进制数,左移3或上右移5,是正好每一位之间不冲撞的,也就是X1X2X3X4X5X6X7X8(无论第一个1在第几位,都可以前面补0表示为八位)经过运算成为X4X5X6X7X8X1X2X3。
与此同时我们也该清楚,这个出题人是想限制在8位运算里,左移高出八位或者右移的都要截断,这个由于我们计算机不是8位,所以最后还要根据这个处理。
经过我们之前的运算,可以已知X4X5X6X7X8X1X2X3,并且知道这个X4X5X6X7X8X1X2X3是怎么由ord(i)运算的来的。那么我们利用八位截断特性,可以将X4X5X6X7X8X1X2X3左移5位得X1X2X3OOOOO或上右移三位的OOOX4X5X6X7X8,就可以得到X1X2X3X4X5X6X7X8。
但是由于我们计算机不会超过8位就给你截断,但是右移的截断还是有的,经过上述运算他会得到X4X5X6X7X8X1X2X3X4X5X6X7X8在这里需要我们自己处理,可以上网找类似8位截断的函数处理,我是找了一通没找到,直接与上0000011111111就可以把前面五位处理掉。
解密脚本:
answer = []
for j in flag:
answer.append(chr(0b0000011111111&(((j^123)>>3) | ((j^123)<<5))))
最后就可以得到17个原字符串了: