Marco Faggian

Identifying WireGuard (VPN) Traffic Using RSA NetWitness Network

Blog Post created by Marco Faggian Employee on Apr 18, 2019

WireGuard is a new open-source VPN protocol used to create point to point tunnels. It uses the most modern cryptographic protocols and it works on the network layer for both IPv4 and IPv6.
One of the advantages of WireGuard implementation is the size of it's code. It uses just 4000 rows of code, which is much smaller compared with openVPN or IPsec implementations.  Initially released for the Linux kernel, it is now cross-platform and widely deployable.  All these aspects make the WireGuard protocol a perfect software for those who need to create a secure channel.

 

Considered it's easy implementation and it's wide availability, I tried to create a parser to help to identify this type of traffic.

 

For our purpose we can ignore the header of the packet and concentrate on the payload data only.

first packet

From the payload analysis we see that the first packet starts with 01 00 00 00. The same pattern is used on the following packets, 02 00 00 00 on the response and 04 00 00 00 on the rest of the traffic.

second packet

third packet


If we cross reference this with Wireguard’s documented protocol, we can confirm that the data begins with an 8-bit pattern (0100 0000, 0200 0000, 0400 0000), so we can assume that these pattern will help to identify this type of traffic.

 

With some suggestion from Christopher Ahearn, I started to create my LUA parser.

 

The entry point for my parser is the token 01 00 00 00

WireGuard:setCallbacks({
    [nwevents.OnSessionBegin] = WireGuard.sessionBegin,
    ["\001\000\000\000"] = WireGuard.tokenMATCH, -- find the token 1 0 0 0
})

Once the token is identified inside a session, it's necessary to understand its position as we are looking for the payload that have that token on the first 4 bytes of the payload. 

function WireGuard:tokenMATCH(token, first, last)
    -- check if the token is on the first 4 bytes
    if first == 1 and last == 4 then

If this is the case, then I go to define the request stream and the response stream, then I look for the pattern that I identified before: 02 00 00 00 on first packet of the response stream and 04 00 00 00 on all the other packets.

if requestStream and responseStream then
    -- the first 4 bytes on the first packet response are 2 0 0 0
    if nwstream.getPayload(responseStream,1,4):find("\002\000\000\000",1,4) then
-- the first 4 bytes on the other packets are 4 0 0 0
if (nwpacket.getPayload(requestPacket,1,4):find("\004\000\000\000",1,4) and
    nwpacket.getPayload(responsePacket,1,4):find("\004\000\000\000",1,4)) then

If all the first 4 packets respect the pattern, it means that the analyzed session is a WireGuard session and the parser set the service type as 51820. WireGuard doesn't use a specific port for the communication, so i decided to use the 51820 because it's the value used on the configuration sample available on the WireGuard website.

nw.setAppType(51820)
nw.createMeta(self.keys.ioc, "WireGuard VPN")

 

Once I deployed the parser on the Network Decoder, it allows us to quickly identify if WireGuard VPN traffic is established on the network.

NetWitness

 

WireGuard is evolving and it is possible that something will change, but this parser can help to identify some VPN traffic that otherwise would not have been defined properly using RSA NetWitness.  

Attachments

Outcomes