Previse
Linux · Easy
10.10.11.104
Reconnaissance: NMAP
┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.11.104
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA)
| 256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA)
|_ 256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-title: Previse Login
|_Requested resource was login.php
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
Aggressive OS guesses: Linux 4.15 - 5.8 (96%), Linux 3.1 (95%), Linux 3.2 (95%), Linux 5.3 - 5.4 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), Linux 2.6.32 (94%), Linux 5.0 - 5.5 (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 - 5.4 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 47.25 secondsBased on the OpenSSH and Apache versions, the host is likely running Ubuntu 18.04 Bionic.
80/tcp open http
The site is a file storage site:
Miscellaneous: PWA Web servers: Apache HTTP Server 2.4.29 Programming languages: PHP Operating systems: Ubuntu UI frameworks: UIKit
view-source:http://10.10.11.104/login.php
The footer gives a potential username. Some basic password guessing didn’t work, and I wasn’t able to get any different in error message between bad user and bad password:
EAR Vuln:
Visiting the root / returns a HTTP 302 redirect to /login.php. However, there’s also a full page in that response:
This is an execution after redirect (EAR) vulnerability. The PHP code is likely checking for a session, and if there is none, sending the redirect. This is the example from the OWASP page:
This PHP code should have an exit; after that print. Otherwise, it sends the code that performs the redirect, but also prints the rest of the page.
Skipping Redirects:
By default, Burp intercept only stops requests, not responses. To see the root page, I’ll turn on Server Response Interception in Burp Proxy, and then turn Intercept On:
In Firefox, I’ll try to go to http://10.10.11.104 again, forwarding the request without changes, and Burp catches the response:
I’ll change “302 Found” to “200 OK”, and the page comes back: This page isn’t too useful, but it’s there. The are links across the top that go to four more pages: Accounts (/accounts.php) Files (/files.php) Management Menu –> Website Status (/status.php) Management Menu –> Log Data (file_logs.php)
To make this easier, I’ll put a rule in place to make this change always, keeping in mind that if I get a blank page, I should see if it was supposed to be a redirect:
status.php isn’t too interestingm other than that it identifies the back up database is MySQL:
While I can load both files.php and file_logs.php, they each contain functionality that return proper 302s, so I can’t access them without logging in. I’ll come back to these.
accounts.php has a message that only admins should be here, which is obviously not the case: I’ll fill in the form and submit, and it works: Now I can turn off the Burp rule and just log in.
Files: The files page contains a single file called SITEBACKUP.ZIP:
I was able to view this page using the proxy 302 replace, but not download the zip. Logged in, I can download it. Unsurprisingly, it contains all the source for the site:
Log Data: The other page is file_logs.php: Clicking submit downloads a CSV of file data: If I change the delimiter to “space”, I get the same logs but space delimited, as expected:
Shell as www-data
Identify Command Injection: I got access to the source code for the site, but this command injection can also be identified without it. I’ll show how I would approach it both ways.
Without Source: The first thing I want to look at it the request when I request logs:
The other options submit space and tab. What happens when I submit something not in the list? I’ll send this to Burp Repeater and change it to 0xdf. The response is the same as comma:
I don’t recognize that log format, but the fact that the page is returning it with different delimiters means that likely some text pattern matching and rearranging is going on. While this can be done naturally in PHP, it’s not that easy, compared to Bash. It is possible that the programmer is reading the file and making the manipulations in PHP, but it’s also possible the author is using system or shell_exec to call something outside PHP.
I’ll try using a ; to add a command to the parameter:
I’ll open tcpdump and then send this with Burp, and ICMP comes back:
That’s command injection.
With Source:
With the source code, I’ll start with a grep that will identify many of the dangerous PHP functions:
The first and last ones are comments, but the middle on in logs.php is interesting. That file:
The developer even left a comment about using Python because it was easier. The output is echoed, but then later it ob_clean() to get rid of that so it doesn’t come back in the response. There is no sanitization of the user input before it’s put into the call to exec, which means that I can add all sorts of injections to get execution, like ; [command] and $([command]).
Shell To turn this RCE into a shell, I’ll simple add a reverse shell to the request with nc listening:
On sending, it just hangs, but at nc:
Shell as m4lwhere
Enumeration:
Homedirs There’s only one homedir, and it does have user.txt:
I can’t read it yet, or anything else of use in here.
DB: The status page did mention MySQL. I’ll check out the web directory. There’s a config.php:
That password doesn’t work for any users on the box. I’ll connect to the DB with mysql:
There are five databases, but only one that’s really interesting:
It has two tables:
files looks to hold the actual files, as that’s what a blob type is typically used for:
I don’t want to do a select * from files as it will crash my session because the data is large. The only file is the one I already downloaded:
accounts stores a name, password, and create time:
There is one user that isn’t me:
The hash seems to be using an emoji character as part of the salt. This is a little silly, but nothing I can’t try to break.
Crack Hash: However, it seems that the creator of this box likes to troll a bit and has included an emoji for salt in the password hash. Fortunately, MySQL can output the contents of a table to base64 which should make it easier to process.
I’ll put the hash into a file and feed it to Hashcat. Based on the example hashes page, it looks like md5-crypt, or mode 500:
SSH: That password works over SSH as m4lwhere:
Shell as root
Enumeration: m4lwhere can run sudo on a script, access_backup.sh:
There’s an important line missing from that output where sudo has been misconfigured to allow the next exploit.
The script is backing up logs to /var/backups:
The comment says they knows they shouldn’t be running this as root, but that they need to fix the permissions later. That’s a directory that is owned by and writable by root, which is why m4lwhere needs sudo to run it:
Path Injection: The vulnerability in this script is that gzip is called without a complete path. In /dev/shm, I’ll create a simple script called gzip. There are many things I could do, including just calling bash, though I had some issues getting that to work. I’ll have it write my public key into root’s authorized_keys file and spawn a reverse shell:
Last updated