Skip to content

Commit

Permalink
logic to choose and combine different methods implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
r3nt0n committed Jul 5, 2020
1 parent 96ed7e5 commit 927aa90
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 125 deletions.
38 changes: 29 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
![[Version 0.6~beta](https://github.com/R3nt0n)](http://img.shields.io/badge/version-v0.6~beta-orange.svg)
![[Version 1.0](https://github.com/R3nt0n)](http://img.shields.io/badge/version-v1.0-orange.svg)
![[Python 3.2+](https://github.com/R3nt0n)](http://img.shields.io/badge/python-3.2+-blue.svg)
![[GPL-3.0 License](https://github.com/R3nt0n)](https://img.shields.io/badge/license-GPL%203.0-brightgreen.svg)

<p align="center"><img src="https://github.com/R3nt0n/wiper/blob/master/img/wiper-0.9.gif" /></p>

# wiper
Toolkit to perform secure destruction of sensitive virtual data, temporary files and swap memories.
Toolkit to perform **secure destruction of sensitive virtual data, temporary files and swap memories**.

It has been **designed to make tasks about personal data destruction easier**, for example those which remain on work computers **when employees leave the company**.

You can configure your own overwrite method, choosing and combining between **ones, zeros and/or random data methods** as many times as you want (e.g.: or, rzzrozr, roozr...). By default, it performs a single one-pass with random data.

It has been **designed to make tasks about personal data destruction easier**, those which remain on work computers **when employees leave the company**.

## Usage
```
Expand All @@ -18,18 +19,35 @@ optional arguments:
-i, --interactive interactive mode, the script will guide you
-f path, --free path wipe all free space on given path
-p path, --path path path to dir/file you want to wipe
-m ozr, --method ozr overwrite methods to apply (o: ones, z: zeros, r: random),
you can combine it and choose the order
-r path, --root path set a custom root path if you want to wipe with auto-search modes
an unbooted system (e.g. /media/drive)
-t, --temp auto-search mode: locate actual user temp directory and wipes it
-u, --home auto-search mode: locate actual user home directory and wipes it
-T, --temp-all auto-search mode: locate all users temp directory and wipes it
-U, --home-all auto-search mode: locate all users home directory and wipes it
-s, --swaps auto-search mode: locate swap partitions/pagefiles and wipes it
(be careful: UUID swap partitions also will be wiped)
```

### Interactive example

<p align="center"><img src="https://github.com/R3nt0n/wiper/blob/master/img/wiper-1.0-interactive.gif" /></p>

### CLI example

<p align="center"><img src="https://github.com/R3nt0n/wiper/blob/master/img/wiper-1.0-cli.gif" /></p>

### Advanced examples
+ Wipes all free space in a given partition:
`wiper.py -f /home`
+ Wipes all files inside a given path using zeros, ones, zeros, zeros and random methods:
`wiper.py -p /home/user/Documents -m zozzr`
+ Locate and wipe pagination files inside an unbooted OS (mounted on `/home/media/`) using only zeros method:
`wiper.py -r /home/media -s -m z`

## Features
+ You can **configure your own overwrite method**, choosing and combining between **ones, zeros and/or random data methods** as many times as you want (e.g.: or, rzzrozr, roozr...). By default, it performs a single one-pass with random data.
+ **MANUAL wipe selection**. You can wipe single files, whole directories and free space in partitions.
+ **AUTO wipe selection**. Suggests an automatic selection of paths to wipe, relatives to personal/temporary data and swap memories.
**If you run it with the OS target unmounted**, e.g. from a live OS trying to wipe an
Expand All @@ -48,6 +66,9 @@ unmounted hard drive containing another OS, you should provide the root path/mou
+ wmi (if you want to use auto-search mode booted on a Windows OS)

## Changelist
##### 1.0 version notes (05/07/2020)
+ Logic to choose, combine and apply diferent methods implemented.
+ Temp and temp-all features removed because it doesn't seem useful.
##### 0.9~beta version notes (29/06/2020)
+ One-pass overwrite methods already implemented: random, ones and zeros.
+ Fixing menu bug and updating usage.
Expand All @@ -61,8 +82,7 @@ unmounted hard drive containing another OS, you should provide the root path/mou


## TODO list
+ Implement temp, home_all and temp_all features.
+ Write the logic to switch between different overwrite methods already implemented (ones, zeros and random) and allow user to combines it.
+ Implement home-all feature.


## Legal disclaimer
Expand Down
Binary file removed img/wiper-0.9.gif
Binary file not shown.
Binary file added img/wiper-1.0-cli.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/wiper-1.0-interactive.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
146 changes: 81 additions & 65 deletions r3ntlib/wiper_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,37 @@
from r3ntlib.os_ops import run_command
from r3ntlib.color import color


def progressBar(iterable, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r"):
"""
Found in: https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
"""
total = len(iterable)
# Progress Bar Printing Function
def printProgressBar (iteration):
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print(f'\r{prefix} |{bar}| {percent}% {suffix}', end=printEnd)
# Initial Call
printProgressBar(0)
# Update Progress Bar
for i, item in enumerate(iterable):
yield item
printProgressBar(i + 1)
# Print New Line on Complete
print()

################################################################################

def wipe_bytes(path, mode, size_to_write, method='r'):
Expand All @@ -33,40 +64,41 @@ def wipe_bytes(path, mode, size_to_write, method='r'):
size-to-write -- size in bytes to overwrite
methods -- if tuple contains: r -> random, z -> zeros, o -> ones
"""
status = 0
status = 1
try:
print(u' {}[+]{} Overwriting {}{}{} ({}{}{} bytes)'.format(color.ORANGE,color.END,
color.ORANGE, path, color.END,
color.PURPLE, size_to_write, color.END))
print(u' {}[+]{} Starting one-pass random wipe...'.format(color.ORANGE, color.END))
pointer = 0
if method == 'z':
overwritebyte = b'\x00'
elif method == 'o':
overwritebyte = b'\xff'
with open(path, mode) as dummy_file:
while size_to_write > 0:
if method == 'r':
overwritebyte = bytearray(getrandbits(8) for _ in range(1))
dummy_file.write(overwritebyte)
size_to_write -= 1
if mode == 'wb':
pointer += 1
dummy_file.seek(pointer)
print('{} [+]{} {}{}{} was randomly overwritten'.format(color.PURPLE, color.END,
color.ORANGE, path, color.END))
try:
if os.path.isfile(path):
os.remove(path)
print(' {}[-]{} {}{}{} was {}succesfully{} wiped'.format(color.GREEN, color.END,
for m in method:
if m == 'z':
print(u' {}[-]{} Starting one-pass zeros wipe...'.format(color.ORANGE, color.END))
overwritebyte = b'\x00'
elif m == 'o':
print(u' {}[-]{} Starting one-pass ones wipe...'.format(color.ORANGE, color.END))
overwritebyte = b'\xff'
else:
print(u' {}[-]{} Starting one-pass random wipe...'.format(color.ORANGE, color.END))

pointer = 0
with open(path, mode) as dummy_file:
#while size_to_write > 0:
for j in progressBar(range(1,size_to_write), prefix='Progress:', suffix='Complete', length=50):
if m == 'r':
overwritebyte = bytearray(getrandbits(8) for _ in range(1))
dummy_file.write(overwritebyte)
#size_to_write -= 1
if mode == 'wb':
pointer += 1
dummy_file.seek(pointer)
status = 0
print('\r\n {}[-]{} {}{}{} was {}succesfully{} wiped'.format(color.GREEN, color.END,
color.ORANGE, path, color.END,
color.GREEN, color.END))
except Exception as exception:
status = 2
print('{} [!]{} ERROR: {}'.format(color.RED, color.END, exception))
except Exception as exception:
status = 2
print('{} [!]{} ERROR: {}'.format(color.RED,color.END,exception))

finally:
if (os.path.isfile(path) and status == 0):
os.remove(path)

return status

def dd_linux_wipe(linux_path, method='r'):
Expand All @@ -78,20 +110,24 @@ def dd_linux_wipe(linux_path, method='r'):
status = 6
if os.name == 'posix':
try:
bs = '1024'
if method == 'r':
src = '/dev/zero'
elif method == 'z':
src = "<(yes $'\\ff' | tr -d \"\\n\")"
else:
src = '/dev/urandom'
bs = '4096'
bytes_to_write = disk_usage(linux_path)[2]
print(' {}[+]{} Starting to wipe {}{}{} ({}{}{} bytes) with dd tool...\r\n'.format(color.ORANGE, color.END,
color.ORANGE,linux_path,color.END,
color.PURPLE,bytes_to_write,color.END))
command = 'dd if={} of={} bs={} status=progress'.format(src,linux_path,bs)
status = run_command(command)
for m in method:
bs = '1024'
if m == 'z':
src = '/dev/zero'
print(u' {}[-]{} Starting one-pass zeros wipe...'.format(color.ORANGE, color.END))
elif m == 'o':
src = "<(yes $'\\ff' | tr -d \"\\n\")"
print(u' {}[-]{} Starting one-pass ones wipe...'.format(color.ORANGE, color.END))
else:
src = '/dev/urandom'
bs = '4096'
print(u' {}[-]{} Starting one-pass random wipe...'.format(color.ORANGE, color.END))
bytes_to_write = disk_usage(linux_path)[2]
print(' {}[+]{} Starting to wipe {}{}{} ({}{}{} bytes) with dd tool...\r\n'.format(color.ORANGE, color.END,
color.ORANGE,linux_path,color.END,
color.PURPLE,bytes_to_write,color.END))
command = 'dd if={} of={} bs={} status=progress'.format(src,linux_path,bs)
status = run_command(command)
except Exception as exception:
status = 4
print('{} [!]{} ERROR: {}'.format(color.RED, color.END, exception))
Expand All @@ -101,37 +137,17 @@ def dd_linux_wipe(linux_path, method='r'):

################################################################################

def wipe_free_space(path):
def wipe_free_space(path, method):
"""Fill free space disk with random bytes and secure delete the file
previously created.
Returns a status code:
0 - OK, 1-Space wasn't even filled randomly, 2-Space wasn't secure delete
Arguments:
path -- root directory where it begins to search.
"""
tempfile = os.path.join(path,'00000001')
tempfile = os.path.join(path,'00000000.dummyfile')
try:
free_space = disk_usage(path)[2]
wipe_bytes(tempfile, 'ab+', free_space)
wipe_bytes(tempfile, 'ab+', free_space, method)
except Exception as exception:
print('{} [!]{} ERROR: {}'.format(color.RED, color.END, exception))
finally:
# Makes sure to clean-up tempfile
try: os.remove(tempfile)
except: pass

def wipe_file(path):
"""Wipe a single file
Returns True or False regarding if it was succesfuly deleted or not.
Arguments:
path -- path to file
"""
try:
bytesize_to_write = os.stat(path).st_size
wipe_bytes(path, 'wb', bytesize_to_write)
status = True
except Exception as exception:
print('{} [!]{} ERROR: {}'.format(color.RED, color.END, exception))
status = False
return status

Loading

0 comments on commit 927aa90

Please sign in to comment.