forked from peass-ng/PEASS-ng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
peas2json.py
executable file
·168 lines (125 loc) · 5.07 KB
/
peas2json.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/env python3
import sys
import re
import json
# Pattern to identify main section titles
TITLE1_PATTERN = r"══════════════╣" # The size of the first pattern varies, but at least should be that large
TITLE2_PATTERN = r"╔══════════╣"
TITLE3_PATTERN = r"══╣"
INFO_PATTERN = r"╚ "
TITLE_CHARS = ['═', '╔', '╣', '╚']
# Patterns for colors
## 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)
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'],
}
# Final JSON structure
FINAL_JSON = {}
#Constructing the structure
C_SECTION = FINAL_JSON
C_MAIN_SECTION = FINAL_JSON
C_2_SECTION = FINAL_JSON
C_3_SECTION = FINAL_JSON
def is_section(line: str, pattern: str) -> bool:
"""Returns a boolean
Checks if line matches the pattern and returns True or False
"""
return line.find(pattern) > -1
def get_colors(line: str) -> dict:
"""Given a line return the colored strings"""
colors = {}
for c,regexs in COLORS.items():
colors[c] = []
for reg in regexs:
split_color = line.split(reg)
# Start from the index 1 as the index 0 isn't colored
if split_color and len(split_color) > 1:
split_color = split_color[1:]
# For each potential color, find the string before any possible color terminatio
for potential_color_str in split_color:
color_str1 = potential_color_str.split('\x1b')[0]
color_str2 = potential_color_str.split("\[0")[0]
color_str = color_str1 if len(color_str1) < len(color_str2) else color_str2
if color_str:
color_str = clean_colors(color_str.strip())
#Avoid having the same color for the same string
if color_str and not any(color_str in values for values in colors.values()):
colors[c].append(color_str)
if not colors[c]:
del colors[c]
return colors
def clean_title(line: str) -> str:
"""Given a title clean it"""
for c in TITLE_CHARS:
line = line.replace(c,"")
line = line.encode("ascii", "ignore").decode() #Remove non ascii chars
line = line.strip()
return line
def clean_colors(line: str) -> str:
"""Given a line clean the colors inside of it"""
for reg in re.findall(r'\x1b\[[^a-zA-Z]+\dm', line):
line = line.replace(reg,"")
line = line.replace('\x1b',"").replace("[0m", "").replace("[3m", "") #Sometimes that byte stays
line = line.strip()
return line
def parse_title(line: str) -> str:
""" Given a title, clean it"""
return clean_colors(clean_title(line))
def parse_line(line: str):
"""Parse the given line adding it to the FINAL_JSON structure"""
global FINAL_JSON, C_SECTION, C_MAIN_SECTION, C_2_SECTION, C_3_SECTION
if "Cron jobs" in line:
a=1
if is_section(line, TITLE1_PATTERN):
title = parse_title(line)
FINAL_JSON[title] = { "sections": {}, "lines": [], "infos": [] }
C_MAIN_SECTION = FINAL_JSON[title]
C_SECTION = C_MAIN_SECTION
elif is_section(line, TITLE2_PATTERN):
title = parse_title(line)
C_MAIN_SECTION["sections"][title] = { "sections": {}, "lines": [], "infos": [] }
C_2_SECTION = C_MAIN_SECTION["sections"][title]
C_SECTION = C_2_SECTION
elif is_section(line, TITLE3_PATTERN):
title = parse_title(line)
C_2_SECTION["sections"][title] = { "sections": {}, "lines": [], "infos": [] }
C_3_SECTION = C_2_SECTION["sections"][title]
C_SECTION = C_3_SECTION
elif is_section(line, INFO_PATTERN):
title = parse_title(line)
C_SECTION["infos"].append(title)
#If here, then it's text
else:
#If no main section parsed yet, pass
if C_SECTION == {}:
return
C_SECTION["lines"].append({
"raw_text": line,
"colors": get_colors(line),
"clean_text": clean_title(clean_colors(line))
})
def main():
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
parse_line(line)
with open(JSON_PATH, "w") as f:
json.dump(FINAL_JSON, f)
# Start execution
if __name__ == "__main__":
try:
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\npeas2json.py <output_file> <json_file.json>")
sys.exit(1)
main()