DolphinPHP1.5.1版本的RCE
侵权声明本文章中的全部内容(包罗但不限于文字、图像和其他媒体)仅供教育和参考目的。如果在本文章中使用了任何受版权掩护的材料,我们满怀敬意地承认该内容的版权归原作者全部。
如果您是版权持有人,并且认为您的作品被侵犯,请通过以下方式与我们联系: 。我们将在确认后的合理时间内采取适当措施,包罗删除相干内容。
感谢您的理解与支持。
漏洞原理:
call_user_func(代码执行,体系命令)实现rce
漏洞成因:
用seay工具自动审计得出一个命令执行点。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101223915-936843101.png
判定参数param和参数log[$param]是否可控。
起首走读param参数
由代码可知流程:
param数组从value通过分割'|'得来,而value是从match二维数组中得来的。
foreach ($match 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);https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101252161-1501812174.png
通过查询可以得出'admin/action'所指向的数据库名为admin_action
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101319433-766142682.png
通过sql_front或其他数据库工具,可以找到该数据表,发现其字段名有一个是module还有一个是name。此时就对应上来两个可控参数。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101342545-892737970.png
通过和背景的对比发现,体系中的行为管理和该数据表内容相同。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101348661-575214366.png
点开数据表中的log再点击背景的编辑,此时就可以发现param参数是可控的。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101400272-1260503112.png
因为从前面可知param数组是从value通过分割'|'得来,而value又是通过log过滤空格得来的。
所以可以得出如上图所示:
如果log= 编辑了用户:
得出value=user|get_nickname
param = user
param = get_nickname
走读参数log[$param]
参数二是有两部分组成。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101421584-1674894658.png
在log数组中有两个参数是可控的
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101442504-1415706723.png
因为第一个可控参数需要用于查询数据库,所以我们可以利用第二个可控参数。
由此可得如果需要得到第二个可控参数通过代码$log[$param]可以看出param需要即是details
通过查看有61处调用了该函数,随机选择一个跟进。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101452697-1409564021.png
跟进方法可以发现可控参数details是data数组中name参数的值,而data数组内容又是通过post方法获取的。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101505918-2061157637.png
结合前面分析可以得出:
call_user_func()中的参数一是从log以"|"分割的右边参数获取,而参数二是从post请求中的name参数获取的,但是有个条件是log以"|"分割的左边参数需要即是details。
最后有个绕过
因为1.5.0以及修复该漏洞了,现在有绕过本领。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101521654-1579668882.png
更进is_disable_func()方法,发现还是没有被过滤的执行函数。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101527819-711863052.png
于是想到了debug调试,发现了那些被过滤的执行函数。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101535873-421139948.png
发现熟知的可执行命令的函数都被过滤在外了,但是发现验证返回的函数是in_array()于是想着绕过该函数,又想到ctf题中有一种绕过本领即在命令前加一个"\"可以成功绕过判定并且可以正常执行。
复现
1、在体系 —> 行为管理然后搜刮role_add再点击编辑
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101544790-702114260.png
2、修改日志规则为 添加了角色:之后提交生存。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101555444-1957458114.png
3、选择用户 -> 角色管理 -> 新增
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101626246-1420606069.png
4、角色名称填写dir或其他体系命令,点击确定前需要用bp抓包,以便下一条命令执行。
https://img2024.cnblogs.com/blog/3473131/202407/3473131-20240725101634412-1674052461.png
这只是一个功能点的漏洞复现其他调用该函数的功能都能实现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
免责声明
本博客所提供的技术知识和信息仅旨在教育和分享网络安全最佳实践,促进网络安全意识的提升。作者严禁将这些技术和信息用于任何非法或不道德的目的。
使用本博客内容而导致的任何违法行为或后果,作者不承担任何法律责任。全部读者在使用本博客的信息时,应自行承担风险,并确保遵守当地法律法规。
我们鼓励全部读者合法地使用所提供的信息和技术,致力于维护安全和负责任的网络情况。
感谢您的理解与支持。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]