做网站项目体会网站建设OA系统开发
- 作者: 五速梦信息网
- 时间: 2026年04月18日 09:56
当前位置: 首页 > news >正文
做网站项目体会,网站建设OA系统开发,购买一个网站需要多少钱?,沈阳关键词自然排名通过前两篇文章的铺垫#xff0c;现在我们可以了解 CVE-2024-4577这个漏洞的原理
漏洞原理
CVE-2024-4577是CVE-2012-1823这个老漏洞的绕过#xff0c;php cgi的老漏洞至今已经12年#xff0c;具体可以参考我的另一个文档
简单来说#xff0c;就是使用cgi模式运行的PHP现在我们可以了解 CVE-2024-4577这个漏洞的原理
漏洞原理
CVE-2024-4577是CVE-2012-1823这个老漏洞的绕过php cgi的老漏洞至今已经12年具体可以参考我的另一个文档
简单来说就是使用cgi模式运行的PHP根据RFC3875的规定Apache会将请求的QUERY_STRING作为命令行参数交给php-cgi执行。攻击者利用这个特性就可以-d选项修改PHP的配置项最后执行任意代码。
文章的最后我也提到了当时PHP官方修复了两次才完成的补丁 if((query_string getenv(QUERY_STRING)) ! NULL strchr(query_string, ) NULL) {/* weve got query string that has no - apache CGI will pass it to command line */unsigned char *p;decoded_query_string strdup(query_string);php_url_decode(decoded_query_string, strlen(decoded_query_string));for (p decoded_query_string; *p p ; p) {/ skip all leading spaces */}if(p -) {skip_getopt 1;}free(decoded_query_string);
}修复方式就是在获取到QUERY_STRING后检查其开头是否是横线-如果是-则跳过后面对参数的解析。而Orange 这次发现的CVE-2024-4577实际上就是横线检查的绕过来说下原理。 在Windows中如果当前系统的字符集也被称为代码页Code Page非Unicode编码在main()函数获取argv的时候会自动执行编码的转换其中就会涉及到所谓的Best-Fit。cp936
gbk
Best-Fit是一种字符映射策略用以解决源代码页中的字符在目标代码页中没有直接等价物时的问题。在将Unicode代码页中字符转换成非Unicode代码页字符时如果无法找到对应的字符就会按照Best-Fit预定义的一个转换表进行转换。 比如GBK编码cp936的Best-Fit Mapping转换表是https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit936.txt
其中有一些有趣的字符转换比如0xaa在转换后会变成a0xb2在转换后会变成20xad在转换后会变成-。
所以这里我们就可以利用Best-Fit这个特性使用%ad来代替横线-。PHP在执行上述检查的时候会认为命令行的第一个字符是0xAD实际上main()函数的argv的第一个字符已经被Windows按照best-fit mapping转换成-。 本质来说这仍然是一个利用解析差异绕过防御措施的案例。 什么情况下才会使用Best-Bit转换字符串 我们可以编写下面这个简单的Python代码来复现best-fit这个trick os.system(php \xadh) 虽然传入的是\xad但实际最后执行成功。 但我们多测试几次就会发现并不是所有程序的所有参数都会进行Best-Bit的转换我们测试下面几个命令
php -h php \xadh 成功
php -v php \xadv 出错
python -h python \xadh 出错
arp -h arp \xadh 成功
有的成功有的出错。这是为什么呢 阅读PHP代码就会发现有一部分选项是直接使用的main()函数的argv另一部分选项是从Windows API GetCommandLineW()函数获取。由GetCommandLineW()获取的这部分参数仍然保持原样没有转换成横线最后无法正确执行。 XAMPP为什么可以被利用 Orange在文章中提到XAMPP默认配置就可以被利用。最初读到这里的时候我会以为XAMPP是以php-cgi模式运行的PHP服务器但下载安装XAMPP后我发现PHP实际上是以Apache 2.0 Handler的方式运行。 这时候就非常有趣了为什么XAMPP仍然可以在不修改任何配置文件的情况下直接利用呢为什么很多人在实际测试中会遇到500错误呢
这实际上是PHP没有修复的另一个安全机制bypass
比如默认情况下我们需要将php解释器放在cgi-bin目录下这样用户通过访问/cgi-bin/php/dir/script.php即可执行/dir/script.php。
这个操作是很危险的所以PHP增加了如下配置cgi.force_redirect1开启了这个选项默认开启以后只有经过了重定向规则请求才能执行。
Apache在重定向rewrite的时候会增加一个名为REDIRECT_STATUS的环境变量cgi.force_redirect就是依赖这个环境变量来判断是否经历了重定向。
如果非Apache服务器我们就需要设置一下cgi.redirect_status_env来指定php判断请求是否经历重定向的条件。
XAMPP默认使用的sapi
我们下载XAMPP后查看PHPINFO可以发现其运行PHP的模式是“Apache 2.0 Handler”。在这个模式下PHP会被编译成Apache的一个模块dll动态链接库并由Apache来调用执行。
我们在apache/conf/extra/httpd-xampp.conf中可以找到相关的配置 LoadFile /program/xampp/xampp/php/php8ts.dllLoadFile /program/xampp/xampp/php/libpq.dllLoadFile /program/xampp/xampp/php/libsqlite3.dllLoadModule php_module /program/xampp/xampp/php/php8apache2_4.dllFilesMatch .php\(SetHandler application/x-httpd-php/FilesMatchFilesMatch \.phps\)SetHandler application/x-httpd-php-source/FilesMatch可见这里所有的.php后缀文件会被交给php8apache2_4.dll来执行这和PHP CGI是没有任何关系的。
如何正常配置使用PHP CGI 思考一个问题如果我们需要正常配置一个使用PHP CGI解析PHP的Apache服务器应该如何编写配置文件呢 如果是部署基于脚本的CGI服务器我们需要将可执行文件放置在某个目录下比如/cgi-bin/hello.cgi。这个hello.cgi脚本的第一行是“shebang”用以指定当前脚本的解释器比如 # !/bin/bash ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ Directory /usr/lib/cgi-bin AllowOverride None Options ExecCGI AddHandler cgi-script .cgi .pl .php Require all granted /Directory 设置 PHP 文件的 Shebang 行和 Content-Type 头 在每个 PHP 脚本的开头添加 Shebang 行和 Content-Type 头。例如/cgi-bin/hello.cgi 文件内容如下 #!/usr/bin/php
?php
header(Content-Type: text/html; charsetUTF-8);echo html;
echo headtitleHello, CGI!/title/head;
echo body;
echo h1Hello, World!/h1;
echo /body;
echo /html其中#!/usr/bin/php 是 Shebang 行用于指定 PHP 解释器的路径。 设置文件权限 确保 PHP 文件具有执行权限使其可以作为 CGI 脚本运行 chmod x /cgi-bin/hello.cgi测试脚本 通过浏览器访问该脚本。例如如果 CGI 脚本路径是 /cgi-bin/hello.cgi则访问 http://yourdomain.com/cgi-bin/hello.cgi。
事实上几乎没有PHP应用会这么编写代码相比于这种将脚本直接作为可执行文件的方法PHP另辟蹊径专门设计了一个SAPI就叫php-cgi。
调用php-cgi执行一个PHP文件时它会负责输出“Content-Type”头。比如执行echo ?php echo 123; | php-cgi
所以类似于hello.cgi我们也可以直接将php-cgi这个可执行文件映射到/cgi-bin/目录下然后再使用Apache的Action指令将PHP相关请求“重定向”到php-cgi上最后执行PHP代码。
此时配置文件如下 ScriptAlias /php-cgi/ /program/xampp/xampp/php/Directory /program/xampp/xampp/htdocsAddHandler application/x-httpd-php .phpAction application/x-httpd-php /php-cgi/php-cgi.exe/Directory
ScriptAlias指令的作用是将/php-cgi/路径指向/program/xampp/xampp/php/目录
Action指令的作用就是将所有对.php文件的请求都使用/php-cgi/php-cgi.exe也就是/program/xampp/xampp/php/php-cgi.exe来执行。
Apache在调用php-cgi的时候会设置环境变量REDIRECT_STATUS。php-cgi为了确认这个请求确实是由Action指令执行的而不是用户直接请求的增加了一个开关“cgi.force_redirect”默认开启。开启这个开关的情况下php-cgi会验证此次执行是否包含环境变量REDIRECT_STATUS。
XAMPP为什么可以被利用
了解了php-cgi正常的部署方式我们回来看下XAMPP。虽然XAMPP执行PHP时使用的是Apache 2.0 Handler但它仍然给PHP CGI预留了一个口子就是使用ScriptAlias指令把php-cgi.exe映射到了Web目录下。
上述两个关键指令XAMPP中使用了ScriptAlias指令但是Action指令被注释了 这本身也没太大问题因为有cgi.force_redirect的限制在没有Action指令的情况下直接访问php-cgi.exeREDIRECT_STATUS环境变量不会被设置。我们可以做个测试直接请求/php-cgi/php-cgi.exe会返回500错误查看日志会有Security Alert!的字眼
php-cgi.exe 接收cgi格式 -dcgi.force_redirect0 说明不再检测环境变量REDIRECT_STATUS
因为我们前面说到对于REDIRECT_STATUS环境变量的限制是cgi.force_redirect这个开关来决定的。那么我们直接利用CVE-2024-4577漏洞添加-d cgi.force_redirect0关闭这个开关即可绕过限制了。
值得注意的是因为在高版本PHP中allow_url_include这个开关已经被废弃所以会抛出一个警告导致Content-Type头输出失败也会返回500。网上很多人没有注意到这一点我们需要添加一个-d error_reporting0来规避这一点。
PHP没有修复的另一种cgi.force_redirect绕过
前面我们使用-d cgi.force_redirect0关闭PHP的检查实际上PHP中有另一个Bug也可以导致cgi.force_redirect的绕过而且最新版本仍然没有修复
我们查看PHP源码sapi/cgi/cgi_main.c中对于REDIRECT_STATUS环境变量的检查代码 / check force_cgi after startup, so we have proper output /if (cgi CGIG(force_redirect)) {/ Apache will generate REDIRECT_STATUS,* Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.* redirect.so and installation instructions available from* http://www.koehntopp.de/php.* – kknetuse.de/if (!getenv(REDIRECT_STATUS) !getenv (HTTP_REDIRECT_STATUS) / this is to allow a different env var to be configured* in case some server does something different than above /(!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))) {zend_try {SG(sapi_headers).http_response_code 400;PUTS(bSecurity Alert!/b The PHP CGI cannot be accessed directly.\n\n\pThis PHP CGI binary was compiled with force-cgi-redirect enabled. This\n\means that a page will only be served up if the REDIRECT_STATUS CGI variable is\n\set, e.g. via an Apache Action directive./p\n\pFor more information as to iwhy/i this behaviour exists, see the a href\PHP: 以 CGI 模式安装时 - Manual \manual page for CGI security/a./p\n\pFor more information about changing this behaviour or re-enabling this webserver,\n\consult the installation file that came with this distribution, or visit \n\a href\PHP: Windows 系统下的安装 - Manual \the manual page/a./p\n);} zend_catch {} zend_end_try();if defined(ZTS) !defined(PHP_DEBUG)/ XXX were crashing here in msvc6 debug builds at* php_message_handler_for_zend:839 because* SG(request_info).path_translated is an invalid pointer.* It still happens even though I set it to null, so something* weird is going on.*/tsrm_shutdown();endif free(bindpath);return FAILURE;}} 可见除了getenv(REDIRECT_STATUS)以外还有一个getenv(HTTP_REDIRECT_STATUS)这两个环境变量都可以用于cgi.force_redirect的检查。而第二个环境变量HTTP_REDIRECT_STATUS是由HTTP_开头。
httpoxy漏洞就是因为很多HTTP客户端会使用HTTP_PROXY环境变量的值作为代理因为这个环境变量是HTTP_开头导致我们可以通过HTTP请求头控制造成漏洞
PHP这里也是一样的问题环境变量HTTP_REDIRECT_STATUS原本是为了兼容Netscape但它是由HTTP_开头所以用户可以直接控制。
PHP这里也是一样的问题环境变量HTTP_REDIRECT_STATUS原本是为了兼容Netscape但它是由HTTP_开头所以用户可以直接控制。
我们去掉前面POC中的-d cgi.force_redirect0并添加一个HTTP头Redirect-Status: 1仍然可以成功利用漏洞 虽然CVE-2024-4577漏洞在最新的PHP版本中已经修复了但这个环境变量HTTP_REDIRECT_STATUS仍然可以导致cgi.force_redirect的绕过。
- 上一篇: 做网站项目计划书门户网站 源码
- 下一篇: 做网站销售会遇到哪些问题百度搜索引擎营销如何实现
相关文章
-
做网站项目计划书门户网站 源码
做网站项目计划书门户网站 源码
- 技术栈
- 2026年04月18日
-
做网站显示不同字体镇江网站开发公司
做网站显示不同字体镇江网站开发公司
- 技术栈
- 2026年04月18日
-
做网站先做前端好还是先做逻辑WordPress之类的
做网站先做前端好还是先做逻辑WordPress之类的
- 技术栈
- 2026年04月18日
-
做网站销售会遇到哪些问题百度搜索引擎营销如何实现
做网站销售会遇到哪些问题百度搜索引擎营销如何实现
- 技术栈
- 2026年04月18日
-
做网站销售一个星期的计划南宁做网站建设
做网站销售一个星期的计划南宁做网站建设
- 技术栈
- 2026年04月18日
-
做网站销售怎么找客户友链是什么
做网站销售怎么找客户友链是什么
- 技术栈
- 2026年04月18日

