From 08380ee33dcdc17b5b4f236664ae623383259925 Mon Sep 17 00:00:00 2001 From: Freyja Odinthrir Date: Fri, 27 Sep 2024 14:02:43 -0700 Subject: [PATCH] Add new entry to blog - Revisit entry from may 12th --- .../09/27/scripts-with-passwords-revisited.md | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 content/2024/09/27/scripts-with-passwords-revisited.md diff --git a/content/2024/09/27/scripts-with-passwords-revisited.md b/content/2024/09/27/scripts-with-passwords-revisited.md new file mode 100644 index 0000000..7c6a08a --- /dev/null +++ b/content/2024/09/27/scripts-with-passwords-revisited.md @@ -0,0 +1,106 @@ +title: Using passwords in script, revisited! +description: Another look at my entry from 12th May, 2024 where I explore a method for obfuscating scripts to keep borg passphrases secure while automating my backup process. +tags: security, scripting, unix, linux +date: 2024-09-27 12:11 + +# Table of Contents + +- [Revisiting an old topic](#revisiting-an-old-topic) +- [The process](#the-process) + - [Obfuscation](#obfuscation) + - [Deobfuscation](#deobfuscation) +- [Conclusion](#conclusion) + +# Revisiting an old topic + +[In this blog entry dated 12th May, 2024](https://blog.raer.me/2024/05/01/20240512.html) I discuss a method where I'm able to keep passphrases stored inside of a bash script, while still being able to execute the bash script. Its been a few months and I've improved the process for obfuscating/deobfuscating scripts, since I'm now using this method as part of my process in writing/editing backup scripts. Thus I'd like to retouch the topic since rereading the previous blogpost leaves me a bit undersatisfied. + +# The process + +You start by writing a script, and don't forget to include your sensitive data. I'll include an example below of one of my backup scripts: + +```bash +#!/usr/bin/env bash + +NAME=pi_$(date +'%Y%m%d%H%M%S') +DIR="/home/freyja/.mnt/pi" + + +tmux new-session -d -s borg-pi-archive "sshfs pi:/opt $DIR; \ + export BORG_PASSPHRASE=yesthisistotallymyrealpassphraseyougotmeididanoopsie; \ + borg create --stats --progress --compression lz4 /home/freyja/Documents/.borg/pi::$NAME $DIR; \ + export BORG_PASSPHRASE=''; \ + rclone sync -P -v /home/freyja/Documents/.borg/pi proton:/borg/pi; \ + umount $DIR; \ + " +``` + +## Obfuscation + +Obviously, saving this as plaintext would be insecure. It has a whole encryption passphrase in there! But remembering all that and typing it in every time isn't ideal either. That's where the `obfuscate` script comes in. That looks a 'lil somethin' like this: + +```bash +#!/bin/bash +## +# obfuscate script. This will encrypt any script with a gpg id, +# then stick it into the body of a variable in a new script that can +# decrypt the variable and pipe the original script directly to bash. +# +## +if [ -z "$1" ]; then + read -p "Please enter the filename: " filename +else + filename="$1" +fi + +GPG_ID='my-gpg-identity' + +printf "#!/bin/bash\n\nSCRIPT=\"$(cat $filename | gpg --encrypt --armor -r $GPG_ID | base64 --wrap 0)\"\n\necho \$SCRIPT | base64 -d | gpg --decrypt --quiet | bash\n\n" > $filename.obf + +chmod +x $filename.obf +``` + +calling that with `obfuscate script` will spit out a file called `script.obf` that is just as easy to execute as the script you obfuscated. In fact, it is literally that exact script! Except its been encrypted with your supplied `GPG_ID`, turned into base64, then stuck inside a variable called `SCRIPT` inside of the `script.obf` file - along with some other stuff that allows `script.obf` to decrypt the data stored in `SCRIPT` variable then pipe it directly into bash. + +The obfuscated script will look a bit like this: + +```bash +#!/bin/bash + +SCRIPT="LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgpoUUlNQXhCRUVPVU9vQ1JEQVEvL1EvM29FOHBoeUlQSFN6bVFjSWtpUzFDR1pCQU1oWFY3RU9ld2ZaSVhpcDZOClZHM1lDMGQ5QjVwRjZ6emFQVUZmVkJPQzZSV2NPR1pHQU91QW83bXVSSmZNVU5YVWpYbDRrVFRIRnFpdE8ydFIKVHQ3d0lyVm5YMnJjVUNHR0Iva29lSDdsVG9xeG00TEtiZUkvSis2VVpCejNMSlBEQ2hkcXhtQURkbjlIRCtBMwpJT2pMNW5mbVZoRzRRUXBIa01KVFZyOUVoVXNsanJzNXRJNWNUMmg5NEZyaHBnbHE1OVhIOEJCOTJKQ25jSVo0Cis2eW1hZVdSRXBLOGFXRkF6aFVEZUd6bDdhV1VzMUs4NXRraUszdnFwRkYxUDZLdjZQb3dJOU9RRERHNmtLL08KaXlaRFNtTTNIVUJOQ3lEK29SKzBRRGJneG1TTGdUdkdkbW9xUUxCcm9ESVNLMkRiRWNBWkVqR3RwM25ienhwNwo2T1d6cDZLUzhGZURvTGZtMzdBdnpreTBMQ2ZTUGlZQm1QcFVEZzg1NlJOMytSQWlPeTgydkU0TFd4Mm14N3FZCmVCN1dQS3FNbTlhZDNnTVJUVEpUUGhzSUZrTWc4bEtEeW5uenhnUGFyQStFcnlyMUhnZVBqaThFRUZMVk44cmIKYlVtUE1BL3d6UVVFRFNyaXBBTE5WQ3lXOFF0eHh5QmtYWW9ERldTc2w5RXRCNDRCWHk4amozbHlKcXV6TzFZZgpTTjJmZThRdW9FMk1JTHM1MmRxbjBvdlFBZUN6RVF3Z29udC9hcXpzRUZ4b29tSFRPa1dVT1BUeGVoTXFhRjZKCjlKSnk2aUs0MEMrUHFTbVNVaktQMmtBZDRRQ3YzYXlabU8zaTZyRHZIM25hN0g1OHFLRlkwb2NoRWI4Qzh6blUKY0FFSkFoQk56bm5zRmNrTlVpOUhEQ05hcG1ubkxzb0xycDNWVE9yMFhZQUpyYUFZYStZZDh2RHJsYUNaeFNxTQpOYW1kUFZkc3J4K2JPTTdkbk1VbXFldm1GRzVPUm5nSUF0KytxdkNzaGNmRk42V01qcUpyYStBdWZRMFRldUZzClZZNHRVY3JzRU90REFrWHUxWDEzZVh3PQo9WENRdgotLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tCg==" + +echo $SCRIPT | base64 -d | gpg --decrypt --quiet | bash +``` + +## Deobfuscation + +As you can see, the encrypted script is stored as base64. To run it, that script is decoded, decrypted, then piped into bash. So long as the machine you're on has the private key for the gpg key you used to encrypt the script, it will simply ask you for your gpg passphrase before proceeding~~! How neat! But what if we want to edit the script? Seems like a bit of a pain to get your original script back, right? Well... to a degree. If you wanted to, you could lop of that pipe and `bash` command at the end of the last script, replace it with `>> script.deobfuscated`, and you'd have your original script back. But, that's also kind of annoying to do every time. So I just made a `deobfuscate` script that'll do the job for you. Its just like the `obfuscate` script but in reverse. It takes a file as input, looks for a variable called `script`, then decodes, decrypts, and dumps it into a file appended with `.deobfuscated`. Here's the deobfuscate script: + +```bash +#!/bin/bash +if [ -z "$1" ]; then + read -p "Please enter the filename: " SCRIPT_FILE +else + SCRIPT_FILE="$1" +fi + + +if [ ! -f "$SCRIPT_FILE" ]; then + echo "$SCRIPT_FILE not found!" + exit 1 +fi + + +cat $SCRIPT_FILE | xargs | awk -F 'SCRIPT=' '{print $2}' | awk -F ' ' '{print $1}' | base64 -d | gpg --decrypt --quiet > $SCRIPT_FILE.deobfuscated + +if [ $? -eq 0 ]; then + echo "$SCRIPT_FILE has been deobfuscated." +else + echo "Failed to decrypt the script. Ensure you have the correct GPG key and it's available." + exit 1 +fi +``` + +# Conclusion + +That's about it, I don't have anything else. This section is simply a formality. I hope that if you're reading this, you find it interesting. <3 \ No newline at end of file