//#ETH/TCP/CAT IPV6 EDITION - MEOW!! #include #include #include #include #include #include #include #include #include #include #include #include #define PACKET_SIZE 2048 #define MTU 1280 void fixpacket(uint8_t *packet){ //clearing memset(packet+14+40+16,0,2); uint8_t pseudopacket[PACKET_SIZE]={0}; memcpy(pseudopacket,14+packet+8,32); memcpy(pseudopacket+34,14+packet+4,2); pseudopacket[39]=6; memcpy(pseudopacket+40,14+packet+40,MTU); uint32_t sum = 0; int pseudolength = ((pseudopacket[34]<<8) | (pseudopacket[35])) + 40; if(pseudolength&1){pseudolength++;} for(int i = 0;pseudolength>i;i+=2){ sum += (pseudopacket[i]<<8)|(pseudopacket[i+1]); } while(sum>>16){ sum=(sum&0xFFFF)+(sum>>16); } sum=~sum; //printf("c:%d %d\n",packet[14+40+16],packet[14+40+16+1]); packet[14+40+16]=sum>>8; packet[14+40+16+1]=sum&255; } int main(int argc,char* argv[]){ if(argc!=5){ fprintf(stderr,"Invalid argument count:%d\n\nUsage:\tethtcpcat [IFACE] [SRC_V6_ADDR] [TARGET_V6_ADDR] [TARGET_TCP_PORT]\n\nThis is a generic netcat-like TCP client using its own network stack\n\n",argc); return 1; } uint16_t dport=atoi(argv[4]); int s = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); struct sockaddr_ll sa = {.sll_family=AF_PACKET,.sll_protocol=htons(ETH_P_ALL),.sll_ifindex=if_nametoindex(argv[1])}; bind(s,(void*)&sa,sizeof sa); uint8_t packet[PACKET_SIZE] = { [12]=0x86,0xdd, //Ethertype IPv6 0x60,0,0,0, //Version 6,class and flowlabel 0 0,20,6,64, //Length 20, TCP, TTL 64 [14+40+2]=dport>>8,dport&255, // Source and destination port [14+40+12]=0x50,0x02,5,0 // Dataoffset 5, Flag SYN, window 1280 }; getrandom(packet+14+40+4,4,GRND_RANDOM); getrandom(packet+14+40,2,GRND_RANDOM); { char macfilepath[256]; snprintf(macfilepath,256,"/sys/class/net/%s/address",argv[1]); FILE *fp; char c=0; int i=0; fp=fopen(macfilepath,"r"); while( 12>i && (c=fgetc(fp))!=EOF ){ if(c!=':'){ packet[6+(i>>1)]<<=4; packet[6+(i>>1)]|=(c>'9')?(10+c-'a'):(c-'0'); i++; } } fclose(fp); } { FILE *fp; char c=0; int i=0; fp=fopen("/proc/net/arp","r"); fseek(fp,120,SEEK_CUR); while( 12>i && (c=fgetc(fp))!=EOF ){ if(c!=':'){ packet[(i>>1)]<<=4; packet[(i>>1)]|=(c>'9')?(10+c-'a'):(c-'0'); i++; } } fclose(fp); } inet_pton(AF_INET6,argv[2],packet+14+8); inet_pton(AF_INET6,argv[3],packet+14+24); //We send SYN!!! fixpacket(packet); write(s,packet,60+14); //////////////////////// //We receive SYNACK int rxlen=0; uint8_t rxbuf[PACKET_SIZE]={0}; packet[14+40+7]++; for(;;){ rxlen = read(s,rxbuf,MTU); if(!memcmp(rxbuf+14+40+8,packet+14+40+4,4)){ break; } } memcpy(packet+14+40+8,rxbuf+14+40+4,4); /////ACK/////// packet[14+40+13]=16; packet[14+40+11]++; //We send ACK!! fixpacket(packet); write(s,packet,60+14); //We send real data!! uint16_t payloadlen = 20+read(0,packet+14+40+20,MTU); packet[14+4]=payloadlen>>8; packet[14+5]=payloadlen&255; fixpacket(packet); write(s,packet,40+14+payloadlen); //We receive reply for(;;){ rxlen = read(s,rxbuf,MTU); if((rxbuf[14+40]==packet[14+40+2])&&(rxbuf[14+40+1]==packet[14+40+3])&&(rxlen!=14+40+20)){ break; } } write(1,rxbuf+14+40+20,rxlen-(14+40+20)); return 0; }