Exporting Authy Tokens

First up, a note: exporting your Authy tokens presents a security risk, especially if you save them to a file. Anyone that is able to view the tokens can then create the codes needed to access the associated accounts. So… use your head and be safe. With that out of the way:

I’ve recently become very frustrated at the major second-factor authentication (2FA) apps, particularly around the lack of features needed to manage a large number of tokens.

In the security industry, the guideline has long been “use a second factor” mechanism — giving rise to mantras like “something you have and something you know”, which is really the point. However, currently, nearly nobody uses 2FA strictly in that manner: most folks view 2FA as “a second password” mechanism. One they choose, one is based on whatever (generally a seed that’s based on time — the first ‘T’ in TOTP). While that defeats some of the intent behind 2FA, in practice that’s actually probably just fine.

So: as an industry we push vendors and developers to require 2FA. Good news! Many of them are starting to. Herein comes the problem: users now have to manage a lot of tokens. In fact, they have to manage at least one for each app they use.

So what’s the big deal? NONE of the major apps used for 2FA (Authy, 1Password, Duo, Google Authenticator, LastPass, etc.) really provide a useful way to manage a large number of accounts:

  • Users can’t rename them based on what they want to call them (most of the apps use a combination of the Seed Provider name + username to refer to them. That may be OK with a small number of accounts, but wait until you have 15 “Google” accounts and need to figure out which one is which but you can only see the first 2 or 3 chars of what comes after “Google” on the screen…)
  • Tagging doesn’t exist in this world
  • Neither does sorting, for most of them
  • In some of them, you can’t delete accounts without having to wait at least 24 hours.
  • There’s no such thing as export

Now, some of those have good security reasons behind them (well… OK. Just one, really. The one that most applies to this post: lack of export). Why can’t you export from these apps? Simple: allowing export breaks the 2FA model of “something you have, something you know”. If you can get a dump of seeds, that becomes two things you know, since the device is no longer required. Except… for day to day use, nearly everyone is totally fine with 2FA just being 2 pieces of information that you know. Not to mention: what happens if a software company goes away? Do I lose access to my accounts because I can’t access the tokens anymore? Pretty much zero app developers allow someone that has already configured 2FA to display a scannable QR code (or even just get the seed) once the initial configuration is complete (which, again, is in harmony with good “something you have” mode, but contrary to “good user interface” requirements).

So… if you are one of those that wants to dump your tokens out of an existing app you are using — and if that app happens to be Authy — you are in luck! It turns out you can do this. It just isn’t super straight foward.

  1. Open the Authy application, such that you are viewing the accounts you have saved
  2. Open your browser extensions manager. In Chrome, this can be done by going to chrome://extensions
  3. In the extensions manager, click “Developer Mode” on the top right
  4. Find the Authy application (note: this is different than the Authy extension. It should be at the bottom of the page in the “Chrome Apps” section)
  5. You should see a bit that says “Inspect Views”. It may say “background page, 1 more”. Click the link, until you see “main.html”.
  6. Click “main.html”, and the Chrome developer tools window should open
  7. Open the Console (this is the Javascript Console)
  8. Paste the codeblock below into the console window
  9. Enjoy your list of accounts. (I recommend doing something like right clicking on the console and “save as” to export the data to a file — but please understand you do this at your own risk, as anyone that is able to access the file can then create a 2FA token for the accounts in the list).

Here’s the code to paste in step 8 (hat tip to gboudreau and nmurthy):

/* base32 / /
 Copyright (c) 2011, Chris Umbel
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

function quintetCount (buff) {
  var quintets = Math.floor(buff.length / 5)
  return buff.length % 5 === 0 ? quintets : quintets + 1

const encode = function (plain) {
  var i = 0
  var j = 0
  var shiftIndex = 0
  var digit = 0
  var encoded = new Array(quintetCount(plain) * 8)
  /* byte by byte isn't as pretty as quintet by quintet but tests a bit faster. will have to revisit. */
  while (i < plain.length) {
    var current = plain[i]; if (shiftIndex > 3) {
      digit = current & (0xff >> shiftIndex)
      shiftIndex = (shiftIndex + 5) % 8
      digit = (digit << shiftIndex) | ((i + 1 < plain.length) ? plain[i + 1] : 0) >> (8 - shiftIndex)
    } else {
      digit = (current >> (8 - (shiftIndex + 5))) & 0x1f
      shiftIndex = (shiftIndex + 5) % 8
      if (shiftIndex === 0) i++
    encoded[j] = charTable.charCodeAt(digit); j++
  for (i = j; i < encoded.length; i++) {
    encoded[i] = 0x3d // '='.charCodeAt(0)
  return encoded.join('')
/* base32 end */

var hexToInt = function (str) {
  var result = []
  for (var i = 0; i < str.length; i += 2) {
    result.push(parseInt(str.substr(i, 2), 16))
  return result
function hexToB32 (str) {
  return encode(hexToInt(str))

const getTotps = function () {
  var totps = []
  console.warn("Here's your Authy tokens:")
  appManager.getModel().forEach(function (i) {
    var secret = (i.markedForDeletion === false || !i.secretSeed) ? i.decryptedSeed : hexToB32(i.secretSeed)
    console.log('TOTP Secret: ' + secret)
      name: i.name,
      secret: secret
  return totps

Unlocking Verizon Pixel Bootloader

  1. Remove Google account and any kind of screen lock (fingerprint, PIN, pattern, etc.) from your device.
    1. Quickest way is to just factory reset the device
  2. Eject sim card from your device.
  3. Reset your device. In setup wizard, skip everything you can. ESPECIALLY:
    1. DO NOT connect to WiFi
    2. DO NOT add fingerprints
    3. DO NOT add a screen lock.
  4. Enable Developer Options
  5. In Developer Options, enable USB debugging.
  6. Connect your phone to PC
  7. Check the box to always allow your PC
  8. Open a command shell and run the following: adb shell pm uninstall --user 0 com.android.phone
  9. Restart your device (using the power button).
  10. Connect to WiFi
  11. Open Chrome and go to google.com
  12. Go to Developer Options and the option to enable OEM unlocking should be available.
  13. Enable OEM unlocking.
  14. Reboot into bootloader and run fastboot oem unlock
    1. On newer phones ( >= Pixel2) you may need to use fastboot flashing unlock instead
  15. Reboot, and enjoy your now unlocked bootloader!

NOTE: You may need to run the factory reset twice in a row, and reboot twice after step 8.

Special thanks to: https://forum.xda-developers.com/pixel-xl/how-to/how-to-unlock-bootloader-verizon-pixel-t3796030

Setting Up The Nuand BladeRF On Mac OS X for Bluetooth Low Energy (BLE) Hacking

(Cross-posted to peerlyst.com)

This is a quick guide to getting the Nuand BladeRF software defined radio (SDR) up and running on Mac OS X. The end goal is to have an environment that can be used to perform basic Bluetooth Low Energy (BLE) hacking. The initial focus will be getting it set up to perform BLE scanning and advertising.

A note on formatting: I’ve bolded commands that should be entered in at the command prompt. Any other code formatted content is output from running the commands, shown for reference.

Here’s the steps needed:

1. Install the dependencies, clone the repo, compile the software:

brew install libusb pkgconfig cmake libtecla
git clone --recursive https://github.com/Nuand/bladeRF.git
cd bladeRF/host
mkdir build ; cd build
sudo make install

2. Make sure the device is recognized by the system:

$ bladeRF-cli -p
  Description:    Nuand bladeRF
  Backend:        libusb
  Serial:         7ddf0461b8c6cb36ffe8358189bc5d1d
  USB Bus:        20
  USB Address:    6

3. Download the most recent FPGA image

  • Make sure you get the correct version for your FPGA size. 
  • You can get the size by running: `bladeRF-cli -e info`
  • Look for a line similar to: `FPGA size:                40 KLE`

4. Setup the FPGA auto-load up so you don’t have to do this manually every time you reconnect the SDR:

  • Create the Nuand directory: `mkdir -p $HOME/.Nuand/bladeRF/`
  • Move the FPGA image to the Nuand directory: `mv $HOME/Downloads/hostedx40-latest.rbf $HOME/.Nuand/bladeRF/hostedx40.rbf`

5. Run the CLI, and you will likely see a warning message, followed by the bladeRF command prompt:

$ bladeRF-cli

table not found. Manual gain control will be used instead.
[INFO @ /<redacted>/bladeRF/host/libraries/libbladeRF/src/board/bladerf1/bladerf1.c:1706] To enable AGC, see "Generating a DC offset table" at https://github.com/Nuand/bladeRF/wiki/DC-offset-and-IQ-Imbalance-Correction

6. Setup the AGC. This can be done either manually each time, or a table can be created:

  1. To set the AGC Manually:

    1. Set the frequency you wish to use. Since BLE uses 2.4 GHz, we’ll want to use that. In the example below, we set the frequencies to BLE Frequency Channel 37, which is used for BLE advertising. Channel 37 is centered at 2402 MHz, so we can set transmit to 2401 MHz, and receive to 2402 MHz:

    bladeRF> set frequency tx 2401M

      TX1 Frequency: 2401000001 Hz (Range: [237500000, 3800000000])

    bladeRF> set frequency rx 2402M

      RX1 Frequency: 2401999999 Hz (Range: [237500000, 3800000000])

    2. Set the gain (we set it to 8 dB here. There’s nothing magic about that, I picked it on a whim):

    bladeRF> set rxvga2 8
      Note: This change will not be visible until the channel is enabled.
      Setting RX1 rxvga2 gain to 8 dB
        rxvga2:    6 dB (Range: [0, 30])

    3. Calibrate the LMS module:

    bladeRF> cal lms
      LPF tuning module: 23

      TX LPF I filter: 27
      TX LPF Q filter: 39

      RX LPF I filter: 30
      RX LPF Q filter: 30

      RX VGA2 DC reference module: 25
      RX VGA2 stage 1, I channel: 37
      RX VGA2 stage 1, Q channel: 45
      RX VGA2 stage 2, I channel: 30
      RX VGA2 stage 2, Q channel: 33

    4. Run the DC offset calibration routines (look for `Error` values to be near 0:

    bladeRF> cal dc rx

    RX DC I: Value =   352, Error =  0.456
    RX DC Q: Value =   640, Error =  0.265

    bladeRF> cal dc tx

    TX DC I: Value =  -208, Error =  0.347
    TX DC Q: Value =   160, Error =  0.349

  2. To generate a table:

    1. Run the cal command. This will take some time, and should be done after the bladeRF has been running a bit so it is properly warmed up:

    bladeRF> cal table dc rx
    Calibrated @  237500000 Hz: I= 384 (Error: 3.63), Q= 224 (Error: 0.95)      DC-LUT: Max (I=-46, Q=-38) Mid (I=  7, Q= 10) Min
    Calibrated @  247500000 Hz: I= 384 (Error: 2.44), Q= 224 (Error: 1.81)      DC-LUT: Max (I=-43, Q=-39) Mid (I=  7, Q= 10) Min
    Calibrated @  257500000 Hz: I= 384 (Error: 0.81), Q= 224 (Error: 0.30)      DC-LUT: Max (I=-41, Q=-39) Mid (I=  8, Q= 10) Min

    2. Once complete, check the current directory on the file system. There should be a file named `<serial #>_dc_rx.tbl`.

  • For example: Using the device shown in the info command above, the file name would be `7ddf0461b8c6cb36ffe8358189bc5d1d_dc_rx.tbl`

    3. Move the file to the Nuand directory: mv 7ddf0461b8c6cb36ffe8358189bc5d1d_dc_rx.tbl $HOME/.Nuand/bladeRF

That’s all there is to it. Now when you run `bladeRF-cli`, the FPGA will be auto-loaded, and the AGC table will be loaded as well, leaving you ready to rock. In a future post, I’ll talk about where to go next to start listening to beaconing BLE devices near you.