wagglewunguswoo

This commit is contained in:
2024-09-12 22:24:27 -06:00
parent 0c3234dec5
commit 9ae39356a9
19 changed files with 2504 additions and 7 deletions
+51
View File
@@ -0,0 +1,51 @@
CC=gcc
OPT=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#OPT=-Wall -D_DEBUG_ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
INSTALL_DIR=/usr/local/bin
MAN_DIR=/usr/local/man
DOC_DIR=/usr/share/doc/secure_delete
OPT_MOD=-D__KERNEL__ -DMODULE -fomit-frame-pointer -fno-strict-aliasing -pipe
#LD_MOD=-r
all: sdel-lib.o srm sfill sswap smem
@echo
@echo "A Puritan is someone who is deathly afraid that someone, somewhere, is"
@echo "having fun."
@echo
@echo "I hope YOU have fun!"
@echo
sdel-lib.o: sdel-lib.c
$(CC) ${OPT} -c sdel-lib.c
srm: srm.c
$(CC) ${OPT} -o srm srm.c sdel-lib.o
-strip srm
sfill: sfill.c
$(CC) ${OPT} -o sfill sfill.c sdel-lib.o
-strip sfill
sswap: sswap.c
$(CC) ${OPT} -o sswap sswap.c sdel-lib.o
-strip sswap
smem: smem.c
$(CC) ${OPT} -o smem smem.c sdel-lib.o
-strip smem
clean:
rm -f sfill srm sswap smem sdel sdel-lib.o core *~
install: all
mkdir -p -m 755 ${INSTALL_DIR} 2> /dev/null
rm -f sdel && ln -s srm sdel
cp -f sdel srm sfill sswap smem the_cleaner.sh ${INSTALL_DIR}
chmod 711 ${INSTALL_DIR}/srm ${INSTALL_DIR}/sfill ${INSTALL_DIR}/sswap ${INSTALL_DIR}/smem ${INSTALL_DIR}/the_cleaner.sh
mkdir -p -m 755 ${MAN_DIR}/man1 2> /dev/null
cp -f srm.1 sfill.1 sswap.1 smem.1 ${MAN_DIR}/man1
chmod 644 ${MAN_DIR}/man1/srm.1 ${MAN_DIR}/man1/sfill.1 ${MAN_DIR}/man1/sswap.1 ${MAN_DIR}/man1/smem.1
mkdir -p -m 755 ${DOC_DIR} 2> /dev/null
cp -f CHANGES FILES README secure_delete.doc usenix6-gutmann.doc ${DOC_DIR}
#-test -e sdel-mod.o && cp -f sdel-mod.o /lib/modules/`uname -r`/kernel/drivers/char
# @-test '!' -e sdel-mod.o -a `uname -s` = 'Linux' && echo "type \"make sdel-mod install\" to compile and install the Linux loadable kernel module for secure delete"
@echo
@echo "If men could get pregnant, abortion would be a sacrament."
@echo
+1
View File
@@ -0,0 +1 @@
# [Original Project is secure-delete here](https://github.com/BlackArch/secure-delete)
+5
View File
@@ -0,0 +1,5 @@
#define BLOCKSIZE 32769 /* must be mod 3 = 0, should be >= 16k */
#define RANDOM_DEVICE "/dev/urandom" /* must not exist */
#define DIR_SEPERATOR '/' /* '/' on unix, '\' on dos/win */
#define FLUSH sync() /* system call to flush the disk */
#define MAXINODEWIPE 4194304 /* 22 bits */
+235
View File
@@ -0,0 +1,235 @@
--- src/rm.c.orig Sat Nov 23 23:11:12 1996
+++ src/rm.c Sun Jan 24 13:37:20 1999
@@ -1,3 +1,10 @@
+/* patch for rm from fileutils-3.16 to support secure data deletion
+ * to be activated by -s. -sss gives full erasure security (38 overwrites)
+ * This patch is from the secure_delete-2.0.tar.gz package available
+ * at http://www.thehackerschoice.com - get it, and read the documentation!
+ * (c)1999 by van Hauser / [THC] - The Hacker's Choice, vh@reptile.rug.ac.be
+ */
+
/* `rm' file deletion utility for GNU.
Copyright (C) 88, 90, 91, 94, 95, 1996 Free Software Foundation, Inc.
@@ -21,6 +28,11 @@
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
+/* SRM BEGIN */
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+/* SRM END */
#include "system.h"
#include "error.h"
@@ -50,6 +62,14 @@
int yesno ();
void strip_trailing_slashes ();
+/* SRM BEGIN */
+#define BLOCKSIZE 32769
+#define DIR_SEPERATOR '/'
+#define FLUSH sync()
+#define RANDOM_DEVICE "/dev/urandom"
+/* SRM END */
+
+static int secure_delete ();
static int clear_directory __P ((struct stat *statp));
static int duplicate_entry __P ((struct pathstack *stack, ino_t inum));
static int remove_dir __P ((struct stat *statp));
@@ -68,6 +88,12 @@
/* Path of file now being processed; extended as necessary. */
static char *pathname;
+/* SRM BEGIN */
+static int secure; /* secure overwrite mode */
+static char fillbuf[BLOCKSIZE];
+static FILE *devrandom;
+/* SRM END */
+
/* Number of bytes currently allocated for `pathname';
made larger when necessary, but never smaller. */
static int pnsize;
@@ -104,6 +130,9 @@
{"force", no_argument, NULL, 'f'},
{"interactive", no_argument, NULL, 'i'},
{"recursive", no_argument, &recursive, 1},
+/* SRM BEGIN */
+ {"secure_delete", no_argument, NULL, 's'},
+/* SRM END */
{"verbose", no_argument, &verbose, 1},
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
@@ -125,8 +154,8 @@
= unlink_dirs = 0;
pnsize = 256;
pathname = xmalloc (pnsize);
-
- while ((c = getopt_long (argc, argv, "dfirvR", long_opts, (int *) 0)) != EOF)
+
+ while ((c = getopt_long (argc, argv, "dfirsvR", long_opts, (int *) 0)) != EOF)
{
switch (c)
{
@@ -147,6 +176,11 @@
case 'R':
recursive = 1;
break;
+/* SRM BEGIN */
+ case 's':
+ secure++;
+ break;
+/* SRM END */
case 'v':
verbose = 1;
break;
@@ -198,6 +232,116 @@
exit (err > 0);
}
+/* SRM BEGIN */
+
+void fill_buf(char pattern[3]) {
+ int loop;
+ int where;
+ for (loop = 0; loop < (BLOCKSIZE / 3); loop++) {
+ where = loop * 3;
+ fillbuf[where] = pattern[0];
+ fillbuf[where+1] = pattern[1];
+ fillbuf[where+2] = pattern[2];
+ }
+}
+void random_buf() {
+ int loop;
+ if (devrandom != NULL)
+ for (loop = 0; loop < BLOCKSIZE; loop++)
+ fillbuf[loop] = (unsigned char) (256.0*rand()/(RAND_MAX+1.0));
+ else
+ fread(&fillbuf, BLOCKSIZE, 1, devrandom);
+}
+
+/* overwriting the file several times */
+
+ static int
+ secure_delete (delfile)
+ char *delfile;
+ {
+ unsigned char write_modes[27][3] = {
+ {"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"},
+ {"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"},
+ {"\x33\x33\x33"}, {"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
+ {"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"}, {"\xaa\xaa\xaa"},
+ {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"}, {"\xdd\xdd\xdd"}, {"\xee\xee\xee"},
+ {"\xff\xff\xff"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
+ {"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
+ };
+ unsigned char std_array[3] = "\xff\xff\xff";
+ FILE *f;
+ int file;
+ unsigned long writes;
+ unsigned long counter;
+ unsigned long filesize;
+ struct stat filestat;
+ int turn;
+ int result;
+ unsigned char ch;
+ char newname[512];
+
+/* open the file, get the filesize, calculate the numbers of needed writings */
+ if (lstat(delfile, &filestat))
+ return 1;
+ if (! S_ISREG(filestat.st_mode))
+ return 1;
+ if ((f = fopen(delfile, "r+b")) == NULL)
+ return 1;
+ filesize = filestat.st_size;
+ writes = (1 + (filesize / BLOCKSIZE));
+ file=fileno(f);
+ (void) setvbuf(stdout, NULL, _IONBF, 0);
+ devrandom = fopen(RANDOM_DEVICE, "r");
+
+ if (verbose)
+ printf(" ");
+
+
+ if (secure > 1) {
+ fill_buf(std_array);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ if (verbose)
+ printf("*");
+ fflush(f);
+ fsync(file);
+ }
+
+/* do the overwriting stuff */
+ for (turn=0; turn<=36; turn++) {
+ rewind(f);
+ if ((secure < 3) && (turn > 0)) break;
+ if ((turn>=5) && (turn<=31)) {
+ fill_buf(write_modes[turn-5]);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ } else {
+ for (counter=1; counter<=writes; counter++) {
+ random_buf();
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ }
+ }
+ fflush(f);
+ if (fsync(file) < 0)
+ FLUSH;
+ if (verbose)
+ printf("*");
+ }
+ (void) fclose(f);
+ (void) fclose(devrandom);
+/* Hard Flush -> Force cached data to be written to disk */
+ FLUSH;
+/* open + truncating the file, so an attacker doesn't know the diskblocks */
+ if ((file = open(delfile, O_WRONLY | O_TRUNC)) >= 0)
+ close(file);
+ if (verbose)
+ printf(" wiped\n");
+ return 0;
+}
+
+/* SRM END */
+
/* Remove file or directory `pathname' after checking appropriate things.
Return 0 if `pathname' is removed, 1 if not. */
@@ -264,8 +408,16 @@
return 1;
}
- if (verbose)
- printf ("%s\n", pathname);
+ if (verbose) {
+ printf ("%s", pathname);
+ if (secure == 0)
+ printf ("\n");
+ }
+
+/* SRM BEGIN */
+ if (secure)
+ secure_delete(pathname);
+/* SRM END */
if (unlink (pathname) && (errno != ENOENT || !ignore_missing_files))
{
@@ -536,11 +688,13 @@
-f, --force ignore nonexistent files, never prompt\n\
-i, --interactive prompt before any removal\n\
-r, -R, --recursive remove the contents of directories recursively\n\
+ -s, --secure_delete secure overwrite (-sss for full security)\n\
-v, --verbose explain what is being done\n\
--help display this help and exit\n\
--version output version information and exit\n\
"));
puts (_("\nReport bugs to fileutils-bugs@gnu.ai.mit.edu"));
+ puts (_("\nWith secure_delete patch by van Hauser <vh@reptile.rug.ac.be>"));
}
exit (status);
}
+249
View File
@@ -0,0 +1,249 @@
--- remove.c.orig 2003-05-05 15:15:48.000000000 +0200
+++ remove.c 2003-05-05 15:26:08.000000000 +0200
@@ -26,6 +26,12 @@
#include <sys/types.h>
#include <assert.h>
+/* SRM BEGIN */
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+/* SRM END */
+
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
@@ -81,6 +87,18 @@
int euidaccess ();
int yesno ();
+/* SRM BEGIN */
+#define BLOCKSIZE 32769
+#define DIR_SEPERATOR '/'
+#define FLUSH sync()
+#define RANDOM_DEVICE "/dev/urandom"
+static int secure = 0;
+static char fillbuf[BLOCKSIZE];
+static FILE *devrandom;
+/* Functions */
+static int secure_delete();
+/* SRM END */
+
extern char *program_name;
/* state initialized by remove_init, freed by remove_fini */
@@ -605,6 +623,103 @@
return status;
}
+/* SRM BEGIN */
+void fill_buf(char pattern[3]) {
+ int loop;
+ int where;
+ for (loop = 0; loop < (BLOCKSIZE / 3); loop++) {
+ where = loop * 3;
+ fillbuf[where] = pattern[0];
+ fillbuf[where+1] = pattern[1];
+ fillbuf[where+2] = pattern[2];
+ }
+}
+
+void random_buf() {
+ int loop;
+ if (devrandom != NULL)
+ for (loop = 0; loop < BLOCKSIZE; loop++)
+ fillbuf[loop] = (unsigned char) (256.0*rand()/(RAND_MAX+1.0));
+ else
+ fread(&fillbuf, BLOCKSIZE, 1, devrandom);
+}
+
+/* overwriting the file several times */
+ static int
+ secure_delete (delfile)
+ char *delfile;
+ {
+ unsigned char write_modes[27][3] = {
+ {"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"},
+ {"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"},
+ {"\x33\x33\x33"}, {"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
+ {"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"}, {"\xaa\xaa\xaa"},
+ {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"}, {"\xdd\xdd\xdd"}, {"\xee\xee\xee"},
+ {"\xff\xff\xff"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
+ {"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
+ };
+ unsigned char std_array[3] = "\xff\xff\xff";
+ FILE *f;
+ int file;
+ unsigned long writes;
+ unsigned long counter;
+ unsigned long filesize;
+ struct stat filestat;
+ int turn;
+ int result;
+ unsigned char ch;
+ char newname[512];
+
+/* open the file, get the filesize, calculate the numbers of needed writings */
+ if (lstat(delfile, &filestat))
+ return 1;
+ if (! S_ISREG(filestat.st_mode))
+ return 1;
+ if ((f = fopen(delfile, "r+b")) == NULL)
+ return 1;
+ filesize = filestat.st_size;
+ writes = (1 + (filesize / BLOCKSIZE));
+ file=fileno(f);
+ (void) setvbuf(stdout, NULL, _IONBF, 0);
+ devrandom = fopen(RANDOM_DEVICE, "r");
+
+ if (secure > 1) {
+ fill_buf(std_array);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ fflush(f);
+ fsync(file);
+ }
+
+/* do the overwriting stuff */
+ for (turn=0; turn<=36; turn++) {
+ rewind(f);
+ if ((secure < 3) && (turn > 0)) break;
+ if ((turn>=5) && (turn<=31)) {
+ fill_buf(write_modes[turn-5]);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ } else {
+ for (counter=1; counter<=writes; counter++) {
+ random_buf();
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ }
+ }
+ fflush(f);
+ if (fsync(file) < 0)
+ FLUSH;
+ }
+ (void) fclose(f);
+ (void) fclose(devrandom);
+/* Hard Flush -> Force cached data to be written to disk */
+ FLUSH;
+/* open + truncating the file, so an attacker doesn't know the diskblocks */
+ if ((file = open(delfile, O_WRONLY | O_TRUNC)) >= 0)
+ close(file);
+ return 0;
+}
+/* SRM END */
+
/* Query the user if appropriate, and if ok try to remove the
file or directory specified by FS. Return RM_OK if it is removed,
and RM_ERROR or RM_USER_DECLINED if not. */
@@ -646,9 +761,16 @@
return RM_USER_DECLINED;
}
- if (x->verbose)
- printf (_("removing %s\n"), quote (full_filename (pathname)));
+ if (x->verbose) {
+ if (secure)
+ printf (_("wiping %s\n"), quote (full_filename (pathname)));
+ else
+ printf (_("removing %s\n"), quote (full_filename (pathname)));
+ }
+ if (secure)
+ secure_delete(pathname);
+
if (unlink (pathname) && (errno != ENOENT || !x->ignore_missing_files))
{
error (0, errno, _("cannot unlink %s"), quote (full_filename (pathname)));
@@ -821,6 +943,8 @@
{
mode_t filetype_mode;
+ secure = x->secure;
+
if (user_specified_name)
{
/* CAUTION: this use of base_name works only because any
--- rm.c.orig 2003-05-05 14:58:35.000000000 +0200
+++ rm.c 2003-05-05 15:16:31.000000000 +0200
@@ -58,7 +58,7 @@
#define PROGRAM_NAME "rm"
#define AUTHORS \
- "Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering"
+ "Paul Rubin, David MacKenzie, Richard Stallman, Jim Meyering, and van Hauser"
void strip_trailing_slashes ();
@@ -71,6 +71,9 @@
{"force", no_argument, NULL, 'f'},
{"interactive", no_argument, NULL, 'i'},
{"recursive", no_argument, NULL, 'r'},
+/* SRM BEGIN */
+ {"secure", no_argument, NULL, 's'},
+/* SRM END */
{"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -93,6 +96,7 @@
-f, --force ignore nonexistent files, never prompt\n\
-i, --interactive prompt before any removal\n\
-r, -R, --recursive remove the contents of directories recursively\n\
+ -s, --secure secure overwrite (-sss for full security)\n\
-v, --verbose explain what is being done\n\
--help display this help and exit\n\
--version output version information and exit\n\
@@ -105,10 +109,11 @@
\n\
Note that if you use rm to remove a file, it is usually possible to recover\n\
the contents of that file. If you want more assurance that the contents are\n\
-truly unrecoverable, consider using shred.\n\
+truly unrecoverable, use the -s option.\n\
"),
program_name, program_name);
puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
+ puts (_("\nWith secure_delete patch by van Hauser <vh@thc.org>"));
}
exit (status);
}
@@ -122,6 +127,7 @@
x->recursive = 0;
x->stdin_tty = isatty (STDIN_FILENO);
x->verbose = 0;
+ x->secure = 0;
}
int
@@ -140,7 +146,7 @@
rm_option_init (&x);
- while ((c = getopt_long (argc, argv, "dfirvR", long_opts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "dfirsvR", long_opts, NULL)) != -1)
{
switch (c)
{
@@ -161,6 +167,11 @@
case 'R':
x.recursive = 1;
break;
+/* SRM BEGIN */
+ case 's':
+ x.secure++;
+ break;
+/* SRM END */
case 'v':
x.verbose = 1;
break;
--- remove.h.orig 2003-05-05 15:13:47.000000000 +0200
+++ remove.h 2003-05-05 15:14:13.000000000 +0200
@@ -18,6 +18,9 @@
Only works for the super-user. */
int unlink_dirs;
+ /* If nonzero, secure overwrites file contents */
+ int secure;
+
/* If nonzero, display the name of each file removed. */
int verbose;
};
+349
View File
@@ -0,0 +1,349 @@
/* Secure Delete Library - by van Hauser / [THC], vh@thc.org
*
* Secure Delete Library provides the following public functions:
*
* void sdel_init(int secure_random)
* Initializiation function for sdel_overwrite. It needs to be called
* once at program start, not for each file to be overwritten.
* Options:
* secure_random - if != 0 defines that the secure random number
* generator RANDOM_DEVICE should be used
*
* void sdel_finnish()
* Clean-up function, if sdel_init() was called in a program. It needs
* only to be called at the end of the program.
*
* int sdel_overwrite(int mode, int fd, long start, unsigned long bufsize,
* unsigned long length, int zero)
* This is the heart of sdel-lib. It overwrites the target file
* descriptor securely to make life hard even for the NSA.
* Read the next paragraph for the techniques.
* Options:
* mode = 0 - once overwrite with random data
* 1 - once overwrite with 0xff, then once with random data
* 2 - overwrite 38 times with special values
* fd - filedescriptor of the target to overwrite
* start - where to start overwriting. 0 is from the beginning
* this is needed for wiping swap spaces etc.
* bufsize - size of the buffer to use for overwriting, depends
* on the filesystem
* length - amount of data to write (file size), 0 means until
* an error occurs
* zero - last wipe is zero bytes, not random
* returns 0 on success, -1 on errors
*
* int sdel_unlink(char *filename, int directory, int truncate, int slow)
* First truncates the file (if it is not a directory), then renames it
* and finally rmdir/unlinks the target.
* Options:
* filename - filename/directory to unlink/rmdir
* directory - if != 0, it is a directory
* truncate - if != 0, it truncates the file
* slow - is either O_SYNC (see open(2)) or 0
* returns 0 on success, -1 on errors
*
* Compiles clean on OpenBSD, Linux, Solaris, AIX and I guess all others.
*
*/
/*
* For security reasons full 32kb blocks are written so that the whole block
* on which the file(s) live are overwritten. (change #define #BLOCKSIZE)
* Standard mode is a real security wipe for 38 times, flushing
* the caches after every write. The wipe technique was proposed by Peter
* Gutmann at Usenix '96 and includes 10 random overwrites plus 28 special
* defined characters. Take a look at the paper of him, it's really worth
* your time.
*
* Read the manual for limitations.
*/
#include "sdel-lib.h"
//
// STARTING FUNCTIONS
//
void __sdel_fill_buf(char pattern[3], unsigned long bufsize, char *buf) {
int loop;
int where;
for (loop = 0; loop < (bufsize / 3); loop++) {
where = loop * 3;
*buf++ = pattern[0];
*buf++ = pattern[1];
*buf++ = pattern[2];
}
}
void __sdel_random_buf(unsigned long bufsize, char *buf) {
int loop;
if (devrandom == NULL)
for (loop = 0; loop < bufsize; loop++)
*buf++ = (unsigned char) (256.0*rand()/(RAND_MAX+1.0));
else
fread(buf, bufsize, 1, devrandom);
}
void __sdel_random_filename(char *filename) {
int i;
for (i = strlen(filename) - 1;
(filename[i] != DIR_SEPERATOR) && (i >= 0);
i--)
if (filename[i] != '.') /* keep dots in the filename */
filename[i] = 97+(int) ((int) ((256.0 * rand()) / (RAND_MAX + 1.0)) % 26);
}
void sdel_init(int secure_random) {
(void) setvbuf(stdout, NULL, _IONBF, 0);
(void) setvbuf(stderr, NULL, _IONBF, 0);
if (BLOCKSIZE<16384)
fprintf(stderr, "Programming Warning: in-compiled blocksize is <16k !\n");
if (BLOCKSIZE % 3 > 0)
fprintf(stderr, "Programming Error: in-compiled blocksize is not a multiple of 3!\n");
srand( (getpid()+getuid()+getgid()) ^ time(0) );
devrandom = NULL;
#ifdef RANDOM_DEVICE
if (secure_random) {
if ((devrandom = fopen(RANDOM_DEVICE, "r")) != NULL)
if (verbose)
printf("Using %s for random input.\n", RANDOM_DEVICE);
}
#endif
__internal_sdel_init = 1;
}
void sdel_finnish() {
if (devrandom != NULL) {
fclose(devrandom);
devrandom = NULL;
}
if (! __internal_sdel_init) {
fprintf(stderr, "Programming Error: sdel-lib was not initialized before calling sdel_finnish().\n");
return;
}
__internal_sdel_init = 0;
}
/*
* secure_overwrite function parameters:
* mode = 0 : once overwrite with random data
* 1 : once overwrite with 0xff, then once with random data
* 2 : overwrite 38 times with special values
* fd : filedescriptor of the target to overwrite
* start : where to start overwriting. 0 is from the beginning
* bufsize : size of the buffer to use for overwriting, depends on the filesystem
* length : amount of data to write (file size), 0 means until an error occurs
*
* returns 0 on success, -1 on errors
*/
int sdel_overwrite(int mode, int fd, long start, unsigned long bufsize, unsigned long length, int zero) {
unsigned long writes;
unsigned long counter;
int turn;
int last = 0;
char buf[65535];
FILE *f;
if (! __internal_sdel_init)
fprintf(stderr, "Programming Error: sdel-lib was not initialized before sdel_overwrite().\n");
if ((f = fdopen(fd, "r+b")) == NULL)
return -1;
/* calculate the number of writes */
if (length > 0)
writes = (1 + (length / bufsize));
else
writes = 0;
/* do the first overwrite */
if (start == 0)
rewind(f);
else
if (fseek(f, start, SEEK_SET) != 0)
return -1;
if (mode != 0 || zero) {
if (mode == 0)
__sdel_fill_buf(std_array_00, bufsize, buf);
else
__sdel_fill_buf(std_array_ff, bufsize, buf);
if (writes > 0)
for (counter=1; counter<=writes; counter++)
fwrite(&buf, 1, bufsize, f); // dont care for errors
else
do {} while(fwrite(&buf, 1, bufsize, f) == bufsize);
if (verbose)
printf("*");
fflush(f);
if (fsync(fd) < 0)
FLUSH;
if (mode == 0)
return 0;
}
/* do the rest of the overwriting stuff */
for (turn = 0; turn <= 36; turn++) {
if (start == 0)
rewind(f);
else
if (fseek(f, start, SEEK_SET) != 0)
return -1;
if ((mode < 2) && (turn > 0))
break;
if ((turn >= 5) && (turn <= 31)) {
__sdel_fill_buf(write_modes[turn-5], bufsize, buf);
if (writes > 0)
for (counter = 1; counter <= writes; counter++)
fwrite(&buf, 1, bufsize, f); // dont care for errors
else
do {} while(fwrite(&buf, 1, bufsize, f) == bufsize);
} else {
if (zero && ((mode == 2 && turn == 36) || mode == 1)) {
last = 1;
__sdel_fill_buf(std_array_00, bufsize, buf);
}
if (writes > 0) {
for (counter = 1; counter <= writes; counter++) {
if (! last)
__sdel_random_buf(bufsize, buf);
fwrite(&buf, 1, bufsize, f); // dont care for errors
}
} else {
do {
if (! last)
__sdel_random_buf(bufsize, buf);
} while (fwrite(&buf, 1, bufsize, f) == bufsize); // dont care for errors
}
}
fflush(f);
if (fsync(fd) < 0)
FLUSH;
if (verbose)
printf("*");
}
(void) fclose(f);
/* Hard Flush -> Force cached data to be written to disk */
FLUSH;
return 0;
}
/*
* secure_unlink function parameters:
* filename : the file or directory to remove
* directory : defines if the filename poses a directory
* truncate : truncate file
* slow : do things slowly, to prevent caching
*
* returns 0 on success, -1 on errors.
*/
int sdel_unlink(char *filename, int directory, int truncate, int slow) {
int fd;
int turn = 0;
int result;
char newname[strlen(filename) + 1];
struct stat filestat;
/* open + truncating the file, so an attacker doesn't know the diskblocks */
if (! directory && truncate)
if ((fd = open(filename, O_WRONLY | O_TRUNC | slow)) >= 0)
close(fd);
/* Generate random unique name, renaming and deleting of the file */
strcpy(newname, filename); // not a buffer overflow as it has got the exact length
do {
__sdel_random_filename(newname);
if ((result = lstat(newname, &filestat)) >= 0)
turn++;
} while ((result >= 0) && (turn <= 100));
if (turn <= 100) {
result = rename(filename, newname);
if (result != 0) {
fprintf(stderr, "Warning: Couldn't rename %s - ", filename);
perror("");
strcpy(newname, filename);
}
} else {
fprintf(stderr,"Warning: Couldn't find a free filename for %s!\n",filename);
strcpy(newname, filename);
}
if (directory) {
result = rmdir(newname);
if (result) {
printf("Warning: Unable to remove directory %s - ", filename);
perror("");
(void) rename(newname, filename);
} else
if (verbose)
printf("Removed directory %s ...", filename);
} else {
result = unlink(newname);
if (result) {
printf("Warning: Unable to unlink file %s - ", filename);
perror("");
(void) rename(newname, filename);
} else
if (verbose)
printf(" Removed file %s ...", filename);
}
if (result != 0)
return -1;
return 0;
}
void sdel_wipe_inodes(char *loc, char **array) {
char *template = malloc(strlen(loc) + 16);
int i = 0;
int fail = 0;
int fd;
if (verbose)
printf("Wiping inodes ...");
array = malloc(MAXINODEWIPE * sizeof(template));
strcpy(template, loc);
if (loc[strlen(loc) - 1] != '/')
strcat(template, "/");
strcat(template, "xxxxxxxx.xxx");
while(i < MAXINODEWIPE && fail < 5) {
__sdel_random_filename(template);
if (open(template, O_CREAT | O_EXCL | O_WRONLY, 0600) < 0)
fail++;
else {
array[i] = malloc(strlen(template));
strcpy(array[i], template);
i++;
}
}
FLUSH;
if (fail < 5) {
fprintf(stderr, "Warning: could not wipe all inodes!\n");
}
array[i] = NULL;
fd = 0;
while(fd < i) {
unlink(array[fd]);
free(array[fd]);
fd++;
}
free(array);
array = NULL;
FLUSH;
if (verbose)
printf(" Done ... ");
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef _SDEL_LIB_H_
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "config.h"
//
// STARTING CONSTANTS AND VARIABLES
//
unsigned char write_modes[27][3] = {
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"},
{"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"},
{"\x33\x33\x33"}, {"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"}, {"\xaa\xaa\xaa"},
{"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"}, {"\xdd\xdd\xdd"}, {"\xee\xee\xee"},
{"\xff\xff\xff"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
};
unsigned char std_array_ff[3] = "\xff\xff\xff";
unsigned char std_array_00[3] = "\x00\x00\x00";
FILE *devrandom = NULL;
int verbose = 0;
int __internal_sdel_init = 0;
#define _SDEL_LIB_H_
#endif
+36
View File
@@ -0,0 +1,36 @@
#ifndef _SDEL_H
#include "config.h"
#define VERSION "v3.1"
#define AUTHOR "van Hauser / THC"
#define EMAIL "vh@thc.org"
#define WEB "http://www.thc.org"
#ifndef O_SYNC
#ifdef O_FSYNC
#define O_SYNC O_FSYNC
#else
#define O_SYNC 0
#endif
#endif
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
char *prg;
extern int verbose;
extern void sdel_init(int secure_random);
extern void sdel_finnish();
extern int sdel_overwrite(int mode, int fd, long start, unsigned long bufsize, unsigned long length, int zero);
extern int sdel_unlink(char *filename, int directory, int truncate, int slow);
extern void sdel_wipe_inodes(char *loc, char **array);
extern void __sdel_fill_buf(char pattern[3], unsigned long bufsize, char *buf);
extern void __sdel_random_buf(unsigned long bufsize, char *buf);
extern void __sdel_random_filename(char *filename);
#define _SDEL_H
#endif
+134
View File
@@ -0,0 +1,134 @@
.\" This definition swiped from the gcc(1) man page
.de Sp
.if n .sp
.if t .sp 0.4
..
.TH SFILL 1
.SH NAME
sfill \- secure free disk and inode space wiper (secure_deletion toolkit)
.SH SYNOPSIS
.B sfill [-f] [-i] [-I] [-l] [-l] [-v] [-z] directory/mountpoint
.SH DESCRIPTION
.I sfill
is designed to delete data which lies on available diskspace on mediums
in a secure manner which can not be recovered by thiefs, law enforcement
or other threats.
The wipe algorythm is based on the paper "Secure Deletion of Data from
Magnetic and Solid-State Memory" presented at the 6th Usenix Security
Symposium by Peter Gutmann, one of the leading civilian cryptographers.
.PP
The
.I secure data deletion
process of sfill goes like this:
.PP
.TP
.B *
1 pass with 0xff
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.TP
.B *
27 passes with special values defined by Peter Gutmann.
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.PP
afterwards as many temporary files as possible are generated to wipe the
free inode space. After no more temporary files can be created, they are
removed and sfill is finnished.
.PP
.SH COMMANDLINE OPTIONS
.PP
.TP
.B \-f
fast (and insecure mode): no /dev/urandom, no synchronize mode.
.TP
.B \-i
wipe only free inode space, not free disk space
.TP
.B \-I
wipe only free disk space, not free inode space
.TP
.B \-l
lessens the security. Only two passes are written: one mode with 0xff
and a final mode with random values.
.TP
.B \-l
-l for a second time lessons the security even more: only one random pass
is written.
.TP
.B \-v
verbose mode
.TP
.B \-z
wipes the last write with zeros instead of random data
.PP
.PP
.B directory/mountpoint
this is the location of the file created in your filesystem. It should
lie on the partition you want to write.
.PP
.SH LIMITATIONS
.TP
.B FILESYSTEM INTELLIGENCE
Most filesystems (ext2, ffs, etc.) have several features included to enhance
performance, which will result in that sfill might not receive all available
free space. Sad but true. Nothing can be done about that ...
.TP
.B NFS
Beware of NFS. You can't ensure you really completely wiped your data
from the remote disks. (especially because of caching)
.TP
.B Raid
Raid Systems use stripped disks and have got large caches. It's hard to wipe
them.
.TP
.B swap
Some of your data might have a copy in your swapspace.
.I sswap
is available for this task.
.PP
.SH BUGS
No bugs. There was never a bug in the secure_deletion package (in contrast
to my other tools, whew, good luck ;-)
Send me any that you find. Patches are nice too :)
.SH AUTHOR
.Sp
van Hauser / THC
.I <vh@thc.org>
.SH DISTRIBUTION
The newest version of the
.I secure_deletion package
can be obtained from
.I http://www.thc.org
.Sp
.I sfill
and the
.I secure_deletion package
is (C) 1997-2003 by van Hauser / THC (vh@thc.org)
.Sp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; Version 2.
.Sp
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
.SH SEE ALSO
.I srm
(1),
.I sswap
(1),
.I smem
(1)
+237
View File
@@ -0,0 +1,237 @@
/* Secure FILL - by van Hauser / [THC], vh@thc.org
*
* Secure FILL overwrites all available free diskspace by creating a file,
* wiping all free diskspace it gets and finally deleting the file.
*
* Standard mode is a real security wipe for 38 times, flushing
* the caches after every write. The wipe technique was proposed by Peter
* Gutmann at Usenix '96 and includes 10 random overwrites plus 28 special
* defined characters. Take a look at the paper of him, it's really worth
* your time.
* The option -l overwrites two times the data. (0xff + random)
* The option -ll overwrites the data once. (random)
* New with v2.3: wipes all inodes in the defined directory
*
* Read the manual for limitations.
* Compiles clean on OpenBSD, Linux, Solaris and AIX
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "sdel.h"
#ifdef BLOCKSIZE
#undef BLOCKSIZE
#endif
#define BLOCKSIZE 65535
#define MAXINODEWIPE 4194304 /* 22 bits */
char **array = NULL;
int slow = O_SYNC;
int debug = 1;
int zero = 0;
int inode_only = 0;
int fd = -1;
char *filename = NULL;
FILE *f;
void help() {
printf("sfill %s (c) 1997-2003 by %s <%s>\n\n", VERSION, AUTHOR, EMAIL);
printf("Syntax: %s [-fiIlvz] directory\n\n", prg);
printf("Options:\n");
printf("\t-f fast (and insecure mode): no /dev/urandom, no synchronize mode.\n");
printf("\t-i wipe only inodes in the directory specified\n");
printf("\t-I just wipe space, not inodes\n");
printf("\t-l lessens the security (use twice for total insecure mode).\n");
printf("\t-v is verbose mode.\n");
printf("\t-z last wipe writes zeros, not random data.\n");
printf("\nsfill does a secure overwrite of the free space on the partition the specified\ndirectory resides and all free inodes of the directory specified.\n");
printf("Default is secure mode (38 writes).\n");
printf("You can find updates at %s\n", WEB);
exit(1);
}
void cleanup(int signo) {
fprintf(stderr,"\nTerminated by signal. Clean exit.\n");
if (fd > 0) {
fsync(fd);
(void) close(fd);
sync();
if (filename != NULL && unlink(filename) != 0)
fprintf(stderr, "Error: Could not remove temporary file %s!\n", filename);
}
if (array != NULL) {
int i = 0;
while(array[i] != NULL) {
unlink(array[i]);
i++;
}
}
exit(1);
}
int main (int argc, char *argv[]) {
int result;
int secure = 2; /* standard is secure mode */
int loop;
int turn;
int counter;
struct stat filestat;
struct rlimit rlim;
char type[15] = "random";
if (getuid() != 0)
fprintf(stderr,"Warning: you are not root. You might not be able to wipe the whole filesystem.\n");
prg = argv[0];
if (argc == 1 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--h", 3) == 0)
help();
while (1) {
result = getopt(argc, argv, "fFiIlLsSvVzZ");
if (result < 0)
break;
switch (result) {
case 'f' :
case 'F' : slow = 0;
break;
case 'i' : inode_only = 1;
break;
case 'I' : inode_only = -1;
break;
case 'l' :
case 'L' : if (secure) secure--;
break;
case 's' :
case 'S' : secure++;
break;
case 'v' :
case 'V' : verbose++;
break;
case 'Z' :
case 'z' : zero++;
break;
default : help();
}
}
loop = optind;
if (loop >= argc)
help();
if (zero) strcpy(type, "zero");
do {
char newname[strlen(argv[loop]) + 16];
strcpy(newname, argv[loop]); // can not overflow
if (opendir(newname) == NULL) { /* no need for ensuring close */
fprintf(stderr, "Error: %s is not a directory\n", newname);
} else {
/* Generate random unique name for tempfile */
srand(getpid()+getuid());
if (newname[strlen(newname)-1] != DIR_SEPERATOR)
strcat(newname, "/");
turn = 0; result = 0;
strcat(newname, "oooooooo.ooo");
result = lstat(newname, &filestat);
while ((result >= 0) && (turn <= 250)) {
for (counter = strlen(newname)-1;
(newname[counter] != DIR_SEPERATOR);
counter--)
if (newname[counter] != '.')
newname[counter] = 97+(int) (27.0 * rand() / (RAND_MAX + 1.0));
if ((result = lstat(newname, &filestat)) >= 0)
turn++;
};
if (result >= 0)
fprintf(stderr,"Error: couldn't find a free filename in %s\n",argv[loop]);
else {
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGHUP, cleanup);
sdel_init(slow);
if (verbose && inode_only < 1) {
switch (secure) {
case 0 : printf("Wipe mode is insecure (one pass [%s])\n",type);
break;
case 1 : printf("Wipe mode is insecure (two passes [0xff/%s])\n",type);
break;
default: printf("Wipe mode is secure (38 special passes)\n");
}
printf("Wiping now ...\n");
}
#ifdef RLIM_INFINITY
#ifdef RLIMIT_FSIZE
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_FSIZE, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for filesize.\n");
#else
fprintf(stderr, "Warning: not compiled with support for resetting ulimit for filesize.\n");
#endif
#else
fprintf(stderr, "Warning: not compiled with support for resetting ulimit for filesize.\n");
#endif
result = 9;
if (inode_only < 1) {
/* create the file */
if (verbose) printf("Creating %s ... ", newname);
if ((fd = open(newname, O_RDWR | O_EXCL | O_CREAT | O_LARGEFILE | slow, 0600 )) < 0)
result = 1;
else {
filename = newname;
result = sdel_overwrite(secure, fd, 0, BLOCKSIZE, 0, zero);
/* Hard Flush -> Force cached data to be written to disk - the defines above! */
FLUSH;
if ((fd = open(newname, O_WRONLY | O_TRUNC)) >= 0)
close(fd);
}
}
if ((result == 0 && inode_only == 0) || inode_only > 0) {
if (result == 0 && inode_only == 0)
printf(" ");
sdel_wipe_inodes(argv[loop], array);
result = 0;
}
switch (result) {
case 0 : if (verbose) printf(" Finished\n");
break;
case 1 : fprintf(stderr, "Error: No write permission for %s. ", argv[loop]);
perror("");
break;
case 9: break;
default: fprintf(stderr, "Unknown error\n");
}
if (unlink(newname) != 0)
fprintf(stderr, "Error: Could not remove temporary file %s!\n", newname);
filename = NULL;
}
}
loop++;
} while (loop < argc);
sdel_finnish();
exit(0);
}
+107
View File
@@ -0,0 +1,107 @@
.\" This definition swiped from the gcc(1) man page
.de Sp
.if n .sp
.if t .sp 0.4
..
.TH SMEM 1
.SH NAME
smem \- secure memory wiper (secure_deletion toolkit)
.SH SYNOPSIS
.B smem [-f] [-l] [-l] [-v]
.SH DESCRIPTION
.I smem
is designed to delete data which may lie still in your memory (RAM)
in a secure manner which can not be recovered by thiefs, law enforcement
or other threats.
Note that with the new SDRAMs, data will not wither away but will be kept
static - it is easy to extract the necessary information!
The wipe algorythm is based on the paper "Secure Deletion of Data from
Magnetic and Solid-State Memory" presented at the 6th Usenix Security
Symposium by Peter Gutmann, one of the leading civilian cryptographers.
.PP
The
.I secure data deletion
process of smem goes like this:
.PP
.TP
.B *
1 pass with 0x00
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.TP
.B *
27 passes with special values defined by Peter Gutmann.
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.PP
.SH COMMANDLINE OPTIONS
.PP
.TP
.B \-f
fast (and insecure mode): no /dev/urandom.
.TP
.B \-l
lessens the security. Only two passes are written: the first with 0x00
and a final random one.
.TP
.B \-l
-l for a second time lessons the security even more: only one pass with
0x00 is written.
.TP
.B \-v
verbose mode
.PP
.SH BEWARE
.TP
.B SLOW
Wiping the memory is very slow. You might use smem with the -ll option. (tip)
.TP
.B BETA!
.I smem
is still beta.
.PP
.SH BUGS
No bugs. There was never a bug in the secure_deletion package (in contrast
to my other tools, whew, good luck ;-)
Send me any that you find. Patches are nice too :)
.SH AUTHOR
.Sp
van Hauser / THC
.I <vh@thc.org>
.SH DISTRIBUTION
The newest version of the
.I secure_deletion package
can be obtained from
.I http://www.thc.org
.Sp
.I smem
and the
.I secure_deletion package
is (C) 1997-2003 by van Hauser / THC (vh@thc.org)
.Sp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; Version 2.
.Sp
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
.SH SEE ALSO
.I srm
(1),
.I sfill
(1),
.I sswap
(1)
+209
View File
@@ -0,0 +1,209 @@
/* Secure MEMORY cleaner - by van Hauser / [THC], vh@thc.org
*
* Note that this program is beta. It was tested with linux, solaris and
* openbsd but I can't tell for other platforms.
*
* Secure MEMORY overwrites all data in your memory it gets.
* The any -l option this does a real security wipe for 38 times, flushing
* the caches after every write. The wipe technique was proposed by Peter
* Gutmann at Usenix '96 and includes 10 random overwrites plus 29 special
* defined characters. Take a look at the paper of him, it's really worth
* your time.
* If run with one -l option, it wipes the memory twice, first with null
* bytes, then with random values.
* If run with two -l options, it wipes the memory only once with null bytes.
*
* Note that it is *very* slow. You might run it with "-llf"
*
* Read the manual for limitations.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "sdel.h"
#ifdef BLOCKSIZE
#undef BLOCKSIZE
#endif
#define BLOCKSIZE 65536
char buf[BLOCKSIZE+2];
int slow = 1;
extern FILE *devrandom;
void help() {
printf("smem %s (c) 1997-2003 by %s <%s>\n\n", VERSION, AUTHOR, EMAIL);
printf("Syntax: %s [-flv]\n\n", prg);
printf("Options:\n");
printf("\t-f fast (and insecure mode): no /dev/urandom.\n");
printf("\t-l lessens the security (use twice for total insecure mode).\n");
printf("\t-v is verbose mode.\n");
printf("\nsmem does a secure overwrite of the memory (RAM), because memory contents can\n");
printf("be recovered even after a shutdown! Default is secure mode (38 writes).\n");
printf("You can find updates at %s\n", WEB);
exit(1);
}
int smash_it(int mode) {
unsigned char write_modes[27][3] = {
{"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"},
{"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"},
{"\x33\x33\x33"}, {"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
{"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"}, {"\xaa\xaa\xaa"},
{"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"}, {"\xdd\xdd\xdd"}, {"\xee\xee\xee"},
{"\xff\xff\xff"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
{"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
};
int turn;
unsigned int counter = 0;
unsigned char buffers[27][BLOCKSIZE+2];
char *ptr;
struct rlimit rlim;
if (verbose) {
switch (mode) {
case 0 : printf("Wipe mode is insecure (one pass with 0x00)\n");
break;
case 1 : printf("Wipe mode is insecure (two passes [0x00/random])\n"); break;
default: printf("Wipe mode is secure (38 special passes)\n");
}
}
if (slow && mode)
if ((devrandom = fopen(RANDOM_DEVICE, "r")) != NULL)
if (verbose)
printf("Using %s for random input.\n", RANDOM_DEVICE);
/* We set a new ulimit, so we can grab all memory ... */
#ifdef RLIM_INFINITY
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
#ifdef RLIMIT_DATA
if (setrlimit(RLIMIT_DATA, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for data.\n");
#endif
#ifdef RLIMIT_STACK
if (setrlimit(RLIMIT_STACK, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for stack.\n");
#endif
#ifdef RLIMIT_RSS
if (setrlimit(RLIMIT_RSS, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for rss.\n");
#endif
#ifdef RLIMIT_MEMLOCK
if (setrlimit(RLIMIT_MEMLOCK, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for mem locked.\n");
#endif
#ifndef RLIMIT_DATA
#ifndef RLIMIT_STACK
#ifndef RLIMIT_RSS
#ifndef RLIMIT_MEMLOCK
fprintf(stderr, "Warning: Not compiled with support for resetting ulimits for memory\n");
#endif
#endif
#endif
#endif
#else
fprintf(stderr, "Warning: Not compiled with support for resetting ulimits for memory\n");
#endif
if (mode > 1) {
for (turn=0; turn<27; turn++) {
__sdel_fill_buf(write_modes[turn], BLOCKSIZE + 2, buf);
memcpy(buffers[turn], buf, BLOCKSIZE);
}
}
alarm(600); /* needed to prevent mem caching */
while ( (ptr = calloc(4096, 16)) != NULL) {
if (mode > 0) {
for (turn=0; turn<=36; turn++) {
if ((mode == 1) && (turn > 0)) break;
if ((turn>=5) && (turn<=31)) {
memcpy(ptr, buffers[turn-5], BLOCKSIZE);
} else {
__sdel_random_buf(BLOCKSIZE + 2, buf);
memcpy(ptr, buf, BLOCKSIZE);
}
}
}
if (verbose && (counter > 8)) { /* every 512kb */
printf("*");
counter = 0;
} else counter++;
}
if (devrandom)
fclose(devrandom);
if (verbose)
printf(" done\n");
return 0;
}
void cleanup() {
fprintf(stderr,"Terminated by signal. Clean exit.\n");
if (devrandom)
fclose(devrandom);
fflush(stdout);
fflush(stderr);
exit(1);
}
int main (int argc, char *argv[]) {
int secure = 2;
int result;
prg = argv[0];
if (argc == 2)
if ( (strncmp(argv[1],"-h", 2) == 0) || (strcmp(argv[1],"-?") == 0) )
help();
while (1) {
result = getopt(argc, argv, "FfLlSsVvZz");
if (result<0) break;
switch (result) {
case 'F' :
case 'f' : slow = 0;
break;
case 'L' :
case 'l' : if (secure) secure--;
break;
case 'S' :
case 's' : secure++;
break;
case 'V' :
case 'v' : verbose++;
break;
case 'Z':
case 'z': break;
default : help();
}
}
if (optind < argc)
help();
printf("Starting Wiping the memory, press Control-C to abort earlier. Help: \"%s -h\"\n", prg);
(void) setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGHUP, cleanup);
signal(SIGALRM, cleanup);
smash_it(secure);
/* thats all */
exit(0);
}
+140
View File
@@ -0,0 +1,140 @@
.\" This definition swiped from the gcc(1) man page
.de Sp
.if n .sp
.if t .sp 0.4
..
.TH SRM 1
.SH NAME
srm \- secure remove (secure_deletion toolkit)
.SH SYNOPSIS
.B srm [-d] [-f] [-l] [-l] [-r] [-v] [-z] files
.SH DESCRIPTION
.I srm
is designed to delete data on mediums in a secure manner which can not be
recovered by thiefs, law enforcement or other threats.
The wipe algorythm is based on the paper "Secure Deletion of Data from
Magnetic and Solid-State Memory" presented at the 6th Usenix Security
Symposium by Peter Gutmann, one of the leading civilian cryptographers.
.PP
The
.I secure data deletion
process of srm goes like this:
.PP
.TP
.B *
1 pass with 0xff
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.TP
.B *
27 passes with special values defined by Peter Gutmann.
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.TP
.B *
Rename the file to a random value
.TP
.B *
Truncate the file
.PP
.PP
As an additional measure of security, the file is opened in O_SYNC mode
and after each pass an fsync() call is done.
.I srm
writes 32k blocks for the purpose of speed, filling buffers of disk caches
to force them to flush and overwriting old data which belonged to the file.
.PP
.SH COMMANDLINE OPTIONS
.PP
.TP
.B \-d
ignore the two special dot files . and .. on the commandline. (so you can
execute it like "srm -d .* *")
.TP
.B \-f
fast (and insecure mode): no /dev/urandom, no synchronize mode.
.TP
.B \-l
lessens the security. Only two passes are written: one mode with 0xff
and a final mode random values.
.TP
.B \-l
-l for a second time lessons the security even more: only one random pass
is written.
.TP
.B \-r
recursive mode, deletes all subdirectories.
.TP
.B \-v
verbose mode
.TP
.B \-z
wipes the last write with zeros instead of random data
.PP
.SH LIMITATIONS
.TP
.B NFS
Beware of NFS. You can't ensure you really completely wiped your data
from the remote disks.
.TP
.B Raid
Raid Systems use stripped disks and have got large caches. It's hard to wipe
them.
.TP
.B swap, /tmp, etc.
Some of your data might have a temporary (deleted) copy somewhere on the
disk. You should use
.I sfill
which comes with the
.I secure_deletion package
to ensure to wipe also the free diskspace. However, If already a small
file aquired a block with your precious data, no tool known to me can help
you here. For a secure deletion of the swap space
.I sswap
is available.
.PP
.SH BUGS
No bugs. There was never a bug in the secure_deletion package (in contrast
to my other tools, whew, good luck ;-)
Send me any that you find. Patches are nice too :)
.SH AUTHOR
.Sp
van Hauser / THC
.I <vh@thc.org>
.SH DISTRIBUTION
The newest version of the
.I secure_deletion package
can be obtained from
.I http://www.thc.org
.Sp
.I srm
and the
.I secure_deletion package
is (C) 1997-2003 by van Hauser / THC (vh@thc.org)
.Sp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; Version 2.
.Sp
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
.SH SEE ALSO
.I sfill
(1),
.I sswap
(1),
.I smem
(1)
+309
View File
@@ -0,0 +1,309 @@
/* Secure RM - by van Hauser / [THC], vh@thc.org
*
* Secure ReMove first overwrites then renames and finally deletes the target
* file(s) specified via parameters.
* For security reasons full 32kb blocks are written so that the whole block
* on which the file(s) live are overwritten. (change #define #BLOCKSIZE)
* The option -l overwrites two times the data.
* The option -ll overwrites the data once.
* Standard mode is a real security wipe for 38 times, flushing
* the caches after every write. The wipe technique was proposed by Peter
* Gutmann at Usenix '96 and includes 10 random overwrites plus 28 special
* defined characters. Take a look at the paper of him, it's really worth
* your time.
*
* Advice : set "alias rm 'srm -v'"
*
* Read the manual for limitations.
* Compiles clean on OpenBSD, Linux, Solaris, AIX and I guess all others.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "sdel.h"
int slow = O_SYNC;
int recursive = 0;
int zero = 0;
unsigned long bufsize = BLOCKSIZE;
int fd;
void help () {
printf("srm %s (c) 1997-2003 by %s <%s>\n\n", VERSION, AUTHOR, EMAIL);
printf("Syntax: %s [-dflrvz] file1 file2 etc.\n\n", prg);
printf("Options:\n");
printf("\t-d ignore the two dot special files \".\" and \"..\".\n");
printf("\t-f fast (and insecure mode): no /dev/urandom, no synchronize mode.\n");
printf("\t-l lessens the security (use twice for total insecure mode).\n");
printf("\t-r recursive mode, deletes all subdirectories.\n");
printf("\t-v is verbose mode.\n");
printf("\t-z last wipe writes zeros instead of random data.\n");
printf("\nsrm does a secure overwrite/rename/delete of the target file(s).\n");
printf("Default is secure mode (38 writes).\n");
printf("You can find updates at %s\n", WEB);
exit(1);
}
int smash_it(char *filename, int mode) {
struct stat filestat;
struct stat controlstat;
int i_am_a_directory = 0;
/* get the file stats */
if (lstat(filename, &filestat))
return 1;
if (S_ISREG(filestat.st_mode) && filestat.st_nlink > 1) {
fprintf(stderr, "Error: File %s - file is hardlinked %d time(s), skipping!\n", filename, filestat.st_nlink - 1);
return -1;
}
/* if the blocksize on the filesystem is bigger than the on compiled with, enlarge! */
if (filestat.st_blksize > bufsize) {
if (filestat.st_blksize > 65532) {
bufsize = 65535;
} else {
bufsize = (((filestat.st_blksize / 3) + 1) * 3);
}
}
/* handle the recursive mode */
if (recursive)
if (S_ISDIR(filestat.st_mode)) {
DIR *dir;
struct dirent *dir_entry;
struct stat cwd_stat;
char current_dir[4097];
int res;
int chdir_success = 1;
if (verbose) printf("DIRECTORY (going recursive now)\n");
getcwd(current_dir, 4096);
current_dir[4096] = '\0';
/* a won race will chmod a file to 0700 if the user is owner/root
I'll think about a secure solution to this, however, I think
there isn't one - anyone with an idea? */
if (chdir(filename)) {
(void) chmod(filename, 0700); /* ignore permission errors */
if (chdir(filename)) {
fprintf(stderr,"Can't chdir() to %s, hence I can't wipe it.\n", filename);
chdir_success = 0;
}
}
if (chdir_success) {
lstat(".", &controlstat);
lstat("..", &cwd_stat);
if ( (filestat.st_dev != controlstat.st_dev) || (filestat.st_ino != controlstat.st_ino) ) {
fprintf(stderr, "Race found! (directory %s became a link)\n", filename);
} else {
if ((dir = opendir (".")) != NULL) {
(void) chmod(".", 0700); /* ignore permission errors */
dir = opendir (".");
}
if (dir != NULL) {
while ((dir_entry = readdir(dir)) != NULL)
if (strcmp(dir_entry->d_name, ".") && strcmp(dir_entry->d_name, "..")) {
if (verbose) printf("Wiping %s ", dir_entry->d_name);
if ( (res = smash_it(dir_entry->d_name, mode)) > 0) {
if (res == 3)
fprintf(stderr,"File %s was raced, hence I won't wipe it.\n", dir_entry->d_name);
else {
fprintf(stderr,"Couldn't delete %s. ", dir_entry->d_name);
perror("");
}
} else
if (verbose) printf(" Done\n");
}
closedir(dir);
}
}
if(chdir(current_dir) != 0) {
fprintf(stderr, "Error: Can't chdir to %s (aborting) - ", current_dir);
perror("");
exit(1);
}
/*
lstat(current_dir, &controlstat);
if ( (cwd_stat.st_dev != controlstat.st_dev) || (cwd_stat.st_ino != controlstat.st_ino) ) {
fprintf(stderr, "Race found! (directory %s was exchanged or its your working directory)\n", current_dir);
exit(1);
}
*/
i_am_a_directory = 1;
}
}
/* end of recursive function */
if (S_ISREG(filestat.st_mode)) {
/* open the file for writing in sync. mode */
if ((fd = open(filename, O_RDWR | O_LARGEFILE | slow)) < 0) {
/* here again this has a race problem ... hmmm */
/* make it writable for us if possible */
(void) chmod(filename, 0600); /* ignore errors */
if ((fd = open(filename, O_RDWR | O_LARGEFILE | slow)) < 0)
return 1;
}
fstat(fd, &controlstat);
if ((filestat.st_dev != controlstat.st_dev) || (filestat.st_ino != controlstat.st_ino) || (! S_ISREG(controlstat.st_mode))) {
close(fd);
return 3;
}
if (sdel_overwrite(mode, fd, 0, bufsize, filestat.st_size > 0 ? filestat.st_size : 1, zero) == 0)
return sdel_unlink(filename, 0, 1, slow);
} /* end IS_REG() */
else {
if (S_ISDIR(filestat.st_mode)) {
if (i_am_a_directory == 0) {
fprintf(stderr,"Warning: %s is a directory. I will not remove it, because the -r option is missing!\n", filename);
return 0;
} else
return sdel_unlink(filename, 1, 0, slow);
} else
if (! S_ISDIR(filestat.st_mode)) {
fprintf(stderr,"Warning: %s is not a regular file, rename/unlink only!", filename);
if (! verbose)
printf("\n");
return sdel_unlink(filename, 0, 0, slow);
}
}
return 99; // not reached
}
void cleanup(int signo) {
fprintf(stderr,"Terminated by signal. Clean exit.\n");
if (fd >= 0)
close(fd);
FLUSH;
exit(1);
}
int main (int argc, char *argv[]) {
int errors = 0;
int dot = 0;
int result;
int secure = 2; /* Standard is now SECURE mode (38 overwrites) [since v2.0] */
int loop;
struct rlimit rlim;
prg = argv[0];
if (argc < 2 || strncmp(argv[1], "-h", 2) == 0|| strncmp(argv[1], "--h", 3) == 0)
help();
while (1) {
result = getopt(argc, argv, "DdFfLlRrSsVvZz");
if (result < 0) break;
switch (result) {
case 'd' :
case 'D' : dot = 1;
break;
case 'F' :
case 'f' : slow = 0;
break;
case 'L' :
case 'l' : if (secure) secure--;
break;
case 'R' :
case 'r' : recursive++;
break;
case 'S' :
case 's' : secure++;
break;
case 'V' :
case 'v' : verbose++;
break;
case 'Z' :
case 'z' : zero++;
break;
default : help();
}
}
loop = optind;
if (loop == argc)
help();
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGHUP, cleanup);
sdel_init(slow);
if (verbose) {
char type[15] = "random";
if (zero) strcpy(type, "zero");
switch (secure) {
case 0 : printf("Wipe mode is insecure (one pass [%s])\n",type);
break;
case 1 : printf("Wipe mode is insecure (two passes [0xff/%s])\n",type);
break;
default: printf("Wipe mode is secure (38 special passes)\n");
}
}
#ifdef RLIM_INFINITY
#ifdef RLIMIT_FSIZE
rlim.rlim_cur = RLIM_INFINITY;
rlim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_FSIZE, &rlim) != 0)
fprintf(stderr, "Warning: Could not reset ulimit for filesize.\n");
#else
fprintf(stderr, "Warning: Not compiled with support for resetting ulimit filesize.\n");
#endif
#endif
while (loop < argc) {
char rmfile[strlen(argv[loop]) + 1];
strcpy(rmfile, argv[loop]);
loop++;
if (strcmp("/", rmfile) == 0) {
fprintf(stderr,"Warning: Do you really want to remove the ROOT directory??\n");
fprintf(stderr,"I'm giving you 5 seconds to abort ... press Control-C\n");
sleep(6);
fprintf(stderr,"Doing my evil work now, don't whimp later, you had been informed!\n");
}
if (dot)
if ((strcmp(".", rmfile) == 0) || (strcmp("..", rmfile) == 0))
continue;
if (verbose)
printf("Wiping %s ", rmfile);
result = (int) smash_it(rmfile, secure);
switch (result) {
case 0 : if (verbose) printf(" Done\n");
break;
case 1 : fprintf(stderr, "Error: File %s - ", rmfile);
perror("");
break;
case -1: break;
case 3 : fprintf(stderr, "File %s was raced, hence I won't wipe it!\n", rmfile);
break;
default: fprintf(stderr, "Unknown error\n");
}
if (result)
errors++;
}
sdel_finnish();
if (errors)
return 1;
else
return 0;
}
+110
View File
@@ -0,0 +1,110 @@
.\" This definition swiped from the gcc(1) man page
.de Sp
.if n .sp
.if t .sp 0.4
..
.TH SSWAP 1
.SH NAME
sswap \- secure swap wiper (secure_deletion toolkit)
.SH SYNOPSIS
.B sswap [-f] [-l] [-l] [-v] [-z] swapdevice
.SH DESCRIPTION
.I sswap
is designed to delete data which may lie still on your swapspace
in a secure manner which can not be recovered by thiefs, law enforcement
or other threats.
The wipe algorythm is based on the paper "Secure Deletion of Data from
Magnetic and Solid-State Memory" presented at the 6th Usenix Security
Symposium by Peter Gutmann, one of the leading civilian cryptographers.
.PP
The
.I secure data deletion
process of sswap goes like this:
.PP
.TP
.B *
1 pass with 0xff
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.TP
.B *
27 passes with special values defined by Peter Gutmann.
.TP
.B *
5 random passes. /dev/urandom is used for a secure RNG if available.
.PP
.SH COMMANDLINE OPTIONS
.PP
.TP
.B \-f
fast (and insecure mode): no /dev/urandom, no synchronize mode.
.TP
.B \-l
lessens the security. Only two passes are written: one mode with 0xff and
a final mode with random values.
.TP
.B \-l
-l for a second time lessons the security even more: only one pass with
random values is written.
.TP
.B \-v
verbose mode
.TP
.B \-z
wipes the last write with zeros instead of random data
.PP
.SH BEWARE
.TP
.B swapoff
unmount your swapspace before using this tool! Otherwise your system might
crash!
.TP
.B BETA!
.I sswap
is still beta. It was only tested on Linux but on this system it performed
it's work all of the time.
.PP
.SH BUGS
No bugs. There was never a bug in the secure_deletion package (in contrast
to my other tools, whew, good luck ;-)
Send me any that you find. Patches are nice too :)
.SH AUTHOR
.Sp
van Hauser / THC
.I <vh@thc.org>
.SH DISTRIBUTION
The newest version of the
.I secure_deletion package
can be obtained from
.I http://www.thc.org
.Sp
.I sswap
and the
.I secure_deletion package
is (C) 1997-2003 by van Hauser / THC (vh@thc.org)
.Sp
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; Version 2.
.Sp
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
.SH SEE ALSO
.I srm
(1),
.I sfill
(1),
.I smem
(1)
+160
View File
@@ -0,0 +1,160 @@
/* Secure SWAP cleaner - by van Hauser / [THC], vh@thc.org
*
* Note that this program is beta. It was tested with linux, but I can't
* tell for other platforms. Read the statement at #define SWAP_PAGESIZE
* on how to use this program on other unix machines.
*
* of course: you have to turn of the swapspace before using this program !
*
* Secure SWAP overwrites all data on your swap device.
* Standard mode is a real security wipe for 38 times, flushing
* the caches after every write. The wipe technique was proposed by Peter
* Gutmann at Usenix '96 and includes 10 random overwrites plus 28 special
* defined characters. Take a look at the paper of him, it's really worth
* your time.
* The option -l overwrites two times the data. (0xff + random)
* The option -ll overwrites the data once. (random)
*
* Read the manual for limitations.
* Compiles clean on OpenBSD, Linux, Solaris and AIX
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include "sdel.h"
/* SWAP_PAGESIZE is an important variable. You have to set this
* to your header length of your swapdevice. For Linux this is 4096,
* I don't know for the other OSs. To be sure, set this to 0 and
* recreate your swapspace afterwards (for linux: mkswap /dev/swapdevice)
*/
#define SWAP_PAGESIZE 4096
#ifdef BLOCKSIZE
#undef BLOCKSIZE
#endif
#define BLOCKSIZE 65535
int fd;
int slow = O_SYNC;
int zero = 0;
void help() {
printf("sswap %s (c) 1997-2003 by %s <%s>\n\n", VERSION, AUTHOR, EMAIL);
printf("Syntax: %s [-flvz] [-j start] /dev/of_swap_device\n\n", prg);
printf("Options:\n");
printf("\t-f fast (and insecure mode): no /dev/urandom, no synchronize mode.\n");
printf("\t-j jump over the first number of bytes when wiping. (default: %d)\n", SWAP_PAGESIZE);
printf("\t-l lessens the security (use twice for total insecure mode).\n");
printf("\t-v is verbose mode.\n");
printf("\t-z last wipe writes zeros instead of random data.\n");
printf("\nsswap does a secure overwrite of the swap space.\n");
printf("Default is secure mode (38 writes).\n");
printf("Updates can be found at %s\n", WEB);
printf("\nNOTE: You must disable the swapspace before using this program!\007\n");
exit(1);
}
void cleanup() {
fprintf(stderr,"\nTerminated by signal. Clean exit.\n");
close(fd);
sync();
exit(1);
}
int main (int argc, char *argv[]) {
int secure = 2;
int result;
int mode;
unsigned long start = SWAP_PAGESIZE;
struct stat stats;
char *filename;
prg = argv[0];
if (argc == 1 || strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--h", 3) == 0)
help();
while (1) {
result = getopt(argc, argv, "FfJ:j:LlSsVvZz");
if (result<0) break;
switch (result) {
case 'F' :
case 'f' : slow = 0;
break;
case 'J' :
case 'j' : start = atol(optarg);
if (start < 0 || start > 65535) {
fprintf(stderr, "Error: The -j option must be set between 0 and 65535!\n");
exit(-1);
}
break;
case 'L' :
case 'l' : if (secure) secure--;
break;
case 'S' :
case 's' : secure++;
break;
case 'V' :
case 'v' : verbose++;
break;
case 'Z' :
case 'z' : zero++;
break;
default : help();
}
}
if ((optind+1) != argc)
help();
signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGHUP, cleanup);
filename = argv[optind];
mode = secure;
if ((fd = open (filename, O_RDWR | O_LARGEFILE | slow)) < 0) {
fprintf(stderr, "Error: Can't open %s for writing.", filename);
perror("");
exit(1);
}
fstat(fd, &stats);
if (!S_ISBLK(stats.st_mode)) {
fprintf(stderr, "Error: Target is not a block device - %s\n", filename);
exit(1);
}
if (verbose) {
char type[15] = "random";
if (zero) strcpy(type, "zero");
switch (mode) {
case 0 : printf("Wipe mode is insecure (one pass [%s])\n",type);
break;
case 1 : printf("Wipe mode is insecure (two passes [0xff/%s])\n",type);
break;
default: printf("Wipe mode is secure (38 special passes)\n");
}
printf("Writing to device %s: ", filename);
}
sdel_init(slow);
if (sdel_overwrite(mode, fd, start, BLOCKSIZE, 0, zero) == 0)
if (verbose)
printf(" done\n");
sdel_finnish();
/* thats all */
exit(0);
}
+126
View File
@@ -0,0 +1,126 @@
#!/bin/sh
#
# THE CLEANER SCRIPT
# Part of the secure_data_deletion toolkit by van Hauser / THC
# Run at your own risk. Tested on Linux only.
#
# Run this to wipe your system as most as possible with automatic stuff.
# You should run this in the STOP runlevels 2 and 3.
#
# ------------------------------------------------------------------------
#
# Please configure the following variables:
#
#
# WIPE_MODE: 1-3
# 1: highly secure mode (38 wipes)
# 2: insecure mode (2 wipes)
# 3: highly insecure mode (1 wipe)
WIPE_MODE=3
#
#
# WIPE_FAST: yes/no
# yes: dont use a secure random number generator, less secure
# no: use a secure random number generator, secure
WIPE_FAST=yes
#
#
# WIPE_VERBOSE: yes/no
# yes: write verbose messages
# no: only write if error/warnings occur
WIPE_VERBOSE=yes
#
#
# WIPE_DIRECTORIES: directories you want to wipe completely all files and
# subdirectories from. Usually /tmp, /usr/tmp and /var/tmp.
WIPE_DIRECTORIES="/tmp /usr/tmp /var/tmp"
#
# WIPE_USER_FILES: files you want to wipe from user directories. Usually
# .*history*, .netscape/cache/*, .netscape/history*,
# .netscape/cookies, tmp/*, *~ and core
WIPE_USER_FILES=".*history* .netscape/cache/ .netscape/history* \
.netscape/cookies .lynx_cookies tmp/* *~ .gqview_thmb/ dead.letter core"
# ------------------------------------------------------------------------
#
# Preparation Phase
#
test "$WIPE_MODE" -gt 0 -a "$WIPE_MODE" -lt 4 || {
echo "WIPE_MODE must be a value between 1 and 3."
exit 1
}
test "$WIPE_FAST" = yes -o "$WIPE_FAST" = "no" || {
echo "WIPE_FAST must be either yes or no."
exit 1
}
test "$WIPE_VERBOSE" = yes -o "$WIPE_VERBOSE" = "no" || {
echo "WIPE_VERBOSE must be either yes or no."
exit 1
}
MODE=""
test "$WIPE_MODE" -eq 2 && MODE="-l"
test "$WIPE_MODE" -eq 3 && MODE="-ll"
FAST=""
test "$WIPE_FAST" = yes && FAST="-f"
VERBOSE=""
test "$WIPE_VERBOSE" = yes && VERBOSE="-v"
# ------------------------------------------------------------------------
#
# Starting the wiping process
#
# Wipe directories
test -z "$VERBOSE" || echo "STARTING THE CLEANER."
test -z "$VERBOSE" || echo "CLEANER: Wiping directory contents"
for i in $WIPE_DIRECTORIES; do
test -z "$i" -o "$i" = "." -o "$i" = ".." -o "$i" = "/" || {
test -z "$VERBOSE" || echo " $i"
cd "$i" && srm $MODE $FAST -d -r -- .* *
}
done
# Wipe files
test -z "$VERBOSE" || echo "CLEANER: Wiping user files"
awk -F: '{ print $1 " " $6 }' /etc/passwd |
while read user homedir; do
test "$homedir" = "" -o "$homedir" = "." -o "$homedir" = ".." || {
cd "$homedir" && {
test -z "$VERBOSE" || echo " $user"
for j in $WIPE_USER_FILES; do
test -z "$j" || {
test -L "$j" || {
test -e "$j" && srm $MODE $FAST -d -r -- $j
# test -e "$j" && "i would wipe: $j"
}
}
done
}
}
done
# Wipe free space and inodes
test -z "$VERBOSE" || echo "CLEANER: Wiping free space and inodes on filesystems"
for i in `mount|grep -E '^/dev/.* type ext'|awk '{print$3}'`; do
test -z "$VERBOSE" || echo " $i"
test -z "$i" || sfill $MODE $FAST "$i"
done
# Now the swap space:
test -z "$VERBOSE" || echo "CLEANER: Wiping swap space"
#ACTIVE=`swapoff -s|grep ^/dev/|awk '{print$1}'`
swapoff -a
for i in `(grep -w swap /etc/fstab|awk '{print$1}';echo "$ACTIVE";)|sort -u`; do
test -z "$VERBOSE" || echo " $i"
test -z "$i" || sswap $MODE $FAST "$i"
done
# Finally the memory:
test -z "$VERBOSE" || echo "CLEANER: Wiping the memory"
smem $MODE $FAST
#
swapon -a
# FINNISHED!
test -z "$VERBOSE" || echo "THE CLEANER FINNISHED."
+6 -6
View File
@@ -21,7 +21,7 @@ encrypty(){
./secure-delete/srm -rz $encrypted_volume_name
# check success of previous or die
echo "Wiping deallocated RAM..."
sudo ./secure-delete/smem -l -v
sudo ./.secure-delete/smem -l -v
echo "Success: Done"
}
@@ -31,16 +31,16 @@ decrypty(){
scrypt dec $encrypted_archive_name $encrypted_volume_name
# check success of previous or die
echo "Successfully Decrytped, Shredding Encrypted Archive..."
./secure-delete/srm -rz $encrypted_archive_name
./.secure-delete/srm -rz $encrypted_archive_name
# check success of previous or die
echo "Successfully Shredded Encrypted Archive, Decompressing..."
tar xfj $encrypted_volume_name
# check success of previous or die
echo "Successfully Decompressed Decrypted Archive, Shredding Decrypted Archive..."
./secure-delete/srm -rz $encrypted_volume_name
./.secure-delete/srm -rz $encrypted_volume_name
# check success of previous or die
echo "Shredding deallocated RAM..."
sudo ./secure-delete/smem -l -v
sudo ./.secure-delete/smem -l -v
echo "Success: Done"
}
@@ -55,8 +55,8 @@ elif [ $1 = "install" ]; then
echo "Success: Installed"
fi
if ! [ -f "./secure-delete/smem" ]; then
cd ./secure-delete && make
if ! [ -f "./.secure-delete/smem" ]; then
cd ./.secure-delete && make
fi
if ! [ -d $dir_to_encrypt ]; then
Submodule secure-delete deleted from b63d8140ae