今日学习收获
基础源码逆向分析,学会找到一个思路去分析比较简单的混淆脚本
学习资料
2025春季学期云曦开学考逆向:“源码!启动”
题目如下:
import base64,hashlib,math
def _kernalize(s):
return hashlib.md5(s.encode()).hexdigest()[:8]
def redcordage(sakura, glg=0x1F):
Franxx = []
for i, char in enumerate(sakura):
a = ord(char) ^ (glg + i % 111 )
x = ord(char) ^ (glg + i % 8)
a = ((x >> 6) | (x << 7)) & 0xFF
x = ((x >> 3) | (x << 5)) & 0xFF
a = ord(char) ^ (glg + i % 111)
a = ((x >> 6) | (x << 7)) & 0xFF
Franxx.append(x)
return base64.b64encode(bytes(Franxx)).decode()
if __name__ == "__main__":
text = input("这里就是加密flag的入口噢")
print(redcordage(text))
#redcordage(text)=yKrpS0nrCELPgojiCMJoAmUiIgjIgmLCb0Ij6AiDo+gF4mIC4mIL
源码审计:
这里调用了3个库,定义了 _kernalize()和redcordage()函数;从整个流程来看,运行整个程序后会要求输入内容,然后执行加密函数。
这里要注意,第一个函数引用了变量s,但是整个程序都没有出现过s这个变量,这里可以判断出第一个函数是干扰函数接着看下面,发现在加密过程中只使用了x变量,而a变量没有输出,根据分析是冗余代码(干扰项)
接着分析加密过程:导入数据——经过redcordage()函数加密——base64加密
redcordage()函数加密过程
def redcordage(sakura, glg=0x1F):
Franxx = []
for i, char in enumerate(sakura):
a = ord(char) ^ (glg + i % 111 )
x = ord(char) ^ (glg + i % 8)
a = ((x >> 6) | (x << 7)) & 0xFF
x = ((x >> 3) | (x << 5)) & 0xFF
a = ord(char) ^ (glg + i % 111)
a = ((x >> 6) | (x << 7)) & 0xFF
Franxx.append(x)
return base64.b64encode(bytes(Franxx)).decode()
首先是引入变量Sakura和一个glg=0x1F;
设置了一个Franxx来储存循环语句中的结果;
然后调用了异或算法,而这个key就是之前提到的glg,值是0x1F;
接着调用了循环位移算法,先向右移3位,再向左移5位,通过|连接起来
最后再进行了base64加密
理清楚思路后,可以通过删除冗余代码来简化过程
import base64
def redcordage(sakura, glg=0x1F):
Franxx = []
for i, char in enumerate(sakura):
x = ord(char) ^ (glg + i % 8)
x = ((x >> 3) | (x << 5)) & 0xFF
Franxx.append(x)
return base64.b64encode(bytes(Franxx)).decode()
if __name__ == "__main__":
text = input("这里就是加密flag的入口噢")
print(redcordage(text))
#redcordage(text)=yKrpS0nrCELPgojiCMJoAmUiIgjIgmLCb0Ij6AiDo+gF4mIC4mIL
学习反思
这道题的关键就是要学会识别代码,能够分辨是否是冗余代码和干扰项,不能依赖人工智能来一股脑分析,而要建立自己的分析思路。
最后的解密脚本
逆向的过程就是将整个源码反向过来去执行函数
思路:
根据源码里面的加密过程:导入数据——经过redcordage()函数加密——base64加密——得到结果
逆向分析:得到了结果——base64解密——edcordage()函数加密[先进行循环左移3位,再进行异或]——还原出原来的初始内容