Created
June 26, 2022 22:15
-
-
Save purplemonkeymad/097c1db89541c066c2358035df4048a5 to your computer and use it in GitHub Desktop.
Basic Regex brute forcer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class RegExExpandedValues { | |
| <# wet with class as it keeps stuff together and I can put a bit of code in it. | |
| I extend to other types might use inheritance at some point. shrug #> | |
| $OriginalString | |
| $ValueList | |
| <# I can't be bothered to fill it out right now, feel free.#> | |
| static [hashtable]$SlashCodes = @{ | |
| [char]'d' = 0..9 | ForEach-Object { "$_" } | |
| [char]'-' = '-' | |
| } | |
| # the order of these or terms means we should always match in a logical way. | |
| static [regex]$TermMatcher = [regex]'\[.+?\]|\\.|.' | |
| static [regex]$CharGroupMatcher = [regex]'\\.|.\-.|.' | |
| RegExExpandedValues ([string] $StartingString) { | |
| $term = $StartingString | |
| $this.OriginalString = $term | |
| $this.ValueList = switch ($term[0]) { | |
| '\' { | |
| if ([RegExExpandedValues]::SlashCodes[$term[1]]) { | |
| [RegExExpandedValues]::SlashCodes[$term[1]] | |
| } | |
| else { | |
| Write-Error "Expected value after backslash got unknown value or no value. : $_ " -ErrorAction Stop | |
| throw | |
| } | |
| } | |
| '[' { | |
| $InnerTerms = $term.Trim('[]') | |
| [RegExExpandedValues]::CharGroupMatcher.Matches($InnerTerms).Value | ForEach-Object { | |
| <# kinda undry but whatever. #> | |
| if ($_[0] -eq '\') { | |
| if ([RegExExpandedValues]::SlashCodes[$_[1]]) { | |
| [RegExExpandedValues]::SlashCodes[$_[1]] | |
| } | |
| else { | |
| Write-Error "Expected value after backslash got unknown value or no value in char grouping. : $_ " -ErrorAction Stop | |
| throw | |
| } | |
| } | |
| elseif ($_[1] -eq '-') { | |
| ([int][char]$_[0])..([int][char]$_[2]) | ForEach-Object { [char]$_ } | |
| } | |
| else { | |
| $_ | |
| } | |
| } | |
| } | |
| Default { $_ } | |
| } | |
| } | |
| } | |
| function Get-RegExTerms { | |
| param([Parameter(Mandatory)][regex]$RegularExpression) | |
| begin { | |
| } | |
| end { | |
| $parser = [RegExExpandedValues]::TermMatcher | |
| $parser.Matches($RegularExpression.ToString()).Value | ForEach-Object { | |
| $term = $_ | |
| [RegExExpandedValues]::new($term) | |
| } | |
| } | |
| } | |
| function Get-RegExBruteStats { | |
| param([Parameter(Mandatory)][regex]$RegularExpression) | |
| end { | |
| $TermList = Get-RegExTerms $RegularExpression | |
| $accumulator = [bigint]::One | |
| $TermList | ForEach-Object { | |
| $exp = [bigint]$_.ValueList.count | |
| $accumulator = [bigint]::Multiply($accumulator, $exp) | |
| } | |
| $byteSize = [bigint]::Multiply($accumulator, $TermList.count) | |
| $FileSize = [bigint]::Multiply($accumulator, ($TermList.count + 2)) | |
| [pscustomobject]@{ | |
| StringLength = $TermList.count | |
| Combinations = $accumulator | |
| CombinationsSI = $accumulator.ToString('E') | |
| ByteSize = $byteSize | |
| FileSizeWin = $FileSize | |
| FileSizeWinGB = $FileSize / 1GB | |
| } | |
| } | |
| } | |
| function Get-RegExBruteCombination { | |
| param ( | |
| [Parameter(Mandatory)][regex]$RegularExpression | |
| ) | |
| # use a nested recusion function | |
| <# This limits us to about 3.8k term regexs. This includes single chars as a term. | |
| Could combine conseutive combination terms to deduce the stack depth?#> | |
| $RegExTermList = Get-RegExTerms $RegularExpression | |
| function nestedGenerator { | |
| <# the function can access the parent scope so using an index here should prevent any | |
| need to copy the array around.#> | |
| Param([int]$ListIndex, [string]$StringSoFar) | |
| if ($ListIndex -ge $RegExTermList.count) { | |
| Write-Error "Overran index, check code." -ErrorAction Stop | |
| return | |
| } | |
| if ($ListIndex -eq ($RegExTermList.count -1)) { | |
| # no recurse | |
| $ListItem = $RegExTermList[$ListIndex] | |
| foreach ( $Value in $ListItem.ValueList) { | |
| $StringSoFar + $Value | |
| } | |
| return | |
| } | |
| # time to nest | |
| $ListItem = $RegExTermList[$ListIndex] | |
| foreach ( $Value in $ListItem.ValueList ) { | |
| $newStringSoFar = $StringSoFar + $Value | |
| nestedGenerator -ListIndex ($ListIndex + 1) -StringSoFar $newStringSoFar | |
| } | |
| } | |
| nestedGenerator -ListIndex 0 -StringSoFar "" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment