Compare commits

..

2 Commits

Author SHA1 Message Date
PrincessPi 36e647ac7f migration 2026-05-26 21:50:04 -06:00
PrincessPi d14dfccb64 initial commit via gitinitshit 2026-05-24 04:34:40 -06:00
17 changed files with 59 additions and 572 deletions
+2 -21
View File
@@ -1,21 +1,2 @@
# dirs */secrets_*
## archives dir */parsed_*
archives/*
!archives/README.md
## keystore dir
keystore/*
!keystore/README.md
## out dir
out/*
!out/README.md
## out/content dir
out/content/*
!out/content/README.md
# files
*/*.7z
*/*.sha512
*/*.sha256
*/private_*
*/*.sig
anonymous_signer
-1
View File
@@ -1 +0,0 @@
# File Map
-13
View File
@@ -1,13 +0,0 @@
# Verifiably, Attributably Secure Archives
verifuably, durably, and attributing information as anonymously as desired
## Scripts (Linux Only)
- [verify-everything.sh](./verify-everything.sh) verifies the integrity of the data
- [test_validate_passphrase.sh](./test_validate_passphrase.sh)
## Files
- README.md : this file
- checksums.sha512 : sha512 checksums of all the files in the outer archive (here)
- attribution-checksum.sha512 : sha512 checksum of a passphrase+contents.7z to test for attribution by passphrase
- anonymous_signer : holds ed25519 public key and name (anonymous)
- contents.7z.sig : ed25519 signature file of contents.7z
+6 -80
View File
@@ -1,80 +1,6 @@
# Verifiably, Attributably Secure Archives # fuck_git_downloader
For when you need to distribute information anonymously, but wish to keep it provably full and intact, but _also_ wish to have options to prove attribution. downloads all of a github users public repos, scans them for secrets, then parses into something you can use.
## Writeup this is barely even a script and yet its so hysterically effective that id be remiss not to post it. here be dragons and all idk
### Purpose
todo ![i'm your biggest fan i'll folliow you until you love me, papa, paparazi](./rarity-webcore.jpeg)
### Method
todo
### Issues
- two-way deanonymization is assumed when either method to attribute is used
- when sha512 method is used, originator is assumed to be the owner of the ed25519 key and vice versa
- any reveal of either signed note or sha512 attribution passphrase, the other is assumed to belong to the same entity
- opsec failures can result in two-way deanonymization
## Usage
### Installation
todo
### Usage
todo
## todo
1. x validate attribution thing
2. clean up output
3. **fix password audit!**
4. x sanity checks
5. this README.md
6. x the README-instructions.txt and placedment for archive
7. x passphrase strength/length checks
8. sha256 mode with independant passphrase(?)
9. encrypt archive option
1. inner
1. goes first
2. gets passphrase
3. tests passphrase
4. generates txt file backup
5. then tests with passphrase
2. outer
1. goes second
2. gets passphrase
3. tests passphrase
4. generates txt file backup
5. then tests with passphrase
10. x random data optional
1. x `read -n 1 -s -r -p "In another terminal/window, fill $inner_dir with whatever you please then press any key to continue..."`
2. x now only takes up 2Kb!
3. x only use 128 bytes (1024 bits) x 2
1. x `openssl rand -out "$out_dir/.$RANDOM" 128`
2. x `openssl rand -out "$inner_dir/.$RANDOM" 128`
3. x `find "$out_dir" -type f -name ".*" -exec chown $USER:$USER "{}" \;`
4. x `find "$out_dir" -type f -name ".*" -exec chmod 600 "{}" \;`
11. writeup in this README
12. usage in this README
13. specification definition
1. Specification.md
14. FileMap.md
15. x function: passphrase checkin
1. x match
2. x pass cracklib-check
3. x =>35 chars long
4. x pass call to haveibeenpwned.com api
16. x exit trap with cleanup
## Changelog
- reduced random data to 2x 10Kb
- reduced random data to 2x 1Kb
- added password strength check with cracklib-check
- cleaned up output
- added housekeeping
- set perms and ownership on archives and keystore to minimum
- shred all erronious files and dirs
- cleaned up code
- better rng
- better passphrase check
- checks for exact match
- minimum of 35 chars
- checks with cracklib-check
- checks online with haveibeenpwned.com
- bug fixes
- random data is now actually optional and is only 128 bytes (1024 bits) and are generated securely
- better antiforensics by unsetting vars and cleaning up on exit
-1
View File
@@ -1 +0,0 @@
# Specification (WIP)
-1
View File
@@ -1 +0,0 @@
completed archives here
-355
View File
@@ -1,355 +0,0 @@
#!/usr/bin/env bash
# packages: 7zip, shred, secure-delete, cracklib-runtime, openssl, curl
set -o errtrace
set -o nounset
set -o pipefail
IFS=$'\n\t'
unix_seconds=$(date +%s)
key_path="./private_ed25519_${unix_seconds}"
signature_tag="file-integrity"
out_dir="./out"
inner_dir="$out_dir/contents"
RED='\033[31m'
GREEN='\033[32m'
RESET='\033[0m'
num_of_args="$#"
all_args="$@"
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing required command: $1" >&2
exit 1
fi
}
require_dependencies() {
local deps=(bash shred srm openssl curl ssh-keygen 7z sha512sum awk grep realpath)
for dep in "${deps[@]}"; do
require_command "$dep"
done
}
checkcode() {
local retcode="${1:-}"
if [[ -z "$retcode" ]]; then
echo -e "\n${RED}ERROR!${RESET} checkcode missing return code parameter\n" >&2
exit 1
fi
if [[ "$retcode" -ne 0 ]]; then
echo -e "${RED}ERROR!${RESET} Response code: $retcode" >&2
exit "$retcode"
fi
printf ' %bOK!%b\n' "$GREEN" "$RESET"
}
run_cmd() {
"$@"
checkcode $?
}
reset() {
printf 'Autoshredding known artifacts...\n'
find . -maxdepth 1 -type f \( -name 'private_*' -o -name 'attribution_passphrase_*' -o -name '*.sha512' -o -name 'checksums*' -o -name '*.sig' -o -name '*.7z' -o -name 'anonymous_signer' \) -exec shred -uz {} +
checkcode $?
if compgen -G 'private_*' >/dev/null 2>&1; then
printf 'Shredding errant private key files...\n'
shred -uz private_* || true
fi
if compgen -G 'attribution_passphrase_*' >/dev/null 2>&1; then
printf 'Shredding errant attribution passphrase files...\n'
shred -uz attribution_passphrase_* || true
fi
printf 'Removing previous output directory...\n'
rm -rf "$out_dir"
checkcode $?
printf 'Rebuilding output directory structure...\n'
mkdir -p "$inner_dir"
checkcode $?
printf 'Writing placeholder README files...\n'
echo 'put files to verifiably archive in here' > "$inner_dir/README.md"
checkcode $?
echo '# todo: make this nice' > "$out_dir/README.md"
checkcode $?
printf 'Copying verification helpers...\n'
cp test_validate_passphrase.txt "$out_dir/test_validate_passphrase.sh"
checkcode $?
chmod +x "$out_dir/test_validate_passphrase.sh"
checkcode $?
cp verify-everything.txt "$out_dir/verify-everything.sh"
checkcode $?
chmod +x "$out_dir/verify-everything.sh"
checkcode $?
local housekeeping_dirs=(archives keystore)
for dir in "${housekeeping_dirs[@]}"; do
if [[ -d "$dir" ]]; then
printf 'Hardening %s...\n' "$dir"
chmod 700 "$dir"
checkcode $?
find "$dir" -mindepth 1 -type d -exec srm -r -z -l '{}' + >/dev/null 2>&1 || true
find "$dir" -type f \( -name 'private_ed25519_*' -o -name 'attribution_passphrase_*' \) -exec shred -uz '{}' + >/dev/null 2>&1 || true
find "$dir" -type f -exec chmod 600 '{}' +
checkcode $?
fi
done
}
audit_passphrase() {
local raw_password="$1"
local check_password="$2"
if [[ -z "$raw_password" ]]; then
echo '[ERROR] No passphrase provided for validation.' >&2
return 2
fi
if [[ -z "$check_password" ]]; then
echo '[ERROR] No check passphrase provided for validation.' >&2
return 2
fi
if [[ "$raw_password" != "$check_password" ]]; then
echo '[ERROR] Passphrases do not match!' >&2
return 2
fi
unset check_password
local pass_len=${#raw_password}
if [[ "$pass_len" -lt 35 ]]; then
echo "❌ REJECTED: Passphrase is too short ($pass_len characters). Minimum length required is 35."
return 1
fi
echo "[PASS] Length verification satisfied ($pass_len characters)."
if command -v cracklib-check >/dev/null 2>&1; then
if ! printf '%s' "$raw_password" | cracklib-check | grep -q 'OK$'; then
echo '❌ REJECTED by cracklib-check.'
return 1
fi
echo '[PASS] Local dictionary and structural complexity audit clear.'
else
echo '[WARN] cracklib-check not found; skipping local dictionary audit.' >&2
fi
local full_hash prefix suffix response
full_hash=$(printf '%s' "$raw_password" | openssl dgst -sha1 | awk '{print toupper($2)}')
prefix=${full_hash:0:5}
suffix=${full_hash:5}
if ! response=$(curl -fsS -A 'Bash-Passphrase-Audit-Script' "https://api.pwnedpasswords.com/range/$prefix"); then
echo -e "${RED}[FATAL]${RESET} Failed to communicate with HIBP API." >&2
return 3
else
echo -e "connected to hibp...${GREEN}OK${RESET}"
fi
if printf '%s\n' "$response" | grep -qi "^$suffix:"; then
echo -e "${RED}[FATAL]${RESET} Passphrase has been leaked!" >&2
return 1
else
echo -e "not leaked! (via hibp)... ${GREEN}OK${RESET}"
fi
return 0
}
error_handle() {
local exit_code=$?
local script_path
if command -v realpath >/dev/null 2>&1; then
script_path=$(realpath "$0")
else
script_path="$PWD/$0"
fi
local hr='===================================================='
echo
echo "$hr"
echo -e "🚨 ${RED}FATAL ERROR DETECTED${RESET}"
echo "$hr"
echo "-> Script : $0"
echo "-> Num Script Args : $num_of_args"
echo "-> Script Args : $all_args"
echo "-> Shell : ${SHELL:-unknown}"
echo "-> Script Path : $script_path"
echo "-> Script (full) : $SHELL $script_path $all_args"
echo "-> User : ${USER:-unknown}"
echo "-> Working Directory : $PWD"
echo "-> Failed Command : $BASH_COMMAND"
echo "-> Line Number : $LINENO"
echo "-> Exit Status : $exit_code"
echo "-> Seconds Elapsed : $SECONDS"
echo "-> Date Failed : $(date)"
echo '-> Stack Trace'
local frame=0
while caller "$frame"; do
frame=$((frame + 1))
done
echo
echo "$hr"
echo
exit "$exit_code"
}
exit_cleanup() {
printf "cleaning up on exit"
reset > /dev/null 2>&1
checkcode $?
# todo: uset vars
}
trap error_handle ERR
trap exit_cleanup EXIT
audit_passphrase "yw0EKY6wbSxU6KJxWN3vFZDgnSjJ4F8wqFrAJMcDxfU" "yw0EKY6wbSxU6KJxWN3vFZDgnSjJ4F8wqFrAJMcDxfU"
require_dependencies
printf 'Setting up environment...\n'
reset
printf '\n\n'
read -n 1 -s -r -p "In another terminal/window, fill $inner_dir with whatever you please then press any key to continue..."
printf '\n'
printf 'ssh-keygen: creating new key: %s...\n' "$key_path"
ssh-keygen -t ed25519 -f "$key_path" -C 'anonymous' -N '' >/dev/null 2>&1
checkcode $?
printf 'ssh-keygen: fixing permissions on %s and %s...\n' "$key_path" "${key_path}.pub"
chmod 600 "$key_path" "${key_path}.pub"
checkcode $?
printf 'ssh-keygen: creating %s/anonymous_signer...\n' "$out_dir"
echo "anonymous namespaces=\"$signature_tag\" $(cat "${key_path}.pub")" > "$out_dir/anonymous_signer"
checkcode $?
printf 'Inject random data? (y/N): '
read -r random
if [[ -z "$random" || "$random" =~ ^[nN]$ ]]; then
echo -e "No random data added. ${GREEN}OK!${RESET}\n"
else
printf 'random: adding 1/2 random blocks of data (128 bytes) to outer archive...\n'
openssl rand -out "$out_dir/.$RANDOM" 128 >/dev/null 2>&1
checkcode $?
printf 'random: adding 2/2 random blocks of data (128 bytes) to inner archive...\n'
openssl rand -out "$inner_dir/.$RANDOM" 128 >/dev/null 2>&1
checkcode $?
fi
printf '7z: compressing inner volume...\n'
7z a "$out_dir/contents.7z" "$inner_dir" >/dev/null 2>&1
checkcode $?
printf 'Deleting %s...\n' "$inner_dir"
rm -rf "$inner_dir"
checkcode $?
printf 'ssh: signing %s...\n' "$out_dir/contents.7z"
ssh-keygen -Y sign -f "$key_path" -n "$signature_tag" "$out_dir/contents.7z" >/dev/null 2>&1
checkcode $?
printf 'Changing directory to %s...\n' "$out_dir"
cd "$out_dir"
checkcode $?
printf 'sha512: generating checksums...\n'
sha512sum * > checksums.sha512
checkcode $?
printf 'Changing directory back...\n'
cd ..
checkcode $?
printf 'Enter attribution passphrase:\n'
read -r -s attribution_passphrase
printf '\nEnter attribution passphrase again:\n'
read -r -s attribution_passphrase_check
printf '\n'
printf 'Auditing attribution passphrase...\n'
ret=$(audit_passphrase "$attribution_passphrase" "$attribution_passphrase_check")
echo "$ret"
printf 'Unsetting attribution_passphrase_check...\n'
unset attribution_passphrase_check
printf 'Calculating attribution checksum...\n'
{
printf '%s' "$attribution_passphrase"
cat "$out_dir/contents.7z"
} | sha512sum | awk '{print $1}' > "$out_dir/attribution-checksum.sha512"
checkcode $?
printf 'Sanity checking: changing working directory to %s...\n' "$out_dir"
cd "$out_dir"
checkcode $?
printf 'Sanity checking: verification...\n'
bash verify-everything.sh "$attribution_passphrase"
checkcode $?
printf 'Sanity checking: validate attribution passphrase...\n'
bash test_validate_passphrase.sh "$attribution_passphrase"
checkcode $?
printf 'Returning to project root...\n'
cd ..
checkcode $?
printf 'Unsetting attribution_passphrase...\n'
unset attribution_passphrase
printf '7z archiving outer dir...\n'
7z a ./out.7z "$out_dir" >/dev/null 2>&1
checkcode $?
printf 'Moving out.7z to archives...\n'
mv out.7z "archives/verifiable_archive_${unix_seconds}.7z"
checkcode $?
printf 'Enter keystore passphrase:\n'
read -r -s keystore_passphrase
printf '\nEnter keystore passphrase again:\n'
read -r -s keystore_passphrase_check
printf '\n'
printf 'Auditing keystore passphrase...\n'
ret="$(audit_passphrase \"$keystore_passphrase\" \"$keystore_passphrase_check\")"
echo -e "$ret"
printf 'Unsetting keystore_passphrase_check...\n'
unset keystore_passphrase_check
printf 'Archiving keys...\n'
set +u
shopt -s nullglob
private_files=(private_*)
passphrase_files=(attribution_passphrase_*)
shopt -u nullglob
set -u
if [[ ${#private_files[@]} -eq 0 && ${#passphrase_files[@]} -eq 0 ]]; then
echo 'No key or attribution passphrase files found to archive.' >&2
exit 1
fi
7z a "keystore/keystore_${unix_seconds}.7z" "${private_files[@]}" "${passphrase_files[@]}" -p"$keystore_passphrase" -mhe=on >/dev/null 2>&1
checkcode $?
printf 'Testing key archive...\n'
7z t "keystore/keystore_${unix_seconds}.7z" -p"$keystore_passphrase" >/dev/null 2>&1
checkcode $?
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
# packages required: git trufflehog gitsecrets pup
# todo: make dis an arg
github_username='nationalsecurityagency'
github_base='https://github.com/'
github_repos_page="$github_base/$github_username/"
# todo: make dis handle pagination
repos=$(curl -sS "${github_repos_page}?tab=repositories" | grep 'name codeRepository' | pup 'a attr{href}' | sed 's/\/PrincessPi3\///')
out_dir="$PWD/$github_username" #todo: make dis an arg
mkdir -p "$out_dir"
secretsfile="$PWD/secrets_${github_username}.txt"
nuke_repos_dir() {
if [ -d "$out_dir" ]; then
printf "deleting existing $out_dir... "
rm -rf "$out_dir" > /dev/null 2>&1
printf "$?\n"
printf "remaking $out_dir... "
mkdir -p "$out_dir"
printf "$?\n"
fi
}
clone_repos() {
for repo in "${repos[@]}"; do
printf "cloning $repo into $out_dir/$repo..."
git clone --recursive "$github_repos_page/$repo" "$out_dir/$repo" > /dev/null 2>&1
printf "$?\n"
done
}
snoop_repos() {
for repo in "${repos[@]}"; do
cd "$out_dir/$repo"
pwd | tee -a "$secretsfile"
trufflehog git file://. | tee -a "$secretsfile"
gitleaks detect -v | tee -a "$secretsfile"
cd -
done
}
# run em ig
nuke_repos_dir
clone_repos
snoop_repos
-2
View File
@@ -1,2 +0,0 @@
# Keystore
where encrypted archives of previous keys and attibriution passphrases are stored
View File
-1
View File
@@ -1 +0,0 @@
# todo: make this nice
-1
View File
@@ -1 +0,0 @@
put files to verifiably archive in here
-19
View File
@@ -1,19 +0,0 @@
#!/bin/bash
set -e
attrib_hash=$(cat "./attribution-checksum.sha512")
if [ -z "$1" ]; then
echo "enter passphrase to test"
read passphrase
echo
else
passphrase="$1"
fi
tested_hash=$( ( echo -n "$passphrase"; cat "./contents.7z" ) | sha512sum | awk '{print $1}')
if [[ "$attrib_hash" == "$tested_hash" ]]; then
echo -e "Attribution With Password $passphrase: \033[0;32mOK!\033[0m"
else
echo -e "Attribution With Password $passphrase: \033[0;31mFAIL!\033[0m"
fi
-29
View File
@@ -1,29 +0,0 @@
#!/bin/bash
set -e
checkcode () {
if [ -z "$1" ]; then
echo -e "\n\e[31mERROR!\033[0m chkcode missing return code paramater\n"
exit 1
else
retcode=$1
fi
if [ $retcode -ne 0 ]; then
echo -e "\t\e[31mERROR!\033[0m Response Code: $retcode"
else
printf '\e[1;32mOK!\e[0m\n'
fi
}
printf "Testing contents.7z integrity... "
7z t contents.7z > /dev/null 2>&1
checkcode $?
printf "Checking sha512 checksums... "
sha512sum -c checksums.sha512 > /dev/null 2>&1
checkcode $?
printf "Checking signature against provided public key... "
ssh-keygen -Y verify -f "./anonymous_signer" -I "anonymous" -n "file-integrity" -s contents.7z.sig < contents.7z > /dev/null > /dev/null > /dev/null 2>&1
checkcode $?
Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

-19
View File
@@ -1,19 +0,0 @@
#!/bin/bash
set -e
attrib_hash=$(cat "./attribution-checksum.sha512")
if [ -z "$1" ]; then
echo "enter passphrase to test"
read passphrase
echo
else
passphrase="$1"
fi
tested_hash=$( ( echo -n "$passphrase"; cat "./contents.7z" ) | sha512sum | awk '{print $1}')
if [[ "$attrib_hash" == "$tested_hash" ]]; then
echo -e "Attribution With Password $passphrase: \033[0;32mOK!\033[0m"
else
echo -e "Attribution With Password $passphrase: \033[0;31mFAIL!\033[0m"
fi
-29
View File
@@ -1,29 +0,0 @@
#!/bin/bash
set -e
checkcode () {
if [ -z "$1" ]; then
echo -e "\n\e[31mERROR!\033[0m chkcode missing return code paramater\n"
exit 1
else
retcode=$1
fi
if [ $retcode -ne 0 ]; then
echo -e "\t\e[31mERROR!\033[0m Response Code: $retcode"
else
printf '\e[1;32mOK!\e[0m\n'
fi
}
printf "Testing contents.7z integrity... "
7z t contents.7z > /dev/null 2>&1
checkcode $?
printf "Checking sha512 checksums... "
sha512sum -c checksums.sha512 > /dev/null 2>&1
checkcode $?
printf "Checking signature against provided public key... "
ssh-keygen -Y verify -f "./anonymous_signer" -I "anonymous" -n "file-integrity" -s contents.7z.sig < contents.7z > /dev/null > /dev/null > /dev/null 2>&1
checkcode $?