/* does stuff when you attempt to connect to ports in a certain order */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "/usr/include/sys/ioctl.h" #define RSTS 10 #define IF "eth0" #define MYPORT 4950 /* the port users will be sending to */ #define MAXBUFLEN 100 int sp_fd; unsigned short ip_fast_csum(unsigned char *iph,unsigned long ihl) { unsigned long sum; __asm__ __volatile__(" movl (%1), %0 subl $4, %2 jbe 2f addl 4(%1), %0 adcl 8(%1), %0 adcl 12(%1), %0 1: adcl 16(%1), %0 lea 4(%1), %1 decl %2 jne 1b adcl $0, %0 movl %0, %2 shrl $16, %0 addw %w2, %w0 adcl $0, %0 notl %0 2: " : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl)); return(sum); } struct tcppk { struct iphdr ip; struct tcphdr tcp; char data[1500]; }; struct pseudo { unsigned long saddr, daddr; unsigned char zero, proto; unsigned short len; }; void raw(void) { int opt=1; if((sp_fd=socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) <0){ perror("\nRAWIP() RAW Socket problems [Died]"); exit(); } if(setsockopt(sp_fd, IPPROTO_IP, IP_HDRINCL, &opt, sizeof(opt)) <0){ perror("RAWIP() Cannot set IP_HDRINCL [Died]"); exit(); } } int tap(char* device,int mode) { int fd; struct ifreq ifr; if((fd=socket(AF_INET, SOCK_PACKET, htons(0x3))) <0){ perror("SNIFF() SOCK_PACKET allocation problems [Died]"); exit(); } strcpy(ifr.ifr_name,device); if((ioctl(fd, SIOCGIFFLAGS, &ifr)) <0){ perror("SNIFF() Can't get device flags [Died]"); close(fd); exit(); } if(!mode)ifr.ifr_flags ^= IFF_PROMISC; else ifr.ifr_flags |= IFF_PROMISC; if((ioctl(fd, SIOCSIFFLAGS, &ifr)) <0){ perror("SNIFF() Can't set/unset promiscuous mode [Died]"); close(fd); exit(); } if(!mode){ close(fd); return(0); } else return(fd); } void root_shell() { int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */ struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connector's address information */ int sin_size; int numbytes; struct linger lingerparam; int reuseparam; char outmsg[1024]; sockfd = socket(AF_INET, SOCK_STREAM, 0); /* do some error checking! */ my_addr.sin_family = AF_INET; /* host byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */ /* don't forget your error checking for these calls: */ /* set linger to 1s... */ lingerparam.l_onoff = 1; lingerparam.l_linger = 1; if (setsockopt(sockfd, SOL_SOCKET,SO_LINGER,&lingerparam,sizeof(lingerparam)) != 0) { fprintf(stderr, "Error setting socket options\n"); return; } /* now set SO_REUSEADDR so we can rebind soon */ reuseparam = 0; if (setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,&reuseparam,sizeof(reuseparam)) != 0) { fprintf(stderr, "Error setting socket options\n"); return; } fprintf(stderr,"Binding...\n"); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) != 0) { close(sockfd); fprintf(stderr, "Bind error\n"); return; } fprintf(stderr,"Listen...\n"); if (listen(sockfd, 0) != 0) { close(sockfd); fprintf(stderr, "Listen error"); return; } sin_size = sizeof(struct sockaddr_in); fprintf(stderr,"Accept...\n"); new_fd = accept(sockfd, &their_addr, &sin_size); fprintf(stderr,"sending thing\n"); sprintf(outmsg, "Adding firewall allowance rule for %s\n", inet_ntoa(their_addr.sin_addr.s_addr)); if ((numbytes=send(new_fd, outmsg, strlen(outmsg), 0)) == -1) { close(sockfd); perror("send"); exit(1); } close(new_fd); shutdown(sockfd,0); close(sockfd); } unsigned long in_aton(const char *str) { unsigned long l; unsigned long val; int i; l = 0; for (i = 0; i < 4; i++) { l <<= 8; if (*str != '\0') { val = 0; while (*str != '\0' && *str != '.') { val *= 10; val += *str - '0'; str++; } l |= val; if (*str != '\0') str++; } } return(htonl(l)); } void uff(void) { printf("\nUso: RST sourceIP src_port destIP dest_port\n\n"); exit(1); } int main(int argc, char **argv) { unsigned char buffer[1500], checkbuff[32], checkbuff2[32]; struct sockaddr_in sin, sin2; struct iphdr *ip; struct tcphdr *tcp; struct pseudo *psp, *psp2; struct tcppk tpk, tpk2; int sniff, snt, snt2, rst=0; unsigned long saddr, daddr; unsigned short src, dest; int combo_ctr = 0; int combo_list[3] = {7000,8000,9000}; #define HOST_MAX 10 long last_host; long last_time; int host_count; struct timeval tv; struct timezone tz; int x; /* if(argc<5) { uff(); exit(1); } saddr=in_aton(argv[1]);daddr=in_aton(argv[3]); src=htons(atoi(argv[2]));dest=htons(atoi(argv[4])); */ sniff=tap(IF, 1); /* raw(); */ if(setpriority(0, 0, -20) <0){ fprintf(stderr,"\nRST setpriority Error\n"); } ip = (struct iphdr *)(((char *)buffer)+14); tcp = (struct tcphdr *)(((char *)buffer)+(sizeof(struct iphdr)+14)); psp = (struct pseudo *)checkbuff; psp2 = (struct pseudo *)checkbuff2; memset(&sin, 0, sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=src; sin.sin_addr.s_addr=saddr; memset(&sin2, 0, sizeof(sin2)); sin.sin_family=AF_INET; sin.sin_port=dest; sin.sin_addr.s_addr=daddr; memset(&tpk, 0, sizeof(tpk)); memset(&tpk2, 0, sizeof(tpk2)); memset(psp, 0, sizeof(struct pseudo)); memset(psp2, 0, sizeof(struct pseudo)); tpk.ip.ihl=5; tpk.ip.version=4; tpk.ip.tos=0; tpk.ip.tot_len=htons(40); tpk.ip.frag_off=0; tpk.ip.ttl=64; tpk.ip.protocol=IPPROTO_TCP; tpk.ip.saddr=daddr; tpk.ip.daddr=saddr; tpk.tcp.source=dest; tpk.tcp.dest=src; tpk.tcp.doff=5; tpk.tcp.rst=1; tpk.tcp.ack=1; tpk.tcp.window=0; psp->saddr=tpk.ip.daddr; psp->daddr=tpk.ip.saddr; psp->zero=0; psp->proto=IPPROTO_TCP; psp->len=htons(20); tpk2=tpk; tpk2.ip.saddr=saddr; tpk2.ip.daddr=daddr; tpk2.tcp.source=src; tpk2.tcp.dest=dest; psp2->saddr=tpk.ip.saddr; psp2->daddr=tpk.ip.daddr; psp2->zero=0; psp2->proto=IPPROTO_TCP; psp2->len=htons(20); /* printf("RSTing :\t%s:%d > %s:%d\n", argv[1], src, argv[3], dest); */ while(read(sniff, &buffer, sizeof(buffer))) { /* printf("src addr %d src port: %d\n", ip->saddr,ntohs(tcp->source)); */ /* printf("%li",tv.tv_usec); */ gettimeofday(&tv, &tz); if ((tv.tv_usec > last_time + 1000000) && (combo_ctr > 0)) { combo_ctr = 0; last_time = tv.tv_usec; fprintf(stderr,"resetting(time)\n");} if (((combo_ctr > 0) && (last_host == ip->saddr)) || (combo_ctr == 0)) { last_host = ip->saddr; last_time = tv.tv_usec; if (combo_list[combo_ctr] == ntohs(tcp->source)) { combo_ctr++; printf("Incrementing ctr %i\n",combo_ctr); if(combo_ctr == 3) { fprintf(stderr,"GOT TRIPLET\n"); root_shell(); combo_ctr = 0; } } else { if ((combo_ctr > 0) && ( last_host != ip->saddr)) { printf("resetting\n"); combo_ctr = 0; } } } } printf("\n"); tap(IF, 0); exit(0); }