修复hash_32的bug,增加进程监控(没做完,还需要加一些东西)

This commit is contained in:
huoji
2023-05-08 22:44:27 +08:00
parent 7484922894
commit 7f1d3e37d3
48 changed files with 226 additions and 3350 deletions

View File

@@ -356,9 +356,24 @@ msg.o: /home/duck/project/linux_kernel/msg.c \
include/net/netns/hash.h include/net/inet_timewait_sock.h \
include/net/timewait_sock.h include/uapi/linux/tcp.h include/linux/udp.h \
include/uapi/linux/udp.h include/linux/inet.h include/linux/cdev.h \
include/linux/kprobes.h include/linux/ftrace.h \
include/linux/trace_recursion.h include/linux/trace_clock.h \
arch/x86/include/asm/trace_clock.h include/linux/kallsyms.h \
include/linux/ptrace.h include/linux/pid_namespace.h \
include/uapi/linux/ptrace.h arch/x86/include/asm/ftrace.h \
include/linux/compat.h include/uapi/linux/aio_abi.h \
arch/x86/include/asm/compat.h include/linux/sched/task_stack.h \
include/uapi/linux/magic.h arch/x86/include/asm/user32.h \
include/asm-generic/compat.h arch/x86/include/asm/syscall_wrapper.h \
include/linux/freelist.h include/linux/rethook.h \
arch/x86/include/asm/kprobes.h include/asm-generic/kprobes.h \
arch/x86/include/asm/text-patching.h arch/x86/include/asm/insn.h \
arch/x86/include/asm/inat.h arch/x86/include/asm/inat_types.h \
/home/duck/project/linux_kernel/some_struct.h \
/home/duck/project/linux_kernel/global.h \
/home/duck/project/linux_kernel/msg.h \
/home/duck/project/linux_kernel/ip_hashmap.h \
/home/duck/project/linux_kernel/network.h \
/home/duck/project/linux_kernel/client_msg.h
/home/duck/project/linux_kernel/client_msg.h \
/home/duck/project/linux_kernel/my_kallsyms_lookup_name.h \
/home/duck/project/linux_kernel/hook.h

View File

@@ -1,6 +1,6 @@
CONFIG_MODULE_SIG=n
obj-m += safe_duck.o
safe_duck-objs := main.o msg.o global.o some_struct.o ip_hashmap.o network.o client_msg.o
safe_duck-objs := main.o msg.o global.o some_struct.o ip_hashmap.o network.o client_msg.o my_kallsyms_lookup_name.o hook.o
PWD := $(shell pwd)
KVER := $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build

View File

@@ -1,5 +1,5 @@
0xe98895fa push_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0xb1b3bd13 get_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0xa24625c1 push_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0x3bd35293 get_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0xb3ceb32b get_msg_list_length /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0x38a1fb31 cleanup_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL
0x50632040 init_msg /home/duck/project/linux_kernel/safe_duck EXPORT_SYMBOL

View File

@@ -23,12 +23,16 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/hash.h>
#include <linux/kprobes.h>
#include "some_struct.h"
#include "global.h"
#include "msg.h"
#include "ip_hashmap.h"
#include "network.h"
#include "client_msg.h"
#include "my_kallsyms_lookup_name.h"
#include "hook.h"
#define DEVICE_NAME "safe_duck"
#define DEVICE_CNT 1
MODULE_LICENSE("GPL");

65
linux_kernel/hook.c Normal file
View File

@@ -0,0 +1,65 @@
#include "hook.h"
#include <linux/sched/signal.h>
#include <linux/kprobes.h>
#include <linux/unistd.h>
#include <linux/fs.h>
#define MAX_PATH_LEN 256
#define MAX_ARGS_LEN 4096
static struct kprobe kp = {
.symbol_name = "do_execveat_common.isra.0",
};
static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
struct task_struct *task = current;
struct task_struct *parent = task->parent;
struct mm_struct *mm = task->mm;
struct file *file;
char *pathname;
char *args_buf;
if (mm) {
file = mm->exe_file;
if (file) {
pathname = kmalloc(PATH_MAX, GFP_KERNEL);
if (pathname) {
printk(KERN_INFO "Program Path: %s\n",
d_path(&file->f_path, pathname, PATH_MAX));
}
}
}
args_buf = kmalloc(MAX_ARGS_LEN, GFP_KERNEL);
if (args_buf) {
if (copy_from_user(args_buf, (const void __user *)regs->di,
MAX_ARGS_LEN) == 0) {
args_buf[MAX_ARGS_LEN - 1] = '\0';
}
// kfree(args_buf);
}
printk(KERN_INFO "PID: %d\n", task->pid);
printk(KERN_INFO "PPID: %d\n", parent->pid);
printk(KERN_INFO "Program Name: %s\n", task->comm);
printk(KERN_INFO "Program Args: %s\n", args_buf);
if (args_buf) {
kfree(args_buf);
}
if (pathname) {
kfree(pathname);
}
return 0;
}
bool init_hooks(void) {
int ret;
ret = register_kprobe(&kp);
if (ret < 0) {
printk(KERN_ERR "register_kprobe failed, returned %d\n", ret);
return false;
}
kp.pre_handler = handler_pre;
printk(KERN_ERR "Planted kprobe at %p\n", kp.addr);
return true;
}
void uninstall_hooks(void) { unregister_kprobe(&kp); }

4
linux_kernel/hook.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
#include "head.h"
extern bool init_hooks(void);
extern void uninstall_hooks(void);

View File

@@ -1,4 +1,5 @@
#include "ip_hashmap.h"
#include <linux/jhash.h>
static struct ip_hash_table g_ip_hashtable;
void thread_demon_ip_hashmap(void *ctx) {
@@ -79,7 +80,12 @@ void check_resize_table(struct ip_hash_table *table) {
container_of(node, struct ip_hashmap_node_t, node);
hlist_del(&data->node);
int idx =
hash_32(data->info.ip_address_key, table->bucket_num);
jhash(&data->info.ip_address_key, sizeof(u32), 0) %
table->bucket_num;
// int idx =
// hash_32(data->info.ip_address_key,
// table->bucket_num);
hlist_add_head(&data->node, &new_heads[idx]);
}
}
@@ -91,11 +97,13 @@ void check_resize_table(struct ip_hash_table *table) {
}
// 获取并插入哈希表节点
void put_ipdata_by_hashmap(size_t ip_address_key,
struct ip_hashmap_info *info) {
void put_ipdata_by_hashmap(u32 ip_address_key, struct ip_hashmap_info *info) {
struct ip_hash_table *table = &g_ip_hashtable;
int idx = hash_32(ip_address_key, table->bucket_num);
// 新建哈希表节点
// int idx = hash_32(ip_address_key, table->bucket_num);
int idx =
jhash(&ip_address_key, sizeof(ip_address_key), 0) % table->bucket_num;
// 新建哈希表节点
struct ip_hashmap_node_t *data =
kmalloc(sizeof(struct ip_hashmap_node_t), GFP_KERNEL);
if (data) {
@@ -108,11 +116,16 @@ void put_ipdata_by_hashmap(size_t ip_address_key,
}
// 通过关键字获取哈希表节点
struct ip_hashmap_node_t *get_ipdata_by_hashmap(size_t ip_address_key) {
struct ip_hashmap_node_t *get_ipdata_by_hashmap(u32 ip_address_key) {
struct ip_hash_table *table = &g_ip_hashtable;
printk(KERN_ERR "ip_address_key %08X table->bucket_num: %d \n",
ip_address_key, table->bucket_num);
spin_lock(&table->lock);
int idx = hash_32(ip_address_key, table->bucket_num);
// int idx = hash_32(ip_address_key, table->bucket_num);
int idx =
jhash(&ip_address_key, sizeof(ip_address_key), 0) % table->bucket_num;
struct hlist_head *head = &table->heads[idx];
struct hlist_node *node = head->first;
while (node) {
@@ -129,11 +142,14 @@ struct ip_hashmap_node_t *get_ipdata_by_hashmap(size_t ip_address_key) {
}
// 从哈希表中删除节点
void del_ipdata_by_hashmap(size_t ip_address_key) {
void del_ipdata_by_hashmap(u32 ip_address_key) {
struct ip_hash_table *table = &g_ip_hashtable;
spin_lock(&table->lock);
int idx = hash_32(ip_address_key, table->bucket_num);
// int idx = hash_32(ip_address_key, table->bucket_num);
int idx =
jhash(&ip_address_key, sizeof(ip_address_key), 0) % table->bucket_num;
struct hlist_head *head = &table->heads[idx];
struct hlist_node *node = head->first;
while (node) {

View File

@@ -23,7 +23,7 @@ struct ip_meta_info_t {
size_t remove_time;
};
struct ip_hashmap_info {
size_t ip_address_key;
u32 ip_address_key;
struct syn_scan_info_t syn_scan_info;
struct crack_ip_info_t crack_ip_info;
struct ip_meta_info_t ip_meta_info;
@@ -34,8 +34,8 @@ struct ip_hashmap_node_t {
};
extern bool init_ip_hashmap(void);
extern void check_resize_table(struct ip_hash_table *table);
extern void put_ipdata_by_hashmap(size_t ip_address_key,
extern void put_ipdata_by_hashmap(u32 ip_address_key,
struct ip_hashmap_info *info);
extern struct ip_hashmap_node_t *get_ipdata_by_hashmap(size_t ip_address_key);
extern void del_ipdata_by_hashmap(size_t ip_address_key);
extern struct ip_hashmap_node_t *get_ipdata_by_hashmap(u32 ip_address_key);
extern void del_ipdata_by_hashmap(u32 ip_address_key);
extern void cleanup_iphashmap(void);

View File

@@ -110,13 +110,20 @@ int cleanup(void) {
}
destory_dev();
cleanup_msg();
uninstall_hooks();
return -1;
}
static int __init driver_entry(void) {
printk(KERN_WARNING "[DebugMessage] safe duck init\n");
if (init_kallsyms_lookup_name() == false) {
printk(KERN_ERR "Failed to init kallsyms_lookup_name\n");
return -1;
}
if (init_hooks() == false) {
printk(KERN_ERR "Failed to init kallsyms_lookup_name\n");
return -1;
}
// Initialize list of addresses
if (build_dev() == false) {
printk(KERN_ERR "Failed to build device\n");

View File

@@ -23,7 +23,7 @@ void push_msg(struct kernel_msg_t *msg) {
wake_up_interruptible(&g_r3_wait_queue);
}
}
void push_msg_new_ip_connect(size_t ip_address) {
void push_msg_new_ip_connect(u32 ip_address) {
struct kernel_msg_t *msg = kmalloc(sizeof(struct kernel_msg_t), GFP_KERNEL);
if (msg == NULL) {
printk(KERN_ERR "Failed to allocate memory for new msg\n");
@@ -33,7 +33,7 @@ void push_msg_new_ip_connect(size_t ip_address) {
msg->u.ip_action.src_ip = ip_address;
push_msg(msg);
}
void push_msg_syn_attack(size_t ip_address) {
void push_msg_syn_attack(u32 ip_address) {
struct kernel_msg_t *msg = kmalloc(sizeof(struct kernel_msg_t), GFP_KERNEL);
if (msg == NULL) {
printk(KERN_ERR "Failed to allocate memory for new msg\n");
@@ -43,7 +43,7 @@ void push_msg_syn_attack(size_t ip_address) {
msg->u.ip_action.src_ip = ip_address;
push_msg(msg);
}
void push_msg_ssh_bf_attack(size_t ip_address) {
void push_msg_ssh_bf_attack(u32 ip_address) {
struct kernel_msg_t *msg = kmalloc(sizeof(struct kernel_msg_t), GFP_KERNEL);
if (msg == NULL) {
printk(KERN_ERR "Failed to allocate memory for new msg\n");

View File

@@ -14,7 +14,7 @@ typedef struct kernel_msg_t {
int type;
union {
struct {
unsigned long src_ip;
unsigned int src_ip;
} ip_action;
} u;
};
@@ -23,7 +23,7 @@ typedef struct client_msg_t {
int type;
union {
struct {
unsigned long src_ip;
unsigned int src_ip;
unsigned long block_time;
} ip_address;
} u;
@@ -38,6 +38,6 @@ extern struct kernel_msg_t *get_msg(void);
extern size_t get_msg_list_length(void);
extern void cleanup_msg(void);
extern void init_msg(void);
extern void push_msg_syn_attack(size_t ip_address);
extern void push_msg_new_ip_connect(size_t ip_address);
extern void push_msg_ssh_bf_attack(size_t ip_address);
extern void push_msg_syn_attack(u32 ip_address);
extern void push_msg_new_ip_connect(u32 ip_address);
extern void push_msg_ssh_bf_attack(u32 ip_address);

View File

@@ -0,0 +1,30 @@
#include "my_kallsyms_lookup_name.h"
unsigned long (*g_kallsyms_lookup_name_fun)(const char *name) = NULL;
int kallsyms_lookup_name_pre(struct kprobe *p, struct pt_regs *regs) {
return 0;
}
static struct kprobe kp_kallsyms_lookup_name = {
.symbol_name = "kallsyms_lookup_name",
};
// 调用kprobe找到kallsyms_lookup_name的地址位置
int init_kallsyms_lookup_name_i(void) {
int ret = -1;
kp_kallsyms_lookup_name.pre_handler = kallsyms_lookup_name_pre;
ret = register_kprobe(&kp_kallsyms_lookup_name);
if (ret < 0) {
printk(KERN_INFO "register_kprobe failed, error:%d\n", ret);
return ret;
}
printk(KERN_INFO "kallsyms_lookup_name addr: %p\n",
kp_kallsyms_lookup_name.addr);
g_kallsyms_lookup_name_fun = (void *)kp_kallsyms_lookup_name.addr;
unregister_kprobe(&kp_kallsyms_lookup_name);
return ret;
}
bool init_kallsyms_lookup_name(void) {
init_kallsyms_lookup_name_i();
return g_kallsyms_lookup_name_fun != NULL;
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "head.h"
extern unsigned long (*g_kallsyms_lookup_name_fun)(const char *name);
extern bool init_kallsyms_lookup_name(void);

View File

@@ -1,6 +1,6 @@
#include "network.h"
void block_ip_address(size_t ip_address, size_t time_sec) {
void block_ip_address(u32 ip_address, size_t time_sec) {
struct ip_hashmap_node_t *data = get_ipdata_by_hashmap(ip_address);
const s64 current_time_sec = ktime_get_real_seconds();
@@ -17,7 +17,7 @@ void block_ip_address(size_t ip_address, size_t time_sec) {
data->info.ip_meta_info.remove_time = current_time_sec + time_sec;
data->info.ip_meta_info.is_attack = true;
}
bool check_is_blacklist_ip(size_t ip_address) {
bool check_is_blacklist_ip(u32 ip_address) {
struct ip_hashmap_node_t *data = get_ipdata_by_hashmap(ip_address);
if (data == NULL) {
return false;
@@ -37,7 +37,7 @@ bool check_syn_attack(struct iphdr *ip_header, struct sk_buff *skb) {
if (tcp_header->syn == 0 || tcp_header->ack || tcp_header->rst) {
break;
}
size_t ip_address_key = ip_header->saddr;
u32 ip_address_key = ip_header->saddr;
struct ip_hashmap_node_t *data = get_ipdata_by_hashmap(ip_address_key);
const s64 current_time_sec = ktime_get_real_seconds();
if (data == NULL) {
@@ -87,7 +87,7 @@ bool check_ssh_brute_force_attack(struct iphdr *ip_header,
if (ntohs(tcp_header->dest) != SSH_PORT) {
break;
}
size_t ip_address_key = ip_header->saddr;
u32 ip_address_key = ip_header->saddr;
struct ip_hashmap_node_t *data = get_ipdata_by_hashmap(ip_address_key);
const s64 current_time_sec = ktime_get_real_seconds();
if (data == NULL) {
@@ -118,20 +118,9 @@ bool check_ssh_brute_force_attack(struct iphdr *ip_header,
} while (false);
return is_block;
}
unsigned int network_callback(const struct nf_hook_ops *ops,
struct sk_buff *skb, const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
bool check_in_packet(struct iphdr *ip_header, struct sk_buff *skb) {
bool is_block = false;
do {
if (skb == NULL) {
break;
}
struct iphdr *ip_header = ip_hdr(skb);
if (ip_header == NULL) {
break;
}
if (check_is_blacklist_ip(ip_header->saddr)) {
is_block = true;
printk(KERN_ERR "Block ip address: %pI4\n", &ip_header->saddr);
@@ -153,7 +142,31 @@ unsigned int network_callback(const struct nf_hook_ops *ops,
// push ip address to list
push_msg_new_ip_connect(ip_header->saddr);
}
} while (false);
return is_block;
}
unsigned int network_callback(const struct nf_hook_ops *ops,
struct sk_buff *skb, const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) {
bool is_block = false;
do {
if (skb == NULL) {
break;
}
struct iphdr *ip_header = ip_hdr(skb);
if (ip_header == NULL) {
break;
}
if (ip_header->saddr == ip_header->daddr) {
// 本机连接本机的数据包
break;
}
if (skb->pkt_type == PACKET_HOST) {
// 这是一个输入数据包
is_block = check_in_packet(ip_header, skb);
}
} while (false);
return is_block ? NF_DROP : NF_ACCEPT;

View File

@@ -11,5 +11,5 @@ extern unsigned int network_callback(const struct nf_hook_ops *ops,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));
extern void block_ip_address(size_t ip_address, size_t time_sec);
extern bool check_is_blacklist_ip(size_t ip_address);
extern void block_ip_address(u32 ip_address, size_t time_sec);
extern bool check_is_blacklist_ip(u32 ip_address);