DolphinPHP1.5.1版本的RCE
侵权声明
本文章中的所有内容(包括但不限于文字、图像和其他媒体)仅供教育和参考目的。如果在本文章中使用了任何受版权保护的材料,我们满怀敬意地承认该内容的版权归原作者所有。
如果您是版权持有人,并且认为您的作品被侵犯,请通过以下方式与我们联系: [360619623@qq.com]。我们将在确认后的合理时间内采取适当措施,包括删除相关内容。
漏洞原理:
call_user_func(代码执行,系统命令)实现rce
漏洞成因:
用seay工具自动审计得出一个命令执行点。
判断参数param[1]和参数log[$param[0]]是否可控。
首先走读param[1]参数
由代码可知流程:
param数组从value通过分割'|'得来,而value是从match二维数组中得来的。
foreach ($match[1] as $value)
$param = explode('|', $value);
match数组通过action_info['log']获取,其中正则/\[(\S+?)\]/
匹配包含在方括号中的任何非空白字符序列,整合给match。
preg_match_all('/\[(\S+?)\]/', $action_info['log'], $match)
action_info是通过sql表查询得来的,其中module和action是可控的。
$action_info = model('admin/action')->where('module', $module)->getByName($action);
通过查询可以得出'admin/action'所指向的数据库名为admin_action
通过sql_front或其他数据库工具,可以找到该数据表,发现其字段名有一个是module还有一个是name。此时就对应上来两个可控参数。
通过和后台的对比发现,系统中的行为管理和该数据表内容相同。
点开数据表中的log再点击后台的编辑,此时就可以发现param[1]参数是可控的。
因为从前面可知param数组是从value通过分割'|'得来,而value又是通过log过滤空格得来的。
所以可以得出如上图所示:
如果log=[user|get_nickname] 编辑了用户:[details]
得出value=user|get_nickname
param[0] = user
param[1] = get_nickname
走读参数log[$param[0]]
参数二是有两部分组成。
在log数组中有两个参数是可控的
因为第一个可控参数需要用于查询数据库,所以我们可以利用第二个可控参数。
由此可得如果需要得到第二个可控参数通过代码$log[$param[0]]可以看出param[0]需要等于details
通过查看有61处调用了该函数,随机选择一个跟进。
跟进方法可以发现可控参数details是data数组中name参数的值,而data数组内容又是通过post方法获取的。
结合前面分析可以得出:
call_user_func()中的参数一是从log以"|"分割的右边参数获取,而参数二是从post请求中的name参数获取的,但是有个前提是log以"|"分割的左边参数需要等于details。
最后有个绕过
因为1.5.0以及修复该漏洞了,现在有绕过手法。
更进is_disable_func()方法,发现还是没有被过滤的执行函数。
于是想到了debug调试,发现了那些被过滤的执行函数。
发现熟知的可执行命令的函数都被过滤在外了,但是发现验证返回的函数是in_array()于是想着绕过该函数,又想到ctf题中有一种绕过手法即在命令前加一个"\"可以成功绕过判断并且可以正常执行。
复现
1、在系统 —> 行为管理然后搜索role_add再点击编辑
2、修改日志规则为[details|\system] 添加了角色:[details]之后提交保存。
3、选择用户 -> 角色管理 -> 新增
4、角色名称填写dir或其他系统命令,点击确定前需要用bp抓包,以便下一条命令执行。
这只是一个功能点的漏洞复现其他调用该函数的功能都能实现rce的,我还试过role_edit也是差不多的。
总结
第一次复现php漏洞我感觉难度还是比较高的。
又学习到了一个危险函数call_user_func()
感谢两位大佬的帖子,学到了很多。
https://xz.aliyun.com/t/14379?time__1311=GqAxuD9DgD00i%3DD%2F7riQGkDR0itbKxn0bD
https://xz.aliyun.com/t/14810?time__1311=GqA2kGkGCD%2FD78G7bDOzDkzR3AKor2mD
免责声明
本博客所提供的技术知识和信息仅旨在教育和分享网络安全最佳实践,促进网络安全意识的提升。作者严禁将这些技术和信息用于任何非法或不道德的目的。
使用本博客内容而导致的任何违法行为或后果,作者不承担任何法律责任。所有读者在使用本博客的信息时,应自行承担风险,并确保遵守当地法律法规。
我们鼓励所有读者合法地使用所提供的信息和技术,致力于维护安全和负责任的网络环境。
感谢您的理解与支持。