
Apache Tomcat 보안 우회 취약점 Poc

최근 Apache는 Apache Tomcat 7, 8, 9의 여러 버전에 보안 우회 취약점이 존재한다는 보안 공고를 발표했습니다. 공격자는 이 문제를 이용하여 일부 보안 제한을 우회하고 승인되지 않은 작업을 수행할 수 있으며, 이는 추가 공격으로 이어질 수 있습니다.
Apache Tomcat 서블릿 주석으로 정의된 보안 제약 조건은 서블릿이 로드된 후에만 한 번 적용됩니다. 이러한 방식으로 정의된 보안 제약 조건은 URL 패턴 및 해당 지점 아래의 모든 URL에 적용되므로 서블릿이 로드되는 순서에 따라 달라질 수 있으며, 이로 인해 리소스가 해당 리소스에 대한 접근 권한이 없는 사용자에게 노출될 수 있습니다.
CVE-2018-1305
Apache Tomcat < 9.0.5
Apache Tomcat < 8.5.28
Apache Tomcat < 8.0.50
Apache Tomcat < 7.0.85
중간
Java EE는 ACL 권한 검사와 유사한 ServletSecurity 애너테이션을 제공하며, 서블릿을 보호하기 위해 이를 사용할 수 있습니다. 두 개의 서블릿이 있다고 가정할 때, Servlet1은 액세스 경로가 "/servlet1/"이고 ServletSecurity 애너테이션이 추가되어 있으며, Servlet2는 액세스 경로가 "/servlet1/servlet2/"이지만 ServletSecurity 애너테이션이 없습니다. 처음 servlet1/servlet2에 접근하면 servlet1의 ServletSecurity 애너테이션이 적용되지 않아 "/servlet1/servlet2" 경로를 보호할 수 없으며, 이로 인해 인증되지 않은 접근이 발생할 수 있습니다.
"/servlet1/servlet2"에 접근하기 전에 먼저 "/servlet1"에 접근한 경우 Tomcat은 ACL을 로드하고 "/servlet1/servlet2"에 대한 보호를 시작하므로 취약점이 트리거되지 않습니다.

Servlet1 앞에 ServletSecurity 애너테이션을 추가하고 Servlet2에는 이 애너테이션이 없습니다.

web.xml 파일에서 servlet에 해당하는 url-pattern을 아래 그림과 같이 수정합니다.

이 프로젝트를 실행합니다. 처음 servlet2의 URL에 접근하면 인증되지 않은 접근이 가능함을 확인할 수 있으며, servlet1에 대한 ACL은 적용되지 않았습니다.
http://localhost:8080/CVE-2018-1305/servlet1/servlet2/

두 번째로 servlet1의 URL에 접근하면 접근이 금지되며, 이때 ACL이 적용됩니다.
http://localhost:8080/CVE-2018-1305/servlet1/

다시 servlet2의 URL에 접근하면 접근이 금지된 것을 확인할 수 있습니다. ACL이 servlet2에 적용되려면 servlet1에 접근한 이력이 있어야 합니다.
http://localhost:8080/CVE-2018-1305/servlet1/servlet2/


따라서 이 취약점의 재현은 Tomcat이 시작된 후 "/servlet1/"에 접근하기 전에 먼저 "/servlet1/servlet2/" 페이지에 접근한 경우로 제한됩니다. 이전에 누군가 "/servlet1/*" 페이지에 접근한 적이 있다면 취약점이 트리거되지 않습니다. 취약점의 위험성은 높지만 악용 조건이 까다로워 영향 범위는 크지 않습니다.
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1305