Abusing Mount Points over the SMB Protocol

Original text by Tyranid’s Lair

This blog post is a quick writeup on an interesting feature of SMBv2 which might have uses for lateral movement and red-teamers. When I last spent significant time looking at symbolic link attacks on Windows I took a close look at the SMB server. Since version 2 the SMB protocol has support for symbolic links, specifically the NTFS Reparse Point format. If the SMB server encounters an NTFS symbolic link within a share it’ll extract the REPARSE_DATA_BUFFER and return it to the client based on the SMBv2 protocol specification§2.2.2.2.1.

Screenshot of symbolic link error response from SMB specifications.

The client OS is responsible for parsing the REPARSE_DATA_BUFFER and following it locally. This means that only files the client can already access can be referenced by symbolic links. In fact even resolving symbolic links locally isn’t enabled by default, although I did find a bypass which allowed a malicious server to bypass the client policy and allowing resolving symbolic links locally. Microsoft declined to fix the bypass at the time, it’s issue 138 if you’re interested.

What I found interesting is while IO_REPARSE_TAG_SYMLINK is handled specially on the client, if the server encounters the IO_REPARSE_TAG_MOUNT_POINT reparse point it would follow it on the server. Therefore, if you could introduce a mount point within a share you could access any fixed disk on the server, even if it’s not shared directly. That could have many uses for lateral movement, but the question becomes how could we add a mount point without already having local access to the disk?

First thing to try is to just create a mount point via a UNC path and see what happens. Using the MKLINKCMD built-in you get the following:

Using mklink on \\localhost\c$\abc returns the error "Local NTFS volumes are required to complete the operation."

The error would indicate that setting mount points on remote servers isn’t supported. This would make some sense, setting a mount point on a remote drive would result in unexpected consequences. You’d assume the protocol either doesn’t support setting reparse points at all, or at least restricts them to only allowing symbolic links. We can get a rough idea what the protocol expects by looking up the details in the protocol specification. Setting a reparse point requires sending the FSCTL_SET_REPARSE_POINT IO control code to a file, therefore we can look up the section on the SMB2 IOCTL command to see if any there’s any information about the control code.

After a bit of digging you’ll find that FSCTL_SET_REPARSE_POINT is indeed supported and there’s a note in §3.3.5.15.13 which I’ve reproduced below.

«When the server receives a request that contains an SMB2 header with a Command value equal to SMB2 IOCTL and a CtlCode of FSCTL_SET_REPARSE_POINT, message handling proceeds as follows:If the ReparseTag field in FSCTL_SET_REPARSE_POINT, as specified in [MS-FSCC] section 2.3.65, is not IO_REPARSE_TAG_SYMLINK, the server SHOULD verify that the caller has the required permissions to execute this FSCTL.<330> If the caller does not have the required permissions, the server MUST fail the call with an error code of STATUS_ACCESS_DENIED.»The text in the specification seems to imply the server only needs to check explicitly for IO_REPARSE_TAG_SYMLINK, and if the tag is something different it should do some sort of check to see if it’s allowed, but it doesn’t say anything about setting a different tag to be explicitly banned. Perhaps it’s just the MKLINK built-in which doesn’t handle this scenario? Let’s try the CreateMountPoint tool from my symboliclink-testing-tools project and see if that helps.

Using CreateMountPoint on \\localhost\c$\abc gives access denied.

CreateMountPoint doesn’t show an error about only supporting local NTFS volumes, but it does return an access denied error. This ties in with the description §3.3.5.15.13, if the implied check fails the code should return access denied. Of course the protocol specification doesn’t actually say what check should be performed, I guess it’s time to break out the disassembler and look at the implementation in the SMBv2 driver, srv2.sys.

I used IDA to look for immediate values for IO_REPARSE_TAG_SYMLINK which is 0xA000000C. It seems likely that any check would first look for that value along with any other checking for the other tags. In the driver from Windows 10 1809 there was only one hit in Smb2ValidateIoctl. The code is roughly as follows:

NTSTATUS Smb2ValidateIoctl(SmbIoctlRequest* request){ // … switch(request>IoControlCode){case FSCTL_SET_REPARSE_POINT: REPARSE_DATA_BUFFER* reparse =(REPARSE_DATA_BUFFER*)request>Buffer;
// Validate length etc. if(reparse>ReparseTag != IO_REPARSE_TAG_SYMLINK &&
!request>SomeOffset->SomeByteValue){
return STATUS_ACCESS_DENIED;} // Complete FSCTL_SET_REPARSE_POINT request. }}

The code extracts the data from the IOCTL request, it fails with STATUS_ACCESS_DENIED if the tag is not IO_REPARSE_TAG_SYMLINK and some byte value is 0 which is referenced from the request data. Tracking down who sets this value can be tricky sometimes, however I usually have good results by just searching for the variables offset as an immediate value in IDA, in this case 0x200 and just go through the results looking for likely MOV instructions. I found an instruction «MOV [RCX+0x200], AL» inside Smb2ExecuteSessionSetupReal which looked to be the one. The variable is being set with the result of the call to Smb2IsAdmin which just checks if the caller has the BUILTIN\Administrators group in their token. It seems that we can set arbitrary reparse points on a remote share, as long as we’re an administrator on the machine. We should still test that’s really the case:

Using CreateMountPoint on \\localhost\c$\abc is successful and listing the directory showing the windows folder.

Testing from an administrator account allows us to create the mount point, and when listing the directory from a UNC path the Windows folder is shown. While I’ve demonstrated this on local admin shares this will work on any share and the mount point is followed on the remote server.

Is this trick useful? Requiring administrator access does mean it’s not something you could abuse for local privilege escalation and if you have administrator access remotely there’s almost certainly nastier things you could do. Still it could be useful if the target machine has the admin shares disabled, or there’s monitoring in place which would detect the use of ADMIN$ or C$ in lateral movement as if there’s any other writable share you could add a new directory which would give full control over any other fixed drive.

I can’t find anyone documenting this before, but I could have missed it as the search results are heavily biased towards SAMBA configurations when you search for SMB and mount points (for obvious reasons). This trick is another example of ensuring you test any assumptions about the security behavior of a system as it’s probably not documented what the actual behavior is. Even though a tool such as MKLINK claims a lack of a support for setting remote mount points by digging into available specification and looking at the code itself you can find some interesting stuff.

Реклама

A look under the hood of a decentralised VPN Application.

( original text byDonatas Kučinskas )

MysteriumVPN is the client application of Mysterium Network, a project focused on providing security and privacy to web 3 applications.

In this article, we will discuss the architecture of MysteriumVPN and how it integrates with Mysterium Node to ensure an encrypted end to end flow of data through Mysterium Network.

Cross-platform architecture

Usually, you need separate builds for each platform. Now that cross-platform technology has improved, this is no longer the case.

For desktop:

Electron is a framework which allows us to build cross-platform applications using common web technologies such as HTMLCSS and Javascript. We are using Electron which allows us to develop one application for two platforms for desktop — Windows and Mac OSLinux coming soon. Download our alpha.

Under the hood of an Electron application, sits a Chromium browser; A website, rendered by an embedded browser.

For mobile:

We are kicking off our mobile development for MysteriumVPN, with Android versions set to release shortly.

For this, we are using React Native for cross-platform applications.

Most of MysteriumVPN is written in Javascript, which is run in a separate process. Javascript generates the virtual structure of the user interface. This Javascript process communicates to native mobile processes which are responsible for rendering the actual user interface as you see it.

The architecture of MysteriumVPN Desktop Client Application

How MysteriumVPN works on desktop:

Since we are using Electron, we have two processes, MAIN and RENDERER.

MAIN is the first process which is started when the application starts. It is a NodeJS process which is responsible for managing the following functions:

  • Application state and internal operations
  • Tray
  • Kicking off the RENDERER process

The second process is RENDERER and it is responsible for displaying the graphical user interface for the application.

Communication between processes:

Both the MAIN and RENDERER processes need to communicate with each other to stay in sync. For this reason, we are using a standard approach of Inter-Process Communication (IPC).

Javascript is not type-safe, which isn’t very reliable. We use Flow static type checker which adds type-safety for Javascript. This especially applies to syncing data between processes — it becomes less reliable when using out-of-the-box IPC. To improve that, with custom implementation on top to have type-safety.

MessageTransport describes a single typed message which is sent between processes. It creates alignment between both processes by introducing sender and receiver objects, ensuring that both sides expect the same arguments of this message.

Here is an implementation:

class MessageTransport<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
 }
buildSender (): MessageSender<T> {
 return new MessageSender(this._channel, this._messageBus)
 }
buildReceiver (): MessageReceiver<T> {
 return new MessageReceiver(this._channel, this._messageBus)
 }
}
class MessageSender<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
 }
send (data: T) {
 this._messageBus.send(this._channel, data)
 }
}
class MessageReceiver<T> {
 _channel: string
 _messageBus: MessageBus
constructor (channel: string, messageBus: MessageBus) {
 this._channel = channel
 this._messageBus = messageBus
 }
on (callback: T => void) {
 this._messageBus.on(this._channel, callback)
 }
removeCallback (callback: T => void) {
 this._messageBus.removeCallback(this._channel, callback)
 }
}

Here is an example of communication between both these MAIN and RENDERER processes:

Example: communicating country proposal updates between processes:

MAIN process is managing country proposals internally and it sends all updates:

this._countryList.onUpdate(countries => {
  this._communication.countryUpdate.send(countries)
})

RENDERER process listens for country updates,

this.rendererCommunication.countryUpdate.on(this.onCountriesUpdate)
...
onCountriesUpdate (countries) {
  this.countriesAreLoading = false
  this.countryList = countries
}

Having such an abstraction layer ensures that communication is type-safe, reliable and features around it are simple to test.

How do we integrate Mysterium Node with MysteriumVPN Application?

Once we’ve rendered the application layer, we still need to connect MysteriumVPN to Mysterium NodeMysterium Nodeis a software that connects you to Mysterium Network where you are able to exchange value for bandwidth.

MysteriumVPN is a client application of Mysterium Network. The successful running of our dVPN on the network will attract other use cases from existing or future businesses that require end-to-end encryption of data, thereby expanding Mysterium Network’s ecosystem.

We require specific information to ensure the successful running of our dVPNservice.

Operation System Service
Since we are running Mysterium Node under the MysteriumVPN application we need to supervise the Mysterium Node to ensure that it works.

Our Data Protection Policy
We make a clear distinction between personal data and usage data. We do not collect information on who you are. We collect data on session and connection inputs and outputs. This is important data for us as it gives us visibility on how our technology fares against the realities of cyber oppression. Check out our privacy policy for more information.

Logging
Since we are integrating Mysterium Node into the MysteriumVPN application, the application itself gets quite complex. That’s why we have to be prepared to log errors from everywhere, — our application, Mysterium Node, and from Electron.

That means that there are three sources of inputs. When we are inspecting something, we need to understand that these errors can happen in three different places. We need to synchronise those and collect all relevant data from these sources.

Data management in the era of web 3 is complex and we hope to do so in an ethical and fair manner. Check out how our no logs policy protects your personal data.

Build on Mysterium Network

We have an npm package that allows for you to connect to Mysterium Nodeeasily. This is the same package that the MysteriumVPN uses to connect to Mysterium Network. This can be used for any application — it’s literally plug and play.

Interested in contributing to Mysterium Network? We are an open source project focused on bringing privacy, security and freedom to web 3. Check out our Github.

Kernel RCE caused by buffer overflow in Apple’s ICMP packet-handling code (CVE-2018-4407)

( Original text )

This post is about a heap buffer overflow vulnerability which I found in Apple’s XNU operating system kernel. I have written a proof-of-concept exploit which can reboot any Mac or iOS device on the same network, without any user interaction. Apple have classified this vulnerability as a remote code execution vulnerability in the kernel, because it may be possible to exploit the buffer overflow to execute arbitrary code in the kernel.

The following operating system versions and devices are vulnerable:

  • Apple iOS 11 and earlier: all devices (upgrade to iOS 12)
  • Apple macOS High Sierra, up to and including 10.13.6: all devices (patched in security update 2018-001)
  • Apple macOS Sierra, up to and including 10.12.6: all devices (patched in security update 2018-005)
  • Apple OS X El Capitan and earlier: all devices

I reported the vulnerability in time for Apple to patch the vulnerability for iOS 12 (released on September 17) and macOS Mojave (released on September 24). Both patches were announced retrospectively on October 30.

Severity and Mitigation

The vulnerability is a heap buffer overflow in the networking code in the XNU operating system kernel. XNU is used by both iOS and macOS, which is why iPhones, iPads, and Macbooks are all affected. To trigger the vulnerability, an attacker merely needs to send a malicious IP packet to the IP address of the target device. No user interaction is required. The attacker only needs to be connected to the same network as the target device. For example, if you are using the free WiFi in a coffee shop then an attacker can join the same WiFi network and send a malicious packet to your device. (If an attacker is on the same network as you, it is easy for them to discover your device’s IP address using nmap.) To make matters worse, the vulnerability is in such a fundamental part of the networking code that anti-virus software will not protect you: I tested the vulnerability on a Mac running McAfee® Endpoint Security for Mac and it made no difference. It also doesn’t matter what software you are running on the device — the malicious packet will still trigger the vulnerability even if you don’t have any ports open.

Since an attacker can control the size and content of the heap buffer overflow, it may be possible for them to exploit this vulnerability to gain remote code execution on your device. I have not attempted to write an exploit which is capable of doing this. My exploit PoC just overwrites the heap with garbage, which causes an immediate kernel crash and device reboot.

I am only aware of two mitigations against this vulnerability:

  1. Enabling stealth mode in the macOS firewall prevents the attack from working. Kudos to my colleague Henti Smith for discovering this, because this is an obscure system setting which is not enabled by default. As far as I’m aware, stealth mode does not exist on iOS devices.
  2. Do not use public WiFi networks. The attacker needs to be on the same network as the target device. It is not usually possible to send the malicious packet across the internet. For example, I wrote a fake web server which sends back a malicious reply when the target device tries to load a webpage. In my experiments, the malicious packet never arrived, except when the web server was on the same network as the target device.

Proof-of-concept exploit

I have written a proof-of-concept exploit which triggers the vulnerability. To give Apple’s users time to upgrade, I will not publish the source code for the exploit PoC immediately. However, I have made a short video which shows the PoC in action, crashing all the Apple devices on the local network.

The vulnerability

The bug is a buffer overflow in this line of code (bsd/netinet/ip_icmp.c:339):

m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);

This code is in the function icmp_error. According to the comment, the purpose of this function is to «Generate an error packet of type error in response to bad packet ip». It uses the ICMP protocol to send out the error message. The header of the packet that caused the error is included in the ICMP message, so the purpose of the call to m_copydata on line 339 is to copy the header of the bad packet into the ICMP message. The problem is that the header might be too big for the destination buffer. The destination buffer is an mbufmbuf is a datatype which is used to store both incoming and outgoing network packets. In this code, n is an incoming packet (containing untrusted data) and m is an outgoing ICMP packet. As we will see shortly, icp is a pointer into mm is allocated on line 294 or line 296:

if (MHLEN > (sizeof(struct ip) + ICMP_MINLEN + icmplen))
  m = m_gethdr(M_DONTWAIT, MT_HEADER);  /* MAC-OK */
else
  m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);

Slightly further down, on line 314mtod is used to get m‘s data pointer:

icp = mtod(m, struct icmp *);

mtod is just macro, so this line of code does not check that the mbuf is large enough to hold an icmp struct. Furthermore, the data is not copied to icp, but to &icp->icmp_ip, which is at an offset of +8 bytes from icp.

I do not have the necessary tools to be able to step through the XNU kernel in a debugger, so I am actually a little unsure about the exact allocation size of the mbuf. Based on what I see in the source code, I think that m_gethdr creates an mbuf that can hold 88 bytes, but I am less sure about m_getcl. Based on practical experiments, I have found that a buffer overflow is triggered when icmplen >= 84.

At this time, I will not say any more about how the exploit works. I want to give Apple users a chance to upgrade their devices first. However, in the relatively near future I will publish the source code for the exploit PoC in our SecurityExploits repository.

Finding the vulnerability with QL

I found this vulnerability by doing variant analysis on the bug that caused the buffer overflow vulnerability in the packet-mangler. That vulnerability was caused by a call to mbuf_copydata with a user-controlled size argument. So I wrote a simple query to look for similar bugs:

**
 * @name mbuf copydata with tainted size
 * @description Calling m_copydata with an untrusted size argument
 *              could cause a buffer overflow.
 * @kind path-problem
 * @problem.severity warning
 * @id apple-xnu/cpp/mbuf-copydata-with-tainted-size
 */

import cpp
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph

class Config extends TaintTracking::Configuration {
  Config() { this = "tcphdr_flow" }

  override predicate isSource(DataFlow::Node source) {
    source.asExpr().(FunctionCall).getTarget().getName() = "m_mtod"
  }

  override predicate isSink(DataFlow::Node sink) {
    exists (FunctionCall call
    | call.getArgument(2) = sink.asExpr() and
      call.getTarget().getName().matches("%copydata"))
  }
}

from Config cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "m_copydata with tainted size."

This is a simple taint-tracking query which looks for dataflow from m_mtod to the size of argument of a «copydata» function. The function named m_mtod returns the data pointer of an mbuf, so it is quite likely that it will return untrusted data. It is what the mtod macro expands to. Obviously m_mtod is just one of many sources of untrusted data in the XNU kernel, but I have not included any other sources to keep the query as simple as possible. This query returns 9 results, the first of which is the vulnerability in icmp_error. I believe the other 8 results are false positives, but the code is sufficiently complicated that I do consider them to be bad query results.

Try QL on XNU

Unlike most other open source projects, XNU is not available to query on LGTM. This is because LGTM uses Linux workers to build projects, but XNU can only be built on a Mac. Even on a Mac, XNU is highly non-trivial to build. I would not have been able to do it if I had not found this incredibly useful blog post by Jeremy Andrus. Using Jeremy Andrus’s instructions and scripts, I have manually built snapshots for the three most recent published versions of XNU. You can download the snapshots from these links: 10.13.410.13.510.13.6. Unfortunately, Apple have not yet released the source code for 10.14 (Mojave / iOS 12), so I cannot create a QL snapshot for running queries against it yet. To run queries on these QL snapshots, you will need to download QL for Eclipse. Instructions on how to use QL for Eclipse can be found here.

Timeline

  • 2018-08-09: Privately disclosed to product-security@apple.com. Proof-of-concept exploit included.
  • 2018-08-09: Report acknowledged by product-security@apple.com.
  • 2018-08-20: product-security@apple.com asked me to send them the exact macOS version number and a panic log.
  • 2018-08-20: Returned the requested information to product-security@apple.com. Also sent them a slightly improved version of the exploit PoC.
  • 2018-08-22: product-security@apple.com confirmed that the issue is fixed in the betas of macOS Mojave and iOS 12. However, they also said that they are «investigating addressing this issue on additional platforms» and that they will not disclose the issue until November 2018.
  • 2018-09-17: iOS 12 released by Apple. The vulnerability was fixed.
  • 2018-09-24: macOS Mojave released by Apple. The vulnerability was fixed.
  • 2018-10-30: Vulnerabilities disclosed.

"Send it back"

Credits

  • «I am Error». Screenshot from Zelda II: The Adventure of Link. The screenshot copyright is believed to belong to Nintendo. Image downloaded from wikipedia.
  • «Send it back». By Edward Backhouse.

A SECURITY ANALYSIS TOOLKIT FOR PROPRIETARY CAR PROTOCOLS CANALYZAT0R

Disclaimer: The elaboration and software project associated to this subject are results of a Bachelor’s thesis created at SCHUTZWERK in collaboration with Aalen University by Philipp Schmied.

While car manufacturers steadily refine and advance vehicle systems, requirements of the underlying networks increase even further. Striving for smart cars, a fast-growing amount of components are interconnected within a single car. This results in specialized and often proprietary car protocols built based on standardized technology. Most of these protocols are based on bus protocols: All network nodes within such a bus network are connected using a single shared data link. This technology provides a feasible way of real time communication between several security and comfort systems. However, often no or insufficient authentication and encryption or other security mechanisms can be found in today’s car systems. As described previously, most of the interchanged data structures on a car network bus, including associated systems, are proprietary. For this reason, there’s a need for open source, extensible, easy to use and publicly available software to analyze the security state of such networks and protocols.

CAN BUS

Starting from mid-1980, the CAN bus is being implemented into vehicles. Still to this day, many components and proprietary protocols rely on the CAN bus. While analyzing today’s car protocols, we focused on this technology – however, there exist multiple additional technologies like FlexRay and automotive Ethernet which will most likely gain an increased relevance and also need to be analyzed in the future.

CAN network packets are defined by the associated packet format, which looks as follows [1]:

CAN packet format

  • Arbitration ID: Describes the meaning of the data segments
  • Control: Flags to manage packet transport
  • Data: Payload of the packet with up to eight bytes of data
  • CRC: Checksum

A general goal of analyzing car protocols is to reverse engineer the CAN matrix. This data structure maps CAN arbitration IDs and corresponding payloads to specific actions. An example for this is the identification of a CAN packet which controls the acceleration of a vehicle.

Depending on intended goals, the CAN bus can be accessed in two ways:

  1. OBD-II interface: Since 2004, this diagnostic interface is mandatory for each car in the European Union. Most of the time, this port can be accessed from the driver’s seat. Inbound packets can and most likely will be filtered by the diagnostic gateway, so fuzzing from this interface can be of limited success rate.
  2. Interacting with bus wires: It’s possible to directly splice analysis hardware into a CAN bus. This way, filtering can be circumvented and otherwise isolated bus segments can be analyzed.

INTRODUCING THE CANALYZAT0R

This Python software project is built from scratch with new ideas for analysis mechanisms. It’s released on GitHub and bundles many features of other other CAN tools in one place. Also, it’s GUI based and organized with one tab per specific analysis task:

CANalyzat0r: Main tab

Most of the existing open source CAN analysis software makes use of SocketCAN. This consists of a bundle of kernel modules that abstract CAN communication in such a way that CAN interfaces can be used similarly to conventional network interfaces on the Linux operating system. So does CANalyzat0r, including many additional features:

  • Manage interface configuration (automatically load kernel modules, manage physical and virtual SocketCAN devices)
  • Multi interface support: Sniff while sending data on a separate SocketCAN interface
  • Manage your work in projects. You can also import and export them in human readable/editable JSON format and track data using a version control system.
  • Transparent logging
  • Graphical sniffing
  • Manage findings, dumps and known packets per project:

CANalyzat0r: Manage known packets per project
  • Easy copy and paste between CANalyzat0r modules. Also, it’s possible to paste text based SocketCAN files directly into the GUI to import existing packet dumps:

CANalyzat0r: Pasting packets
  • Threaded Sending, Fuzzing and Sniffing
  • Ignore packets when sniffing — Automatically filter unique packets by ID or data and ID
  • Compare dumps
  • Allows setting up complex setups using only one window
  • Clean organization in tabs for each analysis task
  • Advanced packet filtering using an interactive packet replay approach
  • Search for action specific packets using background noise filtering
  • SQLite support
  • PDF and HTML code documentation

CANalyzat0r is modular and extensible – using the provided documentation it’s possible to implement new features which integrate into the existing GUI and work flow.

USAGE EXAMPLES

SIMULTANEOUS SNIFFING AND FUZZING

In order to analyze functionalities of proprietary car components, fuzzing mostly acts as a starting point. Using this approach, CAN nodes can be examined to uncover potential security risks. The CANalyzat0r can be used to quickly setup an efficient fuzzing environment:

CANalyzat0r: Integrated fuzzer and sniffer
  1. Connect the CANalyzat0r to the CAN node via SocketCAN and the desired bit rate.
  2. In the fuzzer tab, choose the desired options: For example, it’s possible to define a fuzzing mask and a desired packet length range which will be applied to all randomly generated CAN packets:
Resulting payload Payload mask Length minimum Length maximum
12 AA 34 56 BB 13 XX AA XX XX BB 13 XX XX 0 6
XX AA XX XX BB 13 XX XX 0 6
12 AA 34 88 XX AA XX XX BB 13 37 DD 2 4

Also, CAN Arbitration IDs can be fixed while payloads remain variable. Here’s an example:

Resulting CAN ID ID mask Fuzzing mode
BA4 XAX User defined
832 XXX User defined
563 11 bit IDs

While random packets are being generated and sent over the CAN bus, it’s possible to use the sniffer tab to trace answer packets. Sniffed packet dumps can be saved, replayed or filtered in further steps.

SEMI-AUTOMATED PACKET FILTERING

To exploit and check for packet replay vulnerabilities, it’s often necessary to capture packet dumps while executing a certain task on a car, for example unlocking the doors using the remote control. Once such a packet dump that causes a CAN node to execute the desired task has been captured, it’s mostly desired to minimize such a set of packets. To gain the desired effect on a car’s component, it’s not required to replay thousands of packets every time. In fact, desired actions can usually be performed using only a few particular CAN packets.

For this task, the filtering tab of the CANalyzat0r can be used:

CANalyzat0r: Filtering packets
  1. Capture “noise” packets: While the desired action is not being executed by the CAN component, packets that pass the bus will be captured. These packets will be useful in further analysis steps.
  2. Record an arbitrary amount of packet sets while executing the task once per packet set.
  3. Filtering: First, all previously captured noise packets will be removed from each packet set. After that, only packets which occur in every packet set will be shown. This resulting set of packets causes the CAN node to perform the desired task while being heavily minimized.

Large packet dumps often are the result of fuzzing attempts. To assist in filtering relevant packets, the searcher tab of the described toolkit can be used:

  1. Load the desired packet dump by using either copy-and-paste mechanisms of the CANalyzat0r tabs, text based packet dumps or database queries.
  2. After connecting the CANalyzat0r to the target vehicle, start the searching process.
  3. The loaded packet set will be split into small chunks, which are replayed one after another. After one chunk has been replayed, the tool asks the user whether the desired action has been executed by the car. On success, the previously replayed packet set acts as the new base data set and the searching process restarts from the beginning.
  4. If no chunk generates the desired output, randomization will be used. This results in shuffled packet chunks which will be used for further retries. Using this approach, actions which require multiple packets to be sent can be identified.

DATABASE MANAGEMENT

Once packet dumps for specific results have been identified, they can be saved to the SQLite based database with an associated description. This allows a centralized finding management. Using the JSON based database import and export functionality, database states can be version controlled. It’s also possible to work on multiple CANalyzat0r projects simultaneously by creating separate projects.

EASY SETUP USING DOCKER

To get started quickly, the provided docker image can be used. No dependencies have to be present on the host system and the CANalyzat0r is up and ready using only a few commands. Please refer to the docker folder within the CANalyzat0r repository for additional information.

REFERENCES