From 220706e78aefe66221dbb93d6b242d3c49297d67 Mon Sep 17 00:00:00 2001 From: Jack Ullrich Date: Thu, 20 Apr 2017 12:30:32 -0500 Subject: [PATCH] Initial codebase --- ShellcodeStdio/ScStdio.cpp | 128 ++++++++++++++++++ ShellcodeStdio/ScStdio.h | 13 ++ ShellcodeStdio/ShellcodeStdio.vcxproj | 12 +- ShellcodeStdio/ShellcodeStdio.vcxproj.filters | 8 ++ ShellcodeStdio/main.cpp | 6 +- 5 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 ShellcodeStdio/ScStdio.cpp create mode 100644 ShellcodeStdio/ScStdio.h diff --git a/ShellcodeStdio/ScStdio.cpp b/ShellcodeStdio/ScStdio.cpp new file mode 100644 index 0000000..7875f7e --- /dev/null +++ b/ShellcodeStdio/ScStdio.cpp @@ -0,0 +1,128 @@ +#include "ScStdio.h" + +namespace ScStdio { + /* + Suggested VS Compilation Switches: + C/C++ -> Optimization -> /O1, /Ob2, /Oi, /Os, /Oy-, /GL + C/C++ -> Code Generation -> /MT, /GS-, /Gy + Linker -> General -> /INCREMENTAL:NO + */ + + __declspec(naked) void MalCodeBegin() { __asm { jmp MalCode } }; + +#define htons(A) ((((WORD)(A) & 0xff00) >> 8) | (((WORD)(A) & 0x00ff) << 8)) + + __forceinline PEB *get_peb() { + PEB *p; + __asm { + mov eax, fs:[30h] + mov p, eax + } + return p; + } + +#define ROR_SHIFT 13 + + constexpr DWORD ct_ror(DWORD n) { + return (n >> ROR_SHIFT) | (n << (sizeof(DWORD) * CHAR_BIT - ROR_SHIFT)); + } + + constexpr char ct_upper(const char c) { + return (c >= 'a') ? (c - ('a' - 'A')) : c; + } + + constexpr DWORD ct_hash(const char *str, DWORD sum = 0) { + return *str ? ct_hash(str + 1, ct_ror(sum) + ct_upper(*str)) : sum; + } + + DWORD rt_hash(const char *str) { + DWORD h = 0; + while (*str) { + h = (h >> ROR_SHIFT) | (h << (sizeof(DWORD) * CHAR_BIT - ROR_SHIFT)); + h += *str >= 'a' ? *str - ('a' - 'A') : *str; + str++; + } + return h; + } + + LDR_DATA_TABLE_ENTRY *getDataTableEntry(const LIST_ENTRY *ptr) { + int list_entry_offset = offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + return (LDR_DATA_TABLE_ENTRY *)((BYTE *)ptr - list_entry_offset); + } + + PVOID getProcAddrByHash(DWORD hash) { + PEB *peb = get_peb(); + LIST_ENTRY *first = peb->Ldr->InMemoryOrderModuleList.Flink; + LIST_ENTRY *ptr = first; + do { + LDR_DATA_TABLE_ENTRY *dte = getDataTableEntry(ptr); + ptr = ptr->Flink; + + BYTE *baseAddress = (BYTE *)dte->DllBase; + if (!baseAddress) + continue; + IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)baseAddress; + IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS *)(baseAddress + dosHeader->e_lfanew); + DWORD iedRVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + if (!iedRVA) + continue; + IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)(baseAddress + iedRVA); + char *moduleName = (char *)(baseAddress + ied->Name); + DWORD moduleHash = rt_hash(moduleName); + DWORD *nameRVAs = (DWORD *)(baseAddress + ied->AddressOfNames); + for (DWORD i = 0; i < ied->NumberOfNames; ++i) { + char *functionName = (char *)(baseAddress + nameRVAs[i]); + if (hash == moduleHash + rt_hash(functionName)) { + WORD ordinal = ((WORD *)(baseAddress + ied->AddressOfNameOrdinals))[i]; + DWORD functionRVA = ((DWORD *)(baseAddress + ied->AddressOfFunctions))[ordinal]; + return baseAddress + functionRVA; + } + } + } while (ptr != first); + + return NULL; + } + +#define DEFINE_FUNC_PTR(module, function) \ + constexpr DWORD hash_##function = ct_hash(module) + ct_hash(#function); \ + typedef decltype(function) type_##function; \ + type_##function *##function = (type_##function *)getProcAddrByHash(hash_##function) + +#define DEFINE_FWD_FUNC_PTR(module, real_func, function) \ + constexpr DWORD hash_##function = ct_hash(module) + ct_hash(real_func); \ + typedef decltype(function) type_##function; \ + type_##function *##function = (type_##function *)getProcAddrByHash(hash_##function) + + VOID __stdcall MalCode() { + + CHAR strUser32[] = { 'u','s','e','r','3','2','.','d','l','l',0 }; + CHAR strMboxTitle[] = { 'S','h','e','l','l','S','t','d','i','o', 0 }; + CHAR strMboxMsg[] = { 'H','e','l','l','o',' ', 'W','o','r','l','d','!',0 }; + + DEFINE_FUNC_PTR("kernel32.dll", LoadLibraryA); + LoadLibraryA(strUser32); + + DEFINE_FUNC_PTR("user32.dll", MessageBoxA); + MessageBoxA(NULL, strMboxMsg, strMboxTitle, MB_OK); + } + + __declspec(naked) void MalCodeEnd() { }; + + BOOL WriteShellcodeToDisk() + { + DWORD dwWritten; + HANDLE FileHandle = CreateFileW(L"shellcode.bin", GENERIC_ALL, NULL, NULL, CREATE_ALWAYS, NULL, NULL); + + if (!FileHandle) + return false; + + if (WriteFile(FileHandle, &MalCodeBegin, ((DWORD)&MalCodeEnd - (DWORD)&MalCodeBegin), &dwWritten, NULL)) + { + CloseHandle(FileHandle); + return true; + } + + CloseHandle(FileHandle); + return false; + } +} \ No newline at end of file diff --git a/ShellcodeStdio/ScStdio.h b/ShellcodeStdio/ScStdio.h new file mode 100644 index 0000000..bbf92fb --- /dev/null +++ b/ShellcodeStdio/ScStdio.h @@ -0,0 +1,13 @@ +#pragma once + +/* Original: ShellcodeStdio -> @ winternl.com (Jack Ullrich)*/ +/* Much credit to the reddit user: good_nickname */ + +#include +#include +#include + +namespace ScStdio { + VOID __stdcall MalCode(); + BOOL WriteShellcodeToDisk(); +} \ No newline at end of file diff --git a/ShellcodeStdio/ShellcodeStdio.vcxproj b/ShellcodeStdio/ShellcodeStdio.vcxproj index 7b67eb3..8f5da3c 100644 --- a/ShellcodeStdio/ShellcodeStdio.vcxproj +++ b/ShellcodeStdio/ShellcodeStdio.vcxproj @@ -69,7 +69,9 @@ - + + false + Level3 @@ -91,6 +93,10 @@ true true true + AnySuitable + Size + MultiThreaded + false true @@ -112,6 +118,10 @@ + + + + diff --git a/ShellcodeStdio/ShellcodeStdio.vcxproj.filters b/ShellcodeStdio/ShellcodeStdio.vcxproj.filters index 7f33c6b..a9bba5d 100644 --- a/ShellcodeStdio/ShellcodeStdio.vcxproj.filters +++ b/ShellcodeStdio/ShellcodeStdio.vcxproj.filters @@ -14,5 +14,13 @@ Source Files + + Source Files + + + + + Header Files + \ No newline at end of file diff --git a/ShellcodeStdio/main.cpp b/ShellcodeStdio/main.cpp index 19d349b..59fae28 100644 --- a/ShellcodeStdio/main.cpp +++ b/ShellcodeStdio/main.cpp @@ -1,5 +1,7 @@ -#include +#include "ScStdio.h" int main(void) { - // Test + + ScStdio::MalCode(); + ScStdio::WriteShellcodeToDisk(); } \ No newline at end of file