From ed4d60c64de169bec5ecc968bbf6d5d104b1c278 Mon Sep 17 00:00:00 2001 From: Aidan Feess <145503050+AidanFeess@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:34:32 -0800 Subject: [PATCH 1/5] Add winpeas to json powershell parser --- parsers/peas2json.ps1 | 205 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 parsers/peas2json.ps1 diff --git a/parsers/peas2json.ps1 b/parsers/peas2json.ps1 new file mode 100644 index 000000000..ffa1217d2 --- /dev/null +++ b/parsers/peas2json.ps1 @@ -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`npeas2json.ps1 " + exit +} + +main \ No newline at end of file From f5339ae80caee50bd151f2d5f12b0b39a741cdf0 Mon Sep 17 00:00:00 2001 From: Aidan Feess <145503050+AidanFeess@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:35:20 -0800 Subject: [PATCH 2/5] add json to html powershell parser --- parsers/json2html.ps1 | 398 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 parsers/json2html.ps1 diff --git a/parsers/json2html.ps1 b/parsers/json2html.ps1 new file mode 100644 index 000000000..b22e07dbd --- /dev/null +++ b/parsers/json2html.ps1 @@ -0,0 +1,398 @@ +# Based on https://github.com/carlospolop/PEASS-ng/blob/master/parsers/json2html.py +# TODO: create the script +function parse_dict { + param ( + [System.Object] $json_dict + ) + + # Parse the given dict from the given json adding it to the HTML file + $dict_text = "" + foreach($obj in $json_dict.psobject.properties){ + $key = $obj.Name + $value = $obj.Value + $n = Get-Random -Minimum 1 -Maximum 999999 + $infos = [System.Collections.ArrayList]@() + + foreach($info in $value."infos"){ + if(([string]$info).StartsWith('http')){ + $infos.Add("$info
`n") + } + else{ + $infos.Add([string]$info + "
`n") + } + } + + $dict_text += "`t`t
`n" + $dict_text += "" + ($infos -join "") + "" + $dict_text += "
`n" + + if($value."lines"){ + $dict_text += $("`n" + (parse_list $value."lines") + "`n") + } + + if($value."sections"){ + $dict_text += (parse_dict $value."sections") + } + } + + return $dict_text + +} + +function parse_list { + param ( + [System.Object] $json_list + ) + # Parse the given list from the given json adding it to the HTML file + + $color_text="" + $color_class="" + + $special_char = [String][char]0x2550 + $special_char_2 = [String][char]0x2563 + + foreach($i in $json_list){ + if(-not $i."clean_text".Contains($special_char*3)){ + if($i."clean_text"){ + $color_text += "
" + $replacement + "") + if($text.Contains($special_char_2)){ + $text = $text.Replace($special_char_2, "
  • ") + $text += "
  • " + } + } + $color_text += "" + $color_class + " " + } + $color_text += "no_color`" >" + $text + "
    `n" + } + + } + } + return $color_text + "`t`t`t
    `n" +} + +function parse_json { + param ( + $json_data + ) + + $body = "" + $i = 1 + + foreach($obj in $json_data.psobject.properties){ + $key = $obj.Name + $value = $obj.Value + $body += " `t`t
    `n
    `n" + $i += 1 + foreach($obj_2 in $value.psobject.properties) { + $key1 = $obj_2.Name + $value1 = $obj_2.Value + if($value1.GetType().BaseType -eq [System.Object]){ + $body += parse_dict $value1 + } + + } + + $body += "`t`t`t
    `n" + } + + return $body +} + +$HTML_HEADER = @" + + + + + + + + + +"@ + +$HTML_END = @" + + + +"@ + +$HTML_INIT_BODY = @" + +
    +
    + +
    + + + +
    +"@ + +$body = @" + +
    +
    + +
    + + + +
    +"@ + +function main { + $json_data = Get-Content $JSON_PATH -Raw | ConvertFrom-Json + $html = $HTML_HEADER + $html += $HTML_INIT_BODY + $html += parse_json $json_data + $html += $HTML_END + + $html | Out-File $HTML_PATH +} + +try { + $JSON_PATH = $(Read-Host "JSON Path") + $HTML_PATH = $(Read-Host "HTML Path") +} +catch { + Write-Host "Error: Please pass the peas.out file and the path to save the html`npeas2html.ps1 " + exit +} + +main \ No newline at end of file From c131c20a43c2ae69ff28861e53097e41071d4bf4 Mon Sep 17 00:00:00 2001 From: Aidan Feess <145503050+AidanFeess@users.noreply.github.com> Date: Thu, 14 Dec 2023 14:41:14 -0600 Subject: [PATCH 3/5] fix typo --- parsers/json2html.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parsers/json2html.ps1 b/parsers/json2html.ps1 index b22e07dbd..fb3bf1c5b 100644 --- a/parsers/json2html.ps1 +++ b/parsers/json2html.ps1 @@ -391,8 +391,8 @@ try { $HTML_PATH = $(Read-Host "HTML Path") } catch { - Write-Host "Error: Please pass the peas.out file and the path to save the html`npeas2html.ps1 " + Write-Host "Error: Please pass the peas.out file and the path to save the html`njson2html.ps1 " exit } -main \ No newline at end of file +main From 61a4f91baa85a00cbba767c70cf47af36d9df2f4 Mon Sep 17 00:00:00 2001 From: Aidan Feess <145503050+AidanFeess@users.noreply.github.com> Date: Thu, 14 Dec 2023 14:45:01 -0600 Subject: [PATCH 4/5] remove irrelevant error message text --- parsers/json2html.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsers/json2html.ps1 b/parsers/json2html.ps1 index fb3bf1c5b..c50e66058 100644 --- a/parsers/json2html.ps1 +++ b/parsers/json2html.ps1 @@ -391,7 +391,7 @@ try { $HTML_PATH = $(Read-Host "HTML Path") } catch { - Write-Host "Error: Please pass the peas.out file and the path to save the html`njson2html.ps1 " + Write-Host "Error: Please pass the peas.out file and the path to save the html" exit } From ad357d538a59f5c05ef313e8d30eac0820435a66 Mon Sep 17 00:00:00 2001 From: Aidan Feess <145503050+AidanFeess@users.noreply.github.com> Date: Thu, 14 Dec 2023 14:46:00 -0600 Subject: [PATCH 5/5] remove irrelevant error message text --- parsers/peas2json.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parsers/peas2json.ps1 b/parsers/peas2json.ps1 index ffa1217d2..c758cafae 100644 --- a/parsers/peas2json.ps1 +++ b/parsers/peas2json.ps1 @@ -198,8 +198,8 @@ try { $JSON_PATH = $(Read-Host "JSON Path") } catch { - Write-Host "Error: Please pass the peas.out file and the path to save the json`npeas2json.ps1 " + Write-Host "Error: Please pass the peas.out file and the path to save the json" exit } -main \ No newline at end of file +main