Re: Linux Slapper Worm

From: Ajai Khattri (ajaiat_private)
Date: Wed Sep 18 2002 - 09:50:13 PDT

  • Next message: Thor Larholm: "Mozilla vulnerabilities, an update"

    Not seeing any announcement from my vendor (and not wanting to compile 
    SSL from source),
    I set out to see if there was some way of avoiding being infected in the 
    first place. I decided to hack my Apache (1.3.26) source code to send a 
    bogus Server: header (seeing as this is how Slapper detects what web 
    software is running). There is no way of disabling this header or 
    controlling exactly what is included in the string, so I hacked. This is 
    really quite easy to do:
    
    In src/include/httpd.h I added an extra value to the server_token_type 
    enumeration and an extra #define:
    
    #define SERVER_BASEVENDOR   "Apache Group"
    #define SERVER_BASEPRODUCT  "Apache"
    #define SERVER_BASEREVISION "1.3.26"
    #define SERVER_BASEVERSION  SERVER_BASEPRODUCT "/" SERVER_BASEREVISION
    
    #define SERVER_PRODUCT  SERVER_BASEPRODUCT
    #define SERVER_REVISION SERVER_BASEREVISION
    #define SERVER_VERSION  SERVER_PRODUCT "/" SERVER_REVISION
    #define SERVER_HIDE "A p @ c h e"
    
    enum server_token_type {
         SrvTk_MIN,          /* eg: Apache/1.3.0 */
         SrvTk_OS,           /* eg: Apache/1.3.0 (UNIX) */
         SrvTk_FULL,         /* eg: Apache/1.3.0 (UNIX) PHP/3.0 FooBar/1.2b */
         SrvTk_PRODUCT_ONLY, /* eg: Apache */
         SrvTk_SECURE        /* To fool Slapper */
    };
    
    (Note SERVER_HIDE and SrvTk_SECURE. Of course, SERVER_HIDE can be 
    anything you want it to be).
    
    Next, I looked at src/main/http_core.c, in the function set_serv_tokens():
    
    static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, char *arg)
    {
         const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
         if (err != NULL) {
             return err;
         }
    
         if (!strcasecmp(arg, "OS")) {
             ap_server_tokens = SrvTk_OS;
         }
         else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) {
             ap_server_tokens = SrvTk_MIN;
         }
         else if (!strcasecmp(arg, "Full")) {
             ap_server_tokens = SrvTk_FULL;
         }
         else if (!strcasecmp(arg, "Prod") || !strcasecmp(arg, "ProductOnly")) {
             ap_server_tokens = SrvTk_PRODUCT_ONLY;
         }
         else if (!strcasecmp(arg, "Secure")) {
             ap_server_tokens = SrvTk_SECURE;
         }
         else {
             return ap_pstrcat(cmd->pool, "Unrecognised ServerTokens keyword: ",
                               arg, NULL);
         }
         return NULL;
    }
    
    So, when parsing the config file, it looks for a value of "Secure" for 
    the ServerTokens config directive. Here I set it to SrvTk_SECURE which I 
    defined in the src/include/httpd.h earlier.
    
    Finally, in src/main/http_main.c, in the function ap_set_version() I 
    added an extra else if clause:
    
    /*
      * This routine adds the real server base identity to the version string,
      * and then locks out changes until the next reconfig.
      */
    static void ap_set_version(void)
    {
         if (ap_server_tokens == SrvTk_PRODUCT_ONLY) {
             ap_add_version_component(SERVER_PRODUCT);
         }
         else if (ap_server_tokens == SrvTk_MIN) {
             ap_add_version_component(SERVER_BASEVERSION);
         }
         else if (ap_server_tokens == SrvTk_SECURE) {
             ap_add_version_component(SERVER_HIDE);
         }
         else {
             ap_add_version_component(SERVER_BASEVERSION " (" PLATFORM ")");
         }
         /*
          * Lock the server_version string if we're not displaying
          * the full set of tokens
          */
         if (ap_server_tokens != SrvTk_FULL) {
             version_locked++;
         }
    }
    
    That's it - now you can make and make install as usual. Before 
    restarting, edit your httpd.conf file and set ServerTokens to Secure by 
    adding the line:
    
    ServerTokens Secure
    
    Now you can restart and test with a fake HTTP HEAD request to port 80 - 
    you should see your custom string (SERVER_HIDE).
    
    As an added precaution, you may want to rename your gcc binary. I also 
    blocked port 2002 on my firewall for good measure.
    
    
    Hope this is useful for people still waiting for vendor updates ;-)
    
    -- 
    Aj.
    Systems Administrator / Developer
    



    This archive was generated by hypermail 2b30 : Wed Sep 18 2002 - 21:51:22 PDT