[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/ac3ss0r/c2shell/main/Shellcode/shellcode.cpp [Back]  [Original]

#include 
#include 
#include 
#include 
#ifdef _WIN32
    #include 
#else
    #include 
#endif
#include "shcutils.h"

#ifdef _MSC_VER
    #pragma warning(disable:4996)
    #pragma section("shcode", execute)
#endif

// This method should be fully inline. No use of static fields & external methods is allowed since the shellcode
// Is supposed to be fully inline & offset independent (use PEB for windows & syscalls for linux)
SECTION_CODE("shcode") NOINLINE int /*_fastcall*/ shellcode() {
    #ifdef _WINDOWS
        // Typedefs for all the required methods
        typedef void* (*LoadLibraryA_t)(char*);
        typedef void* (*MessageBoxA_t)(int, char*, char*, int);

        // Some compilers insert the strings into the .data no matter what you do. So we need to trick em
        volatile char u32[30]; volatile int i = 0;
        u32[i++] = 'u';  u32[i++] = 's';  u32[i++] = 'e';  u32[i++] = 'r';  u32[i++] = '3';  u32[i++] = '2'; 
        u32[i++] = '.';  u32[i++] = 'd';  u32[i++] = 'l';  u32[i++] = 'l', u32[i++] = '\0';
        volatile char msg[30]; i = 0;
        msg[i++] = 't'; msg[i++] = 'e'; msg[i++] = 's'; msg[i++] = 't', msg[i++] = '\0';

        /* Note that any definitions should remain stack only. Otherwise the shellcode will be invalid
       
        // This gets stored to .data section 100%
        char s1[] = "test";

        // This gets stored to .data section 50/50 on different compilers
        char s2[] = {'t', 'e', 's', 't', 0};

        // This is stored to stack in 100% cases. Allows to trick the compiler
        char s3[32]; int i = 0;
        s3[i++] = 't', s3[i++] = 'e', s3[i++] = 's', s3[i++] = 't',s3[i++] = '\0';

        */
        
        void* base = get_module_handle(HASH("kernel32.dll"));

        if (base) {
            LoadLibraryA_t LoadLibA = (LoadLibraryA_t) get_proc_address(base, HASH("LoadLibraryA"));
            if (LoadLibA) {
                void* handle = LoadLibA((char*)u32);
                if (handle) {
                    MessageBoxA_t MsgBoxA = (MessageBoxA_t) get_proc_address(handle, HASH("MessageBoxA"));
                    MsgBoxA(0, (char*)msg, (char*)msg, MB_OK);
                    return 0;
                }
            }
        }
    #elif defined(_LINUX)
        volatile char msg[30]; volatile int i = 0;
        msg[i++] = 'H'; msg[i++] = 'e'; msg[i++] = 'l'; msg[i++] = 'l' , msg[i++] = 'o',  msg[i++] = ' ', 
        msg[i++] = 'f',  msg[i++] = 'r', msg[i++] = 'o', msg[i++] = 'm', msg[i++] = ' ', msg[i++] = 's',  msg[i++] = 'h', msg[i++] = 'e', msg[i++] = 'l', msg[i++] = 'l',
        msg[i++] = '!',  msg[i++] = '\n' , msg[i++] = '\0';
        inline_syscall(SYS_write, STDOUT_FILENO, (long)msg, i, 0, 0);
        return 0;
    #endif
    return 1;
}
// Next function goes directly after the shellcode, this allows to figure out shellcode size & dump it
SECTION_CODE("shcode") NAKED void shellcode_end(void) {}

typedef int (*shellcode_t)();

int main() {

    FILE* output_file = fopen("shellcode.bin", "wb");
    if (!output_file) {
        fprintf(stderr, "[e] Failed to open shellcode.bin\n");
        return 1;
    }
    size_t shellcode_size = (uintptr_t)shellcode_end - (uintptr_t)shellcode;
    printf("[i] Shellcode size: %lu, located at 0x%p\n", shellcode_size, shellcode);
    fwrite((char*)&shellcode, shellcode_size, 1, output_file);

    if (!fwrite((char*)&shellcode, shellcode_size, 1, output_file)) {
        fprintf(stderr, "[e] Failed to dump shellcode to disk. Check your compiler settings.\n");
        fclose(output_file);
        return 1;
    }
    fclose(output_file);
    printf("[i] Shellcode saved to file shellcode.bin.\n");

    FILE* file = fopen("shellcode.bin", "rb");
    if (!file) {
        fprintf(stderr, "[e] Failed to open shellcode.bin\n");
        return 1;
    }
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    fseek(file, 0, SEEK_SET);

    char* shellcode_buff = (char*)malloc(fileSize);

    if (!shellcode_buff) {
        fprintf(stderr, "[e] Failed to allocate memory for shellcode\n");
        fclose(file);
        return 1;
    }
    if (fread(shellcode_buff, 1, fileSize, file) != fileSize) {
        fprintf(stderr, "[e] Failed to read shellcode\n");
    #ifdef _WIN32
            VirtualFree(shellcode_buff, 0, MEM_RELEASE);
    #else
            free(shellcode_buff);
    #endif
        fclose(file);
        return 1;
    }
    fclose(file);
    printf("[i] Loaded shellcode size: %ld\n", fileSize);

    #ifdef _WIN32
        DWORD flOldProtect;
        if (!VirtualProtect(shellcode_buff, fileSize, PAGE_EXECUTE_READWRITE, &flOldProtect)) {
            fprintf(stderr, "[e] Failed to change memory protection\n");
            VirtualFree(shellcode_buff, 0, MEM_RELEASE);
            return 1;
        }
    #else
        if (mprotect(shellcode_buff, fileSize, PROT_EXEC | PROT_READ | PROT_WRITE) == -1) {
            fprintf(stderr, "[e] Failed to change memory protection\n");
            free(shellcode_buff);
            return 1;
        }
    #endif

    shellcode_t code = (shellcode_t)shellcode_buff;
    printf("Result: %d\n", code());

    printf("Shellcode execution completed successfully.\n");
    
    return 0;
}

Web Proxy Viewer  |  New URL  |  Original Page