Получить подтверждение после синхронизации - PullRequest
2 голосов
/ 13 февраля 2012

Я кодировал небольшой инструмент, который просто генерирует пакет синхронизации на любой IP-адрес и номер порта, который вы ему даете, - и когда я вызывал Wireshark, отправленный пакет выглядит нормально, без ошибок или чего-то еще, он выглядит так же, как ваш типичный пакет TCP SYN. ​​

По какой-то причине ACK не отправляется сервером. Итак, есть две проблемы; один, нет ответа ACK. Во-вторых, я даже не знаю, как получить ответ ack через мою программу (bind ()?).

Я изменил какой-то код из syn flooder, который я нашел в Интернете, потому что мне показалось, что некоторый код script-kiddie будет легко следовать, но я боюсь, что он может что-то упустить и может быть результатом того, что сервер ACK отрицание. Код был изменен, поэтому запрос синхронизации отправляется с допустимого IP-адреса. Следующий код показывает мои заголовки ip + tcp:

 iph->ihl = 5;
 iph->version = 4;
 iph->tos = 0;
 iph->tot_len = sizeof (struct ip) + sizeof (struct tcphdr);
 iph->id = htonl (54321); //Id of this packet
 iph->frag_off = 0;
 iph->ttl = 255;
 iph->protocol = 6;
 iph->check = 0;  //Set to 0 before calculating checksum
 iph->saddr = 0; //Source ip filled in by kernel
 iph->daddr = sin.sin_addr.s_addr;

 //TCP Header
 tcph->source = htons (9999);
 tcph->dest = htons (atoi(argv[2]));
 tcph->seq = random ();
// tcph->ack_seq = 0;
 tcph->doff = 5;  /* first and only tcp segment */
 tcph->syn = 1;
 tcph->window = htonl (65555); /* maximum allowed window size */
 tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack
    should fill in the correct checksum during transmission */
 tcph->urg_ptr = 0;
 //Now the IP checksum
 iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);

Итак, я отправляю это, не обратно. Чего мне не хватает?

Ответы [ 2 ]

3 голосов
/ 13 февраля 2012

Строка:

   tcph->window = htonl (65555);

может вызвать проблемы.Потому что 65555 больше, чем 0xFFFF.Размер поля window равен 16 битам.

Так что это может быть лучше:

   tcph->window = htons (65535);

Примечание: htonl был изменен на htons.

Редактировать:

Или еще лучше (если имеется константа):

   tcph->window = htons (TCP_MAXWIN);

Проблема также может заключаться в отсутствии подсчета контрольной суммы TCP.Ваш код предполагает, что нижние уровни обновляют поле контрольной суммы TCP.Поскольку все сетевые карты не поддерживают разгрузку контрольной суммы TCP , код может работать не на каждом хосте.

0 голосов
/ 26 февраля 2013

вы не написали весь код. может быть область, в которой вы что-то упустили.

этот код поможет вам.

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<errno.h>
#include<netinet/tcp.h>
#include<netinet/ip.h>

struct pseudo_header
{
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t tcp_length;
};

unsigned short csum(unsigned short *ptr,int nbytes) 
{
register long sum;
unsigned short oddbyte;
register short answer;

sum=0;
while(nbytes>1) {
    sum+=*ptr++;
    nbytes-=2;
}
if(nbytes==1) {
    oddbyte=0;
    *((u_char*)&oddbyte)=*(u_char*)ptr;
    sum+=oddbyte;
}

sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;

return(answer);
}

int main (void)
{
int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);

if(s == -1) {
    perror("Failed to create socket");
    exit(1);
}
char datagram[4096] , source_ip[32] , *data , *pseudogram;
char buffer[4096];

memset (datagram, 0, 4096);

struct iphdr *iph = (struct iphdr *) datagram;
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct iphdr));

struct sockaddr_in sin;
struct pseudo_header psh;

data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr);
strcpy(data , "ABCDEFGHIJKLMNOPQRSTUVWXYZ");

strcpy(source_ip , "127.0.0.1");

sin.sin_family = AF_INET;
sin.sin_port = htons(55559);
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");

iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data);
iph->id = htonl (54351);
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
iph->check = 0;
iph->saddr = inet_addr ( source_ip );
iph->daddr = sin.sin_addr.s_addr;
iph->check = csum ((unsigned short *) datagram, iph->tot_len);

tcph->source = htons (55554);
tcph->dest = sin.sin_port;
tcph->seq = htonl(4362);
tcph->ack_seq = htonl(0);
tcph->doff = 5;
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window = 1;
tcph->check = 0;    
tcph->urg_ptr = 0;

psh.source_address = inet_addr( source_ip );
psh.dest_address = sin.sin_addr.s_addr;
psh.placeholder = 0;
psh.protocol = IPPROTO_TCP;
psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) );

int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data);
pseudogram = malloc(psize);

memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data));

tcph->check = csum( (unsigned short*) pseudogram , psize);

int one = 1;
const int *val = &one;

if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
{
    perror("Error setting IP_HDRINCL");
    exit(0);
}
sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin));
return 0;

}

...