개요
Varonis Threat Labs가 공개한 GhostTree는 Windows NTFS의 Junction 기능을 악용해 무한에 가까운 파일 경로 구조를 만들고, 일부 EDR이나 백신 제품의 폴더 스캔을 지연시키거나 멈추게 만드는 경로 조작 기법이다. Varonis는 이 기법이 NTFS Junction을 이용해 무한 파일 경로를 생성하고, 그 결과 EDR 제품이 hang 상태에 빠져 일부 파일을 검사하지 못할 수 있다고 설명했다.
이 기법의 핵심은 단순하다. Windows에서 특정 폴더가 다른 폴더를 가리키도록 만들 수 있는데, 이 가리키는 대상이 자기 자신 또는 부모 폴더라면 파일 시스템 구조가 반복된다. 보안 제품이 이 구조를 재귀적으로 따라가며 검사하면, 같은 위치를 서로 다른 경로로 계속 탐색하게 된다.
NTFS Junction이란?
NTFS Junction은 Windows 파일 시스템에서 디렉터리를 다른 디렉터리로 연결하는 기능이다. 겉으로 보기에는 일반 폴더처럼 보이지만, 실제로는 다른 경로를 가리킨다. Microsoft의 mklink 문서에서도 /J 옵션은 Directory Junction을 생성하는 기능이라고 설명한다.
예를 들어 개념적으로 다음과 같은 구조를 생각할 수 있다.
C:\Parent
├─ program.exe
└─ Child → C:\Parent를 다시 가리킴
이 경우 Child 폴더는 실제 독립적인 폴더가 아니라 C:\Parent를 다시 참조한다. 따라서 같은 파일을 아래처럼 여러 경로로 접근할 수 있다.
C:\Parent\program.exe
C:\Parent\Child\program.exe
C:\Parent\Child\Child\program.exe
C:\Parent\Child\Child\Child\program.exe
실제 파일은 하나지만, 경로는 계속 깊어지는 것처럼 보인다. 이 특성이 GhostTree의 핵심이다.
GhostBranch와 GhostTree
Varonis는 이 기법을 설명하면서 GhostBranch와 GhostTree를 구분한다.
GhostBranch는 하나의 하위 Junction이 부모 폴더를 다시 가리키는 단순한 구조다. 이 경우 경로는 한 줄로 계속 깊어진다. 예를 들어 Parent → Child → Parent → Child와 같은 형태로 반복되는 구조가 만들어진다. Varonis는 이 방식으로 동일한 실행 파일에 대해 계속 길어지는 유효 경로를 만들 수 있다고 설명한다.
GhostTree는 여기서 한 단계 더 나아간다. 하위 Junction을 하나만 만드는 것이 아니라 여러 개 만든다. 예를 들어 Child1, Child2가 모두 부모 폴더를 다시 가리키게 만들면, 경로는 단순한 한 줄이 아니라 트리처럼 분기된다.
C:\Parent
├─ Child1 → C:\Parent
└─ Child2 → C:\Parent
이렇게 되면 가능한 경로는 다음처럼 늘어난다.
C:\Parent\Child1\program.exe
C:\Parent\Child2\program.exe
C:\Parent\Child1\Child1\program.exe
C:\Parent\Child1\Child2\program.exe
C:\Parent\Child2\Child1\program.exe
C:\Parent\Child2\Child2\program.exe
하위 폴더가 두 개만 있어도 각 단계마다 선택지가 두 개씩 생긴다. 그래서 경로 수가 선형적으로 증가하는 것이 아니라 지수적으로 증가한다. Varonis는 전통적인 Windows 경로 길이 제한을 기준으로 약 126단계까지 갈 수 있고, 두 갈래 구조에서는 이론적으로 2^126 수준의 경로 조합이 만들어질 수 있다고 설명한다.
Windows 경로 제한과 GhostTree의 관계
Windows API에는 전통적으로 MAX_PATH라는 경로 길이 제한이 있으며, 이 값은 260자로 정의되어 있다. 다만 Unicode API와 확장 경로 형식을 사용하면 약 32,767자까지 긴 경로를 사용할 수 있다. Microsoft 문서도 일반적인 Windows API 경로 제한은 260자이고, 확장 길이 경로는 약 32,767자까지 가능하다고 설명한다.
GhostTree는 이 경로 길이 제한을 이용한다. 실제 디렉터리와 파일은 많지 않아도, Junction이 반복적으로 같은 부모 폴더를 가리키면 논리적으로는 매우 많은 경로가 만들어진다. 보안 제품이나 파일 탐색 도구가 이 구조를 제대로 처리하지 못하면, 계속 하위 경로를 따라가다가 스캔이 끝나지 않는 상황이 발생할 수 있다.
왜 보안상 문제가 되는가?
보안 제품은 일반적으로 파일 시스템을 재귀적으로 탐색한다. 특정 폴더를 검사하고, 그 안의 하위 폴더를 검사하고, 다시 그 하위 폴더를 검사하는 방식이다.
문제는 Junction이 부모 폴더를 다시 가리키는 경우다. 이때 스캐너가 Junction을 일반 폴더처럼 따라가면, 같은 폴더를 다른 경로로 계속 탐색하게 된다. 결과적으로 스캔이 오래 걸리거나 멈출 수 있고, 같은 폴더에 있는 악성 파일이 검사되지 않을 가능성이 생긴다.
Varonis는 GhostTree 구조가 dir 명령의 재귀 탐색뿐 아니라, 폴더를 재귀적으로 스캔하는 EDR 제품에도 영향을 줄 수 있다고 설명했다. 또한 Windows Defender를 대상으로 테스트했을 때 폴더 스캔 우회에 사용할 수 있음을 확인했으며, Microsoft에 보고했지만 처음에는 “Defender 우회가 보안 경계를 넘는 것은 아니다”라는 이유로 닫혔고, 이후 패치가 이루어졌다고 밝혔다.
즉 GhostTree는 권한 상승이나 원격 코드 실행처럼 시스템을 직접 장악하는 취약점이라기보다는, 보안 제품의 검사 흐름을 방해하는 탐지 회피 기법에 가깝다.
공격 시나리오를 단순화하면
GhostTree의 공격 흐름은 다음처럼 요약할 수 있다.
1. 공격자가 쓰기 가능한 폴더를 찾는다.
2. 해당 폴더 안에 파일을 배치한다.
3. 하위 폴더가 부모 폴더를 다시 가리키는 Junction 구조를 만든다.
4. 보안 제품이 해당 폴더를 재귀적으로 스캔한다.
5. 스캐너가 반복 경로를 계속 따라가며 hang 또는 timeout 상태에 빠진다.
6. 결과적으로 일부 파일이 검사되지 않거나 탐지가 지연될 수 있다.
중요한 점은 Junction 생성 자체가 Windows의 정상 기능이라는 것이다. Microsoft 문서 기준으로도 mklink는 심볼릭 링크, 하드 링크, 디렉터리 Junction을 생성하는 정상 명령이다.
따라서 방어자는 단순히 “Junction이 존재한다”는 이유만으로 악성이라고 판단해서는 안 된다. 정상적인 소프트웨어도 호환성, 경로 재배치, 저장소 관리 목적으로 Junction을 사용할 수 있기 때문이다. 문제는 Junction이 자기 자신 또는 부모 디렉터리를 반복적으로 참조하는 비정상 구조다.
방어 관점에서 봐야 할 지점
GhostTree를 방어하려면 단순 파일 탐지보다 파일 시스템 구조 자체를 봐야 한다. 특히 아래와 같은 행위는 의심 포인트가 될 수 있다.
- 일반 사용자 권한으로 생성된 비정상적인 Junction
- 부모 디렉터리 또는 상위 경로를 다시 가리키는 Junction
- 동일한 디렉터리 구조가 반복되는 경로
- 짧은 시간 안에 여러 개의 reparse point가 생성되는 행위
- EDR 또는 백신 스캔 프로세스의 hang, timeout, CPU 사용률 급증
- 사용자 프로필, Downloads, Temp, AppData, ProgramData 하위의 반복 Junction 구조
특히 공격자가 쓰기 권한을 가진 위치는 더 주의해야 한다.
C:\Users\<사용자>\Downloads
C:\Users\<사용자>\AppData
C:\Users\<사용자>\Temp
C:\ProgramData
공유 폴더
서비스 작업 디렉터리
정상 환경에서 이런 위치에 자기 부모를 다시 가리키는 Junction 구조가 반복적으로 만들어질 이유는 많지 않다.
보안팀이 해야 할 일
첫째, EDR이나 백신이 Junction과 reparse point를 어떻게 처리하는지 확인해야 한다. 단순히 재귀 탐색을 수행하는 방식이라면 반복 경로에 취약할 수 있다.
둘째, 파일 스캔 타임아웃이나 hang 이벤트를 단순 장애로 넘기지 말아야 한다. 특정 폴더에서 스캔이 반복적으로 멈춘다면 악의적인 경로 조작이 있는지 확인해야 한다.
셋째, Junction 생성 이벤트를 모니터링해야 한다. 특히 일반 사용자가 평소 만들지 않던 위치에 Junction을 생성하거나, 부모 디렉터리를 다시 참조하는 구조가 발견되면 조사 대상이 된다.
넷째, 파일 경로 문자열만 보지 말고 실제 파일 객체, reparse point, 최종 대상 경로를 함께 분석해야 한다. GhostTree의 핵심은 실제 파일 수가 아니라 “같은 파일에 도달하는 경로의 폭발적 증가”이기 때문이다.
결론
GhostTree는 Windows NTFS Junction이라는 정상 기능을 악용한 경로 조작 기법이다. 공격자는 폴더가 자기 자신 또는 부모 폴더를 반복적으로 가리키게 만들어 매우 많은 유효 경로를 만들 수 있다. 그 결과 일부 보안 제품은 해당 폴더를 끝까지 스캔하지 못하거나, 스캔이 지연되거나, 파일 검사가 누락될 수 있다.
이 기법은 시스템 권한을 직접 상승시키는 취약점은 아니지만, 방어자 입장에서는 충분히 의미 있는 탐지 회피 기법이다. 특히 EDR이나 백신이 “폴더를 재귀적으로 훑으면 된다”는 전제에 의존하고 있다면 GhostTree 같은 구조에서 문제가 발생할 수 있다.
핵심은 명확하다.
https://www.varonis.com/blog/ghosttree-ntfs-trick
GhostTree: Unveiling Path Manipulation Techniques to Bypass Windows Security
Varonis Threat Labs discovered a new technique that abuses NTFS junctions to generate infinite file paths, causing EDR products to hang and leave files unscanned.
www.varonis.com