Extract UniFi .unf backup file

In this post we are going to extract the contents of a UniFi .unf backup.

This is helpful if we need to do any sort of recovery, or need to look through the database to find system information.

  1. Acquire backup
  2. Decrypt and extract backup
  3. Dump database to JSON file

Acquire Backup

This is easy to do. Log into the web interface go to Settings -> System -> Maintenance -> Backup and Restore

Scroll down to Available Backups and download.

Download Backup in UniFi Controller

You can also get the file via scp or sftp. Manual backups are located in

/usr/lib/unifi/data/backup

and auto backups are in

/usr/lib/unifi/data/backup/autobackup

Decrypt and Extract Backup

We’ll be getting the following decrypt script from here. https://github.com/zhangyoufu/unifi-backup-decrypt More notes on it below.

We’ll need to make sure that openssl and zip are installed

sudo apt install openssl zip

Download the script with wget

wget https://raw.githubusercontent.com/zhangyoufu/unifi-backup-decrypt/master/decrypt.sh

Make it executable

sudo chmod u+x decrypt.sh

And now we can convert the UniFi .unf backup file to a .zip

sudo ./decrypt.sh autobackup_6.2.33.unf autobackup_6.2.33.zip

Now we can extract the zip archive. You can do this on Windows, macOS, or Linux through the GUI or you can extract with

sudo unzip autobackup_6.2.33.zip -d unifi

This will extract all the files and folders to a directory named unifi.

cd unifi

Dump database to JSON

You should now see the db.gz file. This is a compressed archive of the database in BSON (Binary JSON) format. We can use the mongo-tools to convert this to a more human readable JSON format.

sudo apt install mongo-tools

Now we can extract the archive and pipe it through bsondump.

gunzip -c db.gz | bsondump

You can run it through grep to filter out what you need.

You can also dump the db to a json file with

bsondump --bsonFile=db --outFile=db.json

More notes on the decrypt script.

The decrypt script is really simple. It looks like it uses a key to decrypt the UniFi backup and then puts all the contents into a zip file. There is also an encryption script. Theoretically you can decrypt, make changes to the config and then reencrypt and restore to a server.

#!/bin/sh

# Authors:
# 2017-2019 Youfu Zhang
# 2019 Balint Reczey <balint.reczey@canonical.com>

set -e

usage() {
    echo "Usage: $0 <input .unf file> <output .zip file>"
}

if [ -z "$2" -o ! -f "$1" ]; then
    usage
    exit 1
fi

INPUT_UNF=$1
OUTPUT_ZIP=$2

TMP_FILE=$(mktemp)
trap "rm -f ${TMP_FILE}" EXIT

openssl enc -d -in "${INPUT_UNF}" -out "${TMP_FILE}" -aes-128-cbc -K 626379616e676b6d6c756f686d617273 -iv 75626e74656e74657270726973656170 -nopad
yes | zip -FF "${TMP_FILE}" --out "${OUTPUT_ZIP}" > /dev/null 2>&1

Obtain and Decrypt Cambium WiFi Router Password

By default the passwords are “encrypted” so you can not tell what the password is.

No way to view cnPilot WiFi password in the Web UI

We covered decrypting the passwords from the config file from cambium cloud. But what about a local router that is not connected to the cloud. What then?

Thankfully everything you need is on the router. We’ll need to use the command line tools.

1. Enable SSH

First verify that SSH is enabled.

Enable SSH n cnPilot

2. SSH into router

You may need to specify the “diffie-hellman-group1” option if it throws an error.

ssh admin@192.168.11.1 -o KexAlgorithms=+diffie-hellman-group1-sha1

3. Extract Encrypted WiFi Password from config

The config file is stored in “etc/cambium/bkup-config.txt”

cat etc/cambium/bkup-config.txt | grep 

This should dump the encrypted password(s).

Example Output.

WPAPSK1=[c760ba8ffe65c669]
RTDEV_WPAPSK1=[c760ba8ffe65c669]

4. Decrypt WiFi Password

Now we can decrypt the password. Replace the string at the end with the encrypted string

3des_hex -d c760ba8ffe65c669

It should now display the decrypted password

# 3des_hex -d c760ba8ffe65c669
12345678#

Note that it puts the # symbol after the password and if you try to type something in, it clears the line. you can use the following to have cleaner output.

echo $(3des_hex -d c760ba8ffe65c669 )

That will print the password on it’s own line

# echo $(3des_hex -d c760ba8ffe65c669 )
12345678
#

Decrypting Cambium router config passwords

In the cambium cloud you can retrieve a config from a router, modify it and reapply it or make a template from it. All the passwords are “encrypted” so you can’t read what the WiFi password is for example.

Example config line looks like

WPAPSK1=[c760ba8ffe65c669]

Looks like it uses some sort of des3 hex encryption.

Fortunately there is a utility on the routers we can use to decrypt the encrypted string.

First we need a router that we can SSH into.

Info on the encryption

The Cambium router uses the 3des_hex utility to decrypt and encrypt strings

It is located /sbin/3des_hex

Decrypting a password

Decrypting is super easy.

3des_hex -d "c760ba8ffe65c669"

Replace the key with the key you want to decrypt.

Encrypting a password

Not really sure if this would ever be needed, but you can use the -e option to encrypt a string

3des_hex -e "12345678"

More info.

It looks like it needs the lib file “/lib/libuClibc-0.9.33.2.so”

/sbin/3des_hex is where the main file is stored though.

The config_manager.sh script in /sbin has the functions that encrypt and decrypt the config lines.

TMP_FILE="/tmp/tmp_cfg"
TMP_FILE2="/tmp/tmp_cfg2"
TMP_FILE_DECRYPT="/tmp/tmp_cfg_decrypt"
TMP_MFK_FILE="/tmp/multi_function_key.cfg"
decrypt_key="asdfghjkl";
SNMP_DECRYPT_FILE="/etc/cambium/cambium_default.decrypt"
DotFactoryFile="/etc_ro/DoNotFactory.name"

# when security encrypt enable , decrypt.
handle_file_dec()
{
        local enc_enable=`dev_manage_stat_get has_config_enc`
        if [ "$enc_enable" != "1" ]; then
                return 0
        fi
        SecParamListFile="/etc_ro/ConfigFileSecParam"
        [ -x "/sbin/3des_hex" ] || return 0
        [ -f $SecParamListFile ] || return 0
        [ -z "$1" ] && return 1
        awk -F '=' 'ARGIND==1{pname[$0]}ARGIND>1&&($1 in pname){print $0}' $SecParamListFile $1 > $1.tmp
        awk '{if($0~/.+\=\[.*\]/){sub("\=","\|");print $0;}else{print $0}}' $1.tmp > $1.tmp1
        rm -f $1.tmp
        awk -F'|' '{if($2~/\[.*\]/){len=length($2);value=substr($2,2,len-2);while(("3des_hex -d \""value"\""|getline line)>0){printf("%s=%s\n",$1,line);}close("3des_hex -d \""value"\"");}else{print $0}}' $1.tmp1 > $1.tmp2
        rm -f $1.tmp1
        echo "" >> $1
        cat $1.tmp2 >> $1
        rm -f $1.tmp2
}

Extract encrypted Signal backup

https://github.com/xeals/signal-back
More information at the above link

Installation of precompiled binary for Signal-Back

wget https://github.com/xeals/signal-back/releases/download/v0.1.7-alpha.2/signal-back_linux_amd64
chmod +x signal-back_linux_amd64
./signal-back_linux_amd64

Help info

Usage: signal-back_linux_amd64 COMMAND [OPTION…] BACKUPFILE
   --help, -h     show help
   --version, -v  print the version
 Commands: 
   format   Read and format the backup file
   analyse  Information about the backup file
   extract  Retrieve attachments from the backup
   check    Verify that a backup is readable
   help     Shows a list of commands or help for one command

Extract attachments from backup

Replace ~/Desktop/signal…backup with the path to your Signal backup.

./signal-back_linux_amd64 extract ~/Desktop/signal-2019-09-30-01-43-21.backup

It’ll ask for the password and then start pulling out the attachments and putting them in the current directory.

Export messages to CSV file

Default option is XML. CSV will let you open it up in Excel.

./signal-back_linux_amd64 format -f CSV --output signal-output.csv ~/Desktop/signal-2019-09-30-01-43-21.backup

Specify password to use

You can use the -p option to specify the password. It does not matter if there are spaces every 5 numbers or not. Also the -P option is suppose to let you use a file.

./signal-back_linux_amd64 extract -p "48294 55709 09123 94563 74662 12800" ~/Desktop/signal-2019-09-30-01-43-21.backup

Other help options

bob@localhost:~/Downloads/signal-back$ ./signal-back_linux_amd64 help
 Usage: signal-back_linux_amd64 COMMAND [OPTION…] BACKUPFILE
 --help, -h     show help
   --version, -v  print the version
 Commands:
   format   Read and format the backup file
   analyse  Information about the backup file
   extract  Retrieve attachments from the backup
   check    Verify that a backup is readable
   help     Shows a list of commands or help for one command
bob@localhost:~/Downloads/signal-back$ ./signal-back_linux_amd64 help format
 Usage: signal-back_linux_amd64 format [OPTION…] BACKUPFILE
 Parse and transform the backup file into other formats.
 Valid formats include: CSV, XML, RAW.
 --format FORMAT, -f FORMAT  output the backup as FORMAT (default: "xml")
   --message TYPE, -m TYPE     format TYPE messages (default: "sms")
   --output FILE, -o FILE      write decrypted format to FILE
   --password PASS, -p PASS    use PASS as password for backup file
   --pwdfile FILE, -P FILE     read password from FILE
   --verbose, -v               enable verbose logging output
bob@localhost:~/Downloads/signal-back$ ./signal-back_linux_amd64 help extract
 Usage: signal-back_linux_amd64 extract [OPTION…] BACKUPFILE
 Decrypt files embedded in the backup.
 --outdir DIRECTORY, -o DIRECTORY  output attachments to DIRECTORY
   --password PASS, -p PASS          use PASS as password for backup file
   --pwdfile FILE, -P FILE           read password from FILE
   --verbose, -v                     enable verbose logging output
bob@localhost:~/Downloads/signal-back$