- 대규모 언어 모델(LLM)과 다양한 데이터 소스를 활용하여 AI 애플리케이션을 시각적으로 설계하고 구축할 수 있는 low-code 플랫폼 [1][2]
- Python 기반으로 개발되었으며, 특정 모델, API, 데이터베이스에 구애받지 않고 유연하게 사용 가능
2. CVE-2025-3248
[사진 1] CVE-2025-3248 [3]
- /api/v1/validate/code에서 발생하는 임의 코드 실행 취약점 (CVSS : 9.8)
영향받는 버전 Langflow 1.3.0 미만 버전
- /api/v1/validate/code : LLM이 생성한 코드의 유효성을 검증하는 API
> 해당 API를 누구나 호출 가능
> validate_code()를 내부적으로 호출 [4]
async def post_validate_code(code: Code) -> CodeValidationResponse:
try:
errors = validate_code(code.code)
return CodeValidationResponse(
imports=errors.get("imports", {}),
function=errors.get("function", {}),
)
except Exception as e:
logger.opt(exception=True).debug("Error validating code")
raise HTTPException(status_code=500, detail=str(e)) from e
- validate_code()는 파이썬 코드의 문법을 검증하고 exec()를 통해 해당 코드를 실행 [5][6]
> 파이썬 코드에 import문과 함수 선언문이 있는지 확인
> import문이 있는 경우 해당 모듈을 로드하고, 함수가 있는 경우 exec()를 통해 해당 코드 실행 [7][8]
def validate_code(code):
# Initialize the errors dictionary
errors = {"imports": {"errors": []}, "function": {"errors": []}}
# Parse the code string into an abstract syntax tree (AST)
try:
tree = ast.parse(code)
except Exception as e: # noqa: BLE001
if hasattr(logger, "opt"):
logger.opt(exception=True).debug("Error parsing code")
else:
logger.debug("Error parsing code")
errors["function"]["errors"].append(str(e))
return errors
# Add a dummy type_ignores field to the AST
add_type_ignores()
tree.type_ignores = []
# Evaluate the import statements
for node in tree.body:
if isinstance(node, ast.Import):
for alias in node.names:
try:
importlib.import_module(alias.name)
except ModuleNotFoundError as e:
errors["imports"]["errors"].append(str(e))
# Evaluate the function definition
for node in tree.body:
if isinstance(node, ast.FunctionDef):
code_obj = compile(ast.Module(body=[node], type_ignores=[]), "<string>", "exec")
try:
exec(code_obj)
except Exception as e: # noqa: BLE001
logger.opt(exception=True).debug("Error executing function code")
errors["function"]["errors"].append(str(e))
# Return the errors dictionary
return errors
2.1 PoC
- 공개된 Scanner에서는 /api/v1/validate/code URL로 import문과 def문이 포함된 파이썬 코드를 POST 메소드로 전송 [9]
alert tcp any any -> any any (msg:"CVE-2025-3248"; flow:to_server,established; content:"POST"; http_method; content:"/api/v1/validate/code"; http_uri; content:"def"; http_client_body; content:"import"; http_client_body;)
- Elasticsearch에 저장된 데이터를 쉽게 시각화하고 탐색 및 분석할 수 있는 웹 인터페이스를 제공
- 사용자가 Elasticsearch에 쿼리를 실행하고, 결과를 시각화(Discover, Visualize, Dashboard, Canvas, Maps 등)하여 분석할 수 있도록 도와줌
[사진 1] Kibana 예시
1.1 ELK
- Elasticsearch, Logstash, Kibana의 조합으로, 데이터 수집 및 분석을 위한 오픈 소스 솔루션 [2]
> Beats : 데이터 수집 담당
※ 데이터를 안정적으로 버퍼링하고 전달하기 위해 Redis, Kafka, RabbitMQ 등과 같이 사용할 수 있음
>Logstash : 다양한 소스에서 데이터를 수집 및 변환하며, 다른 저장소에 전달하는 데이터 처리 파이프 라인 도구
> Elasticsearch : 실시간 분산형 검색 엔진으로 데이터 검색 및 분석을 위해 사용되고, 대규모 데이터를 저장하고 실시간으로 검색할 수 있도록 설계
> Kibana : Elasticsearch에서 저장된 데이터를 시각화하고 분석하는 데 사용
[사진 2] ELK
2. CVE-2025-25015
[사진 3] CVE-2025-25015 [3]
- Prototype Pollution (프로토타입 오염)을 통한 Kibana 임의 코드 실행 취약점 (CVSS : 9.9)
> 조작된 파일 업로드와 조작된 HTTP 요청을 통해 임의의 코드를 실행할 수 있음
※ Elastic Cloud에서 실행되는 Kibana 인스턴스에만 영향을 미침
※ 코드 실행은 Kibana Docker 컨테이너 내에서 제한되며 컨테이너 이스케이프와 같은 추가 악용은 seccomp-bpf 및 AppArmor 프로필에 의해 방지
영향받는 버전 Kibana 8.15.0 이상 ~ 8.17.3 미만 ※ 8.15.0 <= Kibana < 8.17.1 : Viewer 역할을 가진 사용자만 취약점을 악용할 수 있음 ※ Kibana 8.17.1 및 8.17.2 : "fleet-all, integrations-all, actions:execute-advanced-connectors" 권한을 모두 가지는 사용자만 취약점을 악용할 수 있음
- 벤더사 제공 최신 보안 업데이트 적용 [4][5]
제품명
영향받는 버전
해결 버전
Kibana
8.15.0 이상 ~ 8.17.3 미만
8.17.3
- 즉시 업데이트가 불가한 경우 권고
> Kibana 설정파일 (kibana.yml)에서 Integration Assistant 기능 플래그를 false(xpack.integration_assistant.enabled: false)로 설정
2.1 Prototype Pollution (프로토타입 오염) [6][7]
- JavaScript 런타임을 대상으로 하는 주입 공격으로, 공격자는 이를 악용해 객체 속성의 기본값을 제어할 수 있음
> 애플리케이션의 논리를 조작할 수 있으며, 서비스 거부 또는 원격 코드 실행으로 이어질 수 있음
- JavaScript는 프로토타입 기반 객체 지향 프로그래밍 언어
> 프로토타입 (Prototype)이란 JavaScript에서 객체가 다른 객체의 속성과 메서드를 상속받을 수 있도록 하는 메커니즘
> 프로토타입 기반 언어이므로, 객체는 다른 객체를 원형 (Prototype)으로 삼아 속성과 메서드를 공유할 수 있음
> 주요 특징
① 모든 객체는 프로토타입을 가짐 : 객체가 생성될 때, 해당 객체는 자동으로 다른 객체(프로토타입)를 참조하게 됨
② 객체는 프로토타입을 통해 다른 객체의 속성과 메서드를 상속 : 프로토타입을 활용하면 객체지향 프로그래밍의 상속 기능을 구현할 수 있음
③ 프로토타입은 체인 (Prototype Chain)으로 연결 : 어떤 객체에서 속성을 찾을 때, 해당 객체에 없으면 프로토타입을 따라가면서 검색
- 프로토타입은 체인 (Prototype Chain)
> 객체가 속성을 검색할 때, 자신의 프로퍼티에서 찾지 못하면 프로토타입을 따라가며 탐색하는 구조
> 모든 객체는 Object.prototype을 최상위 프로토타입으로 가지며, 이를 따라가면서 상속됨
> 속성을 찾아 상위 프로토타입을 따라 최종적으로 Object.prototype까지 도달하면 (상위 프로토타입에서도 속성을 찾지못한 경우) undefined 반환
> child에는 familyName 속성이 없지만, 프로토타입 체인을 따라 (parent > grandparent) familyName 속성을 찾음
- 공격자는 JavaScript의 프로토타입을 조작해 모든 객체에 악성 속성을 추가할 수 있음
> Object.prototype을 변경하면 모든 객체에 영향을 줄 수 있음
> __proto__, prototype 등의 속성을 사용해 Object.prototype을 변경할 수 있음
// 프로토타입 오염 전 상태 확인
console.log("프로토타입 오염 전 Object.prototype:");
console.log(Object.prototype.isAdmin); // undefined
// 프로토타입 오염 공격
Object.prototype.isAdmin = true; // true로 설정
// 프로토타입 오염 후 Object.prototype 상태 확인
console.log("\n프로토타입 오염 후 Object.prototype:");
console.log(Object.prototype.isAdmin); // true
// 프로토타입 오염 후 객체 생성 및 속성 확인
let obj = {};
console.log("\n오염된 프로토타입을 상속받은 객체:");
console.log(obj.isAdmin); // true
[사진 5] 오염 전 후 비교 [8]
2.2 대응 방안
① 사용자 입력 값 검증
> Object.prototype, proto 등 특정한 키워드를 필터링하고 안전한 데이터만 허용하도록 검증
② Object.create(null) 사용
> 프로토타입이 없는 객체를 생성 즉, Object.prototype을 상속받지 않으므로 프로토타입 오염 공격의 영향을 받지 않음
③ Object.freeze() 또는 Object.seal() 사용
> Object.freeze() : 객체의 변경을 막는 함수_객체의 속성 추가, 수정, 삭제를 할 수 없음
> Object.seal() : 객체의 변경을 막는 함수_ 객체의 속성추가, 수정, 삭제를 할 수 없음, 단, 쓰기 가능한 속성의 값은 변경 가능
- 네트워크 및 시스템 성능을 모니터링하는 오픈 소스 도구 > SNMP를 기반으로 네트워크 장비, 서버, 애플리케이션 등의 성능 데이터를 수집하고, RRDTool을 사용하여 그래프 형태로 시각화
※ SNMP (Simple Network Management Protocol) : 네트워크 장비(라우터, 스위치, 서버 등)의 상태 및 성능 데이터를 수집하는 프로토콜 ※ RRDTool : 시간에 따라 변화하는 데이터를 저장하고 그래프로 시각화해주는 툴
2. CVE-2025-22604
[사진 1] CVE-2025-22604 [2]
- Cacti의 다중 라인 SNMP 결과 파서의 결함으로 인해 발생하는 원격 코드 실행 취약점 (CVSS : 9.1) [3]
> OID의 일부가 시스템 명령의 일부로 사용되는 배열의 키로 사용되어 취약점이 발생
OID (Object IDentifier) [4]
- SNMP는 네트워크 장비의 정보(CPU 사용량, 메모리 사용량, 포트 Up/Down 상태 등)을 MIB(Management Infomation Base)에 저장해 정보를 주고받음 -MIB 내에 포함되어 있는 각 개별 정보(Object)에 대한 ID를 OID라 함 - 즉, CPU 사용량, 메모리 사용량, 포트 상태 등 각 정보에 대해 구분할 수 있는 ID
영향받는 버전 : Cacti <= 1.2.8
- ss_net_snmp_disk_io() 또는 ss_net_snmp_disk_bytes()로 처리될 때 각 OID의 일부가 시스템 명령의 일부로 사용되는 배열의 키로 사용되어 취약점이 발생 > cacti_snmp_walk()에서 exec_into_array()를 사용해 명령을 실행하고 여러 줄을 배열로 사용해 결과를 읽음 > 그 후, [사진 2]의 코드를 사용해 문자 = 를 기준으로 왼쪽 값을 OID에, 오른쪽 값을 Value에 저장 > Value의 경우 필터링을 적용하지만, OID 값은 필터링 없이 사용
[사진 2] OID와 Value 분할 코드
$i=0;
foreach($temp_array as $index => $value) { // $temp_array 배열 순회
if(preg_match('/(.*=.*/',$value)) { // $value 값이 "키=값" 형식인 경우
$parts=explode('=',$value,2); // = 문자를 기준으로 $value를 두 부분으로 분할
$snmp_array[$i]['oid']=trim($parts[0]); // 공백을 제거한 후 값을 oid에 저장
$snmp_array[$i]['value']=format_snmp_string($parts[1],false,$value_output_format); // 필터링 후 value에 저장
$i++; // 다음 배열 인덱스로 이동
} else { // 멀티라인 값 처리
$snmp_array[$i-1]['value'].=$value;
}
}
- PaloAlto GlobalProtect, SonicWall NetExtender SSL-VPN 클라이언트 등에 심각한 취약점 "NachoVPN" 발견 [1][2][3] - 공격자가 악성 VPN 서버를 통해 피해자 기기에 악성 업데이트 설치 또는 민감한 정보를 탈취할 수 있음 - 소셜 엔지니어링 기법을 활용해 사용자를 악성 VPN 서버로 유도해 익스플로잇
2. 주요내용
2.1 CVE-2024-29014
[사진 1] CVE-2024-29014 [4]
- SonicWall의 NetExtender Windows(32 및 64비트) 클라이언트에서 발생하는 임의 코드 실행 취약점 > 소셜 엔지니어링을 통해 악성 VPN 서버로 연결 하도록 유도 및 가짜 EPC 클라이언트 업데이트를 전달해 시스템 권한으로 임의 코드를 실행
영향받는 버전 - NetExtender Windows (32 and 64 bit) 10.2.339 및 이전 버전
- NetExtender 클라이언트는 SSL-VPN 서버에 연결하는 동안 서버에 EPC 클라이언트 업데이트가 있는지 확인하기 위한 요청 전송 > GET /cgi-bin/sslvpnclient?epcversionquery=nxw > 서버는 버전 번호로 판단되는 값으로 응답 > 응답이 0xFF인 경우 클라이언트는 /NACAgent.exe에 대한 GET 요청을 전송
- NECore.dll의 ValidateSignature()에서 해당 파일이 다운로드되고 유효성을 검증
> 해당 함수는 WINTRUST_ACTION_GENERIC_VERIFY_V2 작업을 사용해 WinVerifyTrust 호출 (실행 파일에 포함된 Authenticode 서명 검증 과정) > 그러나 실행 파일의 서명이 신뢰할 수 있는 CA와 연결되는지만 확인하며, 특정 게시자(Microsoft, Adobe, Oracle 등)에 의해 서명되었는지 확인하지 않음
> 따라서 시스템에서 신뢰하는 코드 서명 인증서로 실행 파일을 서명만 하게되면 서명 검사를 통과할 수 있음
※ 다운로드한 NACAgent.exe는 SYSTEM으로 실행되는 NEService.exe의 자식 프로세스로 실행
[사진 2] ValidateSignature()
- sonicwallconnectagent 사용자 정의 URI 핸들러는 SMA Connect 에이전트에 의해 Windows 레지스트리에 등록
> 핸들러는 클라이언트가 연결해야하는 서버를 지정하는 Base64로 인코딩된 JSON 개체가 포함 > 따라서 공격자는 host 값을 악의적인 SSL-VPN 서버의 IP를 가리키도록 sonicwallconnectagent:// URL을 제작하면 취약점 악용 가능
[사진 3] 레지스트리
[사용자 정의 URI 핸들러 예시] sonicwallconnectagent://eyJhY3Rpb24iOjEwLCJoZWxwZXJ2ZXJzaW9uIjoiMS4xLjQyIiwiaG9zdCI6IjE3Mi4xNy4xMjguMSIsInBvcnQiOiI0NDMiLCJ1c2VybmFtZSI6InVzZXIiLCJleHRlbmRpZCI6IkV0UUJ2MFp3elY0OGsxRVpaQ3JMU3ZwOGJLcFh4NFRCcGVISmlmOVUxczQ9In0
- 사용자가 조작된 페이지를 방문하면 악성 SSL-VPN 서버에 연결 및 서명된 악성 NACAgent.exe 실행 > NetExtender 클라이언트에 EPC 에이전트 업데이트 필요 메시지가 표시되며, 무시 또는 확인을 누를 경우 악성 NACAgent.exe 파일이 시스템 권한으로 실행됨
[사진 4] 악성 SSL-VPN 접속
[영상 1] 공격 시연 [5]
2.2 CVE-2024-5921
[사진 5] CVE-2024-5921 [6]
- PaloAlto Networks GlobalProtect 앱의 불충분한 인증 유효성 검사로 임의의 서버에 연결할 수 있는 취약점 > 소셜 엔지니어링을 통해 악성 VPN 서버로 연결 하도록 유도 및 가짜 업데이트를 전달해 시스템 권한으로 임의 코드를 실행
영향받는 버전 - GlobalProtect 6.2.6 이전 버전
- 클라이언트-서버간 인증 과정 중 클라이언트는 POST 메소드로 서버에 자격 증명을 전송 > 서버는 XML 정책 객체로 포맷된 구성 데이터로 응답
- GlobalProtect 클라이언트는 기본적으로 응답을 신뢰 > 유일한 검증은 서버가 해당 도메인에 대한 유효한 TLS 인증서를 가지는지 확인하고 제공된 자격증명을 수락하는 것 > 익스플로잇에서 root-ca, version, uninstall, client-upgrade 요소가 중요
구분
설명
root-ca
- 클라이언트에 제공된 인증서를 신뢰할 수 있는 인증서 저장소에 설치하도록 지시 - GlobalProtect 게이트웨이의 IP 주소가 클라이언트가 신뢰하는 TLS 인증서를 사용할 수 있도록 하기위함 - 공격자는 인증서가 주장하는 모든 목적을 위해 컴퓨터가 완전히 신뢰하는 인증서를 설치할 수 있음 (MITM이 발생해 데이터 탈취 또는 악성 SW 서명 및 실행이 가능)
version
- 클라이언트에 반환된 version 태그는 업데이트 요청이 트리커되는지 여부를 결정 - 값이 클라이언트에 현재 설치된 버전보다 높은 경우 연결 성공 시 업데이트를 요청 - Portal 인증 응답의 version 태그가 현재 설치된 버전보다 높은 경우 > 클라이언트는 Portal에 업데이트를 요청 > 서버는 클라이언트의 OS와 아키텍처에 맞는 적절한 설치 프로그램으로 302 응답
uninstall
- 업그레이드가 관리되는 방식을 설정 > Allow with Prompt (Default) : 새 버전이 확인될 경우 업데이트 메시지 표시 > Allow Transparently : 사용자 상호 작용 없이 자동으로 업데이트 발생 > Internal : 사용자가 내부 네트워크에서 연결되어 있는 경우에만 사용자 상호 작용 없이 업그레이드되며, 내부 GW와 내부 호스트 감지를 구성해야 함 (외부 네트워크에서 연결된 경우 업그레이드 연기) > Disallow : 업데이트 차단 > Allow Manually : "버전 확인"을 선택해 세 버전이 있는 경우 사용자 판단하 수동 업데이트 적용
client-upgrade
- transparent로 설정된 경우 사용자 위치와 동의와 관계없이 자동 업데이트
[사진 6] 응답 예시
- 공격 성공 조건과 성공 시 가능한 악성 행위는 다음과 같음
구분
설명
공격 성공 조건
- 서버 인증서 : 공인 인증 기관에서 서명한 포털용 인증서 - 사용자 지정 루트 인증 기관(CA) : 로컬에서 생성된 CA PEM 파일이 클라이언트에 제공되어 신뢰할 수 있는 인증서 저장소에 설치 - 코드 서명 인증서 : 사용자 지정 CA가 악성 MSI에 서명하기 위해 서명한 인증서
성공 시 가능한 악성 행위
- 자격 증명 공개 : 사용자가 입력한 인증 세부 정보 수집 - 사기성 루트 인증 기관 설치 : 중간자 공격(MITM)이나 코드 서명과 같은 추가 공격이 가능 - 라우팅 구성 조작 : 네트워크 트래픽을 제어하기 위해 악의적인 라우팅 설정 - 악성 업데이트 요청 : 신뢰할 수 있는 기관에서 서명한 MSI를 가져와서 실행하도록 클라이언트를 트리거
[영상 2] Windows 환경 공격 시연 [7][영상 3] macOS 환경 공격 시연 [8]
3. 대응방안
- 벤더사 제공 업데이트 적용 [9][10]
취약점
제품명
영향받는 버전
해결 버전
CVE-2024-29014
NetExtender Windows (32 and 64 bit)
10.2.339 및 이전 버전
10.2.341 및 이후 버전
CVE-2024-5921
GlobalProtect
6.2.6 이전 버전
6.2.6 (또는 VPN 클라이언트를 FIPS-CC 모드에서 실행)
- NachoVPN 툴 활용 [11]
> 개념 증명용 오픈소스 기반 도구로, 악성 VPN 서버를 시뮬레이션할 수 있음
> Cisco AnyConnect, SonicWall NetExtender, Palo Alto GlobalProtect, Ivanti Connect Secure 등의 VPN 제품 지원
- 권고사항
> SSL-VPN 클라이언트를 최신 버전으로 업데이트
> 호스트 기반 방화벽 규칙을 사용해 VPN 클라이언트가 통신할 수 있는 IP 제한
> WDAC, EDR 등을 사용해 VPN 클라이언트가 승인된 실행 파일과 스크립트만 실행할 수 있도록 설정
- 24.05 무료 S/W의 팝업(Toast) 광고 프로그램을 악용한 TA- RedAnt의 대규모 공격이 탐지 [1] - IE의 자바스크립트 엔진(jscript9.dll)에 존재하는 제로데이 취약점 악용 - 22년 악용한 IE의 Type Confusion 취약점(CVE-2022-41128)에 간단한 코드를 추가하여 보안 패치를 우회
1.1 Chakra
- MS에서 제작한 웹 브라우저의 자바스크립트 엔진 > 웹 브라우저는 HTML, CSS, JavaScript 등의 언어로 작성코드를 사람이 읽을 수 있는 문서로 출력하는 프로그램 > 웹 브라우저에서 자바스크립트 코드를 해석하고 실행하는 역할을 수행
구분
이름
IE 11.0 이하 버전
legacy Chakra engine(jscript9.dll)
Edge Legacy 브라우저
new Chakra engine or Edge engine(Chakra.dll)
1.1.1 동작 과정
- 웹 브라우저에서는 JavaScript의 동작을 위해 자체 엔진을 포함하고 있으며, 빠른 실행을 위해 JIT(Just-In-Time) Compilation 방식을 사용 - MS Chakra에서 JavaScript로 작성된 코드가 실행되는 과정
구분
설명
Parsing
소스코드를 파싱하여 Abstract Syntax Tree(AST)를 생성 ※ Abstract Syntax Tree(AST) : 소스코드의 구조를 트리 형태로 나타낸 자료구조
Interpreting
- AST는 바이트코드(Bytecode)로 변환되어 인터프리터에 의해 실행 - 실행 중인 함수의 데이터 유형 및 호출 횟수와 같은 정보를 분석해 함수의 프로파일을 생성
Compilation
- 생성된 프로파일을 바탕으로 최적화된 기계코드인 JIT’ed code 생성 ※ 인터프리터에서 여러 번 호출되는 코드가 탐지되면 바이트코드를 실행하는 대신 JIT’ed code를 실행해 프로그램 동작 속도를 향상 시킴
- JavaScript엔진에서는 여러 번 호출되는 코드를 따로 관리
구분
설명
Hot
- 자주 반복되는 코드 - 코드가 Hot으로 탐지되면 엔진은 해당 코드를 스텁코드(Stub Code)로 변환 - 이후 바이트코드를 실행하지 않고 미리 생성한 스텁코드를 사용하여 실행 속도를 향상
Warm
덜 자주 반복되는 코드
1.2 Toast 광고
- 다양한 무료 S/W와 함께 설치되어 동작 > 실행 시 광고서버로부터 광고 컨텐츠를 다운받아 PC 화면 우측 하단에 광고창 표시 > 서버는 광고 컨텐츠가 포함된 HTML과 JavaScript로 응답 > Toast 광고 프로그램은 응답값을 IE 브라우저 또는 IE 관련 모듈로 랜더링하여 팝업 광고창을 띄움
2. 주요내용
2.1 CVE-2024-38178
[사진 1] CVE-2024-38178 [2]
- Windows Scripting Engine에서 발생하는 Type Confusion 취약점으로 메모리 손상을 유발해 원격 명령 실행을 가능하게 함 > jscript9.dll에서 발생하는 Type Confusion 취약점
※ Type Confusion 취약점 : 프로그램에서 사용하는 변수나 객체를 선언 혹은 초기화되었을 때와 다른 타입으로 사용할 때 발생하는 취약점
스텁코드는 Type Confusion 문제가 발생할 수 있음 - 매개변수로 정수형 변수를 입력받는 함수가 있으며, 메인에서 100번 호출된다고 가정 > 엔진에서는 Hot으로 간주하여 정수형 변수를 전달받는 스텁코드로 변환 > 그 결과, 해당 변수의 데이터 유형을 정수로 예측 > 이 때, 매개변수를 정수가 아닌 다른 데이터 유형으로 전달할 경우 Type Confusion 발생
2.2 상세분석
[사진 2] iframe이 삽입된 HTML
- 해커는 국내 광고 대행사 중 한 업체의 광고 서버를 해킹 > Toast 광고 프로그램에 전달되는 HTML 코드에 iframe을 삽입하여 경유지를 통해 JavaScript가 로드 되도록 변조 > 해당 JavaScript 파일명은 ad_toast이며 IE(JScript9.dll)의 RCE 취약점이 발현되는 코드가 삽입 > 피해자 PC에 설치된 Toast 광고 프로그램은 취약점 코드를 받아 랜더링하는 과정에서 Exploit 및 해커의 쉘 코드로 실행 흐름이 바뀜
[사진 3] CVE-2024-38178 Exploit
- 해커는 과거 악용했던 CVE-2022-41128(Windows 스크립트 언어 RCE [4]) Exploit 코드에 단 3줄을 추가해 기존 패치 우회
> ex_func(false, false)를 반복 호출하여 JIT 컴파일러의 최적화 오류를 유도한 뒤 인자를 true로 바꿔 호출
- "q=g" 연산으로 Type Confusion 발생
> 정수 배열로 초기화된 변수 q에 변수 g가 가리키는 데이터를 참조하면 변수 q의 Type이 Object로 변경 > 하지만, JIT 컴파일러의 최적화 오류로 인해 Type을 계속해서 정수 배열로 판단
- 이후 q[4], q[11], q[12]의 값을 0x1FFFFFFF로 변경
> 변경하는 이유는 해당 값이 배열 av의 Type(Js::JavascriptNativeIntArray)과 관련 > 변경한 값은 순서대로 배열 av의 Array Length, Array Actual Length, Buffer Length 항목 > 배열의 길이를 조작하면 Object Dataview를 사용하여 임의의 메모리 영역에 대한 읽기 및 쓰기가 가능하게 되어 임의 코드를 실행할 수 있음
※ JIT 컴파일러의 배열 최적화 과정에서 초기화된 변수로 착각하게 만드는 방법을 이용해 CVE-2022-41128의 패치를 우회
[사진 4] 패치
- 해당 취약점은 MS 8월 보안업데이트에서 패치 [4]
> wil::details::FeatureImpl<_ _WilFeatureTraits_Feature_1489045819>::_ _private_ IsEnabled(&`wil::Feature<_ _WilFeatureTraits_Feature_1489045819>::GetImpl’::`2 ’::impl); 함수가 추가 > 해당 함수의 결과 값에 따라 변수 초기화 여부를 검증하는 분기로 진입 > 진입 후 ValueType 클래스에서 정의된 연산자를 통해 두 개의 정수형 값 비교 과정 추가 > 두 Type을 비교해 값이 다를 경우 SetValueType 함수를 호출하여 Type을 일치시키는 추가적인 과정이 수행
2.3 악성코드 유포
- 과거부터 꾸준히 사용해온 RokRAT 악성코드를 유포하며 공격 흐름은 아래와 같음 > Ruby를 사용하여 악성 행위 지속성 확보 및 상용 클라우드 서버를 통해 명령제어를 수행
실행 단계
설명
1차 악성코드(43) 다운로드 및 explorer.exe에 인젝션
- 실행 PC의 파일·프로세스를 확인하여 분석 환경인지 탐지 > 악성코드 43은 첫 1바이트로 XOR 후 실행되는 쉘코드 > 분석 환경이 아니라고 판단되면 경유지에 접속해 2차 악성코드 다운 및 실행
2차 악성코드(23) 다운로드 및 실행
- 컴퓨터 이름 등 시스템 정보를 수집하고 추가 감염 여부 선별 > 악성코드 23은 첫 1바이트로 XOR 후 In-Memory로 실행되는 PE 형태 > 시스템 정보를 경유지로 전송하고, 응답에 따라 3차 악성코드 다운 및 실행
3차 악성코드(move) 다운로드 및 실행 후 추가 파일 다운로드
- 악성 스크립트를 삽입한 ruby standalone 드롭 및 악성 행위 지속성 확보 > 악성코드 move는 첫 1바이트로 XOR 후 In-Memory로 실행되는 PE 형태 > 2차 경유지는 원드라이브 1개와 국내 정상 사이트 2개가 악성코드 내부에 하드코딩 > 지속성 확보를 위해 자동실행 되도록 설정 (주기적 실행 또는 PC 부팅 시 실행)
system32 폴더 내 exe 무작위 선택 후 실행 및 인젝션
- PC에 설치된 백신(AVAST·SYMANTEC)을 확인하여 다르게 동작 > 현재 실행중인 프로세스 명에 "UBY"가 있는지 확인 후 설치된 백신에 따라 동작 결정 > AVAST·SYMANTEC : 현재 프로세스에서 In-Memory 방식으로 실행 > 그 외 백신 : system32 폴더에 있는 랜덤 EXE에 인젝션하여 실행
system32 폴더 내 exe 무작위 선택 후 실행 및 인젝션
- PC에 설치된 백신(AVAST·SYMANTEC)을 확인하여 다르게 동작 > 프로세스의 자체 종료를 막기 위해 ExitProcess 함수를 후킹 및 함수 인자 및 설치된 백신에 따라 동작 결정 > 인자가 0xAC가 아닐 경우 대기 상태, 0xAC일 경우 후킹을 복원 > AVAST·SYMANTEC : rubyw. exe를 재실행 > 그 외 백신 : system32 폴더에 있는 랜덤 EXE에 인젝션하여 실행
In-Memory로 RokRAT 실행
- 상용 클라우드(얀덱스 등)를 경유지로 명령제어를 수행하여 PC 정보 절취 > 윈도우 프로시저에서 수신되는 메시지를 기반으로 해당 핸들러에서 악성 행위를 수행
구분
MD5
ad_toast
e11bb2478930d0b5f6c473464f2a2B6e
43
b9d4702c1b72659f486259520f48b483
23
b18a8ea838b6760f4857843cafe5717d
MOVE
da2a5353400bd5f47178cd7dae7879c5
ban04.bak(top_08.bak,content)
bd2d599ab51f9068d8c8eccadaca103d
operating_system.rb
감염 PC마다 다름
1차 로더
2차 로더
RokRAT
2.4 결론
- MS는 22.06 IE 지원 종료 발표 및 최신 Window OS는 IE가 웹 브라우저로 사용되는 것을 제한하는 등의 조치 > 과거에 비해 워터링홀 공격의 가능성은 희박해짐 > 그러나, 일부 Window 어플리케이션들은 IE를 내장하거나 관련 모듈을 사용해 공격 벡터로 악용될 수 있음 > OS 및 SW 등의 보안 업데이트를 준수하고, 제조사들은 제품 개발 시 보안에 취약한 개발 라이브러리 및 모듈 등이 사용되지 않도록 주의 필요