-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #404 from AidanFeess/master
Create powershell versions of the peas2json.py and json2html.py parsers
- Loading branch information
Showing
2 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
# Based on https://github.com/carlospolop/PEASS-ng/blob/master/parsers/peas2json.py | ||
|
||
# Pattern to identify main section titles | ||
$CHAR_1 = [String][char]0x2550 # ═ | ||
$CHAR_2 = [String][char]0x2554 # ╔ | ||
$CHAR_3 = [String][char]0x2563 # ╣ | ||
$CHAR_4 = [String][char]0x255a # ╚ | ||
$TITLE_CHARS = [String][char]0x2550, [String][char]0x2554, [String][char]0x2563, [String][char]0x255a # ═, ╔, ╣, ╚ | ||
$TITLE1_PATTERN = $CHAR_1*14 + $CHAR_3 #══════════════╣# | ||
#The size of the first pattern varies, but at least should be that large | ||
$TITLE2_PATTERN = $CHAR_2 + $CHAR_1*10 + $CHAR_3 #╔══════════╣# | ||
$TITLE3_PATTERN = $CHAR_1*2 + $CHAR_3 #══╣# | ||
$INFO_PATTERN = $CHAR_4 #╚ # | ||
|
||
$encoding = [System.Text.Encoding]::UTF8 | ||
|
||
# Patterns from color | ||
## The order is important, the first string colored with a color will be the one selected (the same string cannot be colored with different colors) | ||
$global:COLORS = @{ | ||
"REDYELLOW" = "\x1b\[1;31;103m"; | ||
"RED" = "\x1b\[1;31m"; | ||
"GREEN" = "\x1b\[1;32m"; | ||
"YELLOW" = "\x1b\[1;33m"; | ||
"BLUE" = "\x1b\[1;34m"; | ||
"MAGENTA" = "\x1b\[1;95m", "\x1b\[1;35m"; | ||
"CYAN" = "\x1b\[1;36m", "\x1b\[1;96m"; | ||
"LIGHT_GREY" = "\x1b\[1;37m"; | ||
"DARKGREY" = "\x1b\[1;90m"; | ||
} | ||
|
||
$global:FINAL_JSON = @{} | ||
|
||
$global:C_SECTION = $FINAL_JSON | ||
$global:C_MAIN_SECTION = $FINAL_JSON | ||
$global:C_2_SECTION = $FINAL_JSON | ||
$global:C_3_SECTION = $FINAL_JSON | ||
|
||
function is_section { | ||
param ( | ||
[string] $line, | ||
[string] $pattern | ||
) | ||
|
||
# Checks ifa line matches the pattern | ||
return $line.contains($pattern) | ||
} | ||
|
||
function clean_colors { | ||
param ( | ||
[string] $line | ||
) | ||
|
||
# Given a line, clean the colors inside of it | ||
|
||
$line = $line -replace '\x1b\[[0-9;]*m','' | ||
$line = $line.Trim() | ||
return $line | ||
|
||
} | ||
|
||
function clean_title { | ||
param ( | ||
[string] $line | ||
) | ||
# Given a title, clean it | ||
foreach($c in $TITLE_CHARS){ | ||
$line = $line.Replace($c, "") | ||
} | ||
|
||
$line = [System.Text.Encoding]::ASCII.GetString($encoding.GetBytes($line)) | ||
$line = $line.Trim() | ||
return $line | ||
|
||
} | ||
|
||
function get_colors { | ||
param ( | ||
[string] $line | ||
) | ||
|
||
[hashtable]$colors = @{} | ||
|
||
$global:COLORS.GetEnumerator() | ForEach-Object { | ||
$colors[$_.Key] = '' | ||
foreach($reg in $_.Value){ # eq reg in regexs in py | ||
$split_color = $line -split $reg | ||
# Start from index 1 as the index 0 isn't colored | ||
if($split_color -And $split_color.Length -gt 1){ | ||
$split_color = $split_color | Select-Object -Skip 1 | ||
|
||
# For each potential color, find the string before any possible color termination | ||
foreach($potential_color_str in $split_color){ | ||
$color_str1 = ($potential_color_str -split "\x1b")[0] | ||
$color_str2 = ($potential_color_str -split "\[0m")[0] | ||
$color_str = $color_str2 | ||
if($color_str1.Length -lt $color_str2.Length){ | ||
$color_str = $color_str1 | ||
} | ||
|
||
if($color_str){ | ||
$color_str = clean_colors $color_str.trim() | ||
# Avoid having the same color for the same string | ||
if($color_str){ | ||
$colors[$_.Key] += $color_str | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
} | ||
if(-not $colors[$_.Key]){ | ||
$colors.Remove($_.Key) | ||
} | ||
} | ||
|
||
return $colors | ||
|
||
} | ||
|
||
function parse_title { | ||
param ( | ||
[string] $line | ||
) | ||
# Given a title, clean it | ||
|
||
$cleaned_title_pt = clean_title($line) | ||
return clean_colors $cleaned_title_pt | ||
|
||
} | ||
|
||
function parse_line { | ||
param ( | ||
[string] $line | ||
) | ||
#Parse the given line, adding it to the FINAL_JSON structure | ||
|
||
if( $line.Contains("Cron jobs") ){ | ||
$a = 1 | ||
} | ||
|
||
# for debug | ||
#$line | ||
#Start-Sleep -Milliseconds 500 | ||
|
||
if(is_section $line $TITLE1_PATTERN){ | ||
$title = parse_title $line | ||
#New-Object System.Collections.Generic.List[System.Object] | ||
$FINAL_JSON.add($title, @{ "sections" = @{}; "lines" = @(); "infos" = @() }) | ||
$global:C_MAIN_SECTION = $global:FINAL_JSON.$title | ||
$global:C_SECTION = $global:C_MAIN_SECTION | ||
} | ||
elseif(is_section $line $TITLE2_PATTERN){ | ||
$title = parse_title $line | ||
$global:C_MAIN_SECTION.'sections'.Add($title, @{ "sections" = @{}; "lines" = @(); "infos" = @() }) | ||
$global:C_2_SECTION = $global:C_MAIN_SECTION.'sections'.$title | ||
$global:C_SECTION = $global:C_2_SECTION | ||
} | ||
elseif(is_section $line $TITLE3_PATTERN){ | ||
$title = parse_title $line | ||
$global:C_2_SECTION.'sections'.add($title, @{ "sections" = @{}; "lines" = @(); "infos" = @() }) | ||
$global:C_3_SECTION = $global:C_2_SECTION.'sections'.$title | ||
$global:C_SECTION = $global:C_3_SECTION | ||
} | ||
elseif(is_Section $line $INFO_PATTERN){ | ||
$title = parse_title $line | ||
$global:C_SECTION["infos"] += $title | ||
} | ||
|
||
#If here, then it's text | ||
else{ | ||
#If no main section parsed yet, pass | ||
if($global:C_SECTION -eq @{}){ | ||
return | ||
} | ||
$global:C_SECTION['lines'] += @{"raw_text" = $line; "colors" = get_colors $line;"clean_text" = clean_title(clean_colors $line)} | ||
} | ||
} | ||
|
||
function main { | ||
foreach($line in Get-Content -LiteralPath $OUTPUT_PATH){ | ||
$line = $line.Trim() | ||
#Write-Host $line | ||
if(-not $line -or -not (clean_colors $line)){ #Remove empty lines or lines just with colors hex | ||
continue | ||
} | ||
|
||
parse_line $line | ||
} | ||
|
||
$FINAL_JSON | ConvertTo-Json -depth 100 | Out-File $JSON_PATH | ||
|
||
} | ||
|
||
|
||
try { | ||
$OUTPUT_PATH = $(Read-Host "Output Path") | ||
$JSON_PATH = $(Read-Host "JSON Path") | ||
} | ||
catch { | ||
Write-Host "Error: Please pass the peas.out file and the path to save the json" | ||
exit | ||
} | ||
|
||
main |