php隐藏代码
PHP的藏代隐藏代码从来不是加密,而是藏代混淆。真正让人头疼的藏代,不是藏代代码本身有多难读,而是藏代它藏在你想不到的地方。我见过最离谱的藏代一次,是藏代在一个客户的WordPress主题里,function.php文件末尾多了一个空格,藏代空格后面跟着一整段base64编码的藏代字符串。那段代码平时不执行,藏代只在特定时间点、藏代特定IP访问时才激活,藏代专门给管理员账号开后门。藏代 那串代码是藏代怎么进去的?客户说主题是从某论坛下载的破解版。破解者把代码藏在文件末尾的藏代空白区域,肉眼根本看不出来。编辑器打开,显示的是正常的PHP标签闭合,后面全是空白。但PHP解析器不这么认为——它读到`?>`之后,如果后面还有内容,会当作HTML输出。可那段字符串不是HTML,是用`eval(gzinflate(base64_decode(...)))`包裹的压缩代码。这种嵌套方式太老了,但依然有效。 更隐蔽的藏在数组里。有人会把恶意代码拆成多个数组元素,每个元素只是普通字符串,比如`$a['x']='ev';`,`$a['y']='al';`,然后在某个回调函数里用`call_user_func($a['x'].$a['y'], $_POST['cmd'])`拼接执行。这招叫动态函数调用,静态扫描工具很难匹配到危险函数名,因为代码里根本找不到`eval`或`system`的完整字符串。 还有一种藏在常量里。PHP的`define()`可以定义常量,常量值可以是任意字符串,包括PHP代码。有人定义`define('SECRET', 'system($_GET["cmd"]);')`,然后找个看似无关的地方用`preg_replace_callback('/.*/', create_function('$m', SECRET), $input)`触发。`create_function`本身是危险的,但如果你用`preg_replace_callback`搭配`create_function`,很多扫描器会忽略这种组合,因为它们各自看的时候都不算高危。 最让我觉得毛骨悚然的,是藏在自动加载机制里的。PHP的`spl_autoload_register`允许注册多个自动加载函数。攻击者把恶意代码写成一个类,类名是`Cache_Manager`,然后注册为自动加载器。正常业务代码里确实有`new Cache_Manager()`的调用,可没人注意这个类文件里除了缓存逻辑,构造函数里还偷偷执行了`file_put_contents`把webshell写到某个图片目录。这种代码混在业务逻辑里,像混在米堆里的沙子,不仔细嚼根本发现不了。 你要问怎么防?说实话,没有绝对的办法。能做的只有:别用来路不明的源码,上线前用`php -l`检查语法只能发现错误,发现不了恶意逻辑。用`grep -r "eval\|base64_decode"`扫一遍是基本功,但人家早就学会拆开写、动态拼了。更实际的做法是监控文件完整性,比如用`inotifywait`实时监控web目录的写入事件,或者定期用`md5sum`比对文件哈希。可这也有漏洞——攻击者拿到shell后第一件事就是改你的校验脚本。 我个人的经验是:每行代码都要有存在理由。如果你在项目里看到某个变量名特别奇怪,比如`$__k`这种,或者某个函数定义后从未被直接调用,只出现在字符串拼接里,那就要警惕了。真正干净的代码不会故意把自己藏起来。隐藏代码的存在本身,就是最大的破绽——只是你得先怀疑,才能看见。
-
上一篇
-
下一篇
- 最近发表
- 随机阅读
- 搜索
-
- 友情链接
-