scripts.md
1 # Collection of scripts 2 3 [main guide](../README.md) 4 5 ### Nuke 6 7 Will let you try to scrub and sanatize nvme, ssd, hdd; 8 9 > [!WARNING] 10 > it may brick your device. 11 12 13 ``` 14 #!/bin/bash 15 16 # Check if the script is run as root 17 if [[ $EUID -ne 0 ]]; then 18 echo "This script must be run as root. Please use sudo or run as root." 19 exit 1 20 fi 21 22 # Function to install packages based on the distribution 23 install_packages() { 24 local packages=("$@") 25 if command -v apt-get &> /dev/null; then 26 echo "Detected Debian/Ubuntu-based system." 27 apt-get update 28 apt-get install -y "${packages[@]}" 29 elif command -v yum &> /dev/null; then 30 echo "Detected Red Hat/CentOS-based system." 31 yum install -y "${packages[@]}" 32 elif command -v dnf &> /dev/null; then 33 echo "Detected Fedora-based system." 34 dnf install -y "${packages[@]}" 35 elif command -v pacman &> /dev/null; then 36 echo "Detected Arch Linux-based system." 37 pacman -S --noconfirm "${packages[@]}" 38 else 39 echo "Unsupported distribution. Please install the following packages manually: ${packages[*]}" 40 exit 1 41 fi 42 } 43 44 # Check if whiptail or libnewt is installed, install if missing 45 if ! command -v whiptail &> /dev/null && ! pacman -Qi libnewt &> /dev/null; then 46 echo "whiptail or libnewt is not installed. Installing..." 47 if command -v pacman &> /dev/null; then 48 install_packages libnewt 49 else 50 install_packages whiptail 51 fi 52 fi 53 54 # Check if hdparm is installed, install if missing 55 if ! command -v hdparm &> /dev/null; then 56 echo "hdparm is not installed. Installing..." 57 install_packages hdparm 58 fi 59 60 # Check if badblocks is installed, install if missing 61 if ! command -v badblocks &> /dev/null; then 62 echo "badblocks is not installed. Installing..." 63 install_packages e2fsprogs 64 fi 65 66 # Check if nvme-cli is installed, install if missing 67 if ! command -v nvme &> /dev/null; then 68 echo "nvme-cli is not installed. Installing..." 69 install_packages nvme-cli 70 fi 71 72 # Check if parted is installed, install if missing 73 if ! command -v parted &> /dev/null; then 74 echo "parted is not installed. Installing..." 75 install_packages parted 76 fi 77 78 # Display warning message 79 whiptail --title "WARNING" --msgbox "Tactical Nuke Incoming!!!\n\nThis script will securely wipe the devices you specify. All data on selected devices will be permanently erased. Proceed with caution!" 15 60 80 81 # List available block devices 82 devices=$(lsblk -d -o NAME,MODEL,SIZE,TYPE | awk 'NR>1 {print $1, $2, $3, $4}') 83 device_list=() 84 while IFS= read -r line; do 85 device_name=$(echo "$line" | awk '{print $1}') 86 device_info=$(echo "$line" | awk '{print $2, $3, $4}') 87 device_list+=("$device_name" "$device_info" OFF) 88 done <<< "$devices" 89 90 # Prompt user to select devices 91 selected_devices=$(whiptail --title "Select Devices" --checklist "Choose devices to wipe:" 20 60 10 "${device_list[@]}" 3>&1 1>&2 2>&3) 92 if [[ -z "$selected_devices" ]]; then 93 whiptail --title "Error" --msgbox "No devices selected. Exiting." 10 60 94 exit 1 95 fi 96 97 # Convert selected devices into an array 98 IFS=' ' read -r -a device_queue <<< "$(echo "$selected_devices" | sed 's/"//g')" 99 100 # Select HDD wipe method 101 wipe_method=$(whiptail --title "Select Wipe Method" --default-item "3" --menu "Choose a wiping method for HDDs:" 15 60 4 \ 102 "1" "Zero Fill (write zeros to the entire disk)" \ 103 "2" "Random Fill (write random data to the entire disk)" \ 104 "3" "DoD 5220.22-M (3-pass overwrite: zeros, ones, random)" \ 105 "4" "ATA Secure Erase (if supported)" 3>&1 1>&2 2>&3) 106 if [[ -z "$wipe_method" ]]; then 107 whiptail --title "Error" --msgbox "No wipe method selected. Exiting." 10 60 108 exit 1 109 fi 110 111 # Warn about ATA Secure Erase risks and default to DoD method if not explicitly chosen 112 if [[ "$wipe_method" == "4" ]]; then 113 whiptail --title "WARNING" --msgbox "ATA Secure Erase may brick your drive if it is not connected to a SATA port or if the drive does not support it. Proceed with caution!" 10 60 114 else 115 # Default to DoD 5220.22-M if no method is explicitly chosen 116 wipe_method="3" 117 fi 118 119 # Ask if the user wants to verify the wipe 120 verify_wipe=$(whiptail --title "Verify Wipe" --yesno "Do you want to verify the wipe after completion? This will check if all sectors have been properly overwritten." 10 60 3>&1 1>&2 2>&3) 121 verify_wipe=$? 122 123 # Confirm wipe 124 whiptail --title "Confirmation" --yesno "You have selected the following devices for wiping:\n\n${device_queue[*]}\n\nProceed with wiping? This action is irreversible." 15 60 125 if [[ $? -ne 0 ]]; then 126 whiptail --title "Aborted" --msgbox "Operation aborted." 10 60 127 exit 1 128 fi 129 130 # Function to wipe a device 131 wipe_device() { 132 local device=$1 133 local log_file="/tmp/wipe_${device##*/}.log" 134 echo "Processing $device..." > "$log_file" 135 136 # Clear partition table before wiping 137 echo "Clearing partition table on $device..." >> "$log_file" 138 parted --script "$device" mklabel gpt >> "$log_file" 2>&1 139 if [[ $? -ne 0 ]]; then 140 echo "Failed to clear partition table on $device. Aborting wipe for this device." >> "$log_file" 141 return 142 fi 143 144 if lsblk -d "$device" | grep -q nvme; then 145 echo "Detected NVMe device: $device" >> "$log_file" 146 echo "Attempting NVMe cryptographic erase..." >> "$log_file" 147 if nvme sanitize "$device" --sanact=4 --verbose >> "$log_file" 2>&1; then 148 echo "NVMe cryptographic erase completed for $device." >> "$log_file" 149 else 150 echo "NVMe sanitize failed. Falling back to NVMe Format." >> "$log_file" 151 if nvme format "$device" --ses=1 >> "$log_file" 2>&1; then 152 echo "NVMe format completed for $device." >> "$log_file" 153 else 154 echo "NVMe format also failed. Skipping $device." >> "$log_file" 155 return 156 fi 157 fi 158 159 elif hdparm -I "$device" | grep -q "Solid State Device"; then 160 echo "Detected SSD device: $device" >> "$log_file" 161 echo "Attempting secure erase using hdparm..." >> "$log_file" 162 163 # Attempt hdparm secure erase 164 hdparm_output=$(hdparm --user-master u --security-set-pass p "$device" 2>&1) 165 if echo "$hdparm_output" | grep -q "SG_IO: bad/missing sense data"; then 166 echo "Error: $hdparm_output" >> "$log_file" 167 echo "hdparm failed due to SG_IO error. Falling back to 3-pass zero fill." >> "$log_file" 168 169 # Ask if the user wants to perform zero and random fill for SSDs that do not support ATA Secure Erase 170 if whiptail --title "Additional Wipe" --yesno "Do you want to perform a zero fill and random fill for this SSD (since ATA Secure Erase is not supported)?" 10 60 3>&1 1>&2 2>&3; then 171 echo "Performing Zero Fill..." >> "$log_file" 172 dd if=/dev/zero of="$device" bs=1M status=none >> "$log_file" 2>&1 173 sync 174 if [[ $? -ne 0 ]]; then 175 echo "Zero-fill failed on $device. Aborting wipe for this device." >> "$log_file" 176 return 177 fi 178 echo "Zero Fill completed." >> "$log_file" 179 180 echo "Performing Random Fill..." >> "$log_file" 181 dd if=/dev/urandom of="$device" bs=1M status=none >> "$log_file" 2>&1 182 sync 183 if [[ $? -ne 0 ]]; then 184 echo "Random fill failed on $device. Aborting wipe for this device." >> "$log_file" 185 return 186 fi 187 echo "Random Fill completed." >> "$log_file" 188 else 189 echo "Skipping zero and random fill for this SSD." >> "$log_file" 190 fi 191 else 192 hdparm --user-master u --security-erase p "$device" >> "$log_file" 2>&1 193 if [[ $? -eq 0 ]]; then 194 echo "Secure erase completed for SSD $device." >> "$log_file" 195 else 196 echo "hdparm secure erase failed for SSD $device. Falling back to 3-pass zero fill." >> "$log_file" 197 fi 198 fi 199 200 # Fallback: Zero fill the SSD three times if hdparm fails 201 for i in {1..3}; do 202 echo "Zero-fill pass $i for $device..." >> "$log_file" 203 dd if=/dev/zero of="$device" bs=1M status=none >> "$log_file" 2>&1 204 sync 205 if [[ $? -ne 0 ]]; then 206 echo "Zero-fill failed on $device. Aborting wipe for this device." >> "$log_file" 207 break 208 fi 209 echo "Pass $i completed." >> "$log_file" 210 done 211 return 212 213 else 214 echo "Detected HDD: $device" >> "$log_file" 215 echo "Wiping HDD using method $wipe_method..." >> "$log_file" 216 217 case $wipe_method in 218 1) # Zero Fill 219 echo "Writing zeros to $device..." >> "$log_file" 220 dd if=/dev/zero of="$device" bs=1M status=none >> "$log_file" 2>&1 221 sync 222 if [[ $? -ne 0 ]]; then 223 echo "Zero-fill failed on $device. Aborting wipe for this device." >> "$log_file" 224 return 225 fi 226 ;; 227 2) # Random Fill 228 echo "Writing random data to $device..." >> "$log_file" 229 dd if=/dev/urandom of="$device" bs=1M status=none >> "$log_file" 2>&1 230 sync 231 if [[ $? -ne 0 ]]; then 232 echo "Random fill failed on $device. Aborting wipe for this device." >> "$log_file" 233 return 234 fi 235 ;; 236 3) # DoD 5220.22-M 237 echo "Performing DoD 3-pass overwrite on $device..." >> "$log_file" 238 echo "Pass 1: Writing zeros..." >> "$log_file" 239 dd if=/dev/zero of="$device" bs=1M status=none >> "$log_file" 2>&1 240 sync 241 if [[ $? -ne 0 ]]; then 242 echo "Zero pass failed on $device. Aborting wipe for this device." >> "$log_file" 243 return 244 fi 245 echo "Pass 2: Writing ones..." >> "$log_file" 246 yes | tr '\0' '\377' | dd of="$device" bs=1M status=none >> "$log_file" 2>&1 247 sync 248 if [[ $? -ne 0 ]]; then 249 echo "One pass failed on $device. Aborting wipe for this device." >> "$log_file" 250 return 251 fi 252 echo "Pass 3: Writing random data..." >> "$log_file" 253 dd if=/dev/urandom of="$device" bs=1M status=none >> "$log_file" 2>&1 254 sync 255 if [[ $? -ne 0 ]]; then 256 echo "Random pass failed on $device. Aborting wipe for this device." >> "$log_file" 257 return 258 fi 259 ;; 260 4) # ATA Secure Erase 261 echo "Attempting ATA Secure Erase on $device..." >> "$log_file" 262 hdparm --user-master u --security-set-pass p "$device" >> "$log_file" 2>&1 263 hdparm --user-master u --security-erase p "$device" >> "$log_file" 2>&1 264 if [[ $? -ne 0 ]]; then 265 echo "ATA Secure Erase failed on $device. Falling back to DoD 5220.22-M." >> "$log_file" 266 wipe_method=3 267 return 268 else 269 echo "ATA Secure Erase completed successfully." >> "$log_file" 270 fi 271 ;; 272 esac 273 274 # Clear partition table and disk identifier 275 echo "Clearing partition table and disk identifier on $device..." >> "$log_file" 276 dd if=/dev/zero of="$device" bs=512 count=34 status=none >> "$log_file" 2>&1 277 sync 278 if [[ $? -ne 0 ]]; then 279 echo "Failed to clear partition table and disk identifier on $device. Aborting wipe for this device." >> "$log_file" 280 return 281 fi 282 echo "Partition table and disk identifier cleared." >> "$log_file" 283 fi 284 285 echo "Wipe complete for $device." >> "$log_file" 286 } 287 288 # Wipe devices concurrently 289 for device in "${device_queue[@]}"; do 290 device="/dev/$device" 291 wipe_device "$device" & 292 done 293 294 # Wait for all background processes to finish 295 wait 296 297 # Print partition tables for all selected devices 298 echo "Printing partition tables for all selected devices..." 299 for device in "${device_queue[@]}"; do 300 device="/dev/$device" 301 echo "Partition table for $device:" 302 fdisk -l "$device" 303 echo "----------------------------------------" 304 done 305 306 # Ask if the user wants to check the logs 307 if whiptail --title "Check Logs" --yesno "Do you want to check the logs for the wipe operations? The logs are located in /tmp." 10 60; then 308 for device in "${device_queue[@]}"; do 309 device="/dev/$device" 310 log_file="/tmp/wipe_${device##*/}.log" 311 if [[ -f "$log_file" ]]; then 312 whiptail --title "Log for $device" --textbox "$log_file" 20 80 313 else 314 whiptail --title "Error" --msgbox "Log file for $device not found in /tmp." 10 60 315 fi 316 done 317 fi 318 319 whiptail --title "Complete" --msgbox "All requested devices have been wiped." 10 60 320 ``` 321 322 ### Features 323 324 - Zero Fill will zero in data 325 - Random Fill will randomzie data 326 - [DoD 5220.22-M ](https://en.wikipedia.org/wiki/National_Industrial_Security_Program#Data_sanitization)is the standard for clearing drives. 327 - [guttman method](https://en.wikipedia.org/wiki/Gutmann_method#Method) wouldn't want to use this [believe me](https://www.killdisk.com/blog-gutmann-method.htm) 328 329 Edit(s): 330 331 For SSD's you may have to fill it up with randomized data or zeros. 332 333 Got rid of guttman as that's useless leaving you with 3 methods. 334 335 Left a less secure option for SSD erase if hdparam doesn't work. 336 337 Got the less secure option to work, will wipe 3 times; be aware of wear leveling for SSD's. 338 339 Added in whiptail support for easier selection. 340 341 Added in verification of the wipe for sectors on HDD's Also added in secure erase with ATA and a final erase and clearing of partitions so now you have 4 options. 342 343 Added in an option to check to see if badblocks, whiptail and hdparm is installed, if not it will install it for the user. 344 Also added in to see if nvme-cli is installed and to install it. 345 346 Made it to where it can wipe all devices at once; also to confirm a verify. 347 348 Added in logs for /tmp/wipe_$device.log 349 350 Fixed the menu screen from being broken with secure ata erase. 351 352 Will show you the logs after the wipe if you requested it. 353 354 Made DoD a default selection, also made the script warn the user about secure ata erase potentially bricking the selected hard drive. 355 356 # mouse-r 357 358 * record and playback mouse movement; useful for veracrypt. 359 360 --- 361 362 Python3 -m venv venv 363 364 Source venv/bin/activate 365 366 pip install pyautogui numpy matplotlib scipy pynput 367 368 --- 369 370 ``` 371 import time 372 import json 373 import numpy as np 374 import pyautogui 375 from scipy.interpolate import make_interp_spline 376 from pynput import mouse 377 378 class UltraFastMouseRecorder: 379 def __init__(self): 380 self.recorded_data = [] 381 self.is_recording = False 382 self.listener = None 383 self.screen_width, self.screen_height = pyautogui.size() 384 385 def start_recording(self): 386 """Start recording mouse movements with high precision""" 387 self.recorded_data = [] 388 self.is_recording = True 389 print("Recording started... Press middle mouse button to stop.") 390 391 def on_move(x, y): 392 if self.is_recording: 393 self.recorded_data.append({ 394 'x': x, 395 'y': y, 396 'time': time.perf_counter() # Highest precision timer 397 }) 398 399 def on_click(x, y, button, pressed): 400 if button == mouse.Button.middle and pressed: 401 self.stop_recording() 402 return False 403 404 self.listener = mouse.Listener( 405 on_move=on_move, 406 on_click=on_click 407 ) 408 self.listener.start() 409 410 def stop_recording(self): 411 """Stop recording mouse movements""" 412 self.is_recording = False 413 if self.listener: 414 self.listener.stop() 415 print(f"Recording stopped. Captured {len(self.recorded_data)} points.") 416 417 def save_to_file(self, filename): 418 """Save recorded data to a JSON file""" 419 with open(filename, 'w') as f: 420 json.dump(self.recorded_data, f) 421 print(f"Data saved to {filename}") 422 423 def load_from_file(self, filename): 424 """Load recorded data from a JSON file""" 425 with open(filename, 'r') as f: 426 self.recorded_data = json.load(f) 427 print(f"Loaded {len(self.recorded_data)} points from {filename}") 428 return self.recorded_data 429 430 def optimize_playback_data(self, speed_factor=10.0): 431 """Pre-process data for ultra-fast playback""" 432 if len(self.recorded_data) < 2: 433 return self.recorded_data 434 435 # Convert to numpy arrays for faster processing 436 x = np.array([p['x'] for p in self.recorded_data]) 437 y = np.array([p['y'] for p in self.recorded_data]) 438 t = np.array([p['time'] for p in self.recorded_data]) 439 440 # Calculate time differences and apply speed factor 441 t_diff = np.diff(t) 442 t_diff = t_diff / speed_factor 443 444 # Create optimized data structure 445 optimized_data = [] 446 for i in range(len(x)): 447 optimized_data.append({ 448 'x': x[i], 449 'y': y[i], 450 'time_diff': t_diff[i-1] if i > 0 else 0 451 }) 452 453 return optimized_data 454 455 def ultra_fast_playback(self, speed_factor=10.0, relative=False, loop_count=1, loop_delay=0.0): 456 """Extremely fast playback implementation with looping support""" 457 if not self.recorded_data: 458 print("No data to play back") 459 return 460 461 if loop_count <= 0: 462 print("Invalid loop count. Must be 1 or greater.") 463 return 464 465 print(f"Ultra-fast playback at {speed_factor}x speed for {loop_count} loop(s)...") 466 if loop_count > 1: 467 print(f"Loop delay: {loop_delay}s between iterations") 468 469 # Pre-process data for optimal playback 470 playback_data = self.optimize_playback_data(speed_factor) 471 472 for loop_iteration in range(loop_count): 473 if loop_count > 1: 474 print(f"Starting loop {loop_iteration + 1}/{loop_count}") 475 476 # Move to starting position immediately with no delay 477 first_point = playback_data[0] 478 pyautogui.moveTo(first_point['x'], first_point['y'], _pause=False) 479 480 # Use the most performant loop structure 481 start_time = time.perf_counter() 482 483 for i in range(1, len(playback_data)): 484 point = playback_data[i] 485 486 # Calculate target time using pre-computed time differences 487 target_time = start_time + point['time_diff'] 488 489 # Busy-wait for maximum precision (remove sleep completely) 490 while time.perf_counter() < target_time: 491 pass 492 493 # Move mouse with absolute minimum overhead 494 if relative: 495 current_x, current_y = pyautogui.position() 496 dx = point['x'] - current_x 497 dy = point['y'] - current_y 498 pyautogui.move(dx, dy, _pause=False) 499 else: 500 pyautogui.moveTo(point['x'], point['y'], _pause=False) 501 502 # Add delay between loops if specified and not the last iteration 503 if loop_delay > 0 and loop_iteration < loop_count - 1: 504 time.sleep(loop_delay) 505 506 print(f"Playback complete. Average speed: {self.calculate_average_speed(playback_data):.6f}s per point") 507 508 def calculate_average_speed(self, playback_data): 509 """Calculate average time between points""" 510 if len(playback_data) < 2: 511 return 0 512 total_time = sum(p['time_diff'] for p in playback_data[1:]) 513 return total_time / (len(playback_data) - 1) 514 515 # Example usage 516 if __name__ == "__main__": 517 recorder = UltraFastMouseRecorder() 518 519 print("1. Record new movements") 520 print("2. Load from file") 521 print("3. Ultra-fast playback") 522 print("4. Ultra-fast playback with looping") 523 print("5. Save to file") 524 print("6. Exit") 525 526 while True: 527 choice = input("Select an option (1-6): ") 528 529 if choice == '1': 530 recorder.start_recording() 531 while recorder.is_recording: 532 time.sleep(0.1) 533 elif choice == '2': 534 filename = input("Enter filename to load: ") 535 recorder.load_from_file(filename) 536 elif choice == '3': 537 speed_input = input("Enter speed factor (e.g., 10 for 10x speed) [default: 1]: ").strip() 538 speed_factor = float(speed_input) if speed_input else 1.0 539 relative = input("Use relative movements? (y/n): ").lower() == 'y' 540 recorder.ultra_fast_playback(speed_factor=speed_factor, relative=relative) 541 elif choice == '4': 542 speed_input = input("Enter speed factor (e.g., 10 for 10x speed) [default: 1]: ").strip() 543 speed_factor = float(speed_input) if speed_input else 1.0 544 relative = input("Use relative movements? (y/n): ").lower() == 'y' 545 loop_input = input("Enter number of loops (1 for single playback) [default: 1]: ").strip() 546 loop_count = int(loop_input) if loop_input else 1 547 loop_delay = 0.0 548 if loop_count > 1: 549 delay_input = input("Enter delay between loops in seconds [default: 0]: ").strip() 550 loop_delay = float(delay_input) if delay_input else 0.0 551 recorder.ultra_fast_playback(speed_factor=speed_factor, relative=relative, 552 loop_count=loop_count, loop_delay=loop_delay) 553 elif choice == '5': 554 filename = input("Enter filename to save: ") 555 recorder.save_to_file(filename) 556 elif choice == '6': 557 break 558 ``` 559 560 561 ## Sort CSV for blackbird and edit with libre-office calc 562 563 #!/bin/bash 564 565 # Use this to sort generated CSV files from blackbird and edit as txt or use libreoffice calc. 566 567 # Set your target directory 568 TARGET_DIR="results" 569 OUTPUT_FILE="output.csv" 570 571 # Write header 572 echo "name,url" > "$OUTPUT_FILE" 573 574 # Process each CSV file 575 find "$TARGET_DIR" -name "*.csv" -type f | while read csvfile; do 576 echo "Processing: $csvfile" 577 # Skip header and extract first two columns 578 tail -n +2 "$csvfile" | cut -d, -f1,2 >> "$OUTPUT_FILE" 579 done 580 581 echo "Results saved to $OUTPUT_FILE" 582 583 584 # podman stuff for archivebox 585 586 podman exec -it --user archivebox <container_id_or_name> \ 587 /bin/bash -c "archivebox manage createsuperuser" 588