기본 콘텐츠로 건너뛰기

[CVE-2017-5638] Apache Struts2 취약점 분석 정보

 Apache Struts2 취약점(CVE-2017-5638)은 원격 코드 실행 취약점입니다. HTTP Request 헤더의 Content-Type 값을 변조하여 원격 코드실행을 가능하게 합니다. 취약점에 대한 설명을 찾아보면 Content-Type 헤더 필드에 OGNL 표현식을 삽입할 경우 Struts2의 Jakarta 플러그인 오류 처리 과정에서 임의의 코드가 실행될 수 있음을 알 수 있습니다.

 본 문서에서는 Struts 2.3.31 버전을 대상으로 취약점을 분석해 보았습니다. 



공격 코드 동작 확인

 공격 코드를 사용해서 “dir” 명령을 전달하면 다음과 같이 취약한 서버의 파일 목록을 확인할 수 있습니다.

[취약한 서버의 파일 목록을 확인]

 취약한 서버로 전달되는 패킷입니다. Content-Type 항목에 OGNL 표현식으로 작성된 공격코드가 포함되어 있습니다.

[취약한 서버로 전달되는 패킷]



공격 코드 확인

[공격 코드 확인]

 서버에 전달되는 매개 변수 중에 #nike='multipart / form-data'는 공격코드 실행의 토대를 마련합니다.


 #cmd 매개 변수에는 도스 명령어가 지정됩니다. 그리고 취약한 서버의 운영체제를 확인한 뒤에 유형별 공격 명령을 완성합니다.


 마지막으로 공격 명령을 실행합니다.




서버 취약 코드 확인

 서버는 request 요청이 넘어오면 FilterDispatcher Class의 doFilter 메서드를 사용해서 필터 작업을 수행합니다. 그 과정에서 prepareDispatcherAndWrapRequest를 호출하게 됩니다.

[FilterDispatcher.doFilter]

 prepareDispatcherAndWrapRequest는 Request Wrapping 메서드입니다. 해당 메서드는 내부적으로 dispatcher.wrapRequst를 호출합니다.

[FilterDispatcher.prepareDispatcherAndWrapRequest]

 dispatcher.wrapRequst는 다양한 방식으로 전송된 요청에 대한 Wrapping을 수행하는 메서드입니다. Struts2 원격코드실행 취약점(CVE-2017-5638)의 경우 content_type을 'multipart/form-data'로 설정하고 전송하기 때문에 MultiPartRequestWrapper를 호출하게 됩니다.

[dispatcher.wrapRequst]

 MultiPartRequestWrapper.java는 multipart request에 대한 구문을 분석하고 Wrapping 합니다. 이로 인해 구문 분석 메서드인 JakartaMultiPartRequest.parse가 실행됩니다.

[MultiPartRequestWrapper.java]

 구문 처리 과정에서 Content-Type 헤더의 형식을 식별하지 못하므로 예외가 발생하게 되고 JakartaMultiPartRequest.buildErrorMessage가 실행됩니다.

[JakartaMultiPartRequest.parse]

 JakartaMultiPartRequest.buildErrorMessage 내에 존재하는 LocalizedTextUtil.findText는 OGNL 표현식을 실행합니다.

[JakartaMultiPartRequest.buildErrorMessage]

 LocalizedTextUtil.findText의 정의를 살펴보겠습니다. $ {...} 내의 모든 것은 OGNL 표현식으로 간주하고 처리한다고 되어 있습니다. 그 결과 공격코드가 실행되는 것입니다.

\
[LocalizedTextUtil.findText의 정의]

 Struts 2 Core 2.3.4 API에 대한 정의를 간략하게 소개해 놓았습니다. 

※ FilterDispatcher Class

 Master filter for Struts that handles four distinct responsibilities:

- Executing actions
- Cleaning up the ActionContext (see note)
- Serving static content
- Kicking off XWork's interceptor chain for the request lifecycle

IMPORTANT: this filter must be mapped to all requests. Unless you know exactly what you are doing, always map to this URL pattern: /*


※ Method

∙ doFilter: Process an action or handle a request a static resource. The filter tries to match the request to an action mapping.

∙ prepareDispatcherAndWrapRequest: Wrap and return the given request, if needed, so as to to transparently handle multipart data as a wrapped class around the given request.

--------------------------------------------------------------------------------------------------------------

※ dispatcher Class

A utility class the actual dispatcher delegates most of its tasks to. Each instance of the primary dispatcher holds an instance of this dispatcher to be shared for all requests.


※ Method

∙ wrapRequest: Wrap and return the given request or return the original request object. This method transparently handles multipart data as a wrapped class around the given request.

--------------------------------------------------------------------------------------------------------------

※ MultiPartRequestWrapper Class

Parse a multipart request and provide a wrapper around the request.

--------------------------------------------------------------------------------------------------------------

※ JakartaMultiPartRequest Class

Multipart form data request adapter for Jakarta Commons Fileupload package.


※ Method

∙ parse: Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's multipart classes (see class description).




해결 방안

 취약점이 패치된 버전으로 업데이트 수행
  - Apache Struts 2.3.32
  - Apache Struts 2.5.10.1

 Content-Type에 엄격한 필터링 적용 및 ognl 표현식 사용 금지

 commons-fileupload-x.x.x.jar 파일 삭제 (임시조치_삭제 시 업로드 기능 사용 불가)

댓글

이 블로그의 인기 게시물

보안 공부 링크

SSLsplit - SSL/TLS기반의 네트워크 포렌식 및 침투테스트(중간자공격) 도구 http://www.roe.ch/SSLsplit 가상화 서버운영 및 구축을 위한 Xenserver가 오픈소스로 공개 http://www.xenserver.org/ Python과 Fabric를 사용한 SSH 봇넷 C&C 구축 예제 http://raidersec.blogspot.kr/2013/07/building-ssh-botnet-c-using-python-and.html 파워쉘을 이용한 비밀번호 정보 획득 http://www.obscuresecurity.blogspot.kr/2013/07/get-gpppassword.html niktoHelper - Nmap의 Grepable형식을 Nikito와 연동하기 위한 파이썬 스크립트 http://milo2012.wordpress.com/2013/07/07/niktohelper-bridge-between-nmap-grepable-output-and-nikto/ 루비를 통한 심도있는 XSS 방어 방법 http://homakov.blogspot.com.es/2013/07/xss-defense-in-depth-with-rackrails-demo.html IT관련 E-Book 모음 http://www.cyberhades.com/2013/07/04/unos-libritos-tecnicos-para-el-veranito JJEncode 스크립트 분석 http://www.kahusecurity.com/2013/jjencode-script-leads-to-drive-by/ 웹브라우저 호환성 검증 및 분석결과 제공 http://www.modern.ie/ko-kr/ http://browsershots.org/ html 색상 선택 도구 https://kuler.adobe.com/create/color-wheel/ Windows 메모리 보호 메커니즘 http://resources.infosecinstitute.com/window...

dns2proxy 해킹툴

dns2proxy Offensive DNS server This tools offer a different features for post-explotation once you change the DNS server to a Victim. <Referer to help (-h) to new params options> Feature 1 Traditional DNS Spoof adding to the response the original IP address. Using spoof.cfg file: hostname ip.ip.ip.ip root@kali:~/dns2proxy# echo " www.s21sec.com  1.1.1.1" > spoof.cfg // launch in another terminal dns2proxy.py root@kali:~/dns2proxy# nslookup  www.s21sec.com  127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name:  www.s21sec.com Address: 1.1.1.1 Name:  www.s21sec.com Address: 88.84.64.30 or you can use domains.cfg file to spoof all host of a same domain: root@kali:~/demoBH/dns2proxy# cat dominios.cfg .domain.com 192.168.1.1 root@kali:~/demoBH/dns2proxy# nslookup aaaa.domain.com 127.0.0.1 Server: 127.0.0.1 Address: 127.0.0.1#53 Name: aaaa.domain.com Address: 192.168.1.1 Hostnames at nospoof.cfg will no be spoofed. Featu...

어셈블리어(Assembly) 기초

0x01.  어셈블리 언어란 ? &  배우는 목적 CPU  에는 해당 프로세서에 명령을 내리기 위해 고유의 명령어 세트가 마련되어 있는데 이  명령어 세트를 기계어라고 한다 .  이 기계어는 숫자들의 규칙조합임으로 프로그래밍에 상당 히 난해하다 .  그래서 이 기계 명령어를 좀더 이해하기 쉬운 기호 코드로 나타낸것 ( 기계어와  1:1 로 대응된 명령을 기술하는 언어 ) 이 어셈블리어이다 .  어셈블리 언어는 그 코드가 어떤  일을 할지를 추상적이 아닌 ,  직접적으로 보여준다 .  논리상의 오류나 ,  수행 속도 ,  수행 과정 에 대해 명확히 해준다는 점에서 직관적인 언어이다 .  어셈블리 언어를 사용하면 메모리에 대한 이해도도 높아진다 .  어셈블리를 익히고 ,  배우는데 있어서는 여러 가지 목적이 있을 수 있다 .  컴퓨터 시스템 & 구조를 좀 더 깊게 이해하고 ,  메모리상의 데이터나  I/O 기기를 직접 액 세스 하는등의 고급언어에서는 할 수 없는 조작을위해서이다 .  프로그램의 최적화 및 리버 스 엔지니어링을 위해서도 필요하다 . + 2 줄 요약  + -  어셈블리 언어는 기계어와  1:1  대응을 하는 언어이다 . -  어셈블리 언어를 배우면 시스템을 이해하는데 도움이 된다 . 0x02.  어셈블리를 위한 기본 지식 (1)  기본적인 하드웨어 1) CPU -  메모리에 있는 내용을 읽고 ,  쓰고 데이터를 메모리와 각 레지스터로 보낸다 . 프로그램의 명령을 해석하고 실행한다 . 하나의 프로세서는  12~14 개의 레지스터를 가 지고 있으며 , CPU 의 연산 ,  논리 장치는 숫자와 기호에 관한 연산자를...