mirror of
https://github.com/peass-ng/PEASS-ng.git
synced 2025-12-12 15:49:51 -08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a89f235c43 | ||
|
|
7f0bbdbaae | ||
|
|
4206e78080 | ||
|
|
dc7c9db7dd | ||
|
|
48ff8b061b | ||
|
|
ea09bd5f3a | ||
|
|
68f1cf35b5 | ||
|
|
33f4ca923c | ||
|
|
b3c12e22b6 | ||
|
|
ff39a57b49 | ||
|
|
6ce34b2d61 |
@@ -21,6 +21,9 @@ These tools search for possible **local privilege escalation paths** that you co
|
||||
## Quick Start
|
||||
Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
|
||||
|
||||
## JSON, HTML & PDF output
|
||||
Check the **[parsers](./parsers/)** directory to **transform PEASS outputs to JSON, HTML and PDF**
|
||||
|
||||
## Let's improve PEASS together
|
||||
|
||||
If you want to **add something** and have **any cool idea** related to this project, please let me know it in the **telegram group https://t.me/peass** or contribute reading the **[CONTRIBUTING.md](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/CONTRIBUTING.md)** file.
|
||||
|
||||
@@ -551,6 +551,21 @@ search:
|
||||
search_in:
|
||||
- common
|
||||
|
||||
- name: Rocketchat
|
||||
value:
|
||||
config:
|
||||
auto_check: True
|
||||
|
||||
files:
|
||||
- name: "rocketchat.service"
|
||||
value:
|
||||
bad_regex: "mongodb://.*"
|
||||
line_grep: '-i "Environment"'
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
- /lib
|
||||
- /systemd
|
||||
|
||||
- name: Supervisord
|
||||
value:
|
||||
|
||||
@@ -24,12 +24,14 @@ echo ""
|
||||
#-- SY) CVE-2021-4034
|
||||
if [ `command -v pkexec` ] && stat -c '%a' $(which pkexec) | grep -q 4755 && [ "$(stat -c '%Y' $(which pkexec))" -lt "1642035600" ]; then
|
||||
echo "Vulnerable to CVE-2021-4034" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) CVE-2021-3560
|
||||
polkitVersion=$(systemctl status polkit.service | grep version | cut -d " " -f 9)
|
||||
if [[ "$(apt list --installed 2>/dev/null | grep polkit | grep -c 0.105-26)" -ge 1 || "$(yum list installed | grep polkit | grep -c 0.117-2)" ]]; then
|
||||
if [[ "$(apt list --installed 2>/dev/null | grep polkit | grep -c 0.105-26)" -ge 1 || "$(rpm -qa | grep polkit | grep -c '0.117-2\|0.115-6')" -ge 1 ]]; then
|
||||
echo "Vulnerable to CVE-2021-3560" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#--SY) USBCreator
|
||||
|
||||
@@ -220,7 +220,7 @@ print_support () {
|
||||
|---------------------------------------------------------------------------|
|
||||
| ${YELLOW}Become a Patreon${GREEN} : ${RED}https://www.patreon.com/peass${GREEN} |
|
||||
| ${YELLOW}Follow on Twitter${GREEN} : ${RED}@carlospolopm${GREEN} |
|
||||
| ${YELLOW}Respect on HTB${GREEN} : ${RED}SirBroccoli & makikvues${GREEN} |
|
||||
| ${YELLOW}Respect on HTB${GREEN} : ${RED}SirBroccoli ${GREEN} |
|
||||
|---------------------------------------------------------------------------|
|
||||
| ${BLUE}Thank you! ${GREEN} |
|
||||
\---------------------------------------------------------------------------/
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# Privilege Escalation Awesome Scripts JSON exporter
|
||||
# Privilege Escalation Awesome Scripts Parsers
|
||||
|
||||
This script allows you to transform the output of linpeas/macpeas/winpeas to JSON.
|
||||
These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML.
|
||||
|
||||
```python3
|
||||
python3 peass-parser.py </path/to/executed_peass> </path/to/output_peass.json>
|
||||
python3 peass2json.py </path/to/executed_peass.out> </path/to/peass.json>
|
||||
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
|
||||
python3 json2html.py </path/to/peass.json> </path/to/peass.html>
|
||||
```
|
||||
|
||||
This script is still in beta version and has been tested only with linpeas output.
|
||||
|
||||
## Format
|
||||
## JSON Format
|
||||
Basically, **each section has**:
|
||||
- Infos (URLs or info about the section)
|
||||
- Text lines (the real text info found in the section, colors included)
|
||||
@@ -75,4 +76,4 @@ There can also be a `<Third level Section Name>`
|
||||
|
||||
# TODO:
|
||||
|
||||
I'm looking for **someone that could create HTML and PDF reports** from this JSON.
|
||||
- **PRs improving the code and the aspect of the final PDFs and HTMLs are always welcome!**
|
||||
347
parsers/json2html.py
Normal file
347
parsers/json2html.py
Normal file
File diff suppressed because one or more lines are too long
162
parsers/json2pdf.py
Executable file
162
parsers/json2pdf.py
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import json
|
||||
import html
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.platypus import Frame, Paragraph, Spacer, PageBreak,PageTemplate, BaseDocTemplate
|
||||
from reportlab.platypus.tableofcontents import TableOfContents
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
from reportlab.lib.units import cm
|
||||
|
||||
styles = getSampleStyleSheet()
|
||||
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
|
||||
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
|
||||
|
||||
# Required to automatically set Page Numbers
|
||||
class PageTemplateWithCount(PageTemplate):
|
||||
def __init__(self, id, frames, **kw):
|
||||
PageTemplate.__init__(self, id, frames, **kw)
|
||||
|
||||
def beforeDrawPage(self, canvas, doc):
|
||||
page_num = canvas.getPageNumber()
|
||||
canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
|
||||
|
||||
# Required to automatically set the Table of Contents
|
||||
class MyDocTemplate(BaseDocTemplate):
|
||||
def __init__(self, filename, **kw):
|
||||
self.allowSplitting = 0
|
||||
BaseDocTemplate.__init__(self, filename, **kw)
|
||||
template = PageTemplateWithCount("normal", [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')])
|
||||
self.addPageTemplates(template)
|
||||
|
||||
def afterFlowable(self, flowable):
|
||||
if flowable.__class__.__name__ == "Paragraph":
|
||||
text = flowable.getPlainText()
|
||||
style = flowable.style.name
|
||||
if style == "Heading1":
|
||||
self.notify("TOCEntry", (0, text, self.page))
|
||||
if style == "Heading2":
|
||||
self.notify("TOCEntry", (1, text, self.page))
|
||||
if style == "Heading3":
|
||||
self.notify("TOCEntry", (2, text, self.page))
|
||||
|
||||
|
||||
# Poor take at dynamicly generating styles depending on depth(?)
|
||||
def get_level_styles(level):
|
||||
global styles
|
||||
indent_value = 10 * (level - 1);
|
||||
# Overriding some default stylings
|
||||
level_styles = {
|
||||
"title": ParagraphStyle(
|
||||
**dict(styles[f"Heading{level}"].__dict__,
|
||||
**{ "leftIndent": indent_value })),
|
||||
"text": ParagraphStyle(
|
||||
**dict(styles["Code"].__dict__,
|
||||
**{ "backColor": "#F0F0F0",
|
||||
"borderPadding": 5, "borderWidth": 1,
|
||||
"borderColor": "black", "borderRadius": 5,
|
||||
"leftIndent": 5 + indent_value})),
|
||||
"info": ParagraphStyle(
|
||||
**dict(styles["Italic"].__dict__,
|
||||
**{ "leftIndent": indent_value })),
|
||||
}
|
||||
return level_styles
|
||||
|
||||
def get_colors_by_text(colors):
|
||||
new_colors = {}
|
||||
for (color, words) in colors.items():
|
||||
for word in words:
|
||||
new_colors[html.escape(word)] = color
|
||||
return new_colors
|
||||
|
||||
def build_main_section(section, title, level=1):
|
||||
styles = get_level_styles(level)
|
||||
has_links = "infos" in section.keys() and len(section["infos"]) > 0
|
||||
has_lines = "lines" in section.keys() and len(section["lines"]) > 1
|
||||
has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0
|
||||
|
||||
# Only display data for Sections with results
|
||||
show_section = has_lines or has_children
|
||||
|
||||
elements = []
|
||||
|
||||
if show_section:
|
||||
elements.append(Paragraph(title, style=styles["title"]))
|
||||
|
||||
# Print info if any
|
||||
if show_section and has_links:
|
||||
for info in section["infos"]:
|
||||
words = info.split()
|
||||
# Join all lines and encode any links that might be present.
|
||||
words = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words)
|
||||
words = " ".join(words)
|
||||
elements.append(Paragraph(words, style=styles["info"] ))
|
||||
|
||||
# Print lines if any
|
||||
if "lines" in section.keys() and len(section["lines"]) > 1:
|
||||
colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
|
||||
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
|
||||
for (idx, line) in enumerate(lines):
|
||||
colors = colors_by_line[idx]
|
||||
colored_text = get_colors_by_text(colors)
|
||||
colored_line = line
|
||||
for (text, color) in colored_text.items():
|
||||
if color == "REDYELLOW":
|
||||
colored_line = colored_line.replace(text, f'<font color="{text_colors[color]}"><b>{text}</b></font>')
|
||||
else:
|
||||
colored_line = colored_line.replace(text, f'<font color="{text_colors[color]}">{text}</font>')
|
||||
lines[idx] = colored_line
|
||||
elements.append(Spacer(0, 10))
|
||||
line = "<br/>".join(lines)
|
||||
|
||||
# If it's a top level entry remove the line break caused by an empty "clean_text"
|
||||
if level == 1: line = line[5:]
|
||||
elements.append(Paragraph(line, style=styles["text"]))
|
||||
|
||||
|
||||
# Print child sections
|
||||
if has_children:
|
||||
for child_title in section["sections"].keys():
|
||||
element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
|
||||
elements.extend(element_list)
|
||||
|
||||
# Add spacing at the end of section. The deeper the level the smaller the spacing.
|
||||
if show_section:
|
||||
elements.append(Spacer(1, 40 - (10 * level)))
|
||||
|
||||
return elements
|
||||
|
||||
|
||||
def main():
|
||||
with open(JSON_PATH) as file:
|
||||
# Read and parse JSON file
|
||||
data = json.loads(file.read())
|
||||
|
||||
# Default pdf values
|
||||
doc = MyDocTemplate(PDF_PATH)
|
||||
toc = TableOfContents()
|
||||
toc.levelStyles = [
|
||||
ParagraphStyle(name = "Heading1", fontSize = 14, leading=16),
|
||||
ParagraphStyle(name = "Heading2", fontSize = 12, leading=14, leftIndent = 10),
|
||||
ParagraphStyle(name = "Heading3", fontSize = 10, leading=12, leftIndent = 20),
|
||||
]
|
||||
|
||||
elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()]
|
||||
|
||||
# Iterate over all top level sections and build their elements.
|
||||
for title in data.keys():
|
||||
element_list = build_main_section(data[title], title)
|
||||
elements.extend(element_list)
|
||||
|
||||
doc.multiBuild(elements)
|
||||
|
||||
# Start execution
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
JSON_PATH = sys.argv[1]
|
||||
PDF_PATH = sys.argv[2]
|
||||
except IndexError as err:
|
||||
print("Error: Please pass the peas.json file and the path to save the pdf\njson2pdf.py <json_file> <pdf_file.pdf>")
|
||||
sys.exit(1)
|
||||
|
||||
main()
|
||||
@@ -90,7 +90,7 @@ def clean_colors(line: str) -> str:
|
||||
for reg in re.findall(r'\x1b\[[^a-zA-Z]+\dm', line):
|
||||
line = line.replace(reg,"")
|
||||
|
||||
line = line.replace('\x1b',"").replace("[0m", "") #Sometimes that byte stays
|
||||
line = line.replace('\x1b',"").replace("[0m", "").replace("[3m", "") #Sometimes that byte stays
|
||||
line = line.strip()
|
||||
return line
|
||||
|
||||
@@ -145,7 +145,7 @@ def parse_line(line: str):
|
||||
|
||||
|
||||
def main():
|
||||
for line in open(OUTPUT_PATH, 'r').readlines():
|
||||
for line in open(OUTPUT_PATH, 'r', encoding="utf8").readlines():
|
||||
line = line.strip()
|
||||
if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex
|
||||
continue
|
||||
@@ -162,7 +162,7 @@ if __name__ == "__main__":
|
||||
OUTPUT_PATH = sys.argv[1]
|
||||
JSON_PATH = sys.argv[2]
|
||||
except IndexError as err:
|
||||
print("Error: Please pass the peas.out file and the path to save the json\n./peas-parser.py <output_file> <json_file.json>")
|
||||
print("Error: Please pass the peas.out file and the path to save the json\npeas2json.py <output_file> <json_file.json>")
|
||||
sys.exit(1)
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user