解密攻防世界web进阶区web2:strrev与str_rot13的逆向实战
1. 从一道CTF题说起:当加密函数遇上逆向思维
大家好,我是老张,一个在安全圈摸爬滚打了十来年的老兵。今天咱们不聊那些高深莫测的零日漏洞,也不讲复杂的渗透框架,就从一个非常具体、非常经典的CTF题目入手——攻防世界Web进阶区的“web2”。这道题我敢说,但凡你学过一点PHP,对Web安全有点兴趣,它绝对是你绕不开的“新手村毕业考”。我第一次做这道题的时候,也卡了挺久,不是因为它多难,而是它的思路太“正”了,正到你如果只会正向思维,根本无从下手。它的核心,就是让你扮演一个“解密者”,去逆向推演一段PHP加密代码的逻辑,最终从一堆乱码里找到那个代表胜利的“flag”。
这道题给的代码非常短,但信息量巨大。它直接把加密函数 encode 和密文 $miwen 摆在你面前,然后轻描淡写地注释一句:“逆向加密算法,解密$miwen就是flag”。这感觉就像有人给了你一个上了锁的宝箱和一把形状奇怪的钥匙胚,告诉你:“喏,锁是我做的,这是钥匙的毛坯,你自己把它锉成能开锁的样子吧。” 题目里用到了几个PHP里看似简单,但组合起来就让人头疼的函数:strrev、substr、ord、chr,还有 str_rot13。很多新手一看 str_rot13 可能就懵了,这是个啥?别急,咱们后面会把它掰开揉碎了讲。
我经常跟团队里的新人说,做这种逆向题,心态很重要。你不能被那一串长得像天书一样的密文吓住。你得相信,所有的加密,只要不是那种不可逆的哈希(比如MD5、SHA256),只要你知道算法和密钥(或者像本题一样,算法直接给你了),就一定有路可走。这道题就是一个绝佳的练手机会,它能帮你建立起对代码流、数据流逆向分析的最基本感觉。下面,我们就一步步来,看看怎么用“倒推”的思维,把这把锁给撬开。
2. 庖丁解牛:拆解题目中的加密“流水线”
拿到任何加密代码,第一步永远不是急着写解密脚本,而是静下心来,像读小说一样,把加密的“故事线”理清楚。我们来看看题目给出的 encode 函数到底干了些什么。这个过程,我习惯称之为“绘制加密流水线”。
2.1 第一步:字符串反转(strrev)
加密的第一步是 $_o = strrev($str);。strrev 这个函数非常简单,它就是把手头的字符串整个倒过来写。比如输入 “hello”,经过它处理就变成了 “olleh”。这一步在逆向的时候会给我们一个非常重要的提示:解密后的最后一步,必然是一次反转操作,这样才能把顺序给正回来。很多人在逆向时容易忽略操作的顺序,导致解密出来的字符串是反的,这就是没把流水线方向搞对。
2.2 第二步:字符的“集体搬家”(for循环 + ord/chr)
接下来是一个 for 循环,这是整个加密的核心变换。我们拆开看:
for