Fulcrum
Gaining Access
Nmap scan:
$ nmap -p- --min-rate 3000 10.129.136.254
Starting Nmap 7.93 ( https://nmap.org ) at 2024-03-05 04:59 EST
Warning: 10.129.136.254 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.129.136.254
Host is up (0.059s latency).
Not shown: 65173 closed tcp ports (conn-refused), 356 filtered tcp ports (no-response)
PORT STATE SERVICE
4/tcp open unknown
22/tcp open ssh
80/tcp open http
88/tcp open kerberos-sec
9999/tcp open abyss
56423/tcp open unknownPort 4 was open, which was new.
Detailed scan:
$ nmap -p 4,80,88,9999,56423 -sC -sV --min-rate 3000 10.129.136.254
Starting Nmap 7.93 ( https://nmap.org ) at 2024-03-05 05:01 EST
Nmap scan report for 10.129.136.254
Host is up (0.031s latency).
PORT STATE SERVICE VERSION
4/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: 502 Bad Gateway
88/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-robots.txt: 1 disallowed entry
|_/
|_http-title: phpMyAdmin
9999/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: 502 Bad Gateway
56423/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: Fulcrum-API Beta
|_http-title: Site doesn't have a title (application/json;charset=utf-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernePort 80 and 9999 had bad gateways, so I was left with port 4, port 88 and port 56423.
Web Enum -> XXE LFI
Port 4 had a really basic page:

The link was to http://10.129.136.254:4/index.php?page=home, which looked vulnerable for LFI.
However, the page was not returning anything at all, not even an error message. SSRF didn't work as well, so this isn't RFI.
Running a gobuster scan with the .php extension returned 3 results:
upload.php returned nothing. Moving on!

Port 88 had a phpMyAdmin login:

I had no credentials, and default credentials didn't work. Moving on!
Port 56423 was more interesting:

Based on nmap, this was an API. I started enumerating any other endpoints possible. This whole API was custom, since there weren't wasn't anything I could find.
As such, I resorted to just playing around with it, sending POST requests with random variables to see what it would load.
Sending regular parameters did not work, and sending JSON did nothing either. I couldn't find out what to do, so I referred to a writeup (too guessy).
Saw that I had to use <Heartbeat><Ping>Pong</Ping></Heartbeat> to trigger a different response:

From here, XXE should be the path forward. This seems to be a blind injection since this thing shows nothing but PingPong.
Using this payload triggers a callback on my machine:

Since this is blind XXE with SSRF, I can try to exfiltrate data out. I used the OOB with DTD and PHP filter method method from PayloadAllTheThings.
This involved me creating this dtd.xml file:
Afterwards, the payload to send to the website is:
Basically, this makes the website retrieve an external DTD, which loads the filename I want, and then sends it to another port:

This can be scripted using some Python sockets and requests.
Firstly, create the file dtd.xml with the filename I want to read. Afterwards, use a thread to open a port 8000 and listen for connections indefinitely.
Then, just retrieve the output from the socket, parsed using regex and decoded from base64. This took a bit longer to code than I would like, but it felt great making it work with sockets.
There's a short delay in-between files, but otherwise it works. Just start a Python HTTP server in another terminal, and there will be GET requests sent to that server.
File Enum -> Port 4 LFI
For this, nmap stated that this was an nginx server, so I took a look at those files. However, reading /etc/nginx/sites-available/default took too long.
A lucky guess gave me /var/www/api/index.php as a readable file:
RCE -> Webserver
Now that I had a working LFI script, I wanted to view the service on port 4. Guessing led me to /var/www/uploads/index.php.
It only allows requests from localhost to use include. Conveniently, XXE + SSRF was used to get here, so RCE is easy since include executes PHP code and allows for the http:// wrapper.
The exploit path is:
Use XXE SSRF to visit port 4.
Set
pageto a malicious PHP file hosted on my machine.
Here's the exploit script:

WebServer -> File
Surprising to see AD here.
Powershell Creds -> WebUser Pivot
First thing I noticed was this .ps1 file in the folder the shell spawned in:
Here are the contents:
This is a Powershell credential, and it can be decoded. This looked like Active Directory, and that there were other machines present. A quick check on ip route confirms this.
A quick ping sweep reveals there was only one other machine accessible:
I decoded this credential using pwsh. All you have to do is just run the entire script from $1 to $5:

Then, use $5.GetNetworkCredential().password:
I used chisel and proxychains to start pivoting:
From here, I downloaded the nmap binary to scan the ports on that one machine that is reachable, just to see what protocol is to be used with the credentials.
evil-winrm with proxychains is the next step since port 5985 is open.

Can use proxychains -q to remove those debug messages if you desire.
AD Enum -> BTables Creds
This user had no particularly interesting permissions, or files in their directory.
Within the C:\inetpub\wwwroot folder, there were some IIS files:
web.config had some interesting stuff:
There's a password here for LDAP here. There was also mention of dc.fulcrum.local. The current machine I was on was called webserver (based on hostname output).
Anyways, I relied on PowerView.ps1 to enumerate the domain. When I first tested it, all commands failed with this error:
Perhaps I needed to use the credentials from earlier to query LDAP:
This solved the error earlier, and I could view the users present:
923a was a domain admin, and BTables was another user. Using Get-DomainUsershows credentials for BTables:
++FileServerLogon12345++ was the password. However, this user was not present on my current machine.
Network Enum -> Pivot to File
I enumerated all computer objects within this network, which revealed 2 more.
I used ping to see their IPs:
I used chisel.exe to forward port 5985 from FILE, since the password was kinda obvious in telling me the next step.
Then, I could evil-winrm in and finally grab the user flag:

File -> DC
Enumeration -> Shares
This FILE server was empty. Most of the file system was just default Windows. As such, I tried to use the credentials I had to access the shares on the DC, which was something the CRTE lab taught me to do.
These were default shares, but honestly there was nothing else to look at anymore, so I went for it.
Shares Enum -> Admin Creds
The sysvol share had a ton of .ps1 files:
I read one of them, and noticed the user:
Using this, I can try to find 923a, which was a valid domain admin.
Great! Now, I had valid credentials. Using this, I can read the flag:

To get a shell, I did the following:
Then, I can evil-winrm in as the 923a user:

Fun box!
Noclick Scripts
Just made this for fun.
Initial RCE
The same can be done for the LFI.
Last updated