PHP…
0x01 Opcache 简介
Opcache(从PHP5.5.0开始):
字节码缓存。 PHP是解释型语言,构建在Zend 虚拟机之上,PHP解释器在执行PHP脚本时会解析PHP脚本代码,把PHP代码编译成一系列Zend操作码(由于每个操作码都是一个字节长,所以又叫字节码,字节码可以直接被Zend虚拟机执行),然后执行字节码。每次请求PHP文件都是这样,这会消耗很多资源,如果每次HTTP请求都必须不断解析、编译和执行PHP脚本,消耗的资源更多。如果PHP源码不变,相应的字节码也不会变化,显然没有必要每次都重新生成Opcode.下面是启用Opcode缓存之前和之后的流程图
0x02 攻击详情
原理:
由于生成的缓存文件存在可被替换的可能,这样就可能出现后门
缓存目录(PHP7.0出现):
opcache.file_cache=/tmp/opcache
例如访问个index.php,就会在缓存目录下生成/tmp/opcache/[system_id]/[web_path]/index.php.bin
.
其中system_id
和PHP版本、Zend Extension Build、各种数据类型长度(php7以上的数据种类发生改变)有关,system_id的计算;web_path
可以通过phpinfo
获取.
关于缓存目录的权限:
可见web用户是可以替换其中的文件的.
攻击实验:
文件上传不被限制
php.ini配置:
opcache.validate_timestamps = 0
opcache.file_cache_only = 1
关于opcache.validate_timestamps
和opcache.file_cache_only
首先一个上传页面
其中override_me.php
本地搭建相同版本的PHP项目.
之后将override.php.bin的system_id
修改为服务端的system_id
.
之后将override.php.bin上传.
关于opcache.file_cache_only=0
和opcache.validate.timestamps=1
的绕过
opcache.file_cache_only=0
此时内存缓存和文件缓存同时打开,内存缓存优先于文件缓存,该攻击方法失效,除非服务器能够进行重启.但是还可以利用框架中那些已经被抛弃的文件,这种文件并没有在内存中产生缓存,例如Wordpress框架中的registration-functions.php
.
opcache.validate.timestamps=1
此时启用了时间戳认证功能,将会把请求的源文件和缓存文件的header中的时间戳匹配,不同则删除缓存文件并创建新的缓存文件.绕过场景和先前的opcache.file_cache_only=0
相同,有些文件时间戳不会发生改变.
0x03 One’s Strom
php版本会导致缓存文件的格式不相同.
使用vld扩展调试php-Opcache文件
-d vld.active 表示是否子在php执行时启用vld
-d vld.execute 表示是否执行这段脚本
注:可以在启用php服务器时添加扩展
关于php5的APC
php5时存在APC(可选缓存),分为系统缓存和用户数据缓存.
参考链接:
(ง •_•)ง