漏洞描述
WordPress的Hash表单 - 拖放表单构建器插件由于在所有版本中缺失’file_upload_action’函数中的文件类型验证,存在任意文件上传漏洞,包括1.1.0版本。这使得未经身份验证的攻击者可以在受影响站点的服务器上上传任意文件,可能导致远程代码执行。
影响版本
<= 1.1.0 版本
漏洞复现
先在目标网站的源码中找到ajax_nounce
然后发送如下请求包
1 | POST /wp-admin/admin-ajax.php?action=hashform_file_upload_action&file_uploader_nonce=9aa0cc0333&allowedExtensions%5B0%5D=txt&sizeLimit=1048576&qqfile=ycx.txt HTTP/1.1 |
然后请求
1 | http://x.x.x.x/wp-content/uploads/hashform/temp/ycx.txt |
漏洞分析
在本地环境复现时,并未成功,于是进行如下调试
根据漏洞描述,全局搜索一下file_upload_action函数
找到wordpress/wp-content/plugins/hash-form/admin/classes/HashFormBuilder.php
关键点主要是第一段代码
1 | if (!wp_verify_nonce(HashFormHelper::get_var('file_uploader_nonce'), 'hashform-upload-ajax-nonce')) { |
对我们传入的file_uploader_nonce进行一个验证,如果验证通过,则会进行文件上传操作,否则die掉这个进程,初步调试就发现我在源码里面获取的ajax_nounce无法通过该if条件,我们继续看一下逻辑
跟进wp_verify_nonce函数
往下走会到这里
这个excepted变量就是期望的变量,我们传入的file_uploader_nonce必须与其一致才能进入下一步,我们看看i变量是如何获取的
这段代码主要就是返回计算当前时间相对于一天的一半时间(43,200 秒)的倍数,并将结果向上取整。通俗点说就是能生成一个大约持续半天的令牌,在这半天内,i变量的值都是不会改变的
随后调用mp_hash函数生成md5
了解了后端是怎么生成nounce的,我们再看看我们在前端获取的ajax_nounce是如何生成的
还是全局搜索一下ajax_nounce,找到wordpress/wp-includes/pluggable.php
发现tocken这些基本都不一样,token可以通过删除让两者一致,但action变量有点奇怪,居然是wp_rest,也就导致了两者不一样。其实最后调试下来感觉影响不是很大,只要你知道目标版本(可在源码中看到),然后在本地调试一下就能获取nounce了。