StackZero
  • Homepage
  • Cryptography and Privacy
  • Ethical Hacking
  • Reverse Engineering
  • Contacts
  • About Me
No Result
View All Result
StackZero
No Result
View All Result

How to code shellcode runner for your malware analysis

October 27, 2021
in Reverse Engineering
0 0
How to code shellcode runner for your malware analysis
0
SHARES
730
VIEWS
Share on FacebookShare on Twitter

The question that might come naturally after reading this title is:
Why should you know how to code a shellcode runner for your malware analysis?

Malware analysis is a dark art. Every time you conduct a routine analysis, you get a surprise.
Often, you need to extract hidden shell codes and analyze them separately.
While analyzing it, we might meet some unexpected conditions that complicate the understanding of the malware.
In such cases, you can find it easier to execute the shellcode in a separate thread.


In summary, the project will be a simple runner that:

  • takes a shellcode dump as input
  • runs it in a separate thread
  • stops execution by telling us where to set our breakpoint

For more details, you can look at this post on How to embed a shellcode payload into an executable.

Obviously, if you only need to run a shellcode, you can skip this part, copy the whole code and then compile by starting from here.

Table of Contents

Toggle
  • What is the Shellcode?
  • The preliminary part
  • Main method
  • Put all together
  • Further readings

What is the Shellcode?

As a quick refresh, I just want to explain in a few words what is a shellcode.

The term “shellcode” refers to machine code used either as the payload in the exploitation of a software vulnerability or, in this case, as a code to inject into a running process.

It has this cool and scary name because it typically starts a command shell from which the attacker can control the compromised machine, but any machine code can be used as the payload.

Typically, the payload is in the form of a binary piece of executable code, which is injected into the target machine’s process, making sure that through certain techniques it is then executed.

Some of the main requirements are:

  • It has to be very small
  • It has to avoid some “bad characters”
  • It has to be position-independent

They are the consequence of the fact that the attacker doesn’t know the exact memory region where the victim system puts the payload.

Now, after this quick refresh, we are ready to start coding the shellcode runner!

The preliminary part

You are here for one reason, and you surely want to dive into it and start to code it.

But before you can do that, we need to set up everything.

First of all, we’re going to write the required imports and definitions

Anyway, this is a lot easier said than done.
So let’s start getting our hands dirty with the code now!

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

#define MAX_SHELLCODE_LEN 1024

Main method

Then let’s look inside the main function step by step

    HANDLE threadHandle;
    size_t shellcode_len;
    LPVOID shellcode_alloc_mem;
    unsigned char shellcode[MAX_SHELLCODE_LEN];

   
    HANDLE h_file = CreateFile(argv[1], GENERIC_READ ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    BOOL retval = ReadFile(h_file, shellcode, MAX_SHELLCODE_LEN, &shellcode_len, NULL);

The above lines are extremely simple to explain, they:

  • Declare the variables we will need in the following steps
  • Read the file containing the shellcode
  • Pass it via prompt (argv[1]) and save it as an array of unsigned chars.
    Since this is only for our analysis and understanding, we don’t need to do any checks on the input.
    shellcode_alloc_mem = VirtualAlloc(0, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    RtlMoveMemory(shellcode_alloc_mem, shellcode, shellcode_len);

At this point, a memory area with all permissions is allocated where we’re going to move the shellcode with the help of the RtlMoveMemory function.

    printf("%-20s : 0x%-16p\n ", "the shellcode payload addr, put a breakpoint here and then press a key", 
          (void *)shellcode_alloc_mem);
    printf("Press a key to continue:\n");

    getchar();

This is the part of the code that indicates the area of memory where the shellcode resides and stops execution while waiting for a key press event.
You need to take note of this address because this is exactly where we are when we need to attach the debugger to our runner.

In other words, the runner stops its execution at this point and we need to attach the debugger to the process putting the breakpoints we need for our analysis.

    if(shellcode_alloc_mem){

        threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)shellcode_alloc_mem, 0, 0, 0);
        WaitForSingleObject(threadHandle, INFINITE);
    }

And finally, here is the part where we launch a new thread containing the shellcode and then wait for the end with the WaitForSingleObject method.

Put all together

At this point, to get a clearer picture, let’s see the full code.

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

#define MAX_SHELLCODE_LEN 1024

int main(int argc, char *argv[]) {

    HANDLE threadHandle;
    size_t shellcode_len;
    LPVOID shellcode_alloc_mem;
    unsigned char shellcode[MAX_SHELLCODE_LEN];

   
    HANDLE h_file = CreateFile(argv[1], GENERIC_READ ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    BOOL retval = ReadFile(h_file, shellcode, MAX_SHELLCODE_LEN, &shellcode_len, NULL);

    shellcode_alloc_mem = VirtualAlloc(0, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    RtlMoveMemory(shellcode_alloc_mem, shellcode, shellcode_len);

    printf("%-20s : 0x%-16p\n ", "the shellcode payload addr, put a breakpoint here and then press a key", (void *) shellcode_alloc_mem);
    printf("Press a key to continue:\n");

    getchar();
    if(shellcode_alloc_mem){

        threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)shellcode_alloc_mem, 0, 0, 0);
        WaitForSingleObject(threadHandle, INFINITE);
    }
}

We’re finally at the end, now all we have to do is compile.
Open NativeTools and go to the folder containing our file, which we will call “shellcode_runner.cpp“, then run the following command:

cl.exe  /Tcshellcode_runner.cpp /link /OUT:shellcode_runner.exe 

And now, assuming we have saved our shellcode in a file called shellcode.bin in the same folder as our program, let’s try to launch the runner with the following command.

If the folder is different, you just need to specify the path as a command line argument.

shellcode_runner.exe shellcode.bin

I hope the post was useful and that you enjoyed it, in the meantime, I send you goodbye to the next article!

Further readings

Now that you know how to code a shellcode runner for your malware analysis I suggest you do some readings:

  • How to embed a shellcode payload into an executable in just a few minutes
  • How a malware evades analysis – 2 simple techniques in practice
How to embed shellcode payload into an executable
Trending
How to embed shellcode payload into an executable

Tags: cmalware analysisshellcodeshellcode runnerwindowswindows api
Previous Post

How malware evasion works – 2 simple techniques in practice

Next Post

How to create network scanner tool in a few lines of code!

Next Post
How to create network scanner tool in a few lines of code!

How to create network scanner tool in a few lines of code!

You might also like

Cryptographic functions

Cryptographic Hash Functions in Python: Secure Your Data Easily

November 3, 2024
Malware Obfuscation Techniques: All That You Need To Know

Malware Obfuscation Techniques: All That You Need To Know

March 25, 2024
How To Do Process Enumeration: An Alternative Way

How To Do Process Enumeration: An Alternative Way

March 4, 2024
How To Do DLL Injection: An In-Depth Cybersecurity Example

How To Do DLL Injection: An In-Depth Cybersecurity Example

February 8, 2024
Process Injection By Example: The Complete Guide

Process Injection By Example: The Complete Guide

January 24, 2024
How To Build Your Own: Python String Analysis for Malware Insights

How To Build Your Own: Python String Analysis for Malware Insights

November 10, 2023

StackZero

StackZero is a specialized technical blog dedicated to the realm of cybersecurity. It primarily provides insightful articles and comprehensive tutorials designed to educate readers on developing security tools. The blog encompasses a broad spectrum of subjects, starting from the foundational principles of cryptography and extending to more sophisticated areas such as exploitation and reverse engineering. This makes StackZero an invaluable resource for both beginners and professionals in the field of cybersecurity.
The blog covers a wide range of topics, from the basics of cryptography to the more advanced topics of exploitation and reverse engineering.

Tags

application security blind sqli blind sql injection bruteforce c cesar cipher command injection cryptography ctf cybersecurity debugging dom-based xss dvwa ethical-hacking ethical hacking exploitation file inclusion gdb hacking injection javascript malware malware analysis malware evasion network-security pentesting lab picoctf pico ctf python reflected xss reverse engineering sql sqli sql injection static analysis stored xss substitution substitution cipher vulnerable application web application security web exploitation web security windows windows api xss
  • About Me
  • Contacts
  • HomePage
  • Opt-out preferences
  • Privacy Policy
  • Terms and Conditions

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
Manage Cookie Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
Manage options Manage services Manage {vendor_count} vendors Read more about these purposes
View preferences
{title} {title} {title}
No Result
View All Result
  • Homepage
  • Cryptography and Privacy
  • Ethical Hacking
  • Reverse Engineering
  • Contacts
  • About Me