Napper
Gaining Access
Nmap scan:
$ nmap -p- --min-rate 3000 10.129.212.24
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-13 06:54 EST
Nmap scan report for 10.129.212.24
Host is up (0.0085s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT STATE SERVICE
80/tcp open http
443/tcp open https
7680/tcp open pando-pubDid a detailed scan as well:
$ nmap -p 80,443,7680 -sC -sV --min-rate 3000 10.129.212.24
Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-13 06:56 EST
Nmap scan report for 10.129.212.24
Host is up (0.0072s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: Did not follow redirect to https://app.napper.htb
|_http-server-header: Microsoft-IIS/10.0
443/tcp open ssl/http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-generator: Hugo 0.112.3
| ssl-cert: Subject: commonName=app.napper.htb/organizationName=MLopsHub/stateOrProvinceName=California/countryName=US
| Subject Alternative Name: DNS:app.napper.htb
| Not valid before: 2023-06-07T14:58:55
|_Not valid after: 2033-06-04T14:58:55
|_ssl-date: 2023-11-13T11:56:35+00:00; -14s from scanner time.
|_http-title: Research Blog | Home
|_http-server-header: Microsoft-IIS/10.0
| tls-alpn:
|_ http/1.1
7680/tcp open pando-pub?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: -14sI added app.napper.htb and napper.htb to the /etc/hosts file before proceeding with web enumeration.
Web Enum -> Subdomain Enumeration
The website was a security research blog:

There was nothing interesting about the content written there, so I proceeded with the usual fuzzing via wfuzz and gobuster, with the former finding another subdomain.
Visiting this required credentials, which I did not have yet. Looking around at the posts on the blog, I figured the credentials had to be somewhere within one of the posts.
One of the posts was about setting up basic authentication on IIS:

And within that blog, there was an example user used:

I found that example:ExamplePassword worked in authenticating to the internal subdomain.

This page contained some exclusive information about the website, including some kind of backdoor available.

TLDR, here are the interesting parts:
So, I needed a base64 encoded .NET binary to run here. The references were pretty important to read as well:
This basically told us how the binary works, and the value submitted in the parameter will have an assembly object created and executed it using the Run method. The resources were incredibly detailed, so I figured that the exploit used here has to be similar as well.
The blog also contained a nice Python Poc to run payloads:

Payload Creation -> Reverse Shell
I used a basic reverse C# reverse shell that executed powershell.exe (as cmd.exe didn't work for some reason). The code must have a class called Run and a constructor for it.
Afterwards, I used mono to compile the program to get payload.exe.
The next step would be to encode this using base64 and plop it in our inject.py.
Here's the final inject.py script:
Upon running, it returns some headers:
More importantly, I got a reverse shell as the ruben user:

Privilege Escalation
In the first nmap scan I did, port 7680 was listening. Checking the output of netstat -a, I saw some other ports that were open:
Interesting. There was also a directory within C:\Temp that was not the default:
Witin the internal directory, I looked around and found some interesting files:
It seems that Elastic is running on the machine on port 9200, and there's also a weird a.exe binary present. Running it does nothing though.
Elastic + Reversing
Firstly, I used chisel to forward port 9200 to my machine.
When I visited https://localhost:9200, it required credentials to get in. Fortunately, C:\Program Files contained some Elastic files.
Spent like an hour here trying to find out the correct password. Ended up doing Get-ChildItem -Recurse | Select-String -Pattern "password" -List and just going through each line until I found this:
I tried a username of user and elastic with this password, and elastic worked.

Still wasn't sure what this stuff was for though. I tried making a query via _search:

Got some encoded blob here. Interestingly, this blob changes each time, and it is not fixed. This might be a password of some sorts.
Anyways, time to take a look at the binary, which was built in Golang based on ghidra.

I was unable to decode anything meaningful using it, so I looked online to see if there were any plugins or alternatives I could use. Apparently, there's a Golang extension for ghidra.
After downloading this extension and restarting ghidra, a new window popped up.

The binary took a bit longer to analyse. Within the main function, I saw this:

Seems that the binary is attempting to executing cmd.exe /c net user backup. There was also this part that was encrypting something:

Based on all of the information, it seems that the seed used for random generation and some encrypted blob was on Elastic, and it might be a password for the backup user.
Password Decryption -> Root
The blob and seed used was changing every 5 minutes on Elastic. This is the key generation algorithm:

The key is just 1 + rand.Intn(254). Since this uses AES, the IV should be part of the encrypted blob as well.

Based on the fact that the seed is given, I'm assuming insecure RNG is used and the rand parts are actually deterministic. Based on this fact, I ChatGPT-d a Go script to run and decrypt the password:
When run, it produces this output:
Using this password, RunasCs.exe can be used to gain execution as the backup user.

Afterwards, I can easily use this to get a shell as the backup user via another msfvenom shell.

As backup, I was given full privileges to the machine:
The user is also part of the Administrators group:
I could read the root.txt flag, meaning this machine was effectively rooted since backup was an administrator.
Last updated