
Obscure
A TryHackMe box that runs on patience: anonymous FTP hands over a password-recovery binary, Ghidra hands over its hardcoded ID, an Odoo 10 RCE gets a shell in a container, and a ret2libc ROP chain over pwntools finishes it as root.
Kicking things off with an initial Nmap scan we get the following.

nmap -sCV -p- -Pn 10.67.172.42 -v -T5 --min-rate 1500 --max-rtt-timeout 500ms --max-retries 3 --open -oN nmap_targets.txt
We have 21 FTP with anonymous, so the first thing we'll do is check it out and see if we can find any loot.
Coming in hot we found 2 things, a notice.txt and a password file. Let's download everything to our computer and check it out.

The password file is an application ELF file. Running it shows us it's a password recovery program and we just need to give it an employee ID. Let's move on from here and enumerate the web app we saw on port 80.

Let's run feroxbuster and a Nikto scan — it's an Odoo application. We find out that Odoo has a few vulnerabilities, we just need to disclose which version this one is currently at.

So far we have ID'd Werkzeug 0.9.6, Python 2.7.9 and Odoo 10. There's an RCE, but it requires us to be logged in. After trying just about every exploit we found available for these versions we could not get anything to budge, so let's move over to the password binary and throw that into Ghidra to see what's going on there.

After inspecting in Ghidra, we find the pass() function, and upon inspection we see line 18 with a hardcoded id param. Let's throw that into the password app and see if it will work.

Turns out it's the employee's ID and it works, giving us a password!
Through our earlier tests we had discovered that admin@antisoft.thm is a real account, so let's hit it with our password on the Odoo app.

We gain access to the dashboard! Now let's try that RCE CVE for Odoo 10 and see if we can gain a shell. Grabbing 44064.md from searchsploit we follow the instructions and modify our code with our listener.

We get a shell! Now let's upgrade this to a Python shell. After enumerating a bit we realize this is a Docker container.
ls -la /.dockerenv
Enumerating the Odoo directory finds us our first flag.

Now let's enumerate this Docker container. Inspecting the Odoo conf we find some database creds. We will save these in case for later.

Checking that database doesn't give us much lead, so I'm going to transfer over linPEAS and see what we can get. We actually don't have wget, so let's go back to enumerating the psql and see if we can get a version number.
psql -h 172.17.0.2 -U odoo -d main -c "SHOW server_version;"
It's version "9.4.26" — upon researching this one we find out that this version has its vulnerabilities patched, so we will continue enumerating from here.

User odoo is a superuser, we can bust back a shell from here to 443.

We get the shell and begin our enumeration process again. We check for the important stuff obviously, and find exim4 is the oddball of the list.

Let's check the version and see if it is vulnerable — find out it is, it's version 4.89. Let's give CVE-2019-10149 ("Return of the WIZard") a shot.
After trying a bunch of things and running around everywhere, I'm realizing this might have been a dead end. Let's take a step back onto the odoo user and search for important files.

find / -perm -4000 2>/dev/null
Gets us this weird program /ret — wtf is that lol, let's check it out.

Looking like another Ghidra.

Don't waste your time like I did, it's a trap lmao. Enumerating the machine from the root Docker does absolutely nothing we couldn't have done on the odoo account.
Checking the kernel once again we get 4.4.0-210-generic — no exploits available, this is actually the patched version.

Going back on the root account, remember we saw something running on 4444 — turns out it's another one of those ret binaries again. We run the same binary again to port 4444 and bam, we get user on the other machine as zeeshan!

Enumerating as zeeshan, I found /exploit_me — another setuid+setgid root ELF. This one had no win() and no /bin/sh string, so ret2win was out. A quick cyclic-pattern crash in gdb put the offset at 40, and the plan wrote itself: leak puts@got via puts@plt, return into main for a second overflow, then ROP into execve("/bin/sh", NULL, NULL) at the resolved libc address.

pwntools has an SSH transport that lets you drive a remote process the same way as a local one, so I dropped my key into zeeshan@hydra's authorized_keys, scp'd the target's libc back to Kali, and ran the exploit over that SSH channel. Leak came back clean, second payload landed, and interactive mode dropped me into a # prompt as root. /root/root.txt
