Compare commits

..

25 Commits

Author SHA1 Message Date
PrincessPi 8ec2a3dde5 migration 2026-05-26 21:55:29 -06:00
PrincessPi a8f384b201 migration 2026-05-26 21:24:08 -06:00
PrincessPi 668bab17c6 awww 2024-09-12 23:20:17 -06:00
PrincessPi ff69e14c94 Reeeen 2024-09-12 23:15:40 -06:00
PrincessPi a73a06cc61 Red + Green = Reeen 2024-09-12 23:12:54 -06:00
PrincessPi a1c9dd3fdb fixyfungus 2024-09-12 23:02:09 -06:00
PrincessPi a755899f8a :tbh_bounce: 2024-09-12 23:00:45 -06:00
PrincessPi d79c89fd37 awoooooo 2024-09-12 22:58:28 -06:00
PrincessPi 638414b873 okiedokie 2024-09-12 22:42:28 -06:00
PrincessPi 99576d7c40 fixy da makeyfile mayhaps or even perchance 2024-09-12 22:37:03 -06:00
PrincessPi 2aeead77e9 fixyyy 2024-09-12 22:31:33 -06:00
PrincessPi e0fce04767 awoooo 2024-09-12 22:30:21 -06:00
PrincessPi 9ae39356a9 wagglewunguswoo 2024-09-12 22:24:27 -06:00
PrincessPi 0c3234dec5 ADDYONEEE 2024-09-12 22:21:39 -06:00
PrincessPi fb4f59e123 ayyy 2024-09-12 22:18:43 -06:00
PrincessPi f96f255f3e fixed a silly typooooo 2024-09-12 22:17:50 -06:00
PrincessPi f8365df8cf wooo added da silly secure-delete code with da silly edits 2024-09-12 22:09:33 -06:00
PrincessPi f744fd0f3d updoot 2024-09-12 21:54:34 -06:00
PrincessPi c41d5ab89e updooted stuffs to add memory shreddannn 2024-09-12 21:52:48 -06:00
PrincessPi b70c3cc0c4 documentation updoots and added the passphrase guide pdf 2024-09-12 21:02:32 -06:00
PrincessPi 75198873e5 updoots and a rename 2024-09-12 13:29:50 -06:00
PrincessPi 34db75be21 smol polish to script 2024-09-12 05:15:21 -06:00
PrincessPi fe94c0b5af fixed more readme lmao 2024-09-12 04:59:40 -06:00
PrincessPi 3de4f887d2 fixed copying.txt location 2024-09-12 04:57:42 -06:00
PrincessPi e68400ebc9 initial commit 2024-09-12 04:56:50 -06:00
23 changed files with 2631 additions and 2 deletions
+35
View File
@@ -0,0 +1,35 @@
CC=gcc
OPT=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
INSTALL_DIR=/usr/local/bin
MAN_DIR=/usr/local/man
OPT_MOD=-D__KERNEL__ -DMODULE -fomit-frame-pointer -fno-strict-aliasing -pipe
all: sdel-lib.o srm sfill sswap smem
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
+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."
+59
View File
@@ -1,2 +1,61 @@
# hiddencrypto
Silly lil script for using [scrypt](https://github.com/Tarsnap/scrypt), [secure-delete (srm)](https://github.com/BlackArch/secure-delete), and tar to open and close an encrypted (scrypt) and compressed (bz2) and shred (srm) any lingering data immediately.
## Textwall about the frickin thing
Encryption MY way!
I was totally fucked off by the normie file encryption utilities like Veracrypt,. Cryptomator and `openssl enc` because in practice they have a couple absolutely glaring flaws.
For one, they are STILL using PMDKF2 as the KDF (Key Derivation Function, the algo that deterministically generates the 256-bit key from a passphrase) and the simple truth is that PBDKF2 is criminally outdated and no ever increasing number of iterations into the millions and millions are ever gonna change that.
So, I selected the gigachad KDF, Scrypt to generate the 256-bit key. It features appx. 10 billion times the hardware cost to crack vs `openssl enc` it has appx. 20,000 times greater hardware cost to crack vs PBDK2 with any number of iterations, and appx. 4,000 times the hardware cost to crack vs Bcrypt, the algo used to hash Linux passwords.
Scrypt is stable and solid, and has passed countless rounds of cryptanalysis and revision by Cypherpunks and the wider cryptography community, so it should be quite cryptographically secure.
The other glaring issue that the normie cryptography utilities had was the fact that when files are moved to the volume, there is no shredding of the "ghost" file at the location it camer from, and in some cases, even left data traes on the disk without securely shredding them to clean up.
To that end, I'm using the secure-delete package to secure wipe any temporary or ghost bytes off the record.
srm is used to delete files and directories immediately upon compl,eting the next step successfully.
smem is used to wipe unallocated RAM to ensure that no remaning traces of data are left in memory even with a sophisticated memory forensics or cold boot attack.
//todo: There will also have an option to wide empty space on a given disk for convenience.
//todo: A feature that shreds the first 1024 bytes of the encrypted archive so that the data is completely nuked and unrecoverable even with the passphrase. The feature should be easily integrated into other systems such that a nuke order can be executed from any custom event or trigger e.g. Alexa command, key combination on another comptuer, time based dead man's switch, etc.
## Back Up Your Shit
* This script is probably as unstable as I am and will probably end up nuking your files
* If you lose your passphrase or type it in wrong twice on encryption, your data has gone bye bye
* For real, back up your shit
* Do not trust me or my code
## Important Details
* Each time you encrypt the directory, it will use a brand new passphrase that you input. You can still use the old one, but it is set each time to whatever you enter twice regardless of the previous passphrase
* Use a [secure passphrase](assets/how-to-create-a-secure-passphrase-2017-08-10_HQP.pdf) and DO NOT SAVE ON COMPUTER OR PASSSWORD MANAGER! Only save your passphrase on **PHYSICAL PAPER**
* **Back Up Your Shit!** This is a completely unforgiving script when it comes to setting the password wrong
* When creating encrypted backups, be certain to use a seperate, completely dissimilar passphrase for it. Store this passphrase on a seperate piece of paper, stored seperately
* **Test Your Backups** Make completely sure they work and that you a precise and accurate passphrase for them
* If your system has automatic backuops, RAID, cloud storage uplaods, or any other type of redundancy system in place, you should exclude the hiddebncrypto directory from it. Otherwise, partial or even data leaking data could be copied or even uploaded
* **BE AWARE** When moving files from unencrypted drives to the encrypted arcive, **the original files may be recoverable from the original location** even if they are not visible. It is a best practice to shred empty space on that disk afterwords to ensure the orignal data is not forensically recoverable
* Best practice is to disable networking when using hiddencrypto
## Usage
To install:
```
cd ~
git clone https://github.com/PrincessPi3/hiddencrypto.git
cd hiddencrypto
sudo sh hiddencrypto.sh install
```
To encrypt:
`sh hiddencrypto.sh enc`
To decrypt:
`sh hiddencrypto.sh dec`
## License
Distributed under the [WTFPL Version 2](http://www.wtfpl.net/) [![WTFPL](assets/wtfpl-badge.png)](http://www.wtfpl.net/)
See [assets/COPYING.txt](assets/COPYING.txt) for text
```
Todo:
Potential memory key leaks
Potential OS key leaks
Potential side-channel attacks
```
+4
View File
@@ -0,0 +1,4 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

+84
View File
@@ -0,0 +1,84 @@
#!/bin/sh
# fail on error
set -e
dir_to_encrypt=./to_encrypt
encrypted_archive_name=./.volume.bin
encrypted_volume_name=./.encrypted_volume.tar.bz2
encrypty(){
echo "Compressing Directory..."
tar cfj $encrypted_volume_name $dir_to_encrypt
echo "Sucesfully Compressed, Shredding Directory..."
srm -rz $dir_to_encrypt
echo "Successfully Shredded Directory, Encrypting. Please Input Passphrase..."
scrypt enc $encrypted_volume_name $encrypted_archive_name
echo "Successfully Encrypted, Shredding Archive..."
srm -rz $encrypted_volume_name
echo "Wiping deallocated RAM..."
sudo smem -ll # -ll is a single overwrite mode with 0xFF, single mode used for speed
echo "Success: Encryption Done"
}
decrypty(){
echo "Starting..."
echo "Decrypting. Please Input Passphrase..."
scrypt dec $encrypted_archive_name $encrypted_volume_name
echo "Successfully Decrytped, Shredding Encrypted Archive..."
srm -rz $encrypted_archive_name
echo "Successfully Shredded Encrypted Archive, Decompressing..."
tar xfj $encrypted_volume_name
echo "Successfully Decompressed Decrypted Archive, Shredding Decrypted Archive..."
srm -rz $encrypted_volume_name
echo "Wiping deallocated RAM..."
sudo smem -ll # -ll is a single overwrite mode with 0xFF, single mode used for speed
echo "Success: Done"
}
if [ "$1" = "enc" ]; then
encrypty
elif [ "$1" = "dec" ]; then
decrypty
elif [ $1 = "install" ]; then
if ! [ -f "$(command -v scrypt)" ] && [ -f "$(command -v tar)" ] && [ -f "$(command -v make)" ]; then
echo "Needed Applications Not Found, Installing..."
sudo apt install scrypt secure-delete tar build-essential
echo "Success: Installed"
fi
if ! [ -f "./.secure-delete/smem" ]; then
echo "Building Edited secure-delete Utilities..."
cd ./.secure-delete
sudo make
echo "Installing Edited secure-delete Utiliies..."
sudo make install
echo "Cleaning Up From Build..."
cd ..
sudo srm -rz ./.secure-delete
echo "Success: secure-delete Installed"
fi
if ! [ -d $dir_to_encrypt ]; then
echo "$dir_to_encrypt Not Found, Creating..."
mkdir $dir_to_encrypt
fi
echo "Success: Ready to use"
else
echo "Usage:\nEncrypt:\n\tsh hiddencrypto.sh enc\nDecrypt:\n\tsh hiddencrypto.sh dec\nInstall:\n\tsh hiddencrypto.sh install"
fi
View File