{
	"id": "ebb874f7-aad3-4d36-8aaa-0040b630773b",
	"created_at": "2026-04-06T00:18:06.69732Z",
	"updated_at": "2026-04-10T03:37:33.308144Z",
	"deleted_at": null,
	"sha1_hash": "3285e1a5c22cd4e722d5551a3548a949aff88a43",
	"title": "MagicWeb: NOBELIUM’s post-compromise trick to authenticate as anyone | Microsoft Security Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4711825,
	"plain_text": "MagicWeb: NOBELIUM’s post-compromise trick to authenticate as\r\nanyone | Microsoft Security Blog\r\nBy Microsoft Incident Response, Microsoft Threat Intelligence\r\nPublished: 2022-08-24 · Archived: 2026-04-05 14:54:41 UTC\r\nApril 2023 update – Microsoft Threat Intelligence has shifted to a new threat actor naming taxonomy aligned around the\r\ntheme of weather. NOBELIUM is now tracked as Midnight Blizzard.\r\nTo learn about how the new taxonomy represents the origin, unique traits, and impact of threat actors, and to get a complete\r\nmapping of threat actor names, read this blog: Microsoft shifts to a new threat actor naming taxonomy.\r\nThe Microsoft Detection and Response Team (DART) has been renamed to Microsoft Incident Response (Microsoft IR). For\r\nmore information on IR services, go to Microsoft Incident Response\r\nAugust 26, 2022 update: Added instructions to enable collection of AD FS event logs in order to search for Event ID 501,\r\nand added a new resource for AD FS audit logging in Microsoft Sentinel.\r\nMicrosoft security researchers have discovered a post-compromise capability we’re calling MagicWeb, which is used by a\r\nthreat actor we track as NOBELIUM to maintain persistent access to compromised environments. NOBELIUM remains\r\nhighly active, executing multiple campaigns in parallel targeting government organizations, non-governmental organizations\r\n(NGOs), intergovernmental organizations (IGOs), and think tanks across the US, Europe, and Central Asia. The Microsoft\r\nThreat Intelligence Center (MSTIC) assesses that MagicWeb was likely deployed during an ongoing compromise and was\r\nleveraged by NOBELIUM possibly to maintain access during strategic remediation steps that could preempt eviction.\r\nNOBELIUM has used abuse of identities and credentialed access as a method for maintaining persistence, and a specialized\r\ncapability like MagicWeb is not novel for the actor: in September 2021, Microsoft disclosed a post-exploitation capability\r\nnamed FoggyWeb with methods and intent similar to MagicWeb. FoggyWeb was capable of exfiltrating the configuration\r\ndatabase of compromised AD FS servers, decrypting token-signing certificates and token-decryption certificates, and\r\ndownloading and executing additional malware components. MagicWeb goes beyond the collection capabilities of\r\nFoggyWeb by facilitating covert access directly. MagicWeb is a malicious DLL that allows manipulation of the claims\r\npassed in tokens generated by an Active Directory Federated Services (AD FS) server. It manipulates the user authentication\r\ncertificates used for authentication, not the signing certificates used in attacks like Golden SAML.\r\nNOBELIUM was able to deploy MagicWeb by first gaining access to highly privileged credentials and moving laterally to\r\ngain administrative privileges to an AD FS system. This is not a supply chain attack. The attacker had admin access to the\r\nAD FS system and replaced a legitimate DLL with their own malicious DLL, causing malware to be loaded by AD FS\r\ninstead of the legitimate binary. The backdoor was discovered by Microsoft’s Detection and Response Team (DART) in\r\ncoordination with MSTIC and Microsoft 365 Defender Research during an ongoing incident response investigation.\r\nMicrosoft is sharing this information with consent from the client. At the time of this investigation, MagicWeb appears to be\r\nhighly targeted.\r\nLike domain controllers, AD FS servers can authenticate users and should therefore be treated with the same high level of\r\nsecurity. Customers can defend against MagicWeb and other backdoors by implementing a holistic security strategy\r\nincluding the AD FS hardening guidance. In the case of this specific discovery, MagicWeb is one step of a much larger\r\nintrusion chain that presents unique detection and prevention scenarios.\r\nWith all critical infrastructure such as AD FS, it is important to ensure attackers do not gain administrative access. Once\r\nattackers gain administrative access, they have many options for further system compromise, activity obfuscation, and\r\npersistence. We recommend that any such infrastructure is isolated, accessible only by dedicated admin accounts, and\r\nregularly monitored for any changes. Other security measures that can prevent this and other attacks include credential\r\nhygiene to prevent lateral movement. AD FS is an on-premises server, and as with all on-premises servers, deployments can\r\nget out of date and/or go unpatched, and they can be impacted by local environment compromises and lateral movement. For\r\nthese reasons, migration to a cloud-based identity solution such as Azure Active Directory for federated authentication is\r\nrecommended for the robust security it provides. See the mitigation section below for more information. Though we assess\r\nthe capability to be in limited use, Microsoft anticipates that other actors could adopt similar methodologies and therefore\r\nrecommends customers review hardening and mitigation guidance provided in this blog.\r\nHow MagicWeb subverts authentication\r\nMagicWeb is a post-compromise malware that can only be deployed by a threat actor after gaining highly privileged access\r\nto an environment and moving laterally to an AD FS server. To achieve their goal of maintaining persistent access to an\r\nenvironment by validating authentication for any user account on the AD FS server, NOBELIUM created a backdoored DLL\r\nby copying the legitimate Microsoft.IdentityServer.Diagnostics.dll file used in AD FS operations. The legitimate version of\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 1 of 15\n\nthis file is catalog signed by Microsoft and is normally loaded by the AD FS server at startup to provide debugging\r\ncapabilities. NOBELIUM’s backdoored version of the file is unsigned. The threat actor’s highly privileged access that\r\nallowed them to access the AD FS server meant they could have performed any number of actions in the environment, but\r\nthey specifically chose to target an AD FS server to facilitate their goals of persistence and information theft during their\r\noperations.\r\nAfter gaining administrative access to an AD FS server via elevation of privilege and lateral movement, the loading of\r\nNOBELIUM’s malicious Microsoft.IdentityServer.Diagnostics.dll into the AD FS process is possible by editing\r\nC:\\Windows\\AD FS\\Microsoft.IdentityServer.Servicehost.exe.config to specify a different public token, which controls what\r\nloads into the AD FS process when it is started. Because AD FS is a .NET application, it loads the DLLs specified in the\r\nconfig file from the Global Assembly Cache (GAC). By changing the token in the configuration, the adversary directed AD\r\nFS to load in the malicious DLL. The interception and manipulation of claims by MagicWeb enables the actor to generate\r\ntokens that allow the adversary to bypass AD FS policies (role policies, device policies, and network policies) and sign in as\r\nany user with any claims, including multifactor authentication (MFA).\r\nFigure 1. C:\\Windows\\AD FS\\Microsoft.IdentityServer.Servicehost.exe.config being set to load\r\nMicrosoft.IdentityServer.Diagnostics.dll\r\nFigure 2. NOBELIUM uses a different public token than the legitimate\r\nMicrosoft.IdentityServer.Diagnostics.dll, telling AD FS to look for a different file in the GAC\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 2 of 15\n\nFigure 3. Close up from Microsoft.IdentityServer.Servicehost.exe.config showing MagicWeb’s malicious\r\nPublicKeyToken compared to the PublicKeyToken of the legitimate version of the DLL\r\nFigure 4. The directories in the GAC on a server infected with MagicWeb; the malicious\r\nMicrosoft.IdentityServer.Diagnostics.dll file and the legitimate one are located in different directories\r\nTo understand how NOBELIUM can subvert the AD FS process with the MagicWeb malware, it’s important to understand\r\nhow AD FS claims work. AD FS extends the ability to use single sign-on functionality available within a single security or\r\nenterprise boundary to internet-facing applications to provide customers, partners, and suppliers a streamlined user\r\nexperience while accessing an organization’s web-based applications. AD FS relies on claims-based authentication to\r\nvalidate the identity of the user and their authorization claims. These claims are packaged into a token that can be used for\r\nauthentication. MagicWeb injects itself into the claims process to perform malicious actions outside the normal roles of an\r\nAD FS server.\r\nFigure 5. How the AD FS claims pipeline issues a token for a user entering a federated application\r\nSecurity Assertion Markup Language (SAML) uses x509 certificates to establish trust relationships between identity\r\nproviders and services and to sign and decrypt tokens. These x509 certificates contain enhanced key usage (EKU) values\r\nthat specify what applications the certificate should be used for. For instance, an EKU containing an Object Identifier (OID)\r\nvalue of 1.3.6.1.4.1.311.20.2.2 would allow for the use of a SmartCard logon. Organizations can create custom OIDs to\r\nfurther narrow certificate usage.\r\nMagicWeb’s authentication bypass comes from passing a non-standard Enhanced Key Usage OID that is hardcoded in the\r\nMagicWeb malware during an authentication request for a specified User Principal Name. When this unique hard coded OID\r\nvalue is encountered, MagicWeb will cause the authentication request to bypass all standard AD FS processes (including\r\nchecks for MFA) and validate the user’s claims. MagicWeb is manipulating the user authentication certificates used in\r\nSAML sign-ins, not the signing certificates for a SAML claim used in attacks like Golden SAML.\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 3 of 15\n\nFigure 6. Example of a user certificate accepted by MagicWeb; the highlighted numbers under “Unknown\r\nKey Usage” is one of two OIDs hardcoded into MagicWeb\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 4 of 15\n\nFigure 7. Example of a user certificate chain, which shows an invalid digital signature but still works for\r\nauthentication\r\nNOBELIUM uses unique tradecraft per target, so it’s highly likely that the OIDs and public tokens are unique per target as\r\nwell. We’ve redacted these OIDs and tokens in this report. Please see the hunting guidance section for information on how to\r\nlook for variants related to this attack.\r\nHow to mitigate this threat\r\nNOBELIUM’s ability to deploy MagicWeb hinged on having access to highly privileged credentials that had administrative\r\naccess to the AD FS servers, giving them the ability to perform whatever malicious activities they wanted to on the systems\r\nthey had access to.\r\nIt’s critical to treat your AD FS servers as a Tier 0 asset, protecting them with the same protections you would apply to a\r\ndomain controller or other critical security infrastructure. AD FS servers provide authentication to configured relying\r\nparties, so an attacker who gains administrative access to an AD FS server can achieve total control of authentication to\r\nconfigured relying parties (include Azure AD tenants configured to use the AD FS server). Practicing credential hygiene is\r\ncritical for protecting and preventing the exposure of highly privileged administrator accounts. This especially applies on\r\nmore easily compromised systems like workstations with controls like logon restrictions and preventing lateral movement to\r\nthese systems with controls like the Windows Firewall.\r\nMigration to Azure Active Directory (Azure AD) authentication is recommended to reduce the risk of on-premises\r\ncompromises moving laterally to your authentication servers. Customers can use the following references on migration:\r\nUse the activity report to move AD FS apps to Azure AD\r\nMove application authentication to Azure AD\r\nAdvanced hunting queries\r\nRecommended hunting guidance\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 5 of 15\n\nHave Inventory Certificate Issuance policies in your Public Key Infrastructure (PKI) environment, including all EKU\r\nattributes used in the environment and compare to known OID values.\r\nHunt across Windows Event Logs by enabling AD FS verbose logging. Enable security auditing to allow collection\r\nof the AD FS event logs, and specifically look for Event ID 501. This event specifies all the EKU attributes on a\r\nclaim. Hunt across these logs to look for EKU values which your PKI infrastructure isn’t configured to issue.\r\nLook for portable executable files in the GAC or AD FS directories on your systems that aren’t signed by Microsoft\r\nand inspect these files or submit them for analysis.\r\nPerform an audit of your exclusion settings to be sure that the AD FS and GAC are included in scans. Many\r\norganizations exclude the AD FS directories from security software scanning because of performance degradation\r\nconcerns.\r\nMicrosoft Sentinel\r\nMicrosoft Sentinel customers who have enabled verbose mode logging for ADFS can use this query to look for suspicious\r\nOIDs: https://github.com/Azure/Azure-Sentinel/tree/master/Detections/SecurityEvent/ADFSAbnormalEnhancedKeyUsageAttribute-OID.yaml.\r\nNOTE: It’s important to enable the proper connector in Sentinel with the correct Event collection. Refer to this post for more\r\ndetails on AD FS Audit logging collection in Sentinel.\r\nSearching for unsigned files in the GAC\r\nThe legitimate Microsoft.IdentityServer.Diagnostics.dll is catalog signed by Microsoft. Catalog signing is a method\r\nWindows uses for validating code integrity different from Authenticode, and is used for offline validation rather than\r\nruntime enforcement of running only signed code. The catalog signing on this file means the file may appear to be unsigned\r\non the file properties pane and in file integrity checkers, security tools, and online malware repositories. The scripts below\r\nallow you to look for unsigned binaries and understand both catalog-signed binaries and Authenticode-signed binaries.\r\nSurface unsigned DLLs in GAC using Microsoft 365 Defender\r\nThis query surfaces unsigned DLLs in the GAC folder created within the last 60 days.\r\nDeviceImageLoadEvents\r\n| where FolderPath has @\"C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\Microsoft.IdentityServer.\" and\r\nFileName endswith \".dll\" and not(isempty(SHA1))\r\n| join kind = leftanti (DeviceFileCertificateInfo) on SHA1\r\n| distinct DeviceName, FolderPath, FileName, SHA1, SHA256\r\nEnumerate non-Microsoft signed DLLs in the GAC using PowerShell\r\nBelow is an example script that could be used to enumerate non-Microsoft signed DLLs in the relevant GAC folder, where\r\nservers.txt is a list of servers you wish to scan. Because the legitimate Microsoft.IdentityServer.Diagnostics.dll is catalog\r\nsigned, signing won’t appear when viewing file properties, but it will show in PowerShell querying and on load of the DLL.\r\n$servers = get-content -Path (path to file)\\servers.txt\r\nForeach ($server in $servers) {\r\nWrite-Output \"Processing server: $server\"\r\nInvoke-Command -ComputerName $server {Get-ChildItem -Filter \"*.dll\" -Recurse\r\n\"C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\\" | get-authenticodesignature | ft}\r\n}\r\nDetections\r\nMicrosoft Defender Antivirus\r\nMicrosoft Defender Antivirus provides detection for this threat under the following malware name:\r\nTrojan:MSIL/MagicWeb.A!dha\r\nMicrosoft Defender for Endpoint\r\nMicrosoft Defender for Endpoint customers may see the following alert as an indication of possible attack:\r\nADFS persistent backdoor detected\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 6 of 15\n\nIndicators of compromise (IOCs)\r\nMicrosoft isn’t sharing IOCs on this NOBELIUM activity at this time. However, NOBELIUM frequently customizes\r\ninfrastructure and capabilities per campaign, minimizing operational risk should their campaign specific attributes be\r\ndiscovered. If MagicWeb is identified in your environment, it’s unlikely to match any static IOCs from other targets such as\r\na SHA-256 value. It’s recommended to use the hunting guidance provided above to investigate your environment.\r\nTechnical analysis of MagicWeb\r\nNOBELIUM has modified the legitimate Microsoft.IdentityServer.Diagnostics.dll by adding malicious code to the TraceLog\r\nclass from the Microsoft.IdentityServer.Diagnostics namespace/type.\r\nThe header section of the TraceLog class from the legitimate Microsoft.IdentityServer.Diagnostics.dll is shown below:\r\nFigure 8. The header section of the TraceLog class of Microsoft.IdentityServer.Diagnostics namespace/type\r\nfrom the legitimate Microsoft.IdentityServer.Diagnostics.dll\r\nMeanwhile, the header section of the TraceLog class from NOBELIUM’s backdooredversion of\r\nMicrosoft.IdentityServer.Diagnostics.dll is shown below:\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 7 of 15\n\nFigure 9. The header section of the TraceLog class of Microsoft.IdentityServer.Diagnostics namespace from\r\nNOBELIUM’s backdoored version of Microsoft.IdentityServer.Diagnostics.dll\r\nIn the backdoored version of the code, as shown above, NOBELIUM has added a static constructor for the TraceLog class.\r\nA static constructor is used to initialize any static data, or to perform a particular action that needs to be performed only\r\nonce. It’s called automatically before the first instance is created or any static members are referenced.\r\nThe malicious static constructor gets executed once before the first instance of the TraceLog class is created. Given that new\r\ninstances of the TraceLog class is created in various locations in this DLL, the execution of the malicious static constructor\r\nis guaranteed to occur as soon as the DLL is loaded for the first time (which would be upon startup of the AD FS server after\r\nthe malicious changes to Microsoft.IdentityServer.Servicehost.exe.config described above).\r\nNOBELIUM’s malicious static constructor contains a reference to the Initialize() method from a class named AuthLog.\r\nFigure 10. Reference to the Initialize() method from a class named AuthLog in the malicious static constructor\r\nThe AuthLog class is a brand-new and malicious class that’s been added to the DLL by NOBELIUM.\r\nFigure 11. The Initialize() method of the AuthLog class\r\nAs shown above, the Initialize() method references a class named RuntimeHelper, yet another class added to the DLL by the\r\nactor. The primary purpose of the RuntimeHelper class and its OverloadMethod() method is to hook legitimate AD FS\r\nrelated methods at runtime. By hooking the legitimate AD FS methods, the backdoor is capable of intercepting calls to the\r\nlegitimate methods to instead invoke its own custom methods.\r\nThe screenshot above shows the following legitimate AD FS methods being hooked by MagicWeb:\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 8 of 15\n\nTarget assembly/DLL Target type\r\nTarget method to\r\nhook\r\nMa\r\n(ac\r\nMicrosoft.IdentityServer.IdentityModel.dll Microsoft.IdentityModel.X509CertificateChain Build Be\r\nMicrosoft.IdentityServer.WebHost.dll Microsoft.IdentityServer.WebHost.WrappedHttpListenerRequest GetClientCertificate Be\r\nMicrosoft.IdentityServer.WebHost.dll Microsoft.IdentityServer.WebHost.Proxy.ProxyConfigurationData EndpointConfiguration Be\r\nMicrosoft.IdentityServer.Service.dll Microsoft.IdentityServer.Service.IssuancePipeline.PolicyEngine ProcessClaims Be\r\nHook method: BeginBuild()\r\nMagicWeb’s BeginBuild() method is used to hook the legitimate target method Build() (from\r\nMicrosoft.IdentityServer.IdentityModel.dll).\r\nFigure 12. MagicWeb’s BeginBuild() method\r\nThe BeginBuild() method first calls the MagicWeb’s helper method ValidateX509Extensions().\r\nIf the helper method ValidateX509Extensions() returns true, BeginBuild() returns true.\r\nIf ValidateX509Extensions() returns false, or an exception is thrown by calling ValidateX509Extensions(), BeginBuild()\r\ninvokes and returns the value returned by the legitimate Build() method from Microsoft.IdentityServer.IdentityModel.dll.\r\nThis means that before the legitimate target method Build() from the legitimate Microsoft.IdentityServer.IdentityModel.dll\r\ngets an opportunity to inspect/build a certificate, MagicWeb’s hook method first inspects the certificate and returns true if\r\nthe helper method ValidateX509Extensions() returns true.\r\nThis allows the attacker to subvert the normal certificate inspection/build process by introducing a custom certificate\r\ninspection/build method that’s invoked before the legitimate Build() method is invoked.\r\nHelper Method: ValidateX509Extensions()\r\nMagicWeb’s helper method ValidateX509Extensions() is called by BeginBuild() and other methods.\r\nFigure 13. Helper method ValidateX509Extensions()\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 9 of 15\n\nValidateX509Extensions() returns false if the X509 certificate passed to the method is null or the Microsoft Cryptographic\r\nAPI certificate context handle/pointer isn’t set.\r\nNext, the method enumerates the extensions in the X509 certificate passed to the method. If an enumerated extension is of\r\ntype X509EnhancedKeyUsageExtension, the method iterates the OIDs of the extension, calculating the MD5 hash of each\r\nOID (using a custom hash computation helper method ComputeHash() that leverages the .NET MD5 class).\r\nIf the MD5 hash value of the OID matches one of the two following hardcoded MD5 values, the method returns true (this\r\nmethodology is used to check if one of the two OID values below are present in the extension):\r\n67F5BD28A842A1C9[REDACTED] (MD5 hash value corresponding to the OID\r\nvalue 1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].\r\n[REDACTED])\r\n6E3466296D2F63D[REDACTED] (MD5 hash value corresponding to the OID value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].\r\n[REDACTED])\r\nIf none of the OID values are present, the method returns false.\r\nThis helper method returns true if the certificate passed to the method contains one of the two magic OID values listed\r\nabove.\r\nHook method: BeginGetClientCertificate()\r\nFigure 14. MagicWeb’s BeginGetClientCertificate() method, used to hook the legitimate target method\r\nGetClientCertificate() (from Microsoft.IdentityServer.WebHost.dll)\r\nTo retrieve the client’s X509 certificate, this method first calls the legitimate GetClientCertificate() method from\r\nMicrosoft.IdentityServer.WebHost.dll. Next, the hook method calls the helper method ValidateX509Extensions() to determine\r\nwhether the client certificate contains one of the two “magic” OID values. If the client certificate contains one of the two\r\nOID values, the hook method:\r\nObtains the _adapter field from the current object\r\nObtains the _request field from the _adapter object\r\nSets the value of the m_ClientCertificateError field (from the _request object) to 0\r\nThis means that regardless of what the legitimate method GetClientCertificate() (from Microsoft.IdentityServer.WebHost.dll)\r\nsets the m_ClientCertificateError field to, if a client certificate contains one of the magic OID values, the hook method\r\noverwrites or sets the m_ClientCertificateError field to 0.\r\nBy using this technique, the hook method appears to be influencing the normal behavior of the application to treat or accept\r\na non-valid client certificate as a valid certificate.\r\nHook method: BeginProcessClaims()\r\nFigure 15. The BeginProcessClaims() method of MagicWeb, used to hook the legitimate target method\r\nProcessClaims() (from Microsoft.IdentityServer.Service.dll)\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 10 of 15\n\nThe hook method first indirectly invokes the legitimate ProcessClaims() method by invoking the ProcessClaims() method of\r\nthe AuthLog class.\r\nOn line 198 in figure 16, the hook method calls MagicWeb’s helper method GetClaims(), passing in the processed identity\r\nobject returned by invoking the legitimate ProcessClaims() method.\r\nFigure 16. The GetClaims() helper method\r\nAs shown above, the GetClaims() method accepts an identity object as a parameter. The method then initializes three\r\nvariables named type, type2, and type3 with values obtained from the RuntimeHelper’s static field/array named types:\r\nFigure 17. The three variables initialized with values\r\nThe types field contains the following values:\r\nFigure 18. Values in the types field\r\nThe assemblyByName2 variable above contains an assembly object representing the legitimate assembly\r\nMicrosoft.IdentityServer.IdentityModel.dll (if not already loaded, the RuntimeHelper class loads the assembly into the\r\ncurrent application domain). By calling the GetType() method, RunHelper initializes the member of the types field/array\r\nwith .NET types from the Microsoft.IdentityServer.IdentityModel.dll assembly.\r\nReturning to the GetClaims() method and the initialization of type, type2, and type3 the variables type, type2, and type3 get\r\ninitialized with the following type objects from Microsoft.IdentityServer.IdentityModel.dll:\r\ntype: Microsoft.IdentityModel.Claims.IClaimsIdentity type object\r\ntype2: Microsoft.IdentityModel.Claims.ClaimCollection type object\r\ntype3: Microsoft.IdentityModel.Claims.Claim type object\r\nNext, the GetClaims() method retrieves the Claims property of the Microsoft.IdentityModel.Claims.IclaimsIdentity identity\r\nobject. It also retrieves the number of claims (of type Microsoft.IdentityModel.Claims.ClaimCollection) present in the\r\nClaims property:\r\nFigure 19. GetClaims() retrieving the Claims property\r\nGetClaims() then enumerates the claims (of type Microsoft.IdentityModel.Claims.Claim), retrieving the string containing\r\neach claim and the corresponding claim type:\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 11 of 15\n\nFigure 20. GetClaims() enumerating the claims, retrieving the strings, and storing in list\r\nAs shown above, the claim string and claim type string are then stored in a list named list. This list of claims and their\r\ncorresponding claim types is then returned to the caller of the GetClaims() method, BeginProcessClaims().\r\nReturning to the BeginProcessClaims() method, after retrieving the claims using the GetClaims() method, the hook method\r\nBeginProcessClaims() searches the claims list for presence of a claim with claim type of\r\nhttp://schemas.microsoft.com/claims/authnmethodsreferences:\r\nFigure 21. BeginProcessClaims() searching the claims list for a specific claim\r\nAs shown on line 198 above, the claim(s) of type http://schemas.microsoft.com/claims/authnmethodsreferences (if any) is\r\nstored in a list named list. If claim of type http://schemas.microsoft.com/claims/authnmethodsreferences is present and its\r\nvalue is set to http://schemas.microsoft.com/claims/multipleauthn, the hook method returns the IclaimsIdentity object\r\nreturned by the legitimate target method ProcessClaims() (from Microsoft.IdentityServer.Service.dll) on line 191 of the hook\r\nmethod.\r\nThis behavior ensures that if MFA is already satisfied, then the hook method simply acts as a pass-through method and\r\ndoesn’t affect the normal behavior of the claim processing pipeline.\r\nIf a claim of type http://schemas.microsoft.com/claims/authnmethodsreferences is not present or its value is not set to\r\nhttp://schemas.microsoft.com/claims/multipleauthn, the hook method proceeds to perform additional checks on the\r\nunprocessed claims (that is, the claims contained in the unprocessed identity object identity passed to the hook method).\r\nOnce again, the hook method obtains a list of claims by calling the GetClaims() helper method. As mentioned above, instead\r\nof calling the GetClaims() helper method with the processed identity object returned by invoking the legitimate\r\nProcessClaims() method (stored in the result variable on line 191), the hook method calls the GetClaims() helper method\r\nwith the unprocessed identity object identity passed to the hook method:\r\nFigure 22. The hook method calling GetClaims()\r\nOn line 204, the hook method enumerates the value of each claim and uses the ComputeHash() helper method to calculate\r\nthe MD5 hash value of each claim value (from the unprocessed identity object). It then checks if the MD5 value of any of\r\nthe claims equals the MD5 hash value 6E3466296D2F63DE[REDACTED]. This hash value is the only element of a\r\nhardcoded hash list named oidMFAHashes (that is, this list can be expanded to include other hash values of interest):\r\nFigure 23. Hardcoded hash list containing the MD5 hash value of a magic OID valuea\r\nIf none of the claims have a value with MD5 hash value of 6E3466296D2F63DE[REDACTED], on line 206, the method\r\nsimply returns the processed identity object returned by the legitimate target method ProcessClaims() (from\r\nMicrosoft.IdentityServer.Service.dll) on line 191 of the hook method. As previously discussed, the hash value\r\n6E3466296D2F63DE[REDACTED] corresponds to the OID value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].[REDACTED].\r\nHence, the hook method enumerates the claims and if a claim with value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].[REDACTED] isn’t\r\npresent on the claim list, the hook method simply acts as a pass-through method and doesn’t affect the normal behavior of\r\nclaim processing pipeline.\r\nIf by this point in the execution cycle the hook method hasn’t returned yet, it means one of the claims contains the OID\r\nvalue 1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].\r\n[REDACTED] (otherwise, according to the logic described in the paragraph above, the hook method would’ve returned). \r\nProceeding with confirmation that one of the claims contains the OID value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].[REDACTED], the\r\nhook method proceeds to the section that represents the main purpose of MagicWeb, to perform claim injection.\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 12 of 15\n\nFigure 24. Main section of the code responsible for the claim injection process\r\nBefore describing the code responsible for the claim injection process, it’s important to revisit what’s already stored in the\r\nlist and claims variables:\r\nlist: As mentioned before, the hook method invokes the legitimate method ProcessClaims() to process the incoming\r\nidentity object. The processed identity object (stored in result on line 191) is then passed to the GetClaims() helper\r\nmethod to obtain a list of claim type/value pairs extracted from the processed identity object (line 198). After\r\nobtaining the claim type/value pairs, the claim(s) of type\r\nhttp://schemas.microsoft.com/claims/authnmethodsreferences (if any) are stored in a list named list (line 198).\r\nFigure 25. The list variable\r\nclaims: As mentioned above, this variable is used to store a list of claim type/value pairs extracted from the unprocessed\r\nidentity object:\r\nFigure 26. The claims variable\r\nWith this information in mind (and the fact that one of the claims contains the OID value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].[REDACTED]),\r\nonce again here’s the first part of the claim injection code:\r\nFigure 27. Part of the claim injection code\r\nAs shown above, if list is empty (that is, the processed identity object contained no claim type/value pairs of type\r\nhttp://schemas.microsoft.com/claims/authnmethodsreferences), the hook method instead turns to claims (containing the list\r\nof all claim type/value pairs extracted from the unprocessed identity object) and searches for claim type/value pairs of type\r\nhttp://schemas.microsoft.com/claims/authnmethodsreferences in the claims list. If the claims list contains one or more claim\r\ntype/value pairs of type http://schemas.microsoft.com/claims/authnmethodsreferences, the hook method uses the claim\r\ninformation to add an identical claim of type http://schemas.microsoft.com/claims/authnmethodsreferences to the processed\r\nidentity object (line 213 above).\r\nUsing this method, if after passing the identity object to the legitimate ProcessClaims() method, no claim of type\r\nhttp://schemas.microsoft.com/claims/authnmethodsreferences is returned by the legitimate method, the hook method\r\nmanually adds a fraudulent claim of type http://schemas.microsoft.com/claims/authnmethodsreferences to the list of claims\r\nreturned to the caller of the hooked legitimate method ProcessClaims().\r\nAs shown above, to add the fraudulent claim to the list of claims, the hook method calls a helper method named AddClaim().\r\nFigure 28. The helper method\r\nLike the code in the helper method GetClaims(), AddClaims() initializes two variables with the following type objects:\r\ntype: Microsoft.IdentityModel.Claims.IClaimsIdentity type object\r\ntype2: Microsoft.IdentityModel.Claims.ClaimCollection type object\r\nOn line 235, AddClaims() gets the constructor for type Microsoft.IdentityModel.Claims.Claim and invokes the constructor\r\n(passing in the claim type and value from the caller of AddClaim()) to instantiate a new Claim object.\r\nFigure 29. The legitimate internal constructor from Microsoft.IdentityModel.Claims.Claim\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 13 of 15\n\nThe legitimate internal constructor from Microsoft.IdentityModel.Claims.Claim, retrieved and invoked by AddClaim(),\r\ninvokes the internal constructor Claim (overloaded method) with the following method parameters:\r\nFigure 30. The internal constructor Claim\r\nAfter instantiating a new Claim object, AddClaim() uses the Add() method from type\r\nMicrosoft.IdentityModel.Claims.ClaimCollection to add the new claim to the identity object passed to AddClaim() by its\r\ncaller (in this case, the new claim is added to the identity object containing the list of claims returned by the call to the\r\nlegitimate method ProcessClaims()).\r\nFigure 31. The legitimate method Add() from type Microsoft.IdentityModel.Claims.ClaimCollection, invoked\r\nby AddClaim() (line 245)\r\nRevisiting the claim injection code in the hook method BeginProcessClaims() (and recalling the fact that one of the claims\r\ncontains the OID value 1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].\r\n[REDACTED].[REDACTED]), here’s the second part of the claim injection code:\r\nFigure 32. Second part of the claim injection code\r\nRecall that list contains claim type/value pairs of type http://schemas.microsoft.com/claims/authnmethodsreferences\r\nextracted from the processed identity object. If none of the claims in list have the value\r\nhttp://schemas.microsoft.com/claims/multipleauthn, the hook method proceeds to call AddClaim() to add a fraudulent claim\r\nof type http://schemas.microsoft.com/claims/authnmethodsreferences and value\r\nhttp://schemas.microsoft.com/claims/multipleauthn to the list of claims returned to the caller of the hooked legitimate\r\nmethod ProcessClaims().\r\nUsing the fraudulent claim injection techniques described above, if a claim with the Magic OID value\r\n1.3.6.1.4.1.311.21.8.868518.12957973.4869258.12250419.[REDACTED].[REDACTED].[REDACTED].[REDACTED] is\r\npresented to AD FS, regardless of how the legitimate hooked method ProcessClaims() handles the claim, the\r\nBeginProcessClaims() hook function ensures that a claim with value http://schemas.microsoft.com/claims/multipleauthn is\r\nreturned to the caller of the legitimate hooked method ProcessClaims().\r\nHook method: BeginEndpointConfiguration()\r\nThe backdoor BeginEndpointConfiguration() method, used to hook the legitimate target method EndpointConfiguration()\r\n(from Microsoft.IdentityServer.WebHost.dll) is shown below:\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 14 of 15\n\nFigure 33. BeginEndpointConfiguration() method\r\nThe enumType variable is initialized with RuntimeHelper.types[0] which is a\r\nMicrosoft.IdentityServer.WebHost.Proxy.CertificateValidation type object. The PropertyInfo variables propertyInfo,\r\npropertyInfo2, and propertyInfo3 are initialized with property objects retrieved from ‘properties’ field/array of\r\nRuntimeHelper:\r\npropertyInfo: CertificateValidation property from type Microsoft.IdentityServer.WebHost.Proxy.ProxyEndpoint of\r\nMicrosoft.IdentityServer.WebHost.dll\r\npropertyInfo2: Path property from type Microsoft.IdentityServer.WebHost.Proxy.ProxyEndpoint of\r\nMicrosoft.IdentityServer.WebHost.dll\r\npropertyInfo3: Endpoints property from type Microsoft.IdentityServer.WebHost.Proxy.ProxyEndpointConfiguration\r\nof Microsoft.IdentityServer.WebHost.dll\r\nNext, the hook method retrieves the value of the Endpoint property of the value object that the legitimate\r\nEndpointConfiguration() method was called with. The Endpoint property holds a collection of ProxyEndpoint objects. The\r\nhook method enumerates the ProxyEndpoint objects and for each object, it checks if the value of the CertificateValidation\r\nenum is set to ‘1’ which signifies ‘SSL’. If the CertificateValidation enum for a ProxyEndpoint object is set to ‘1’/’SSL’, on\r\nline 165, the hook method overwrites the value of the CertificateValidation enum with ‘0’ which signifies ‘None’. To ensure\r\nthe change is reflected, the hook method then overwrites the Endpoint property of the value object with the updated\r\nEndpoint property containing the overwritten CertificateValidation enum values (that is, ‘SSL’ overwritten with ‘None’).\r\nBehaving as a true hook method, on line 179, the method calls the legitimate EndpointConfiguration() method but with the\r\nmodified ‘value’ object. Hence, when the legitimate EndpointConfiguration() method is invoked during the normal\r\noperation of AD FS, this hook method intercepts the call and, before passing the object to the legitimate\r\nEndpointConfiguration() method was invoked with, it overwrites the CertificateValidation value of each ProxyEndpoint\r\nobject and only then it calls the legitimate EndpointConfiguration() method but now with modified CertificateValidation\r\nvalue(s), changed from ‘SSL’ to ‘None’.\r\nThe purpose of overwriting CertificationValidation value to ‘None’ (wherever it’s ‘SSL’) is to allow WAP to pass the request\r\nwith the specific malicious certificate to AD FS for further authentication processing. According to\r\nMicrosoft.IdentityServer.ProxyService/TLSClientReqeustHandler, WAP stops sending the current request from client to AD\r\nFS if CertificateValidation is ‘1’ (‘SSL’) and the client certificate has an error during validation.\r\nReferences\r\n“I am AD FS and so can you: Attacking Active Directory Federated Services”, Austin Baker and Douglas Bienstock,\r\nTroopers 2019\r\nUnderstanding Key Active Directory Federation Services Concepts, Microsoft documentation\r\nSource: https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nhttps://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/\r\nPage 15 of 15",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE",
		"ETDA"
	],
	"references": [
		"https://www.microsoft.com/security/blog/2022/08/24/magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone/"
	],
	"report_names": [
		"magicweb-nobeliums-post-compromise-trick-to-authenticate-as-anyone"
	],
	"threat_actors": [
		{
			"id": "b43e5ea9-d8c8-4efa-b5bf-f1efb37174ba",
			"created_at": "2022-10-25T16:07:24.36191Z",
			"updated_at": "2026-04-10T02:00:04.954902Z",
			"deleted_at": null,
			"main_name": "UNC2452",
			"aliases": [
				"Dark Halo",
				"Nobelium",
				"SolarStorm",
				"StellarParticle",
				"UNC2452"
			],
			"source_name": "ETDA:UNC2452",
			"tools": [],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "1d3f9dec-b033-48a5-8b1e-f67a29429e89",
			"created_at": "2022-10-25T15:50:23.739197Z",
			"updated_at": "2026-04-10T02:00:05.275809Z",
			"deleted_at": null,
			"main_name": "UNC2452",
			"aliases": [
				"UNC2452",
				"NOBELIUM",
				"StellarParticle",
				"Dark Halo"
			],
			"source_name": "MITRE:UNC2452",
			"tools": [
				"Sibot",
				"Mimikatz",
				"Cobalt Strike",
				"AdFind",
				"GoldMax"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "a241a1ca-2bc9-450b-a07b-aae747ee2710",
			"created_at": "2024-06-19T02:03:08.150052Z",
			"updated_at": "2026-04-10T02:00:03.737173Z",
			"deleted_at": null,
			"main_name": "IRON RITUAL",
			"aliases": [
				"APT29",
				"Blue Dev 5 ",
				"BlueBravo ",
				"Cloaked Ursa ",
				"CozyLarch ",
				"Dark Halo ",
				"Midnight Blizzard ",
				"NOBELIUM ",
				"StellarParticle ",
				"UNC2452 "
			],
			"source_name": "Secureworks:IRON RITUAL",
			"tools": [
				"Brute Ratel C4",
				"Cobalt Strike",
				"EnvyScout",
				"GoldFinder",
				"GoldMax",
				"NativeZone",
				"RAINDROP",
				"SUNBURST",
				"Sibot",
				"TEARDROP",
				"VaporRage"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "46b3c0fc-fa0c-4d63-a38a-b33a524561fb",
			"created_at": "2023-01-06T13:46:38.393409Z",
			"updated_at": "2026-04-10T02:00:02.955738Z",
			"deleted_at": null,
			"main_name": "APT29",
			"aliases": [
				"Cloaked Ursa",
				"TA421",
				"Blue Kitsune",
				"BlueBravo",
				"IRON HEMLOCK",
				"G0016",
				"Nobelium",
				"Group 100",
				"YTTRIUM",
				"Grizzly Steppe",
				"ATK7",
				"ITG11",
				"COZY BEAR",
				"The Dukes",
				"Minidionis",
				"UAC-0029",
				"SeaDuke"
			],
			"source_name": "MISPGALAXY:APT29",
			"tools": [
				"SNOWYAMBER",
				"HALFRIG",
				"QUARTERRIG"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "70872c3a-e788-4b55-a7d6-b2df52001ad0",
			"created_at": "2023-01-06T13:46:39.18401Z",
			"updated_at": "2026-04-10T02:00:03.239111Z",
			"deleted_at": null,
			"main_name": "UNC2452",
			"aliases": [
				"DarkHalo",
				"StellarParticle",
				"NOBELIUM",
				"Solar Phoenix",
				"Midnight Blizzard"
			],
			"source_name": "MISPGALAXY:UNC2452",
			"tools": [
				"SNOWYAMBER",
				"HALFRIG",
				"QUARTERRIG"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "20d3a08a-3b97-4b2f-90b8-92a89089a57a",
			"created_at": "2022-10-25T15:50:23.548494Z",
			"updated_at": "2026-04-10T02:00:05.292748Z",
			"deleted_at": null,
			"main_name": "APT29",
			"aliases": [
				"APT29",
				"IRON RITUAL",
				"IRON HEMLOCK",
				"NobleBaron",
				"Dark Halo",
				"NOBELIUM",
				"UNC2452",
				"YTTRIUM",
				"The Dukes",
				"Cozy Bear",
				"CozyDuke",
				"SolarStorm",
				"Blue Kitsune",
				"UNC3524",
				"Midnight Blizzard"
			],
			"source_name": "MITRE:APT29",
			"tools": [
				"PinchDuke",
				"ROADTools",
				"WellMail",
				"CozyCar",
				"Mimikatz",
				"Tasklist",
				"OnionDuke",
				"FatDuke",
				"POSHSPY",
				"EnvyScout",
				"SoreFang",
				"GeminiDuke",
				"reGeorg",
				"GoldMax",
				"FoggyWeb",
				"SDelete",
				"PolyglotDuke",
				"AADInternals",
				"MiniDuke",
				"SeaDuke",
				"Sibot",
				"RegDuke",
				"CloudDuke",
				"GoldFinder",
				"AdFind",
				"PsExec",
				"NativeZone",
				"Systeminfo",
				"ipconfig",
				"Impacket",
				"Cobalt Strike",
				"PowerDuke",
				"QUIETEXIT",
				"HAMMERTOSS",
				"BoomBox",
				"CosmicDuke",
				"WellMess",
				"VaporRage",
				"LiteDuke"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "f27790ff-4ee0-40a5-9c84-2b523a9d3270",
			"created_at": "2022-10-25T16:07:23.341684Z",
			"updated_at": "2026-04-10T02:00:04.549917Z",
			"deleted_at": null,
			"main_name": "APT 29",
			"aliases": [
				"APT 29",
				"ATK 7",
				"Blue Dev 5",
				"BlueBravo",
				"Cloaked Ursa",
				"CloudLook",
				"Cozy Bear",
				"Dark Halo",
				"Earth Koshchei",
				"G0016",
				"Grizzly Steppe",
				"Group 100",
				"ITG11",
				"Iron Hemlock",
				"Iron Ritual",
				"Midnight Blizzard",
				"Minidionis",
				"Nobelium",
				"NobleBaron",
				"Operation Ghost",
				"Operation Office monkeys",
				"Operation StellarParticle",
				"SilverFish",
				"Solar Phoenix",
				"SolarStorm",
				"StellarParticle",
				"TEMP.Monkeys",
				"The Dukes",
				"UNC2452",
				"UNC3524",
				"Yttrium"
			],
			"source_name": "ETDA:APT 29",
			"tools": [
				"7-Zip",
				"ATI-Agent",
				"AdFind",
				"Agentemis",
				"AtNow",
				"BEATDROP",
				"BotgenStudios",
				"CEELOADER",
				"Cloud Duke",
				"CloudDuke",
				"CloudLook",
				"Cobalt Strike",
				"CobaltStrike",
				"CosmicDuke",
				"Cozer",
				"CozyBear",
				"CozyCar",
				"CozyDuke",
				"Danfuan",
				"EnvyScout",
				"EuroAPT",
				"FatDuke",
				"FoggyWeb",
				"GeminiDuke",
				"Geppei",
				"GoldFinder",
				"GoldMax",
				"GraphDrop",
				"GraphicalNeutrino",
				"GraphicalProton",
				"HAMMERTOSS",
				"HammerDuke",
				"LOLBAS",
				"LOLBins",
				"LiteDuke",
				"Living off the Land",
				"MagicWeb",
				"Mimikatz",
				"MiniDionis",
				"MiniDuke",
				"NemesisGemina",
				"NetDuke",
				"OnionDuke",
				"POSHSPY",
				"PinchDuke",
				"PolyglotDuke",
				"PowerDuke",
				"QUIETEXIT",
				"ROOTSAW",
				"RegDuke",
				"Rubeus",
				"SNOWYAMBER",
				"SPICYBEAT",
				"SUNSHUTTLE",
				"SeaDaddy",
				"SeaDask",
				"SeaDesk",
				"SeaDuke",
				"Sharp-SMBExec",
				"SharpView",
				"Sibot",
				"Solorigate",
				"SoreFang",
				"TinyBaron",
				"WINELOADER",
				"WellMail",
				"WellMess",
				"cobeacon",
				"elf.wellmess",
				"reGeorg",
				"tDiscoverer"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434686,
	"ts_updated_at": 1775792253,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3285e1a5c22cd4e722d5551a3548a949aff88a43.pdf",
		"text": "https://archive.orkl.eu/3285e1a5c22cd4e722d5551a3548a949aff88a43.txt",
		"img": "https://archive.orkl.eu/3285e1a5c22cd4e722d5551a3548a949aff88a43.jpg"
	}
}