深入剖析与利用CVE-2013-4547: Nginx解析漏洞详解
百度安全中心 · 2014/05/19 11:12
0x00 背景
Nginx历史上曾出现过多次解析漏洞,比如80sec发现的解析漏洞,以及后缀名后直接添加%00截断导致代码执行的解析漏洞。
但是在2013年底,nginx再次爆出漏洞(CVE-2013-4547),此漏洞可导致目录跨越及代码执行,其影响版本为:nginx 0.8.41 – 1.5.6,范围较广。
为了更深入的了解漏洞产生的原因,笔者根据官方补丁(nginx.org/download/pa…),对此漏洞进行了进一步的分析,
0x01 漏洞朔源
1.从官方补丁可以看出nginx在ngx_http_parse_request_line函数处做了代码patch,下载nginx源代码,定位其补丁文件为ngx_http_parse.c,函数ngx_http_parse_request_line中,分别位于代码段:
由此可定位本次漏洞需要分析的点,启用gdb调试,将break点设置为ngx_http_parse_request_line,
并且watch变量state和p,因为此函数为状态机,state为状态值,p为指针所指文志,这将是漏洞触发的关键点。
调试过程中需要跟踪nginx的worker子进程,所以需要设置setfollow-fork-mode child,并且在相应的地方设置断点,
图-1 跟进子进程
2.分别发送正常和攻击语句进行测试:
正常语句:
http://127.0.0.1/a.jpg
攻击语句:
http://127.0.0.1/a.jpg(非编码空格)\0.php
使用正常语句一直s或n跟踪,会发现在对url的解析过程中,当路径中存在’.’或url存在’\0’会有如下处理:
#!cpp
case sw_check_uri:
……
case '.':
r->complex_uri = 1; //此作为flag会判断使用ngx_http_parse_complex_uri方法,对路径修复
state = sw_uri;
break;
casesw_check_uri:
……
case '\0': //当遇到\0是,将会判断为非法字符
return NGX_HTTP_PARSE_INVALID_REQUEST;
但是在检查uri中有空格则会进入到sw_check_uri_http_09
的逻辑中,那么当我们发送攻击代码的时候,执行流程将如下:
图-2 \0未触发异常
再回到sw_check_uri
状态,此时后面的字符串为.php,而“.”将被为是uri的扩展名的分隔符
图-3 取后缀名错误
最终导致nginx认为此次请求的后缀名为php,通过配置,会传给fastcgi进行处理,而fastcgi在查找文件的时候被\0截断,最终取到”a.jpg(非编码空格)”文件(注:Linux下php-fpm默认限制的后缀名为php,如未取消限制,访问将出现access denied。测试想要查看执行结果,需修改php-fpm.conf中的security.limit_extensions为空,即允许任意后缀名文件作为php解析。)
跨越
location /protected / {deny all;}
的规则的原理与此类似,均为状态机中判断出现混乱,从导致而可以跨越到protected目录中,访问默认不可访问到的文件。
由此可知,常规利用中如果想触发代码执行,条件为可上传带空格的文件到服务器,并且服务器存储的时候也需要保留空格,而大多数情况下,web应用在处理上传文件时,都会将文件重命名,通过应用自身添加后缀,或者对后缀名去掉特殊字符后,做类型判断。
以上因素都导致此漏洞被认为是鸡肋漏洞,难以利用,而被人们所忽略。
0x02 windows下的RCE
此问题在windows的攻击场景中,则从小汽车变身为变形金刚。
首先,我们了解一下windows读取文件时的特点,即文件系统api创建文件名或查找文件名时,默认会去掉文件名后的空格,再执行操作,参见示例代码,目录下放置a.txt不带空格:
#!cpp
#include "stdafx.h"
#include<windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hFile =CreateFile(L"a.txt ",GENERIC_WRITE|GENERIC_READ, 0, //注意a.txt后有一个空格
NULL,
OPEN_EXISTING, // 打开存在的文件
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile ==INVALID_HANDLE_VALUE)
{
printf("openfailed!");
}
else
{
printf("fileopened");
}
CloseHandle(hFile);
return 0;
}
通过此代码可知道,即使我们传入参数是”a.txt ”带空格,最后访问到却确是”a.txt”不带空格
此时的攻击过程为:
1.上传任意文件(不需要带空格文件),
2.http://127.0.0.1/a.jpg(非编码空格)\0.php
图-4文件a.jpg
图-5漏洞利用
成功将a.jpg文件当作php代码执行,达到了攻击成功的目的。
通过windows的此特性,使CVE-2013-4547在windows+nginx的环境中的危害无限扩大,即在windows下,只要普通用户能上传文件,则可利用本次漏洞,导致代码执行,并进一步入侵服务器。
并且在普通站长中使用windows做为操作系统的数量甚广,CVE-2013-4547在windows的场景下将进行华丽的变身。
from:sec.baidu.com/index.php?r…
下一篇: 赶紧更新 NGINX 防止安全漏洞风险
推荐阅读
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
重现与利用 Nginx 的解析漏洞实操指南
-
第五期:全面梳理 nginx 网站服务器与中间件的漏洞系列——深入解析漏洞集锦(二)
-
深入剖析与利用CVE-2013-4547: Nginx解析漏洞详解
-
详解泛娱乐技术服务报告——深入剖析各类娱乐形态下的架构与实例——具体解析3.2 游戏领域的泛娱乐服务技术(12)
-
剖析RuoYi模块:深入理解日志篇——第二章详解@Log的解析与功能
-
实用的命令行工具指南:深入理解jps、jstack、jmap、jhat、jstat与hprof JVM 性能优化与监控方法" - jps: Java虚拟机进程状态工具 - 全面解读 - jstack: 一步步掌握堆栈跟踪工具 - 实战解析 - jmap & jhat: 内存映射与Java堆分析利器 - 详解篇 - jstat: JVM性能统计与监测工具 - 使用详解 - hprof: 堆/CPU性能剖析工具 - 深入学习指南