修复hash_32的bug,增加进程监控(没做完,还需要加一些东西)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
65
linux_kernel/hook.c
Normal 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
4
linux_kernel/hook.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "head.h"
|
||||
extern bool init_hooks(void);
|
||||
extern void uninstall_hooks(void);
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
30
linux_kernel/my_kallsyms_lookup_name.c
Normal file
30
linux_kernel/my_kallsyms_lookup_name.c
Normal 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;
|
||||
}
|
||||
4
linux_kernel/my_kallsyms_lookup_name.h
Normal file
4
linux_kernel/my_kallsyms_lookup_name.h
Normal 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);
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user