
권한 우회 및 코드 실행을 위한 단계별 익스플로잇과 함께 Nginx CVE-2013-4547 URI 구문 분석 취약점을 시연하는 Docker 기반 랩입니다.
영향 버전: Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7
참고 링크:
이 취약점은 사실 코드 실행과 큰 관련이 없습니다. 주요 원인은 요청된 URI를 잘못 해석하여 사용자가 요청한 파일명을 잘못 가져옴으로써 권한 우회, 코드 실행 등의 연쇄 영향이 발생하는 것입니다.
예를 들어, Nginx가 .php로 끝나는 요청을 매칭하면 fastcgi로 보내 파싱하도록 하는 일반적인 작성 방식은 다음과 같습니다.
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
정상적인 경우(pathinfo를 비활성화한 경우)에는 .php 확장자를 가진 파일만 fastcgi로 보내져 파싱됩니다.
CVE-2013-4547이 존재하는 경우, 1.gif[0x20][0x00].php를 요청하면 이 URI는 정규식 \.php$에 매칭되어 이 Location 블록에 진입할 수 있습니다. 하지만 진입 후 Nginx는 요청된 파일이 1.gif[0x20]이라고 잘못 인식하여 이를 SCRIPT_FILENAME 값으로 설정해 fastcgi로 보냅니다.
fastcgi는 SCRIPT_FILENAME 값을 기준으로 파싱하므로, 결국 파싱 취약점이 발생합니다.
그러므로 우리는 공백으로 끝나는 파일을 업로드하기만 하면 PHP가 이를 파싱하도록 만들 수 있습니다.
또 다른 예로, 많은 웹사이트가 백엔드(admin) 접근을 허용하는 IP를 제한합니다.
location /admin/ {
allow 127.0.0.1;
deny all;
}
우리는 다음과 같은 URI를 요청할 수 있습니다: /test[0x20]/../admin/index.php. 이 URI는 location 뒤의 /admin/과 매칭되지 않으므로 IP 검증을 우회합니다. 하지만 최종적으로 요청된 파일은 /test[0x20]/../admin/index.php, 즉 /admin/index.php이므로 백엔드에 성공적으로 접근할 수 있습니다. (이것은 test 라는 이름의 디렉터리가 있어야 한다는 전제가 필요합니다. 이것은 Linux 시스템의 특징인데, 존재하지 않는 디렉터리가 있으면 상위 디렉터리로 이동하더라도 파일이 존재하지 않는다는 오류가 발생합니다. Windows에는 이 제한이 없습니다.)
취약점 환경을 시작합니다:
docker-compose build
docker-compose up -d
환경이 시작된 후 http://your-ip:8080/에 접속하면 업로드 페이지를 볼 수 있습니다.
이 환경은 블랙리스트 검증을 사용하므로 php 확장자 파일을 업로드할 수 없습니다. CVE-2013-4547을 활용해야 합니다. 1.gif 를 업로드합니다. 뒤의 공백에 주의하세요:

http://your-ip:8080/uploadfiles/1.gif[0x20][0x00].php에 접속하면 PHP가 파싱된 것을 확인할 수 있습니다:

참고로 [0x20]은 공백이고, [0x00]은 \0이며, 이 두 문자는 인코딩할 필요가 없습니다.