2012-02-13 2 views
2

필자가 제공 한 모든 IP 및 포트 번호에서 syn 패킷을 던지는 작은 도구를 코딩했습니다. Wireshark가 나타 났을 때 전송 된 패킷은 오류없이 나타납니다. 전형적인 TCP SYN 패킷처럼 보입니다.syn 이후에 ack 검색

어떤 이유인지, ACK는 서버에 의해 보내지지 않습니다. 그래서 두 가지 문제가 있습니다. 하나, ACK 응답 없음. 둘째, 나는 내 프로그램 (bind()?)을 통해 ack 응답을받는 방법을 모른다.

필자가 온라인에서 찾은 syn flooder에서 일부 코드를 수정했는데, 이는 스크립트 작성자 코드가 쉽게 따라 할 수있는 것처럼 보였지만, 뭔가 빠졌을 수 있으며 서버의 ACK 거부. 합법적 인 IP 주소에서 syn 요청이 전송되도록 코드가 수정되었습니다. 다음 코드는 내 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); 

그래서, 나는 그것을 반송하지 않습니다. 내가 뭘 놓치고 있니?

+0

보인다. 나는 양쪽 끝점에서 스니퍼로 확인하는 것이 좋습니다. – jweyrich

답변

3

라인 :

tcph->window = htonl (65555); 

이 문제가 발생할 수 있습니다. 65555가 0xFFFF보다 크기 때문에 window 필드 크기는 16 비트입니다.

그래서이 더 좋을 수 :

tcph->window = htons (65535); 

주의 사항 : htonl는 htons로 변경되었습니다.

편집 :

또는합니다 (의 상수를 사용할 수있는 경우) 더 나은 :

tcph->window = htons (TCP_MAXWIN); 

문제는 TCP 체크섬 계산의 부족도 할 수있다. 코드에서 하위 레이어가 TCP 체크섬 필드를 업데이트한다고 가정합니다. 모든 네트워크 인터페이스 카드가 TCP checksum offload을 지원하지 않으므로 코드가 모든 호스트에서 작동하지 않을 수 있습니다.

+0

고마워, 그게 미래의 문제를 도왔을 수도 있지만, 여전히 주요 문제는 가까이에있다. 나는 ACK를 얻지 않는다! (예, 여러 호스트를 대상으로 시도했습니다! hping2를 통한 추가 검증을 통해) – Saustin

0

전체 코드를 작성하지 않았습니다. 너가 무언가를 놓칠 지역이 있을지도 모른다.

이 코드는 도움이됩니다. 당신의 패킷이 폐기되고 같은

#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; 

은}

관련 문제