# ZeroTotal: Msfvenom Calc

### Part One: Introduction

The motivation for this research is to demonstrate the fact that at the end of the day, a skilled attacker can overcome detection. Lets begin this series with our initial payload and results.

### Part Two: Getting Started

We make our shellcode with msfvenom. This is particularly a bad idea because these payloads should be thoroughly signatured.

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

We test our payload with runshc64.exe and get a working payload. Let see what VirusTotal says about this payload.

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

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

It's worth noting that in my experiments, using some of msfvenom's built in encoders was enough to return zero results from VirusTotal. But in the spirit of this research, lets aim to achieve that manually.

### Part Three: Editing Opcodes

If we open up our binary in a hex editor, this is what we'll see:

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

Lets disassemble that.

<figure><img src="/files/1PsP7FC4MzBmf0TbgFaM" alt=""><figcaption></figcaption></figure>

Hmm..it looks like we should be able to scramble some of the opcodes around without affecting the functionality of the program. That might be enough to break some of the signatures.

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

Notice that the xor instruction is now on line f instead of line 11 where it was previously.

We run our shellcode to ensure that it still works.

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

Lets try VirusTotal again and see if anything changed.

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

It looks like that single opcode swap reduced our detection from 20 to 14! That’s a 20% reduction with one change.

Before we start getting too complicated, we can try to adding some nops in a couple places (like the very beginning to see if we get positive effects).

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

And it looks like we've reduced our detectability by two more.

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

Lets move a little bit past this primitive workflow and open this binary up in BinaryNinja for a more useful interface.

&#x20;

### Part Three: Lets get to work

We open up our payload and see the following:

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

We tell BinaryNinja to interpret this binary dump as a function for clarity, and we get a nice flow graph of our payload.

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

We change "test rax, rax":

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

To "cmp eax, 0x0".

Note: This change is not perfectly equivalent, but it doesn't break the payload.

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

We can change "mov rdx, 0x1" to "mov edx, 0x1". We can now fill the newly empty space with garbage instructions.

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

And now it looks like this:

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

Lastly, we can make some changes to how we clear variables off the stack. This should help get rid of the things we don't need, and confuse automated analysis because it will break how a function is identified in some cases.

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

Let see what VirusTotal says about our payload now.

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

And it looks like we're down to two contenders. Let see if there's something we can do about that.

If we take another look at our payload in BinaryNinja we notice some hardcoded constants:

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

After doing some research into how msfvenom generates payload, we know that it does not pass the API call by name, but rather by a hash value. It's super likely that one of those values is what's getting us flagged.

Earlier, we turned this instruction:

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

Into this:

<figure><img src="/files/06hdssEPJ6soFE1D8cvE" alt=""><figcaption></figcaption></figure>

But we can rewrite that more succinctly to achieve 0x1 in edx and generate some empty space for us to play with.

So we turn this:

<figure><img src="/files/1sifBO37BAGXIyCG2uMv" alt=""><figcaption></figcaption></figure>

Into this:

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

### Part Four: ???

\[Intentionally left blank]

### Part Five: Profit

We check that our payload still works.

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

Lets see what VirusTotal says about our payload now.

<figure><img src="/files/SgyCkjWGUkgOleYlZkAK" alt=""><figcaption><p>Results: <a href="https://www.virustotal.com/gui/file/470abc7f80b75727785f3f5561a5ce60c2c0a7d8b876d5cb9e5a17ef88aff5f7?nocache=1">https://www.virustotal.com/gui/file/470abc7f80b75727785f3f5561a5ce60c2c0a7d8b876d5cb9e5a17ef88aff5f7?nocache=1</a></p></figcaption></figure>

### Part Six: Conclusion

In this write up, we saw how we were able to bypass all VirusTotal checks without encrypting, encoding, or wrapping our payload in any way. This demonstrates the value that that low-level binary manipulations bring to Red Teams and validates how important these skills are in any engagement.

However, this is not the end of the battle for the Red Team. More advanced analysis by EDR that leverage machine learning, heuristic analysis, or executable emulation are still apt to detect our payload. This is but one skillset and one data point to draw from when analyzing a target's attack surface.

Astute readers might notice that my payload size changed throughout this write up. I ended up injecting a few NOP bytes to give myself space to work and write the opcodes that got use from 2 to 0 detections in Part 4.

### References

{% embed url="<https://github.com/0xTriboulet/Red_Team_Code_Snippets/tree/main/Assembly/Winx64/payloads/5.ZeroTotal/calc>" %}

{% embed url="<https://www.amazon.com/dp/047008023X?ref_=cm_sw_r_cp_ud_dp_9XP79KK1MHTP2B7Q5ZYD>" %}

{% embed url="<https://github.com/rapid7/metasploit-framework/blob/master/msfvenom>" %}


---

# 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://steve-s.gitbook.io/0xtriboulet/archive/notice/zerototal/zerototal-msfvenom-calc.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.
