DEF CON Safe Mode - Zhipeng Huo - Evil Printer How To Hack Windows Machines With Printing Protocol
DEF CON Safe Mode - Zhipeng Huo - Evil Printer How To Hack Windows Machines With Printing Protocol
https://twitter.com/R3dF09/status/1271485928989528064
How does Network Printing Works
Client
Server
Printer
Done!
Rendering in Network Printing
Application Data
Client
Client Printer Driver
Send Application Data
Printer Data
Application Data
Send Printer Data
Server Printer Driver
• Rendering component
• Convert application data into printer specified data
• Configuration component
• Enable user to configure printer
“In order to support both client-side
and server-side rendering, It is a
requirement that printer drivers are
available to print server and print
client.”
Supporting Client-Side Rendering and Server-Side Rendering
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-
prsod/e47fedcc-d422-42a6-89fc-f04eb0c168e3
How is Printer Drivers Distributed?
Point-And-Print
Package Point-And-Print
PowerShell
• AddPrinterConnection
• AddPrinterConnection2
GUI
• printui /im
All Roads to
winspool!AddPrinterConnection2
BOOL AddPrinterConnection2(
_In_ HWND hWnd,
_In_ LPCTSTR pszName,
DWORD dwLevel,
_In_ PVOID pConnectionInfo
);
pszName [in]
A pointer to a null-terminated string that specifies the name of a
printer to which the current user wishes to establish a connection.
Warning Dialog after AddPrinterConnection2
Purpose of Warning Dialog
• What If the Printer Driver is Malicious?
• CVE-2016-3238
• Windows Print Spooler Remote Code Execution
• A remote code execution vulnerability exists when the Windows Print Spooler
service does not properly validate print drivers while installing a printer from
servers.
• “The update addresses the vulnerability by issuing a warning to users
who attempt to install untrusted printer drivers”
AddPrinterConnection2 Internals
Print Client Print server
Print
Applications
Spooler
1. RPC call 2. RPC call
winspool!Ad spoolsv!Rpc
Print
dPrinterCon AddPrinterC
Spooler
nection2 onnection2
4. return 3. return
AddPrinterConnection2 Internals
• ERROR_PRINTER_DRIVER_DOWNLOAD_NEEDED
• 0x00000BB9
• winspool!DownloadAndInstallLegacyDriver
• ntprint!PSetupDownloadAndInstallLegacyDriver
• ntprint!DisplayWarningForDownloadDriver
• ntprint!DownloadAndInstallLegacyDriver
Point-and-Print or Package Point-And-Print?
Capture the Driver Download
Capture the Driver Install
It’s Point-And-Print!
How to enable Package Point-And-Print mechanism?
spoolsv!RpcAddPrinterConnection2
spoolsv!RpcAddPrinterConnection2
win32spl!TPrintOpen::CreateLocalPrinter
win32spl!TPrintOpen::AcquireV3DriverAndAddPrinter
win32spl!TDriverInstall::DeterminateInstallType
win32spl!TDriverInstall::CheckPackagePointAndPrint
win32spl!TDriverInstall::Check
PackagePointAndPrint
if (v5 >= 0) {
v14 = *v1;
if (*(_BYTE *)(v14 + 0xA8) & 1) {
v5 = TDriverInstall::DownloadAndImportDriverPackages(v2,
(struct _DRIVER_INFO_8W *)v14);
}
}
Get Object
InfPath:
C:\Windows\System32\DriverStore\FileRepository\prnms003.inf_amd64_85c8869cca48951c\prnms003.inf
PackagePath:
C:\Windows\System32\spool\drivers\x64\PCC\prnms003.inf_amd64_85c8869cca48951c.cab
DownloadAndImportDriverPackages
• TDriverInstall::DownloadAndImportDriverPackages
• TDriverInstall::DownloadAndExtractDriverPackageCab
• TDriverInstall::InternalCopyFile
• NCabbingLibrary::LegacyCabUnpack
Cabinet File
• Archive-file format for Microsoft Windows
• A file that has the suffix .cab and that acts as a container for other
files
• It serves as a compressed archive for a group of files
File Decompression Interface APIs
• Cabinet!FDICreate
• Creates an FDI context
• Cabinet!FDICopy
• Extracts files from cabinet
• Cabinet!FDIDestroy
• Deletes an open FDI context
FDICopy
BOOL DIAMONDAPI FDICopy(
HFDI hfdi,
LPSTR pszCabinet,
LPSTR pszCabPath,
int flags,
PFNFDINOTIFY pfnfdin,
PFNFDIDECRYPT pfnfdid,
void *pvUser
);
pfnfdin
Pointer to an application-defined callback notification function
to update the application on the status of the decoder. The
function should be declared using the FNFDINOTIFY macro.
win32spl!NCabbingLibrary::LegacyCabUnpack
FDICopy(v12,
pszCabinet,
pszCabPath,
0,
(PFNFDINOTIFY)NCabbingLibrary::FdiCabNotify,
0i64,
&pvUser);
NCabbingLibrary::FdiCabNotify
• fdintCOPY_FILE Information identifying the file to be copied
if ( v15 >= 0 ) {
v17 = *(_QWORD *)v3;
v21 = -1i64;
v15 = NCabbingLibrary::ProcessCopyFile(
(NCabbingLibrary *)Block,
*(const unsigned __int16 **)(v17 + 8),
(const unsigned __int16 *)&v21,
v16);
operator delete(Block);
v4 = v21;
}
NCabbingLibrary::ProcessCopyFile
• NCabbingLibrary::CreateFullPath
• Check ‘..\’ v12 = wcschr(v10, '\\'); // check for ..\
v13 = v12;
• But forget ‘../’ ? if ( !v12 )
break;
*v12 = 0;
• _wopen v14 = *v11 - asc_1800B3FF0[0];
if ( !v14 )
{
• _O_BINARY|_O_CREAT|_O_TRUNC|_O_RDWR v14 = v11[1] - '.';
if ( v11[1] == '.' )
v14 = v11[2];
}
v8 = NCabbingLibrary::CreateFullPath((NCabbingLibrary * if ( v14 )
)FileName, (const unsigned __int16 *)v9); {
if ( v8 >= 0 ) if ( !CreateDirectoryW(v8, 0i64) && GetLastE
rror() != 183 )
{
v7 = (NCoreLibrary::TString *)_wopen(v10, 0x8302, 0
x180i64);
*(_QWORD *)a3 = v7;
Make Malformed Cab
• makecab 112112DiagSvcs2USERENV.dll test.cab
HexEdit Cab file
Malformed Cabinet
Prepare Print Server
• Install Virtual Printer
• CutePDF Writer
• Share the printer
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Environments\Windows
x64\Drivers\Version-3\CutePDF Writer v4.0
•PrinterDriverAttributes = 1
•InfPath = "c:\test\test.inf"
CoCreateInstance(CLSID_PrintTicket,
nullptr,
CLSCTX_LOCAL_SERVER,
IID_PPV_ARGS(&print_ticket));
print_ticket->Bind(L"\\\\[PrintServer]\\[PrinterName]", 1);
Sandbox Escape
CPrintTicketServerBase::Bind GetPrinterDriver
CreateFile CreateFile
Windows OS
Sandbox Escape Demo
Patch
if ( !wcsstr(Str, L"../") && !wcsstr(Str, L"..\\") )
{
v14 = *(_QWORD *)v3;
v22 = -1i64;
v15 = NCabbingLibrary::ProcessCopyFile(
(NCabbingLibrary *)Str,
*(const unsigned __int16 **)(v14 + 8),
(const unsigned __int16 *)&v22,
v13);
operator delete(Str);
v4 = v22;
v3[2] = v15;
return v4;
}
win32spl!NCabbingLibrary::FdiCabNotify
Possible Attack Scenarios
• Lateral movement
• Modify a trusted printer
• Remote code execution
• Connect to attacker-controlled printer
• Privilege escalation
• Make a printer connection attempt
• NT AUTHORITY\SYSTEM for all scenarios
CVE-2020-1300
Don’t Be Panic
do {
if ( v10 >= v6 )
break;
v11 = v7[v10] - 47; // "/"
if ( v11 <= 45u ) // "\"
{
v12 = v11;
v13 = 0x200000000801i64;
if ( _bittest64(&v13, v12) )
v21 = v9 + 1;
}
v10 = ++v9;
} while ( v7[v9] );
cabview!CCabItemList::AddItem
Conclusion