MS Windows IPP Buffer Overflow

October 17, 2008

The Internet Printing Protocol (IPP) is a standard network protocol for managing remote printing. IPP is built on HTTP/1.1 and supports access control, encryption and authentication. The Microsoft IPP implementation consists of an ISAPI extension for Internet Information Service (IIS). Client hosts send IPP requests to the MS IPP service by accessing the "/printers" HTTP directory through IIS. The server replies to these request with an HTML page containing the list of all currently configured printers on the server. The IPP service can be used to query a specific printer on the remote host as well. The following HTTP request is shown as an example:

POST /printers/~5c~5c10~2e0~2e0~2e10~5cdummy/.printer HTTP/1.1
Content-Type: application/ipp

In the above example, the printer is instructed to send an IPP query to a remote SMB printer \ Upon receiving such a request, the IPP service will translate it into SPOOLSS RPC request and redirect it to the given printer. Windows defines a Remote Procedure Call (RPC) interface for the server-side spooler Win32 API. This RPC interface can be accessed via the named pipe "spoolss" with UUID "12345678-1234-abcd-ef00-0123456789ab".

To service the IPP request, the server will establish an SMB connection to the requested printer and send the IPP request translated into RPC function. The RPC reply is then translated into HTTP/IPP reply and sent back to the original requester in the same HTTP session.

One of IPP requests is the Get-Jobs request with operation-id 0x000a. This request translates into the EnumJobs RPC function, its purpose is to enumerate the list of print jobs currently managed by the chosen printer. The function's prototype is shown below:

BOOL EnumJobs(
  HANDLE hPrinter, // handle to printer object
  DWORD FirstJob, // index of first job
  DWORD NoJobs, // number of jobs to enumerate
  DWORD Level, // information level
  LPBYTE pJob, // job information buffer
  DWORD cbBuf, // size of job information buffer
  LPDWORD pcbNeeded, // bytes received or required
  LPDWORD pcReturned // number of jobs received

Normally, the function is called twice. First, the caller specifies an empty buffer cbBuf=0 and the spooler replies with pcbNeeded set to the size of the buffer required to store the request. The caller will then repeat the request setting cbBuf to the required size.

A buffer overrun vulnerability exits within the IPP implementation on Windows servers running IIS. The flaw may be exploited by remote authenticated attackers by sending a crafted Get-Jobs IPP request to the target server. Specifically, the attacker will send the Get-Jobs IPP with the IP address and printer name of an attacker-controlled print server. The attacker's print server will reply to the SMB/RPC requests from the target, waiting for the EnumJobs RPC function call. The reply from the attacker to the EnumJobs call will provide incorrect cbBuf and pcbNeeded values such that when these values are added by the vulnerable IPP server, the sum will overflow a 32-bit integer. The IPP server will allocate memory based on this sum which will be smaller than the size of the pJob string, and this buffer will be overwritten by the received pJob.

Successful exploitation of this vulnerability may allow for arbitrary code injection and execution with the privileges of the ISS server process. Code injection that does not result in execution could terminate the affected process due to memory corruption.

SonicWALL has released an IPS signature that will detect and prevent known exploits of this flaw. The following signature addresses this vulnerability:

  • 5274 - MS Windows Internet Printing Service Integer Overflow PoC (MS08-062)

This vulnerability has been assigned CVE-2008-1446 and has been described in the Microsoft security bulletin MS08-062