前几天在参加FOFA-攻防挑战赛时,遇到了Drupal的盲盒漏洞环境,最终确定漏洞为CVE--,但是还是无法getflag,因为网上相关参考文章并不是很多,大多都只是简单的复现了,于是就想着对这个漏洞进行一个详细的分析。
漏洞描述
环境搭建
环境的搭建,我们可以选择p神的Vulhub上的环境,我们也可以利用vulfocus的在线环境,或者将镜像拉取下来本地启动。
因为p神的环境还需要再进行配置yaml,为了方便,我们这里就选择vulfocus的镜像来进行复现学习
dockerpullvulfocus/drupal-cve__:latestdockerps
访问随机生成的端口
!php/object"O:24:\"GuzzleHttp\\Psr7\\FnStream\":2:{s:33:\"\0GuzzleHttp\\Psr7\\FnStream\0methods\";a:1:{s:5:\"close\";s:7:\"phpinfo\";}s:9:\"_fn_close\";s:7:\"phpinfo\";}"
点击import触发漏洞
①网安学习成长路径思维导图
②60+网安经典常用工具包
③+SRC漏洞分析报告
④+网安攻防实战技术电子书
⑤最权威CISSP认证考试指南+题库
⑥超页CTF实战技巧手册
⑦最新网安大厂面试题合集(含答案)
⑧APP客户端安全检测指南(安卓+IOS)
漏洞分析
漏洞存在于drupal8.3.3所以我们下载存在漏洞的版本drupal8.3.3和修复的版本drupal8.3.4进行对比,发现漏洞位于
core\lib\Drupal\Component\Serialization\YamlPecl.php
我们看到修改的位置有这么一句//Weneverwanttounserialize!php/object.
就大概可以推测出是在这个地方,以!php/object为开头时会产生反序列化漏洞
为了方便进行调试,所以我们换一下docker启动时的命令,方便启动后进行php远程调试,在配置调试环境时出现了各种问题,本来是在本地搭建docker环境进行调试的,但是一直没有成功,所以就采用在虚拟机中搭建docker环境,采用远程调试。
dockerrun-itd-p80:80vulfocus/drupal-cve__:latest
wget
修改php.ini配置文件,在文件中追加以下内容
[Xdebug]zend_extension=/usr/lib/php5//xdebug.so;指定Xdebug扩展文件的路径xdebug.remote_enable=1;是否开启远程调试xdebug.remote_handler=dbgp;指定远程调试的处理协议xdebug.remote_mode=req;可以设为req或jit,req表示脚本一开始运行就连接远程客户端,jit表示脚本出错时才连接远程客户端。xdebug.remote_host=...1;指定远程调试的主机名(安装phpstorm的主机ip)xdebug.remote_port=;指定远程调试的端口号xdebug.idekey="PHPSTORM";指定传递给DBGp调试器处理程序的IDEKeyxdebug.remote_enable=on;[Xdebug]zend_extension=/usr/lib/php5//xdebug.so;xdebug.remote_enable=1;xdebug.remote_handler=dbgp;xdebug.remote_mode=req;xdebug.remote_host=...1;xdebug.remote_port=;xdebug.idekey="PHPSTORM";
访问
先将代码拷贝出来dockercp30:/var/
在phpinfo处加载断点,并访问
如果存在yaml扩展,$serializer就使用YamlPecl类,之后会调用YamlPecl类中的decode函数;
如果不存在yaml扩展,$serializer就使用YamlSymfony类,之后会调用YamlSymfony类中的decode函数。目前的环境是已经安装了yaml扩展了,所以我们只需要寻找,可控输入的Yaml::decode
core/modules/config/src/Form/ConfigSingleImportForm.php::validateForm
如此我们就已经确定了漏洞的触发位置,以及漏洞的入口点,但是距离漏洞的利用成功还差一个payload
我们已经知道这个漏洞是一个反序列化漏洞,我们就要找出这个系统中存在的反序列化链,针对这个漏洞有两条利用链路,任意命令执行以及任意文件写入
任意命令执行
html\vendor\guzzle
漏洞修复
根据对比官方对drupal8.3.4的修补,我们得出针对低于版本drupal8.3.4的代码中在core\lib\Drupal\Component\Serialization\YamlPecl.php的decode函数修改为
publicstaticfunctiondecode($raw){static$init;if(!isset($init)){ini_set(yaml.decode_php,0);$init=TRUE;}if(!trim($raw)){returnNULL;}set_error_handler([__CLASS__,errorHandler]);$ndocs=0;$data=yaml_parse($raw,0,$ndocs,[YAML_BOOL_TAG=\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks,]);restore_error_handler();return$data;}
总结反思
之前也实现过远程调试,但是对docker内的系统进行调试还没有做过,不对的试错过程中,也对docker进一步加深的认知与了解。
更多靶场实验练习、网安学习资料,请访问合天网安实验室。