Checker
Recon
HTTP (8080)
We will come back to port 80 later. 8080 is serving Teampass: Collaborative Passwords Manager

Version Enumeration
We are not able to determine version via headers, so we can try looking in the source code. Usually version are appended to files with ?v=VERSION

Verify in the source code: https://github.com/search?q=repo%3Anilsteampassnet%2FTeamPass+TP_VERSION&type=code

SQLi
TeamPass 2.1.24 - Multiple Vulnerabilities
SQLi was interesting, but
SQLMap also was failing to get valid responses and then it got timed out.
CVE mentions SQLi is inside item.query.php, but that file doesn't exist and is probably items.queries.php. Also probable that it's patched.
Teampass SQL Injection vulnerability - CVE-2023-1545 - SQL injection in API authorization check in nilsteampassnet/teampass
bob's password is cracked
Creds:
bob:cheerleader
TeamPass panel
bob has 2 credentials stored

Creds:
bob@checker.htb:mYSeCr3T_w1kI_P4sSw0rD

Creds:
reader:hiccup-publicly-genesis
SSH credentials work, but we also need a verification code to login.
HTTP (80)

One of the pages mentions that /backup/home_backup is a safe directory, could be useful.

App version seems to be 23.10.2

SSRF
Book Stack v23.10.2 - LFR via Blind SSRF
Follow PoC to replicate the request

No callback.
Image is created with contents of base64, but that seems to be it.
Should have used http:// prefix in the url

Hmmm... to trigger SSRF I had to edit and then save the page.
Fix: https://github.com/BookStackApp/BookStack/releases/tag/v23.10.3 Diff: https://github.com/BookStackApp/BookStack/commit/15d7161428832d2ebf12061f69fff780cdb10550#diff-324822adaa09bd395b1a8bc3ee4a55fd5943c1e84c1065ae89208e507cb73f75
Test was added for LFI, but when testing for it it doesn't read file but saves images with file:///etc/passwd as content.

LFI
PHP wrappers or php_filter_chain_generator also doesn't not work. or they do work but we just can't see any output as the attack is blind.
synacktiv has another research related to php filters: php_filter_chains_oracle_exploit - PHP filter chains: file read from error-based oracle
The payload needs a little tweaking, easiest way was to change this line in core/requestor.py
You need to obtain correct URL from saving drafts, then X-CSRF-TOKEN and Cookie headers in json format. Exfiltration takes really long time so we have to correctly pick the file to exfiltrate.
Note: If you feel like exploit should work but doesn't and you're going insane, try switching VPNs or restarting box. Switched VPNs 3 times and restarted 4 times to finally work... 😭
Read .env
Not really useful, ideally we want to login into SSH but we need 2FA code.
2FA Bypass
BookStack supports 2FA and most likely users use same application like this to logon.

Most popular would be Google Authenticator application.
google-authenticator-libpam: Example PAM module demonstrating two-factor authentication for logging into servers via SSH, OpenVPN, etc…
Following path fails
But following works. If you remember one of the pages talked about secure backup options and this directory was one of them.
SSH (22)
Use tool like https://toolinone.com/otp-generator/ to get 2FA code using the TOTP secret. (Do mind that it changes every 10 second or smth)
User.txt
Privilege Escalation
Mysql doesn't seems to have any new information which we would want.
As sudo we are able to execute check-leak.sh with arguments.
It's sourcing probably env variables for script, then takes username and passes it to check_leak binary.
Binary saves leaked hashes in same directory, probably not crackable.
Create python server which accepts PUT method
Upload the file
Reverse Engineering
The main function basically boils down to this:
We pass the username to binary, it get's checked in database that it's exists and then it's checking if password is inside leaked_hashes.txt
I used ChatGPT to reconstruct decompiled notify_user function into more readable code and I think it's doing pretty good job. It even guessed that function last parameter was related to shm
write_to_shm function:
Creates a shared memory segment.
Attaches to it.
Writes a formatted message.
Detaches from it.
Returns the generated shared memory key.
notify_user function uses mysql command with popen (query_output = popen(query, "r");) instead of calling mysql api using code. This is dangerous since it's using credentials via Shared Memory.
Let's test the functionality. We will need second terminal to run 2 commands or you can use background jobs, second ssh is simpler for me.
Now to exploit the binary we have to win the race. Binary writes to shared memory, waits 1 second and then notifies the user. If we can hijack the share memory region with our payload we can inject into popen and get code execution as root.
Win The Race

Top left: reader@checker:/tmp$ php exp.php | tee exp.log
Top right: reader@checker:~$ watch -n1 sudo /opt/hash-checker/check-leak.sh bob
Bottom: reader@checker:/tmp$ nano exp.php
Start the
sudojob and continuously open shared memoryStart PHP script to automatically find the region using
ipcs -mAttach PHP script to root shared memory
Spam writing payload to win race
Pwned
Root.txt
Last updated