Skip to content

Instantly share code, notes, and snippets.

@h3x4d3c1m4l
Last active June 2, 2022 07:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save h3x4d3c1m4l/884dba007da8d04caf5e8760e43560aa to your computer and use it in GitHub Desktop.
Save h3x4d3c1m4l/884dba007da8d04caf5e8760e43560aa to your computer and use it in GitHub Desktop.
PowerShell script for dumping Bluetooth keys (e.g. for importing into Linux)
#
# Dump Windows Bluetooth encryption keys.
# (e.g. for importing into Linux, so you don't have to repair your HID devices, headphones, etc.)
#
# Script by: Sander in 't Hout (h3x4d3c1m4l)
# License : WTFPL
#
# Note: This script needs to be run as SYSTEM user, due to registry key permissions
# You can do this with PsExec: https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
#
# 1. Have your devices paired at all OS'es, but keep Windows the last (verify your devices actually work on Windows)
# 2. Download and unpack PsExec64.exe (PsExec.exe might work for 32 bit Windows, but not tested)
# 3. Put this script in the same folder
# 4. Open an elevated PowerShell prompt, then `cd` to script folder (I assume C:\temp from now on)
# 5. Run: .\PsExec64.exe -s powershell "-ExecutionPolicy" "Bypass" "-File" "C:\temp\Dump Bluetooth keys.ps1"
# 6. Install the keys on Linux: https://wiki.archlinux.org/title/bluetooth#Finishing_up
#
# This script has only been tested on Windows 11 Professional x64,
# but also might work on Windows 10 and 32 bit systems (let me know!).
#
# Sources:
# - https://wiki.archlinux.org/title/bluetooth
# - https://unix.stackexchange.com/questions/402488/dual-boot-bluetooth-le-low-energy-device-pairing/413831#413831
#
$btAdapters = Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys\*
foreach ($btAdapter in $btAdapters)
{
Write-Output "Keys from: $btAdapters"
# Bluetooth < 5.1
Write-Output "`r`nBluetooth < 5.1 devices:`r`n"
foreach ($btDeviceMac in $btAdapter.Property | Where-Object {$_ -ne "MasterIRK"})
{
$btDeviceKey = $btAdapter.GetValue($btDeviceMac)
Write-Output "$btDeviceMac $(($btDeviceKey|ForEach-Object ToString X2) -join '')"
}
# Bluetooth >= 5.1
Write-Output "`r`nBluetooth >= 5.1 devices:`r`n"
foreach ($btDeviceRegKey in $btAdapter.GetSubKeyNames())
{
Write-Output $btDeviceRegKey
$btDeviceSubKey = $btAdapter.OpenSubKey($btDeviceRegKey)
# LTK
$btLTK = $btDeviceSubKey.GetValue("LTK")
if ($btLTK)
{
Write-Output "LTK : $(($btLTK|ForEach-Object ToString X2) -join '')"
}
# ERand (bytes order reversed for Linux compatibility)
$btERand = $btDeviceSubKey.GetValue("ERand")
if ($btERand)
{
$btERandBytes = [bitconverter]::GetBytes($btERand)
$btERandNumber = [bitconverter]::ToUInt64($btERandBytes, 0)
Write-Output "ERand : $btERandNumber"
[array]::Reverse($btERandBytes)
$btERandNumber = [bitconverter]::ToUInt64($btERandBytes, 0)
Write-Output "ERand : $btERandNumber (but byte order inverted, if the other one didn't work then try this one)"
}
# EDIV
$btEDIV = $btDeviceSubKey.GetValue("EDIV")
if ($btEDIV)
{
Write-Output "EDIV : $btEDIV"
}
# IRK
$btIRK = $btDeviceSubKey.GetValue("IRK")
if ($btIRK)
{
Write-Output "IRK : $(($btIRK|ForEach-Object ToString X2) -join '')"
}
# CSRK
$btCSRK = $btDeviceSubKey.GetValue("CSRK")
if ($btCSRK)
{
Write-Output "CSRK : $(($btCSRK|ForEach-Object ToString X2) -join '')"
Write-Output " but you can probably just remove the CSRK section in your Linux config anyway"
Write-Output " as it seems to be a temporary key ..."
}
else
{
Write-Output "CSRK : I did not found that entry for your device,"
Write-Output " but you can probably just remove the CSRK section in your Linux config anyway"
Write-Output " as it seems to be a temporary key ..."
}
Write-Output ""
}
}
@h3x4d3c1m4l
Copy link
Author

Anyone who tested this, whether it worked or not: please let me know and I'll be happy to help you with this :)

Please note that I have not tested copying Linux keys to Windows... it probably can be done, but this script won't help you.

@BackMountainDevil
Copy link

So the script wants to read the things via PSTool? cool , I will test it on win11 in the near future

@BackMountainDevil
Copy link

emm I test it on win 11. run the key.ps1 but nothing happen. nothing output

@h3x4d3c1m4l
Copy link
Author

@BackMountainDevil Just to be sure - You actually have paired Bluetooth devices on Windows? And you are not using any special Bluetooth stack like BlueSoleil or perhaps a USB receiver (e.g. Logitech) hardware that actually hides the Bluetooth from the PC?

Indeed it uses PsTools in order to get the required registry access, these keys can't be accessed even with normal elevation by an admin user. It's kind of a hack, but it worked for me™ :)

I'll also re-test this myself and I'll get back to you soon. Of course Microsoft could change the storage of keys anytime by OS updates, and then this script might need to be revised in order to work again...

@BackMountainDevil
Copy link

I have do such thing for two years, which log in my blog. Devices are MiMouse and MIIIW KB Airm Mini. Maybe the way I use this script is not proper?

@ciarancoffey
Copy link

This worked very well for me. Thanks for it.
Win11, and two BT headsets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment