Цель этого исследования - обойти блокировку вредоносных сайтов. Поэтому я выбрал метод сегментации пакетов.
p c пытается разделить и отправить пакет с портом назначения 80 443. Проблема возникает после разделения и передачи. Вот как.
- используйте iptables для обнаружения выходных пакетов и управления ими с помощью netfilter_queue.
#iptables
iptables -A OUTPUT -p tcp --dport 443 -j NFQUEUE --queue-num 0
iptables -A OUTPUT -p tcp --dport 80 -j NFQUEUE --queue-num 0
Он управляется с помощью nfqnl_test. c. В nfqnl_test. c исходные пакеты разделяются с использованием сырого сокета, и выполняется вывод (raw socket: sendto ()). [проблемы] [1]:
https://i.stack.imgur.com/t9boJ.png - Разделение прошло успешно. Однако генерируются пакеты повторной передачи TCP.
На текущем этапе тестирования проблем нет, но когда я начал доступ к вредоносному сайту, повторная передача TCP заблокировала доступ к вредоносному сайту.
- Какие сетевые знания вам нужны? Помощь не терпится.
деление. cpp
void division_packet(u_char *packet)
{
struct iphdr * iphdr = reinterpret_cast<struct iphdr*>(packet);
struct tcphdr * tcphdr = reinterpret_cast<struct tcphdr*>(packet+(iphdr->ihl*4));
int iptcp_len = (iphdr->ihl*4) + (tcphdr->doff*4);
u_char *iptcp_temp = static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len)));
iptcp_temp = packet;
int tcp_segment_len = ntohs(iphdr->tot_len) - iptcp_len;
int i=0;
bool fst=true;
bool send=true;
int remainter_segment=tcp_segment_len -1;
while(send)
{
cout<<"################# [+] error checking #################\n";
u_char *assemble;
if(fst)
assemble=static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len+1)));
else
assemble=static_cast<u_char*>(malloc(static_cast<size_t>(iptcp_len+remainter_segment)));
// printf("%02x\n",static_cast<u_char>(packet[i]));
while(true)
{
if(i<iptcp_len){
assemble[i]=packet[i];
}
else if(tcp_segment_len >0)
{
if(fst){
assemble[i]=packet[i];
// remainter_segment = tcp_segment_len -1;
cout<<'\n'<<"[#]first division ------\n";
cout<<"[#]Segment full len: "<<tcp_segment_len<<'\n';
cout<<"[#]remainter len: "<<remainter_segment<<'\n';
struct sockaddr_in sock,sock2;
sock.sin_addr.s_addr =iphdr->saddr;
sock2.sin_addr.s_addr =iphdr->daddr;
cout<<"[#]Source IP: "<<inet_ntoa(sock.sin_addr)<<'\n';
cout<<"[#]Destination IP: "<<inet_ntoa(sock2.sin_addr)<<'\n';
cout<<"[#]Sport: "<<dec<<ntohs(tcphdr->source)<<'\n';
cout<<"[#]Dport: "<<dec<<ntohs(tcphdr->dest)<<'\n';
sendto_packet(assemble,iptcp_len+1);
i=0;
fst=false;
break;
}
else{
if((i-iptcp_len) < remainter_segment)
assemble[i]=packet[i+1];
else{
cout<<'\n'<<"[#]second division ------\n";
struct iphdr * as_ip = reinterpret_cast<struct iphdr*>(assemble);
as_ip->id=htons(ntohs(as_ip->id)+1);
struct tcphdr * as_tcphdr = reinterpret_cast<struct tcphdr*>(assemble+(iphdr->ihl*4));
as_tcphdr->seq = htonl(ntohl(as_tcphdr->seq) + 1);
sendto_packet(assemble,iptcp_len+remainter_segment);
send=false;
break;
}
}
}
i++;
}
free(assemble);
}
cout<<"[#] sendto division end\n";
cout<<"\n";
}
void sendto_packet(u_char *packet,int packet_len)
{
cout<<"[##] Packet Len: "<<packet_len<<"[sendto packet func]"<<'\n';
struct iphdr * iphdr = reinterpret_cast<struct iphdr*>(packet);
struct tcphdr * tcphdr = reinterpret_cast<struct tcphdr*>(packet+(iphdr->ihl*4));
// uint16_t tcp_len= (ntohs(iphdr->tot_len)-(iphdr->ihl*4));
// tcphdr->check = calTCPChecksum(packet,ntohs(iphdr->tot_len));
/*
cout<<"PROTOCOL: "<<dec<<iphdr->protocol<<'\n';
cout<<"Source IP: "<<hex<<iphdr->saddr<<'\n';
cout<<"Destination IP: "<<hex<<iphdr->daddr<<'\n';
cout<<"Sport: "<<tcphdr->source<<'\n';
cout<<"Dport: "<<tcphdr->dest<<'\n';
*/
struct sockaddr_in mysocket;
struct in_addr daddr;
int sockd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
if(sockd<0)
{
perror("error socket\n");
exit(1);
}
int on=1;
if(setsockopt(sockd,IPPROTO_IP,IP_HDRINCL,reinterpret_cast<char*>(&on),sizeof(on)) < 0)
{
perror("error setsockopt\n");
}
daddr.s_addr = iphdr->daddr;
mysocket.sin_addr = daddr;
mysocket.sin_family=AF_INET;
mysocket.sin_port = tcphdr->dest;
ssize_t res = sendto(sockd,packet,static_cast<size_t>(packet_len),0x0,
reinterpret_cast<struct sockaddr*>(&mysocket),sizeof(mysocket));
if(res != static_cast<ssize_t>(packet_len)){
perror("error sendto\n");
exit(1);
}
int c = close(sockd);
if(c<0)
{
perror("error close socket\n");
exit(1);
}
}