/ markdown / scripts.md
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