NeilSec: Security Learning Blog

Pentesting, infosec, hacking, learning.

  • Home
  • Knowledgebase
You are here: Home / CTF / ch4inrulz 1.0.1 Walkthrough

ch4inrulz 1.0.1 Walkthrough

2018-09-06 by Neil Leave a Comment

Initial Enumeration

Having located the VM on 192.168.189.129, we run an nmap scan to see what port action is available:

No known vulnerabilities for the services were found. Taking the ports one at a time:

21/ftp

anonymous FTP access is allowed:

PUT and MKDIR are not allowed: 550 Permission denied

Server is anonymous only so no root, or other user, access allowed

22/SSH

external ssh appears to be allowed

80/HTTP

Website found:

Dirb finds files and listable directories:

root@kali:~/temp# dirb https://192.168.189.129

—————–

DIRB v2.22

By The Dark Raver

—————–

START_TIME: Thu Aug 16 09:01:20 2018

URL_BASE: https://192.168.189.129/

WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

—————–

GENERATED WORDS: 4612

—- Scanning URL: https://192.168.189.129/ —-

+ https://192.168.189.129/cgi-bin/ (CODE:403|SIZE:291)

==> DIRECTORY: https://192.168.189.129/css/

+ https://192.168.189.129/development (CODE:401|SIZE:482)

==> DIRECTORY: https://192.168.189.129/img/

+ https://192.168.189.129/index (CODE:200|SIZE:334)

+ https://192.168.189.129/index.html (CODE:200|SIZE:13516)

==> DIRECTORY: https://192.168.189.129/js/

+ https://192.168.189.129/LICENSE (CODE:200|SIZE:1093)

+ https://192.168.189.129/robots (CODE:200|SIZE:21)

+ https://192.168.189.129/robots.txt (CODE:200|SIZE:21)

+ https://192.168.189.129/server-status (CODE:403|SIZE:296)

==> DIRECTORY: https://192.168.189.129/vendor/

 

—- Entering directory: https://192.168.189.129/css/ —-

(!) WARNING: Directory IS LISTABLE. No need to scan it.

(Use mode ‘-w’ if you want to scan it anyway)

 

—- Entering directory: https://192.168.189.129/img/ —-

(!) WARNING: Directory IS LISTABLE. No need to scan it.

(Use mode ‘-w’ if you want to scan it anyway)

 

—- Entering directory: https://192.168.189.129/js/ —-

(!) WARNING: Directory IS LISTABLE. No need to scan it.

(Use mode ‘-w’ if you want to scan it anyway)

 

—- Entering directory: https://192.168.189.129/vendor/ —-

(!) WARNING: Directory IS LISTABLE. No need to scan it.

(Use mode ‘-w’ if you want to scan it anyway)

 

—————–

END_TIME: Thu Aug 16 09:01:24 2018

DOWNLOADED: 4612 – FOUND: 8

root@kali:~/temp#

===============================================================

dirbuster

dirbuster finds some directories:

Before digging into these, let’s collect some more information with Nikto in case there is anything relevant there:

The main new info there is “The following alternatives to index were found: index.html.bak” – which might indicate a backup file.

Having checked into the directories found by dirb and dirbuster the most interesting is /development:

Checking out hte index.html.bak file:

Excellent, so a user “frank” and his password hash protecting the development path.

hash-identifier identifies it as a possible MD5(APR) hash.

Cracking the hash

After creating a hash file for John the Ripper, we run john on it and get a quick and easy win:

Thanks to an apparently lax and forgetful developer, we now, hopefully, have the credentials for the developer directory.

We’re in. We reset dirbuster up to scan from this point on and in the meantime try some obvious things given the info on the screen and again hit lucky with /developer/uploader, finding the aforementioned tool:

This is an obvious possible route to uploading a shell. The text hints that uploading code might be a bit tricky but not impossible. And trying to upload various test files, we see that it is indeed restricting uploads. It will only allow image file types (jpg, gif etc):

Simply renaming a php file to one of the allowed extensions does not work:

It appears to be able to detect image formats and a little web research comes up with a simple trick to add an identifier to the start of a file to identify it as a gif:

This is now allowed:

We now have to find the location of “my uploads path”. I tried entering in variations of “upload”, “uploaded” etc into a text file for Dirbuster to use but cannot find it. So for the time being, we move on to the, so far, unexplored port: 8011

8011/HTTP

Running dirb:

Maybe the /api/ directory is of interest:

This reveals an API capable of communicating with the Frank server on port 80.

Trying the php files in turn, the the only one that appears to exist is the files_api.php:

It’s always worth reading what the system is telling you: “no parameter called file passed to me”. So maybe a php parameter like .php?file=filename is expected here. Let’s try to see if we can find the /etc/passwd file:

A gotcha! And as it turns out, it’s not triggered by looking for “etc/passwd” but rather

this error occurs for file= anything. It could be just one big red-herring but probably not, and if it’s not then on what basis is it rejecting the request? There are various ways data can be included in HTTP requests and we know the request is not a GET request since that is rejected out of hand so it’s not unreasonable to think that whatever application is supposed to use this API might be using the POST method to send data since it’s the most common method, so let’s try that. You can’t just create a URL query string for POST data like you can GET but the curl command does it:

Great, a working LFI.

the -d option in curl is short for –data and sends a POST request with the payload after the -d, in

Incidentally there was another bit of info given to us by the author of this vulnerable box. He mentioned that the app doesn’t use JSON. This is also important since when you use curl to POST data, it create a basic default header. This is usually fine for apps/apis expecting browser-created posts like forms but might well not be for specific data like JSON. If that was the case we might need to have curl specify the data type and header, like: curl -d ‘{json}’ -H ‘Content-Type: application/json’ https://192.168.189.129/whatever

Using the LFI

So we have an LFI capable of outputting the contents of files that the www-data service has access to. In order to leverage this into a shell we’re going to need to get some data onto the server. Earlier on the port 80 site we found the file uploading service at /development/uploader/upload.php and uploaded a file but we couldn’t then find it. Maybe if we can output the contents of the upload.php file we can see where it stores the files:

So here we’ve successfully located the upload.php code on the server’s file system. And we can see the output is the same as on the website. Clearly the php is being executed by the PHP interpreter. This is great for executing our shell, once we find it, but not so good in seeing the contents of upload.php (the source code). Luckily there are some tricks we can use to get around this. Any php code is going to be executed, so how can we both see the code and yet not have it executed? We can’t but if we could encode the PHP then it wouldn’t be executed and we could decode it later. And for that we can use php filter wrapper:

As you can see we’ve prepended the file path with: php://filter/convert.base64-encode/resource= which tell the php interpreter to base64 encode the resource. I found this trick here: https://kaoticcreations.blogspot.com/2011/12/lfi-tip-how-to-read-source-code-using.html

Now we just need to decode the base64. To do this on Kali just echo the base64 code and | it to the command base64 –decode

OK so immediately we can find where uploaded files go to: $target_dir = “FRANKuploads/”;

Whilst we’re here let’s check out the code. It uses the getimagesize function to check the file is an image. I’m guessing that it expects images and throws up an error if it thinks a file isn’t an image but it’s not designed to be a comprehensive check and indeed https://php.net/manual/en/function.getimagesize.php says that it should not be used to check if a file is an image.

Uploading a webshell

Let’s see if we can find our uploaded files now:

At this point I amended the standard reverse PHP shell in Kali to point back to the Kali box’s IP and uploaded it as webshell.gif. If we just click on that or GET it via curl it will not get interpreted as PHP, rather will just throw up an image file error since PHP thinks it’s an image but it isn’t. Of course we already have a way of triggering php code via the LFI which outputs the content of any file we can access, so:

And with the netcat listener waiting we have a limited webshell:

Upgrading the shell

The first thing I tend to do is to try to upgrade the shell to at least a tty so I can check sudo status (otherwise you get a “no tty present” error). The best  shell upgrade I’ve found so far is to follow this sequence, that I have in my notes:

python -c ‘import pty; pty.spawn(“/bin/bash”)’

Background the shell by pressing Ctrl-Z

on your local terminal:

echo $TERM

stty -a | head -n1

stty raw -echo

fg (will not show on screen)

        export HOME=/root

        export SHELL=/bin/bash

        export TERM=(whatever output you got from “echo $TERM” above)

        stty rows X columns Y (using the output from “stty -a | head -n1” above)

Whether we need to do all this for this particular box isn’t known at this point, but it’s easy to do and it ensures not only a tty shell but one that will interact with editors like Vi and nano properly which is often invaluable.  Plus it gives you good stuff like autocomplete etc which saves lots of annoying typing. Here it is in action and you can see the sudo -l command works. I won’t bother demoing the

Before getting into privesc, I want to see what the files_api.php looks  like. I did previously have a quick go at finding it but I couldn’t guess which directory it was in. Now I should be able to, and I found it in /var/anotherwww/api/:

The LFI vulnerability is clear and very simple as you’d expect and you can see the hacker alert code checking for a GET. Furthermore you can even see the commented out code for checking for someone requesting /etc/passwd, maybe put in for laughs.

Privilege Escalation

I used wget to download a couple of privesc enumeration tools into /tmp and didn’t find a lot other than a pretty old kernel for which there are several kernel exploits

searchsploit shows one for 2.6.35 but it’s not relevant so I search for < 2.6.36

Using the python module SimpleHTTPServer I set up an ad hoc webserver on the Kali box so I can wget files onto the server.

linuxprivescchecker.py mentioned the ia32syscall as a likely candidate but the “CAN BCM” one is specific to the correct Ubuntu version so I try that first. But it doesn’t work. So next I try the ia32syscall and it compiles fine on the target system and works out of the box:

Root Proof

So with root access we can now access the root directory where the root proof file should be:

Summary

This was an interesting box requiring a combination of techniques. I learned a bit:

  1. Thinking about the http methods being used and not just blindly going for url based LFIs
  2. How to use php filter to view php code

Filed Under: CTF, Penetration Testing Tagged With: Boot-to-Root, CTF, Penetration Testing, VulnHub

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

About Me

I’m currently a systems admin / consultant at a IT firm who looks after the computer systems of small businesses in the UK. IT security is only a part of that job. However I’ve always enjoyed breaking into, getting around, subverting and otherwise hacking things, systems and ideas. In tackling some low-level IT security tasks I reignited my interest in the field and this blog charts my progress in the world of Computer Security, legal Hacking, Penetration Testing, Infosec – whatever you want to call it. As a Windows guy I’m learning about Linux, shell-scripting, python and all the other skills needed in this field.

Tags

Apache Boot-to-Root CTF curl dib Dirbuster FreeBSD Hack The Box Linux mysql NFS Penetration Testing PHP RCE shell VulnHub Wordpress

Categories

© 2023 · NeilSec;