sigyllly commited on
Commit
55401d6
·
verified ·
1 Parent(s): 01f6a09

Upload 11 files

Browse files
Obfus/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 K.Dot
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
Obfus/example/test.ps1 ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function Hello-World {
2
+ Write-Host "Hello, World!"
3
+ }
4
+
5
+ function Xor-Encrypt {
6
+ param (
7
+ [string] $string,
8
+ [string] $key
9
+ )
10
+
11
+ $keyLength = $key.Length
12
+ $stringLength = $string.Length
13
+ $encryptedString = ""
14
+
15
+ for ($i = 0; $i -lt $stringLength; $i++) {
16
+ $encryptedString += [char]($string[$i] -bxor $key[$i % $keyLength])
17
+ }
18
+
19
+ return $encryptedString
20
+ }
21
+
22
+ function Xor-Decrypt {
23
+ param (
24
+ [string] $string,
25
+ [string] $key
26
+ )
27
+
28
+ $keyLength = $key.Length
29
+ $stringLength = $string.Length
30
+ $decryptedString = ""
31
+
32
+ for ($i = 0; $i -lt $stringLength; $i++) {
33
+ $decryptedString += [char]($string[$i] -bxor $key[$i % $keyLength])
34
+ }
35
+
36
+ return $decryptedString
37
+ }
38
+
39
+ Hello-World
40
+ $encrypted = Xor-Encrypt -string "Hello, World!" -key "key"
41
+ Write-Host $encrypted
42
+ $decrypted = Xor-Decrypt -string $encrypted -key "key"
43
+ Write-Host $decrypted
44
+
Obfus/example/test_hard.ps1 ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Add-Type -AssemblyName "System.IO.Compression"
2
+
3
+ $compressionTypes = 'Gzip', 'Deflate'
4
+ $method = ""
5
+ $decode_command = @"
6
+ function Decode-Code(`$compressedBytes, `$compressionPick) {
7
+ [System.IO.MemoryStream] `$input1 = New-Object System.IO.MemoryStream
8
+ `$input1.Write(`$compressedBytes, 0, `$compressedBytes.Length)
9
+ `$input1.Seek(0, [IO.SeekOrigin]::Begin)
10
+
11
+ `$compressionStream = $null
12
+ `$reader = $null
13
+ `$decompressedData = $null
14
+
15
+ if (`$compressionPick -eq 'Gzip') {
16
+ `$compressionStream = New-Object System.IO.Compression.GzipStream `$input1, ([IO.Compression.CompressionMode]::Decompress)
17
+ } elseif (`$compressionPick -eq 'Deflate') {
18
+ `$compressionStream = New-Object System.IO.Compression.DeflateStream `$input1, ([IO.Compression.CompressionMode]::Decompress)
19
+ }
20
+
21
+ `$reader = New-Object System.IO.StreamReader `$compressionStream
22
+ `$decompressedData = `$reader.ReadToEnd()
23
+
24
+ `$reader.Close()
25
+ `$compressionStream.Close()
26
+
27
+ `$input1.Close()
28
+ return `$decompressedData
29
+ }
30
+ "@
31
+
32
+ function Read-And-Interpret-Script($scriptPath) {
33
+ $scriptContent = [System.IO.File]::ReadAllBytes($scriptPath)
34
+
35
+ $compressionPick = $compressionTypes | Get-Random
36
+
37
+ $encodedScriptContent = Encode-Code -code $scriptContent -compressionPick $compressionPick
38
+ Write-Host "Encoded Script Content:"
39
+ Write-Host $encodedScriptContent
40
+
41
+ $decodedScriptContent = Decode-Code -compressedBytes $encodedScriptContent -compressionPick $compressionPick
42
+
43
+ Write-Host "Decoded Script Content:"
44
+ Write-Host $decodedScriptContent[1]
45
+ }
46
+
47
+ function Obfuscate-Code($code) {
48
+ $obfuscatedCode = $code
49
+ return $obfuscatedCode
50
+ }
51
+
52
+ function Encode-Code($code, $compressionPick) {
53
+ [System.IO.MemoryStream] $output = New-Object System.IO.MemoryStream
54
+ $compressionStream = $null
55
+
56
+ if ($compressionPick -eq 'Gzip') {
57
+ $compressionStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
58
+ } elseif ($compressionPick -eq 'Deflate') {
59
+ $compressionStream = New-Object System.IO.Compression.DeflateStream $output, ([IO.Compression.CompressionMode]::Compress)
60
+ }
61
+
62
+ $compressionStream.Write($code, 0, $code.Length)
63
+ $compressionStream.Close()
64
+ $compressedBytes = $output.ToArray()
65
+
66
+ $output.Close()
67
+ return $compressedBytes
68
+ }
69
+
70
+ function Decode-Code($compressedBytes, $compressionPick) {
71
+ [System.IO.MemoryStream] $input1 = New-Object System.IO.MemoryStream
72
+ $input1.Write($compressedBytes, 0, $compressedBytes.Length)
73
+ $input1.Seek(0, [IO.SeekOrigin]::Begin)
74
+
75
+ $compressionStream = $null
76
+ $reader = $null
77
+ $decompressedData = $null
78
+
79
+ if ($compressionPick -eq 'Gzip') {
80
+ $compressionStream = New-Object System.IO.Compression.GzipStream $input1, ([IO.Compression.CompressionMode]::Decompress)
81
+ } elseif ($compressionPick -eq 'Deflate') {
82
+ $compressionStream = New-Object System.IO.Compression.DeflateStream $input1, ([IO.Compression.CompressionMode]::Decompress)
83
+ }
84
+
85
+ $reader = New-Object System.IO.StreamReader $compressionStream
86
+ $decompressedData = $reader.ReadToEnd()
87
+
88
+ $reader.Close()
89
+ $compressionStream.Close()
90
+
91
+ $input1.Close()
92
+ return $decompressedData
93
+ }
94
+
95
+
96
+
97
+
98
+
99
+ $scriptPath = "example\test.ps1"
100
+ Read-And-Interpret-Script -scriptPath $scriptPath
Obfus/main.ps1 ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #python import type shi
2
+ $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
3
+
4
+ . "$scriptPath\util\strings\strings.ps1"
5
+ . "$scriptPath\util\variables\variables.ps1"
6
+ . "$scriptPath\util\commands\commands.ps1"
7
+ . "$scriptPath\util\commands\function_names.ps1"
8
+ . "$scriptPath\util\final\encodeOutput.ps1"
9
+ . "$scriptPath\util\numbers\obfuscate_numbers.ps1"
10
+
11
+ $global:pass_number = 1
12
+
13
+ $times = 2
14
+ $verbose = $false
15
+ $verbose_out_file = $true
16
+
17
+ if ($verbose_out_file) {
18
+ #redirect standard output when we need the verbose in a file
19
+ $VerbosePreference = "Continue"
20
+ $date_and_time = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
21
+ $VerboseOutput = "obfuscate$date_and_time.log"
22
+ Start-Transcript -Path $VerboseOutput
23
+ }
24
+
25
+ # this is EXTREMELY NEEDED because the Get-Command function is so utterly slow.
26
+ $CommandTypeCache = @{}
27
+
28
+ $functionNamesIgnore = @("CheckValidationResult")
29
+
30
+ $built_in_aliases = @('foreach', 'where', 'clc', 'cli', 'clp', 'clv', 'cpi', 'cvpa', 'dbp', 'ebp', 'epal',
31
+ 'epcsv', 'fl', 'ft', 'fw', 'gal', 'gbp', 'gc', 'gci', 'gcm', 'gdr', 'gcs', 'ghy', 'gi', 'gl', 'gm', 'gmo', 'gp',
32
+ 'gpv', 'gps', 'group', 'gu', 'gv', 'iex', 'ihy', 'ii', 'ipmo', 'ipal', 'ipcsv', 'measure', 'mi', 'mp', 'nal',
33
+ 'ndr', 'ni', 'nv', 'nmo', 'oh', 'rbp', 'rdr', 'ri', 'rni', 'rnp', 'rp', 'rmo', 'rv', 'gerr', 'rvpa', 'sal',
34
+ 'sbp', 'select', 'si', 'sl', 'sp', 'saps', 'spps', 'sv', 'irm', 'iwr', 'ac', 'clear', 'compare', 'cpp', 'diff',
35
+ 'gsv', 'sleep', 'sort', 'start', 'sasv', 'spsv', 'tee', 'write', 'cat', 'cp', 'ls', 'man', 'mount', 'mv', 'ps',
36
+ 'rm', 'rmdir', 'cnsn', 'dnsn', 'ogv', 'shcm', 'cd', 'dir', 'echo', 'fc', 'kill', 'pwd', 'type', 'h', 'history',
37
+ 'md', 'popd', 'pushd', 'r', 'cls', 'chdir', 'copy', 'del', 'erase', 'move', 'rd', 'ren', 'set', 'icm', 'clhy',
38
+ 'gjb', 'rcjb', 'rjb', 'sajb', 'spjb', 'wjb', 'nsn', 'gsn', 'rsn', 'etsn', 'rcsn', 'exsn', 'sls')
39
+
40
+ function ObfuscateCode($code) {
41
+ $code_copy = $code
42
+ $functionReplacementMap = @{}
43
+ $variableReplacementMap = @{}
44
+ $parameterReplacementMap = @{}
45
+ $stringReplacementMap = @{}
46
+ $numberReplacementMap = @{}
47
+
48
+ $comments = [System.Management.Automation.PSParser]::Tokenize($code_copy, [ref]$null) | Where-Object { $_.Type -eq "Comment" }
49
+ foreach ($comment in $comments) {
50
+ $code_copy = $code_copy.Replace($comment.Content, "")
51
+ }
52
+
53
+ # first pass - handle everything except barewords
54
+ $ast = [System.Management.Automation.Language.Parser]::ParseInput($code_copy, [ref]$null, [ref]$null)
55
+
56
+ # get all function definitions
57
+ $functionDefinitions = $ast.FindAll({ param([System.Management.Automation.Language.Ast] $Ast)
58
+ $Ast -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)
59
+
60
+ # get all command calls
61
+ $allCommandCalls = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $true)
62
+
63
+ # get all variable expressions
64
+ $variableExpressions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.VariableExpressionAst] }, $true)
65
+
66
+ $stringAsts = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst] -and ($args[0].StringConstantType -eq "DoubleQuoted" -or $args[0].StringConstantType -eq "SingleQuoted") }, $true)
67
+
68
+ $numberAsts = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.ConstantExpressionAst] -and $args[0].StaticType.Name -eq "Int32" }, $true)
69
+
70
+ # Process function definitions and create replacement map
71
+ foreach ($func in $functionDefinitions) {
72
+ if (-not $functionReplacementMap.ContainsKey($func.Name)) {
73
+ $functionReplacementMap[$func.Name] = ObfuscateFunctionNames $func.Name
74
+ }
75
+
76
+ # handle parameters in function definition
77
+ if ($func.Parameters) {
78
+ foreach ($param in $func.Parameters) {
79
+ $paramName = $param.Name.VariablePath.UserPath
80
+ if (-not $parameterReplacementMap.ContainsKey($paramName)) {
81
+ $newParamName = ObfuscateVariables $paramName $true
82
+ $parameterReplacementMap[$paramName] = $newParamName.TrimStart('$')
83
+ $variableReplacementMap[$paramName] = $newParamName
84
+ }
85
+ }
86
+ }
87
+ if ($func.Body.ParamBlock) {
88
+ foreach ($param in $func.Body.ParamBlock.Parameters) {
89
+ $paramName = $param.Name.VariablePath.UserPath
90
+ if (-not $parameterReplacementMap.ContainsKey($paramName)) {
91
+ $newParamName = ObfuscateVariables $paramName $true
92
+ $parameterReplacementMap[$paramName] = $newParamName.TrimStart('$')
93
+ $variableReplacementMap[$paramName] = $newParamName
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ # process regular variables
100
+ foreach ($var in $variableExpressions) {
101
+ $varName = $var.VariablePath.UserPath
102
+ if (-not $variableReplacementMap.ContainsKey($varName) -and -not $parameterReplacementMap.ContainsKey($varName)) {
103
+ $variableReplacementMap[$varName] = ObfuscateVariables $var.Extent.Text
104
+ }
105
+ }
106
+
107
+ $allReplacements = @()
108
+
109
+ # add function definitions with improved handling
110
+ foreach ($func in $functionDefinitions) {
111
+ if ($func.Name -in $functionNamesIgnore) { continue }
112
+
113
+ $functionKeyword = "function "
114
+ $fullStartOffset = $func.Extent.StartOffset
115
+ $nameStartOffset = $func.Extent.StartOffset
116
+
117
+ # find actual start of function name by checking for the keyword
118
+ if ($func.Extent.Text.TrimStart().StartsWith($functionKeyword)) {
119
+ $nameStartOffset = $fullStartOffset + $func.Extent.Text.IndexOf($functionKeyword) + $functionKeyword.Length
120
+ }
121
+
122
+ $allReplacements += @{
123
+ StartOffset = $nameStartOffset
124
+ Length = $func.Name.Length
125
+ OriginalName = $func.Name
126
+ Text = $func.Name
127
+ Type = "Function"
128
+ RequiresKeyword = $true # new flag to indicate this needs special handling
129
+ FullStartOffset = $fullStartOffset
130
+ }
131
+ }
132
+
133
+ # add function calls and parameters with improved validation
134
+ foreach ($call in $allCommandCalls) {
135
+ $commandName = $call.CommandElements[0].Extent.Text
136
+
137
+ if ($commandName -in $functionNamesIgnore) { continue }
138
+
139
+ if ($functionReplacementMap.ContainsKey($commandName)) {
140
+ # verify the replacement exists and is valid
141
+ $newName = $functionReplacementMap[$commandName]
142
+ $allReplacements += @{
143
+ StartOffset = $call.CommandElements[0].Extent.StartOffset
144
+ Length = $commandName.Length
145
+ OriginalName = $commandName
146
+ Text = $commandName
147
+ Type = "Function"
148
+ RequiresKeyword = $false # function calls don't need the keyword
149
+ }
150
+
151
+ # process parameters
152
+ for ($i = 1; $i -lt $call.CommandElements.Count; $i++) {
153
+ $element = $call.CommandElements[$i]
154
+ if ($element.Extent.Text.StartsWith('-')) {
155
+ $paramName = $element.Extent.Text.TrimStart('-')
156
+ if ($parameterReplacementMap.ContainsKey($paramName)) {
157
+ $allReplacements += @{
158
+ StartOffset = $element.Extent.StartOffset
159
+ Length = $element.Extent.Text.Length
160
+ OriginalName = $paramName
161
+ Text = "-" + $paramName
162
+ Type = "ParameterName"
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ # add variables
171
+ foreach ($var in $variableExpressions) {
172
+ $varName = $var.VariablePath.UserPath
173
+ $parent = $var.Parent
174
+ $isParameterName = $false
175
+ while ($parent) {
176
+ if ($parent -is [System.Management.Automation.Language.CommandAst]) {
177
+ $isParameterName = $parent.CommandElements | Where-Object { $_.Extent.Text -eq "-$($var.Extent.Text)" }
178
+ if ($isParameterName) { break }
179
+ }
180
+ $parent = $parent.Parent
181
+ }
182
+
183
+ if (-not $isParameterName) {
184
+ $allReplacements += @{
185
+ StartOffset = $var.Extent.StartOffset
186
+ Length = $var.Extent.Text.Length
187
+ OriginalName = $varName
188
+ Text = $var.Extent.Text
189
+ Type = "Variable"
190
+ }
191
+ }
192
+ }
193
+
194
+ # add strings
195
+ foreach ($string in $stringAsts) {
196
+ $stringText = $string.Extent.Text
197
+
198
+ # handle empty strings
199
+ if ([string]::IsNullOrWhiteSpace($stringText) -or $stringText -eq '""' -or $stringText -eq "''") {
200
+ $allReplacements += @{
201
+ StartOffset = $string.Extent.StartOffset
202
+ Length = $string.Extent.Text.Length
203
+ OriginalName = $stringText
204
+ Text = $string.Extent.Text
205
+ Type = "EmptyString"
206
+ NewName = '[string]::Empty'
207
+ }
208
+ continue
209
+ }
210
+
211
+ # check to see if string only contains single or double quotes inside. (if example: "''" or "''''") if the string is empty then just keep going.
212
+ if ($stringText -match "^['""]+$") {
213
+ $allReplacements += @{
214
+ StartOffset = $string.Extent.StartOffset
215
+ Length = $string.Extent.Text.Length
216
+ OriginalName = $stringText
217
+ Text = $string.Extent.Text
218
+ Type = "EmptyString"
219
+ NewName = '[string]::Empty'
220
+ }
221
+ continue
222
+ }
223
+
224
+ # handle normal strings
225
+ if ($string.Extent.Text.Length -lt 3) { continue }
226
+ if (-not $stringReplacementMap.ContainsKey($stringText)) {
227
+ $stringReplacementMap[$stringText] = ObfuscateString $stringText
228
+ }
229
+
230
+ $allReplacements += @{
231
+ StartOffset = $string.Extent.StartOffset
232
+ Length = $string.Extent.Text.Length
233
+ OriginalName = $stringText
234
+ Text = $string.Extent.Text
235
+ Type = "String"
236
+ }
237
+ }
238
+
239
+ # first pass replacements
240
+ $allReplacements = $allReplacements | Sort-Object { $_.StartOffset } -Descending
241
+
242
+ foreach ($replacement in $allReplacements) {
243
+ $newName = switch ($replacement.Type) {
244
+ "Function" { $functionReplacementMap[$replacement.OriginalName] }
245
+ "ParameterName" { "-" + $parameterReplacementMap[$replacement.OriginalName] }
246
+ "Variable" { $variableReplacementMap[$replacement.OriginalName] }
247
+ "String" { $stringReplacementMap[$replacement.OriginalName] }
248
+ "EmptyString" { $replacement.NewName }
249
+ }
250
+
251
+ Write-Host "First Pass - Replacing '$($replacement.Text)' at position $($replacement.StartOffset) with '$newName' (Type: $($replacement.Type))"
252
+
253
+ $code_copy = Replace-TextAtPosition -SourceText $code_copy `
254
+ -StartPosition $replacement.StartOffset `
255
+ -Length $replacement.Length `
256
+ -ReplacementText $newName
257
+ }
258
+
259
+ $newAst = [System.Management.Automation.Language.Parser]::ParseInput($code_copy, [ref]$null, [ref]$null)
260
+ $barewordAsts = $newAst.FindAll({ ($args[0] -is [System.Management.Automation.Language.StringConstantExpressionAst] -and $args[0].StringConstantType -eq "BareWord") -or ($args[0] -is [System.Management.Automation.Language.TypeExpressionAst]) }, $true)
261
+ $bareword_Commands = $newAst.FindAll({ $args[0] -is [System.Management.Automation.Language.CommandAst] }, $true)
262
+ $numberAsts = $newAst.FindAll({ $args[0] -is [System.Management.Automation.Language.ConstantExpressionAst] -and $args[0].StaticType.Name -eq "Int32" }, $true)
263
+
264
+ $barewordReplacements = @()
265
+ $numberReplacements = @()
266
+
267
+ foreach ($bareword in $barewordAsts) {
268
+ if ($bareword.Extent.Text.Length -lt 3) { continue }
269
+ if ($functionReplacementMap.ContainsKey($bareword.Extent.Text)) { continue }
270
+
271
+ # check parent to see if this is a command
272
+ $isCommandFirst = $false
273
+ if ($bareword.Parent -is [System.Management.Automation.Language.CommandAst]) {
274
+ # check if its the first bareword (the actual command)
275
+ $commandElements = $bareword.Parent.CommandElements
276
+ $isCommandFirst = $commandElements[0].Extent.Text -eq $bareword.Extent.Text
277
+
278
+ # if not then skip
279
+ if (-not $isCommandFirst) {
280
+ continue
281
+ }
282
+ }
283
+
284
+ # get command type information
285
+ $commandInfo = Get-CommandType -CommandName $bareword.Extent.Text
286
+
287
+ # generate a new random replacement for each instance
288
+ # pass the command info to ObfuscateCommandTypes
289
+ $newBarewordName = ObfuscateCommandTypes -CommandText $bareword.Extent.Text -CommandInfo $commandInfo -RealBearWord $isCommandFirst
290
+
291
+ $barewordReplacements += @{
292
+ StartOffset = $bareword.Extent.StartOffset
293
+ Length = $bareword.Extent.Text.Length
294
+ OriginalName = $bareword.Extent.Text
295
+ Text = $bareword.Extent.Text
296
+ NewName = $newBarewordName
297
+ Type = "Bareword"
298
+ CommandType = $commandInfo.Type
299
+ IsBuiltIn = $commandInfo.IsBuiltIn
300
+ }
301
+ }
302
+
303
+ # too many numbers lol
304
+ if ($global:pass_number -lt 2) {
305
+ foreach ($number in $numberAsts) {
306
+ $numberText = $number.Extent.Text
307
+ if ($numberReplacementMap.ContainsKey($numberText)) { continue }
308
+
309
+ $newNumber = ObfuscateNumbers $numberText
310
+ $numberReplacements += @{
311
+ StartOffset = $number.Extent.StartOffset
312
+ Length = $number.Extent.Text.Length
313
+ OriginalName = $numberText
314
+ Text = $numberText
315
+ NewName = $newNumber
316
+ Type = "Number"
317
+ }
318
+ }
319
+ }
320
+
321
+
322
+ $allReplacements = @()
323
+
324
+ foreach ($replacement in $barewordReplacements) {
325
+ $allReplacements += $replacement
326
+ }
327
+
328
+ foreach ($replacement in $numberReplacements) {
329
+ $allReplacements += $replacement
330
+ }
331
+
332
+ $allReplacements = $allReplacements | Sort-Object { $_.StartOffset } -Descending
333
+
334
+
335
+ foreach ($replacement in $allReplacements) {
336
+ $newName = switch ($replacement.Type) {
337
+ "Bareword" { $replacement.NewName }
338
+ "Number" { $replacement.NewName }
339
+ }
340
+
341
+ Write-Host "Second Pass - Replacing '$($replacement.Text)' at position $($replacement.StartOffset) with '$newName' (Type: $($replacement.Type))"
342
+
343
+ $code_copy = Replace-TextAtPosition -SourceText $code_copy `
344
+ -StartPosition $replacement.StartOffset `
345
+ -Length $replacement.Length `
346
+ -ReplacementText $newName
347
+ }
348
+
349
+ return $code_copy
350
+ }
351
+
352
+ function Replace-TextAtPosition {
353
+ param(
354
+ [string]$SourceText,
355
+ [int]$StartPosition,
356
+ [int]$Length,
357
+ [string]$ReplacementText
358
+ )
359
+
360
+ try {
361
+ $before = $SourceText.Substring(0, $StartPosition)
362
+ $after = $SourceText.Substring($StartPosition + $Length)
363
+ return $before + $ReplacementText + $after
364
+ }
365
+ catch {
366
+ Write-Host "Error in Replace-TextAtPosition:"
367
+ Write-Host "Source length: $($SourceText.Length)"
368
+ Write-Host "Start: $StartPosition"
369
+ Write-Host "Length: $Length"
370
+ Write-Host "Replacement: $ReplacementText"
371
+ throw $_
372
+ }
373
+ }
374
+
375
+ function Encrypt-Payload($string_payload) {
376
+ $placeholder_code = @"
377
+ function Create-AesManagedObject(`$key, `$IV, `$mode) {`$aesManaged = New-Object "System.Security.Cryptography.AesManaged";if (`$mode="CBC") { `$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC }elseif (`$mode="CFB") {`$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB}elseif (`$mode="CTS") {`$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS}elseif (`$mode="ECB") {`$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB}elseif (`$mode="OFB"){`$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB};`$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7;`$aesManaged.BlockSize = 128;`$aesManaged.KeySize = 256;if (`$IV) {if (`$IV.getType().Name -eq "String") {`$aesManaged.IV = [System.Convert]::FromBase64String(`$IV)}else {`$aesManaged.IV = `$IV}};if (`$key) {if (`$key.getType().Name -eq "String") {`$aesManaged.Key = [System.Convert]::FromBase64String(`$key)}else {`$aesManaged.Key = `$key}};return `$aesManaged};function Decrypt-String(`$key, `$encryptedStringWithIV) {`$bytes = [System.Convert]::FromBase64String(`$encryptedStringWithIV);`$IV = `$bytes[0..15];`$aesManaged = Create-AesManagedObject `$key `$IV;`$decryptor = `$aesManaged.CreateDecryptor();;`$unencryptedData = `$decryptor.TransformFinalBlock(`$bytes, 16, `$bytes.Length - 16);;`$aesManaged.Dispose();return [System.Text.Encoding]::UTF8.GetString(`$unencryptedData).Trim([char]0)};iex(Decrypt-String "YOUR_KEY_HERE" "YOUR_ENCRYPTED_STRING_HERE")
378
+ "@
379
+ $key = Create-AesKey
380
+ $encryptedString = Encrypt-String $key $string_payload
381
+ $new_code1 = $placeholder_code -replace "YOUR_KEY_HERE", $key
382
+ $final_code = $new_code1 -replace "YOUR_ENCRYPTED_STRING_HERE", $encryptedString
383
+ return $final_code
384
+ }
385
+
386
+ function Get-CommandType {
387
+ param(
388
+ [string]$CommandName
389
+ )
390
+
391
+ # simple cache because Get-Command is slow ash
392
+ if ($CommandTypeCache.ContainsKey($CommandName)) {
393
+ return $CommandTypeCache[$CommandName]
394
+ }
395
+
396
+ $command = Get-Command -Name $CommandName -ErrorAction Ignore
397
+
398
+ $result = if ($command) {
399
+ @{
400
+ IsBuiltIn = $true
401
+ Type = $command.CommandType
402
+ Name = $CommandName
403
+ }
404
+ } else {
405
+ @{
406
+ IsBuiltIn = $false
407
+ Type = "Unknown"
408
+ Name = $CommandName
409
+ }
410
+ }
411
+
412
+ # cache the result for future calls
413
+ $CommandTypeCache[$CommandName] = $result
414
+ return $result
415
+ }
416
+
417
+ function Main($payload) {
418
+ $obfuscatedCode = ObfuscateCode $payload
419
+ if ($times -ne 0) {
420
+ $totalSteps = ($times * 2) + 1
421
+ $currentStep = 0
422
+ while ($times -ne 1) {
423
+ $global:pass_number++
424
+ $times = $times - 1
425
+ $obfuscatedCode = Encrypt-Payload $obfuscatedCode
426
+ $currentStep++
427
+ Write-Progress -Activity "Obfuscating Code" -Status "Encrypting Payload" -PercentComplete (($currentStep / $totalSteps) * 100)
428
+ $obfuscatedCode = ObfuscateCode $obfuscatedCode
429
+ $currentStep++
430
+ Write-Progress -Activity "Obfuscating Code" -Status "Obfuscating Code" -PercentComplete (($currentStep / $totalSteps) * 100)
431
+ }
432
+ }
433
+
434
+ Write-Progress -Activity "Obfuscating Code" -Status "Completed" -PercentComplete 100 -Completed
435
+ return $obfuscatedCode
436
+ }
437
+
438
+ function Get-FileLocation {
439
+ while ($true) {
440
+ $file_location = Read-Host "Enter the file location -> "
441
+ if ((Test-Path $file_location) -and $file_location -like "*.ps1") {
442
+ return $file_location
443
+ } else {
444
+ Write-Host "File not found or not a .ps1 file: $file_location"
445
+ }
446
+ }
447
+ }
448
+
449
+ $location_good = Get-FileLocation
450
+
451
+ $stuff = Get-Content $location_good -Raw
452
+
453
+ $obfuscatedCode = Main $stuff
454
+
455
+ $out_file = $location_good -replace ".ps1", "_obf.ps1"
456
+ $obfuscatedCode | Out-File $out_file -Force
Obfus/util/MBA_OBF/mixed_boolean_arithmetic.ps1 ADDED
File without changes
Obfus/util/commands/commands.ps1 ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $printables = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
2
+ $banned = "abefnrtvABEFNRTV"
3
+
4
+ function ObfuscateCommandTypes {
5
+ param(
6
+ [string]$CommandText,
7
+ [hashtable]$CommandInfo,
8
+ [bool]$RealBearWord = $false
9
+ )
10
+
11
+ if ($RealBearWord) {
12
+ return DotObfuscateBareWord $CommandText
13
+ }
14
+
15
+ if ($CommandInfo.IsBuiltIn) {
16
+ switch ($CommandInfo.Type) {
17
+ "Cmdlet" {
18
+ $verb, $noun = $CommandText -split '-'
19
+ if ($noun) {
20
+ if ($verbose) {
21
+ Write-Host $CommandText NOUN
22
+ }
23
+ return DotObfuscateBareWord $CommandText
24
+ }
25
+ if ($verbose) {
26
+ Write-Host $CommandText VERB
27
+ }
28
+ return DotObfuscateBareWord $CommandText
29
+ }
30
+ "BuiltinAlias" {
31
+ return DotObfuscateBareWord $CommandText
32
+ }
33
+ "Function" {
34
+ if ($verbose) {
35
+ Write-Host $CommandText FUNCTION
36
+ }
37
+ return DotObfuscateBareWord $CommandText
38
+ }
39
+ "Alias" {
40
+ return RandomUpercaseCharacters $CommandText
41
+ }
42
+ default {
43
+ return RandomUpercaseCharacters $CommandText
44
+ }
45
+ }
46
+ }
47
+ else {
48
+ if ($verbose) {
49
+ Write-Host $CommandText CUSTOM
50
+ }
51
+ return RandomUpercaseCharacters $CommandText
52
+ }
53
+ }
54
+
55
+ function Get-RandomString {
56
+ $length = Get-Random -Minimum 8 -Maximum 16
57
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
58
+ return -join ((1..$length) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
59
+ }
60
+
61
+ function RandomUpercaseCharacters($string) {
62
+ $string = $string -split ""
63
+ for ($i = 0; $i -lt $string.Length; $i++) {
64
+ if ($i -gt 0 -and $string[$i - 1] -eq '`' -and $printables.Contains($string[$i])) {
65
+ continue
66
+ }
67
+
68
+ if ($printables.Contains($string[$i]) -and ($string[$i] -ne "")) {
69
+ $random = Get-Random -Minimum 0 -Maximum 2
70
+ if ($random -eq 0) {
71
+ $string[$i] = $string[$i].ToUpper()
72
+ }
73
+ else {
74
+ $string[$i] = $string[$i].ToLower()
75
+ }
76
+ }
77
+ }
78
+ return $string -join ''
79
+ }
80
+
81
+ function ObfuscateMethodsGood($string) {
82
+ $last = $false
83
+ $first = $true
84
+ $out_str = ""
85
+ if ($string.Contains("KDOT!?!_")) {
86
+ return $string
87
+ }
88
+ $string = $string -split ""
89
+ $string | ForEach-Object {
90
+ if (($first -eq $true) -and ($_ -ne "")) {
91
+ $out_str += $_
92
+ $first = $false
93
+ }
94
+ else {
95
+ if ($_ -ne "") {
96
+ $random = Get-Random -Minimum 0 -Maximum 3
97
+ if (($random -eq 0) -and ($last -eq $false)) {
98
+ $out_str += "`'$_`'"
99
+ $last = $true
100
+ }
101
+ elseif (($random -eq 1) -and ($last -eq $false) -and ($printables.Contains($_)) -and ($_ -ne "") -and (!($banned.Contains($_)))) {
102
+ $out_str += "``$_"
103
+ $last = $true
104
+ }
105
+ else {
106
+ $out_str += $_
107
+ $last = $false
108
+ }
109
+ }
110
+ }
111
+ }
112
+ return $out_str
113
+ }
114
+
115
+ function DotObfuscateBareWord($string) {
116
+ $split_str = $string -split ""
117
+ $map = @()
118
+ # get the char value for each char in the string
119
+ $split_str | ForEach-Object {
120
+ if ($_ -ne "") {
121
+ $map += [int][char]$_
122
+ }
123
+ }
124
+
125
+ $out_str = ".("
126
+
127
+ $map | ForEach-Object {
128
+ if ($global:pass_number -lt 2) {
129
+ $obfuscated = AddOrSubtractRandomEQ $_
130
+ $out_str += "[char]($obfuscated)+"
131
+ } else {
132
+ $out_str += "[char]($_)+"
133
+ }
134
+
135
+ }
136
+ $out_str = $out_str.Substring(0, $out_str.Length - 1)
137
+ $out_str += ")"
138
+ return $out_str
139
+ }
140
+
141
+ function AddOrSubtractRandomEQ($number_to_obf) {
142
+ #get 3 random numbers
143
+ $number1 = Get-Random -Minimum 1 -Maximum 10000
144
+ $number2 = Get-Random -Minimum 1 -Maximum 10000
145
+ $number3 = Get-Random -Minimum 1 -Maximum 10000
146
+
147
+ $signs = @('+', '-')
148
+
149
+ $num1_sign = Get-Random -Minimum 0 -Maximum 2
150
+ $num2_sign = Get-Random -Minimum 0 -Maximum 2
151
+ $num3_sign = Get-Random -Minimum 0 -Maximum 2
152
+
153
+ $sign1 = $signs[$num1_sign]
154
+ $sign2 = $signs[$num2_sign]
155
+ $sign3 = $signs[$num3_sign]
156
+
157
+ $opposite_sign1 = $signs[1 - $num1_sign]
158
+ $opposite_sign2 = $signs[1 - $num2_sign]
159
+ $opposite_sign3 = $signs[1 - $num3_sign]
160
+
161
+ $final_number = "$number_to_obf $sign1 $number1 $sign2 $number2 $sign3 $number3"
162
+ $out_final = Invoke-Expression $final_number
163
+
164
+ $new_problem = "$out_final $opposite_sign1 $number1 $opposite_sign2 $number2 $opposite_sign3 $number3"
165
+ return "($new_problem)"
166
+ }
167
+
168
+ #ObfuscateMethodsGood "KDOT_frslwSZslJ"
Obfus/util/commands/function_names.ps1 ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Define characters for function name generation
2
+ $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
3
+
4
+ function Create_Random_String {
5
+ $string = $characters[(Get-Random -Minimum 26 -Maximum $characters.Length)]
6
+
7
+ for ($i = 0; $i -lt 15; $i++) {
8
+ $string += $characters[(Get-Random -Minimum 0 -Maximum $characters.Length)]
9
+ }
10
+ return $string
11
+ }
12
+
13
+ function ObfuscateFunctionNames($name) {
14
+ $newName = Create_Random_String
15
+ return $newName
16
+ }
Obfus/util/final/encodeOutput.ps1 ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Taken from https://gist.github.com/ctigeek/2a56648b923d198a6e60
2
+
3
+ function Create-AesManagedObject($key, $IV, $mode) {
4
+ $aesManaged = New-Object "System.Security.Cryptography.AesManaged"
5
+
6
+ if ($mode="CBC") { $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC }
7
+ elseif ($mode="CFB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB}
8
+ elseif ($mode="CTS") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS}
9
+ elseif ($mode="ECB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB}
10
+ elseif ($mode="OFB"){$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB}
11
+
12
+
13
+ $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
14
+ $aesManaged.BlockSize = 128
15
+ $aesManaged.KeySize = 256
16
+ if ($IV) {
17
+ if ($IV.getType().Name -eq "String") {
18
+ $aesManaged.IV = [System.Convert]::FromBase64String($IV)
19
+ }
20
+ else {
21
+ $aesManaged.IV = $IV
22
+ }
23
+ }
24
+ if ($key) {
25
+ if ($key.getType().Name -eq "String") {
26
+ $aesManaged.Key = [System.Convert]::FromBase64String($key)
27
+ }
28
+ else {
29
+ $aesManaged.Key = $key
30
+ }
31
+ }
32
+ return $aesManaged
33
+ }
34
+
35
+ function Create-AesKey() {
36
+ $aesManaged = Create-AesManagedObject
37
+ $aesManaged.GenerateKey()
38
+ return [System.Convert]::ToBase64String($aesManaged.Key)
39
+ }
40
+
41
+ function Encrypt-String($key, $plaintext) {
42
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext)
43
+ $aesManaged = Create-AesManagedObject $key
44
+ $encryptor = $aesManaged.CreateEncryptor()
45
+ $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
46
+ [byte[]] $fullData = $aesManaged.IV + $encryptedData
47
+ return [System.Convert]::ToBase64String($fullData)
48
+ }
49
+
50
+ function Decrypt-String($key, $encryptedStringWithIV) {r
51
+ $bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
52
+ $IV = $bytes[0..15]
53
+ $aesManaged = Create-AesManagedObject $key $IV
54
+ $decryptor = $aesManaged.CreateDecryptor();
55
+ $unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16)
56
+ $aesManaged.Dispose()
57
+ return [System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
58
+ }
59
+
60
+ #$key = Create-AesKey
61
+ #
62
+ #
63
+ #$plaintext = "This is a test string"
64
+ #$mode = "OFB"
65
+ #"== Powershell AES $mode Encyption=="
66
+ #"`nKey: "+$key
67
+ #
68
+ #$encryptedString = Encrypt-String $key $plaintext
69
+ #
70
+ #$bytes = [System.Convert]::FromBase64String($encryptedString)
71
+ #
72
+ #$IV = $bytes[0..15]
73
+ #"Salt: " + [System.Convert]::ToHexString($IV)
74
+ #"Salt: " + [System.Convert]::ToBase64String($IV)
75
+ #
76
+ #$plain = Decrypt-String $key $encryptedString
77
+ #
78
+ #"`nEncrypted: "+$encryptedString
79
+ #
80
+ #"Decrypted: "+$plain
81
+
82
+ function Encrypt-Payload($string_payload) {
83
+ $placeholder_code = @"
84
+ function Decrypt-String(`$key, `$encryptedStringWithIV) {`$bytes = [System.Convert]::FromBase64String(`$encryptedStringWithIV);`$IV = `$bytes[0..15];`$aesManaged = Create-AesManagedObject `$key `$IV;`$decryptor = `$aesManaged.CreateDecryptor();;`$unencryptedData = `$decryptor.TransformFinalBlock(`$bytes, 16, `$bytes.Length - 16);;`$aesManaged.Dispose();return [System.Text.Encoding]::UTF8.GetString(`$unencryptedData).Trim([char]0)};iex(Decrypt-String "YOUR_KEY_HERE" "YOUR_ENCRYPTED_STRING_HERE")
85
+ "@
86
+ $key = Create-AesKey
87
+ $encryptedString = Encrypt-String $key $string_payload
88
+ $placeholder_code -replace "YOUR_KEY_HERE", $key
89
+ $placeholder_code -replace "YOUR_ENCRYPTED_STRING_HERE", $encryptedString
90
+ return $placeholder_code
91
+ }
92
+
93
+ $placeholder_code -replace "YOUR_KEY_HERE" | Out-Null
Obfus/util/numbers/obfuscate_numbers.ps1 ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function ObfuscateNumbers($number) {
2
+ $number_to_obf = $number
3
+ $obf_number = AddOrSubtractRandomEQ $number_to_obf
4
+ return $obf_number
5
+ }
6
+
7
+ function AddOrSubtractRandomEQ($number_to_obf) {
8
+ #get 3 random numbers
9
+ $number1 = Get-Random -Minimum 1 -Maximum 10000
10
+ $number2 = Get-Random -Minimum 1 -Maximum 10000
11
+ $number3 = Get-Random -Minimum 1 -Maximum 10000
12
+
13
+ $signs = @('+', '-')
14
+
15
+ $num1_sign = Get-Random -Minimum 0 -Maximum 2
16
+ $num2_sign = Get-Random -Minimum 0 -Maximum 2
17
+ $num3_sign = Get-Random -Minimum 0 -Maximum 2
18
+
19
+ $sign1 = $signs[$num1_sign]
20
+ $sign2 = $signs[$num2_sign]
21
+ $sign3 = $signs[$num3_sign]
22
+
23
+ $opposite_sign1 = $signs[1 - $num1_sign]
24
+ $opposite_sign2 = $signs[1 - $num2_sign]
25
+ $opposite_sign3 = $signs[1 - $num3_sign]
26
+
27
+ $final_number = "$number_to_obf $sign1 $number1 $sign2 $number2 $sign3 $number3"
28
+ $out_final = Invoke-Expression $final_number
29
+
30
+ $new_problem = "$out_final $opposite_sign1 $number1 $opposite_sign2 $number2 $opposite_sign3 $number3"
31
+ return "($new_problem)"
32
+ }
Obfus/util/strings/strings.ps1 ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #TODO add env var obf
2
+ $split_string_verbose = $false
3
+
4
+ function ObfuscateString($string) {
5
+ $splitting = $true
6
+ if ($string.Length -lt 4) {
7
+ $splitting = $false
8
+ }
9
+ if ($string.StartsWith("'") -and $string.EndsWith("'")) {
10
+ $string = $string.Substring(1, $string.Length - 2)
11
+ }
12
+ if ($string.StartsWith('"') -and $string.EndsWith('"')) {
13
+ $string = $string.Substring(1, $string.Length - 2)
14
+ }
15
+ $string = $string -replace "`'", "`'`'"
16
+ if ($string -eq "") {
17
+ return "''"
18
+ }
19
+ $out_content = ""
20
+
21
+ if ($splitting -eq $false) {
22
+ $string_pieces = @($string)
23
+ } else {
24
+ try {
25
+ [string[]]$string_pieces = SplitStrings $string
26
+ }
27
+ catch {
28
+ Write-Host "Error splitting string: $string"
29
+ Read-Host "Press enter to exit..."
30
+ exit 1
31
+ }
32
+ }
33
+
34
+ for ($i = 0; $i -lt $string_pieces.Count; $i++) {
35
+ $small_string = $string_pieces[$i]
36
+ $obfuscationFunctions = @(
37
+ #"ObfuscateStringReverse",
38
+ "ObfuscateBase64String",
39
+ #"ObfuscateReplaceString",
40
+ "ObfuscateHexString",
41
+ "ObfuscateByteArrayString",
42
+ "ObfuscateMixedString"
43
+ )
44
+ $random = Get-Random -Minimum 0 -Maximum $obfuscationFunctions.Length
45
+ $obfuscationFunction = $obfuscationFunctions[$random]
46
+ $out_content2 = & $obfuscationFunction $small_string
47
+
48
+ if ($i -lt ($string_pieces.Count - 1)) {
49
+ $out_content += "$out_content2 + "
50
+ } else {
51
+ $out_content += $out_content2
52
+ }
53
+ }
54
+
55
+ return "($out_content)"
56
+ }
57
+
58
+ function ObfuscateStringReverse($string) {
59
+ #WORKING
60
+ $split_string = $string -split ""
61
+ [array]::Reverse($split_string)
62
+ $reversed_string = $split_string -join ''
63
+ $command = "('$reversed_string'[-1..-$($reversed_string.Length)] -join '')"
64
+ return $command
65
+ }
66
+
67
+ function ObfuscateBase64String($string) {
68
+ #WORKING
69
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
70
+ $encoded = [System.Convert]::ToBase64String($bytes)
71
+ $command = "[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('$encoded'))"
72
+ return $command
73
+ }
74
+
75
+ function ObfuscateByteArrayString($string) {
76
+ #WORKING
77
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
78
+ $good_bytes = "(" + ($bytes -join ', ') + ")"
79
+ $command = "[System.Text.Encoding]::UTF8.GetString($good_bytes)"
80
+ return $command
81
+ }
82
+
83
+ function ObfuscateHexString($string) {
84
+ if ([string]::IsNullOrEmpty($string)) {
85
+ return "''"
86
+ }
87
+
88
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
89
+ $hexString = $bytes | ForEach-Object { "0x{0:x2}" -f $_ }
90
+ $hexString = "($($hexString -join ', '))"
91
+ $command = "[System.Text.Encoding]::UTF8.GetString($hexString)"
92
+ return $command
93
+ }
94
+
95
+ function ObfuscateMixedString($string) {
96
+ $bytes = [System.Text.Encoding]::UTF8.GetBytes($string)
97
+ $hexArray = $bytes | ForEach-Object { "0x{0:x2}" -f $_ }
98
+
99
+ if ($bytes.Length -eq 1) {
100
+ $byteArrayString = $bytes[0]
101
+ } else {
102
+ $mixedArray = for ($i = 0; $i -lt $bytes.Length; $i++) {
103
+ if ((Get-Random -Minimum 0 -Maximum 2) -eq 0) {
104
+ $bytes[$i]
105
+ } else {
106
+ $hexArray[$i]
107
+ }
108
+ }
109
+ $byteArrayString = "(" + ($mixedArray -join ', ') + ")"
110
+ }
111
+
112
+ $command = "[System.Text.Encoding]::UTF8.GetString($byteArrayString)"
113
+ return $command
114
+ }
115
+
116
+ function SplitStrings {
117
+ param (
118
+ [string]$string
119
+ )
120
+
121
+ $string_length = $string.Length
122
+ if ($string_length -lt 2) {
123
+ return @($string)
124
+ }
125
+
126
+ # array to store chunks
127
+ $result = @()
128
+ $i = 0
129
+
130
+ while ($i -lt $string_length) {
131
+ if ($string_length -lt 10) {
132
+ $chunk_length = Get-Random -Minimum 2 -Maximum 5
133
+ } elseif ($string_length -lt 50) {
134
+ $chunk_length = Get-Random -Minimum 15 -Maximum 25
135
+ } elseif ($string_length -lt 100) {
136
+ $chunk_length = Get-Random -Minimum 24 -Maximum 50
137
+ } elseif ($string_length -lt 200) {
138
+ $chunk_length = Get-Random -Minimum 50 -Maximum 100
139
+ } elseif ($string_length -lt 500) {
140
+ $chunk_length = Get-Random -Minimum 75 -Maximum 200
141
+ } elseif ($string_length -lt 1000) {
142
+ $chunk_length = Get-Random -Minimum 100 -Maximum 300
143
+ } else {
144
+ $chunk_length = Get-Random -Minimum 200 -Maximum 500
145
+ }
146
+
147
+ # make sure we got the remaining string length
148
+ $length = [Math]::Min($chunk_length, $string_length - $i)
149
+
150
+ # add it to the chunk array
151
+ $result += $string.Substring($i, $length)
152
+
153
+ # move the index forward of how far we've gone.
154
+ $i += $length
155
+
156
+ if ($split_string_verbose) {
157
+ Write-Host "Chunk: $($result[-1])"
158
+ }
159
+ }
160
+
161
+ #pretty print the chunks
162
+ if ($split_string_verbose) {
163
+ Write-Host "Chunks: $($result -join ', ')"
164
+ }
165
+
166
+ return $result
167
+ }
168
+
169
+ function ObfuscateReplaceString($string) {
170
+ #BROKEN
171
+ $split_str = SplitStrings $string
172
+ $replaces_amount = $split_str.Length
173
+
174
+ $set_dict = @{}
175
+
176
+ for ($i = 0; $i -lt $replaces_amount; $i++) {
177
+ $set_dict[$i] = $split_str[$i]
178
+ }
179
+
180
+ $shuffled_key_locations = @()
181
+ for ($i = 0; $i -lt $replaces_amount; $i++) {
182
+ $shuffled_key_locations += $i
183
+ }
184
+
185
+ #this is the order we will put the keys in the string.
186
+ $shuffled_keys = $shuffled_key_locations | Sort-Object {Get-Random}
187
+
188
+ $format_string = ""
189
+ $arguments = @()
190
+
191
+ #make the output look like "{1}{0}{2}" -f "b", "a", "c"
192
+ for ($i = 0; $i -lt $shuffled_keys.Length; $i++) {
193
+ $format_string += "{$($shuffled_keys[$i])}"
194
+ $arguments += $set_dict[$i]
195
+ }
196
+
197
+ $format_string = '"' + $format_string + '"'
198
+ $arguments = '"' + ($arguments -join '", "') + '"'
199
+
200
+ $command = "($format_string -f $arguments)"
201
+
202
+ Write-Host "Obfuscated: $command"
203
+ Write-Host $shuffled_key_locations
204
+ Write-Host $shuffled_keys
205
+ Write-Host $format_string
206
+ Write-Host $arguments
207
+
208
+ return $command
209
+ }
210
+
211
+ function make_random_string($length) {
212
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
213
+ return -join ((1..$length) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
214
+ }
215
+
216
+ ## Test the obfuscation
217
+ #for ($i = 0; $i -lt 1000; $i++) {
218
+ # $length = Get-Random -Minimum 1 -Maximum 10
219
+ # $string = make_random_string $length
220
+ # $obfuscated_string = ObfuscateReplaceString $string
221
+ # $deobfuscated_string = Invoke-Expression $obfuscated_string
222
+ #
223
+ # if ($string -ne $deobfuscated_string) {
224
+ # Write-Host "-------------------------------------"
225
+ # Write-Host "$string"
226
+ # Write-Host "$deobfuscated_string"
227
+ # Write-Host "Failed to deobfuscate string: $string"
228
+ # Write-Host "Obfuscated: $obfuscated_string"
229
+ # Write-Host "Deobfuscated: $deobfuscated_string"
230
+ # Write-Host "Press Enter to continue..."
231
+ # Read-Host
232
+ # }
233
+ #}
Obfus/util/variables/variables.ps1 ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $bad_vars2 = @('$_', '$ignore', '$PSScriptRoot', '$global', '$MyInvocation', '$local', '`$', '$args', '$ErrorActionPreference', '$ProgressPreference', '$PROFILE')
2
+ $good_chars = "cdghijklmopqsuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
3
+
4
+ function ObfuscateVariables($variable_good, $parameter) {
5
+ $lower_var = $variable_good.ToLower()
6
+ switch ($lower_var) {
7
+ '$true' { return ObfuscateTrue }
8
+ '$false' { return ObfuscateFalse }
9
+ '$null' { return ObfuscateNull }
10
+ }
11
+
12
+ foreach ($bad_var in $bad_vars2) {
13
+ if ($lower_var -contains $bad_var) {
14
+ return $variable_good
15
+ }
16
+ }
17
+ $var = MakeRandomVariableName 10
18
+ $new_var_final = RandomChangeVar $var $parameter
19
+ Write-Host "Obfuscating variable: $variable_good to $new_var_final"
20
+ return $new_var_final
21
+ }
22
+
23
+ function MakeRandomVariableName($length) {
24
+ $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
25
+ $name = "`$KDOT"
26
+ for ($i = 0; $i -lt $length; $i++) {
27
+ $name += $chars[(Get-Random -Minimum 0 -Maximum $chars.Length)]
28
+ }
29
+ return $name
30
+ }
31
+
32
+ function RandomChangeVar($variable, $parameter) {
33
+ # if the variable is in good_chars, do random capitalization and randomly add a ` in front.
34
+ $ticks = Get-Random -Minimum 0 -Maximum 2
35
+ if ($parameter -eq $true) {
36
+ $ticks = 999
37
+ }
38
+ $variable = $variable -split ""
39
+ for ($i = 0; $i -lt $variable.Length; $i++) {
40
+ if ($i -gt 0 -and $variable[$i - 1] -eq '`' -and $good_chars.Contains($variable[$i])) {
41
+ continue
42
+ }
43
+
44
+ if ($good_chars.Contains($variable[$i]) -and ($variable[$i] -ne "")) {
45
+ $random = Get-Random -Minimum 0 -Maximum 2
46
+ $random2 = Get-Random -Minimum 0 -Maximum 2
47
+ if ($random -eq 0) {
48
+ $variable[$i] = $variable[$i].ToUpper()
49
+ } else {
50
+ $variable[$i] = $variable[$i].ToLower()
51
+ }
52
+
53
+ if (($random2 -eq 0) -and ($ticks -eq 0)) {
54
+ $variable[$i] = "``" + $variable[$i]
55
+ }
56
+ }
57
+ }
58
+ $variable = $variable -join ''
59
+ if ($ticks -eq 0) {
60
+ #insert a { at the beginning after the first character and a } at the end
61
+ $variable = $variable.Insert(1, "{")
62
+ $variable += "}"
63
+ }
64
+ return $variable
65
+ }
66
+
67
+ function ObfuscateTrue {
68
+ return '$true'
69
+ }
70
+
71
+ function ObfuscateFalse {
72
+ return '$false'
73
+ }
74
+
75
+ function ObfuscateNull {
76
+ return '$null'
77
+ }
78
+
79
+ #ObfuscateVariables '$this_is_a_test'