more
This commit is contained in:
parent
5958199a63
commit
1c32c04879
@ -69,7 +69,7 @@ peas_storages_markup: "peass{STORAGES_HERE}"
|
||||
storage_line_markup: "peass{STORAGE_PARAMS_HERE}"
|
||||
storage_line_extra_markup: "peass{STORAGE_PARAMS_EXTRA_HERE}"
|
||||
storage_template: >
|
||||
$(echo "peass{STORAGE_PARAMS_HERE}" peass{STORAGE_PARAMS_EXTRA_HERE} | sort | uniq | head -n 100)
|
||||
$(echo -e "peass{STORAGE_PARAMS_HERE}" peass{STORAGE_PARAMS_EXTRA_HERE} | sort | uniq | head -n 70)
|
||||
|
||||
int_hidden_files_markup: "peass{INT_HIDDEN_FILES}"
|
||||
|
||||
@ -82,7 +82,7 @@ defaults:
|
||||
just_list_file: False #Just mention the path to the file, do not cat it
|
||||
line_grep: "" #The regex to grep lines in a file (if only_bad_lines), by default bad_regex is used here if empty
|
||||
only_bad_lines: False #Only print lines containing something red
|
||||
remove_empty_lines: False #Remove empty lines
|
||||
remove_empty_lines: False #Remove empty lines, use only for text files (-I param in grep)
|
||||
remove_path: "" #Not interested in files containing this path
|
||||
remove_regex: "" #Extra regex to remove some lines
|
||||
search_in: #By default search in defined common
|
||||
@ -160,13 +160,13 @@ search:
|
||||
config:
|
||||
auto_check: True
|
||||
exec:
|
||||
- "echo Version: $(warn_exec psql -V 2>/dev/null)"
|
||||
- 'echo "Version: $(warn_exec psql -V 2>/dev/null)"'
|
||||
|
||||
files:
|
||||
? "pgadmin*.db"
|
||||
:
|
||||
type: f
|
||||
bad_regex: ".*"
|
||||
just_list_file: True
|
||||
search_in:
|
||||
- common
|
||||
|
||||
@ -181,13 +181,19 @@ search:
|
||||
|
||||
? "postgresql.conf"
|
||||
:
|
||||
bad_regex: "auth|password|md5|user=|pass=|trust"
|
||||
type: f
|
||||
remove_empty_lines: True
|
||||
remove_regex: '\W+\#|^#'
|
||||
search_in:
|
||||
- common
|
||||
|
||||
? "pgsql.conf"
|
||||
:
|
||||
bad_regex: "auth|password|md5|user=|pass=|trust"
|
||||
type: f
|
||||
remove_empty_lines: True
|
||||
remove_regex: '\W+\#|^#'
|
||||
search_in:
|
||||
- common
|
||||
|
||||
@ -195,7 +201,7 @@ search:
|
||||
config:
|
||||
auto_check: True
|
||||
exec:
|
||||
- "echo Version: $(warn_exec apache2 -v 2>/dev/null; warn_exec httpd -v 2>/dev/null)"
|
||||
- 'echo "Version: $(warn_exec apache2 -v 2>/dev/null; warn_exec httpd -v 2>/dev/null)"'
|
||||
- "print_3title 'PHP exec extensions'"
|
||||
- 'grep -R -B1 "httpd-php" /etc/apache2 2>/dev/null'
|
||||
|
||||
@ -320,7 +326,7 @@ search:
|
||||
? "tomcat-users.xml"
|
||||
:
|
||||
bad_regex: "dbtype|dbhost|dbuser|dbhost|dbpass|dbport"
|
||||
line_grep: "username=|password="
|
||||
line_grep: '"username=|password="'
|
||||
only_bad_lines: True
|
||||
type: f
|
||||
search_in:
|
||||
@ -330,7 +336,7 @@ search:
|
||||
config:
|
||||
auto_check: True
|
||||
exec:
|
||||
- "echo Version: $(warn_exec mongo --version 2>/dev/null; warn_exec mongod --version 2>/dev/null)"
|
||||
- 'echo "Version: $(warn_exec mongo --version 2>/dev/null; warn_exec mongod --version 2>/dev/null)"'
|
||||
|
||||
files:
|
||||
? "mongod*.conf"
|
||||
@ -430,7 +436,9 @@ search:
|
||||
|
||||
Ldap:
|
||||
config:
|
||||
auto_check: False
|
||||
auto_check: True
|
||||
exec:
|
||||
- echo "The password hash is from the {SSHA} to 'structural'"
|
||||
|
||||
files:
|
||||
? "ldap"
|
||||
@ -440,7 +448,7 @@ search:
|
||||
? "*.bdb"
|
||||
:
|
||||
bad_regex: "administrator|password|ADMINISTRATOR|PASSWORD|Password|Administrator"
|
||||
line_grep: '-i -a -E -o "description.*"'
|
||||
line_grep: '-i -a -o "description.*" | sort | uniq'
|
||||
type: d
|
||||
search_in:
|
||||
- common
|
||||
@ -576,6 +584,7 @@ search:
|
||||
? "*ssh*config*"
|
||||
:
|
||||
type: f
|
||||
remove_path: '\..{1,4}$' #No interested in filenames with extensions
|
||||
search_in:
|
||||
- /usr
|
||||
- $HOMESEARCH
|
||||
@ -583,6 +592,7 @@ search:
|
||||
? "*config*ssh*"
|
||||
:
|
||||
type: f
|
||||
remove_path: '\..{1,4}$' #No interested in filenames with extensions
|
||||
search_in:
|
||||
- /usr
|
||||
- $HOMESEARCH
|
||||
@ -711,12 +721,12 @@ search:
|
||||
config:
|
||||
auto_check: True
|
||||
exec:
|
||||
- echo "Version: $(curl -X GET '127.0.0.1:9200' 2>/dev/null | grep number | cut -d ':' -f 2)"
|
||||
- echo "The version is $(curl -X GET '127.0.0.1:9200' 2>/dev/null | grep number | cut -d ':' -f 2)"
|
||||
|
||||
files:
|
||||
? "elasticsearch.y*ml"
|
||||
:
|
||||
line_grep: "path.data|path.logs|cluster.name|node.name|network.host|discovery.zen.ping.unicast.hosts"
|
||||
line_grep: '"path.data|path.logs|cluster.name|node.name|network.host|discovery.zen.ping.unicast.hosts"'
|
||||
remove_regex: '\W+\#|^#'
|
||||
type: f
|
||||
search_in:
|
||||
@ -936,7 +946,8 @@ search:
|
||||
:
|
||||
|
||||
bad_regex: "password|pass|user|database|host"
|
||||
only_bad_lines: True
|
||||
line_grep: >-
|
||||
"'pass'|'password'|'user'|'database'|'host'"
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
@ -944,6 +955,8 @@ search:
|
||||
? "database.php"
|
||||
:
|
||||
bad_regex: "password|pass|user|database|host"
|
||||
line_grep: >-
|
||||
"'pass'|'password'|'user'|'database'|'host'"
|
||||
only_bad_lines: True
|
||||
type: f
|
||||
search_in:
|
||||
@ -1353,13 +1366,6 @@ search:
|
||||
auto_check: True
|
||||
|
||||
files:
|
||||
? ".git"
|
||||
:
|
||||
just_list_file: True
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
? ".github"
|
||||
:
|
||||
just_list_file: True
|
||||
@ -1381,6 +1387,13 @@ search:
|
||||
search_in:
|
||||
- common
|
||||
|
||||
? ".git"
|
||||
:
|
||||
just_list_file: True
|
||||
type: f
|
||||
search_in:
|
||||
- common
|
||||
|
||||
Svn:
|
||||
config:
|
||||
auto_check: True
|
||||
|
File diff suppressed because one or more lines are too long
@ -4,10 +4,10 @@ import re
|
||||
|
||||
|
||||
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
LINPEAS_BASE_PATH = CURRENT_DIR + "/base/" + "linpeas_base.sh"
|
||||
FINAL_LINPEAS_PATH = CURRENT_DIR + "/" + "linpeas.sh"
|
||||
LINPEAS_BASE_PATH = CURRENT_DIR + "/linpeas_base.sh"
|
||||
FINAL_LINPEAS_PATH = CURRENT_DIR + "/../" + "linpeas.sh"
|
||||
YAML_NAME = "sensitive_files.yaml"
|
||||
FILES_YAML = CURRENT_DIR + "/../build_lists/" + YAML_NAME
|
||||
FILES_YAML = CURRENT_DIR + "/../../build_lists/" + YAML_NAME
|
||||
|
||||
with open(FILES_YAML, 'r') as file:
|
||||
YAML_LOADED = yaml.load(file, Loader=yaml.FullLoader)
|
||||
@ -141,8 +141,29 @@ class LinpeasBuilder:
|
||||
#Replace interesting hidden files markup for a list of all the serched hidden files
|
||||
self.__replace_mark(INT_HIDDEN_FILES_MARKUP, self.hidden_files, "|")
|
||||
|
||||
#Check if there are duplecate peass marks
|
||||
peass_marks = self.__get_peass_marks()
|
||||
for i,mark in enumerate(peass_marks):
|
||||
for j in range(i+1,len(peass_marks)):
|
||||
assert mark != peass_marks[j], f"Found repeated peass mark: {mark}"
|
||||
|
||||
#Generate autocheck sections
|
||||
sections = self.__generate_sections()
|
||||
for section_name, bash_lines in sections.items():
|
||||
mark = "peass{"+section_name+"}"
|
||||
assert mark in peass_marks, f"Mark {mark} wasn't found in linpeas base"
|
||||
self.__replace_mark(mark, list(bash_lines), "")
|
||||
|
||||
#Check that there aren peass marks left in linpeas
|
||||
peass_marks = self.__get_peass_marks()
|
||||
assert len(peass_marks) == 0, f"There are peass marks left: {', '.join(peass_marks)}"
|
||||
|
||||
self.__write_linpeas()
|
||||
|
||||
|
||||
def __get_peass_marks(self):
|
||||
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
|
||||
|
||||
|
||||
def __get_files_to_search(self):
|
||||
"""Given a PEASLoaded and find the files that need to be searched on each root folder"""
|
||||
@ -205,18 +226,21 @@ class LinpeasBuilder:
|
||||
bsp = '\\.' #A 'f' expression cannot contain a backslash, so we generate here the bs need in the line below
|
||||
grep_names = f" | grep -E \"{'|'.join([frecord.regex.replace('.',bsp).replace('*', '.*')+'$' for frecord in precord.filerecords])}\""
|
||||
|
||||
#Grep by searched folders
|
||||
grep_folders_searched = f" | grep -E \"^{'|^'.join(list(set([d for frecord in precord.filerecords for d in frecord.search_in])))}\"".replace("HOMESEARCH","GREPHOMESEARCH")
|
||||
|
||||
#Grep extra paths. They are accumulative between files of the same PEASRecord
|
||||
grep_extra_paths = ""
|
||||
if any(True for frecord in precord.filerecords if frecord.check_extra_path):
|
||||
grep_extra_paths = f" | grep -E '{'|'.join([frecord.check_extra_path for frecord in precord.filerecords if frecord.check_extra_path])}'"
|
||||
grep_extra_paths = f" | grep -E '{'|'.join(list(set([frecord.check_extra_path for frecord in precord.filerecords if frecord.check_extra_path])))}'"
|
||||
|
||||
#Grep to remove paths. They are accumulative between files of the same PEASRecord
|
||||
grep_remove_path = ""
|
||||
if any(True for frecord in precord.filerecords if frecord.remove_path):
|
||||
grep_remove_path = f" | grep -v -E '{'|'.join([frecord.remove_path for frecord in precord.filerecords if frecord.remove_path])}'"
|
||||
grep_remove_path = f" | grep -v -E '{'|'.join(list(set([frecord.remove_path for frecord in precord.filerecords if frecord.remove_path])))}'"
|
||||
|
||||
#Construct the final line like: STORAGE_MYSQL=$(echo "$FIND_DIR_ETC\n$FIND_DIR_USR\n$FIND_DIR_VAR\n$FIND_DIR_MNT" | grep -E '^/etc/.*mysql|/usr/var/lib/.*mysql|/var/lib/.*mysql' | grep -v "mysql/mysql")
|
||||
storage_line = storage_line.replace(STORAGE_LINE_EXTRA_MARKUP, f"{grep_remove_path}{grep_extra_paths}{grep_names}")
|
||||
storage_line = storage_line.replace(STORAGE_LINE_EXTRA_MARKUP, f"{grep_remove_path}{grep_extra_paths}{grep_folders_searched}{grep_names}")
|
||||
storage_line = f"{bash_storage_var}={storage_line}"
|
||||
storages.append(storage_line)
|
||||
|
||||
@ -224,10 +248,84 @@ class LinpeasBuilder:
|
||||
|
||||
|
||||
|
||||
def __generate_sections(self):
|
||||
"""Generate auto_check sections"""
|
||||
pass
|
||||
def __generate_sections(self) -> dict:
|
||||
"""Generate sections for records with auto_check to True"""
|
||||
sections = {}
|
||||
|
||||
for precord in self.ploaded.peasrecords:
|
||||
if precord.auto_check:
|
||||
section = f' print_2title "Analizing {precord.name} Files (limit 70)"\n'
|
||||
|
||||
for exec_line in precord.exec:
|
||||
if exec_line:
|
||||
section += " " + exec_line + "\n"
|
||||
|
||||
for frecord in precord.filerecords:
|
||||
section += " " + self.__construct_file_line(precord, frecord) + "\n"
|
||||
|
||||
sections[precord.name] = section
|
||||
|
||||
return sections
|
||||
|
||||
def __construct_file_line(self, precord: PEASRecord, frecord: FileRecord, init: bool = True) -> str:
|
||||
real_regex = frecord.regex[1:] if frecord.regex.startswith("*") else frecord.regex
|
||||
real_regex = real_regex.replace("*",".*").replace(".","\\.")
|
||||
real_regex += "$"
|
||||
|
||||
analise_line = ""
|
||||
if init:
|
||||
analise_line = 'printf "%s" "$PSTORAGE_'+precord.bash_name+'" | grep -E "'+real_regex+'" | while read f; do ls -ld "$f" | sed -${E} "s,'+real_regex+',${SED_RED},"; '
|
||||
|
||||
#If just list, just list the file/directory
|
||||
if frecord.just_list_file:
|
||||
if frecord.type == "d":
|
||||
analise_line += 'ls -lRA "$f";'
|
||||
analise_line += 'done; echo "";'
|
||||
return analise_line
|
||||
|
||||
if frecord.type == "f":
|
||||
grep_empty_lines = ' | grep -IEv "^$"'
|
||||
grep_line_grep = f' | grep -E {frecord.line_grep}' if frecord.line_grep else ""
|
||||
grep_only_bad_lines = f' | grep -E "{frecord.bad_regex}"' if frecord.bad_regex else ""
|
||||
grep_remove_regex = f' | grep -Ev "{frecord.remove_regex}"' if frecord.remove_regex else ""
|
||||
sed_bad_regex = ' | sed -${E} "s,'+frecord.bad_regex+',${SED_RED},g"' if frecord.bad_regex else ""
|
||||
sed_good_regex = ' | sed -${E} "s,'+frecord.good_regex+',${SED_GOOD},g"' if frecord.good_regex else ""
|
||||
|
||||
if init:
|
||||
analise_line += 'cat "$f" 2>/dev/null'
|
||||
else:
|
||||
analise_line += 'cat "$ff" 2>/dev/null'
|
||||
|
||||
if grep_empty_lines:
|
||||
analise_line += grep_empty_lines
|
||||
|
||||
if grep_line_grep:
|
||||
analise_line += grep_line_grep
|
||||
|
||||
if frecord.only_bad_lines and not grep_line_grep:
|
||||
analise_line += grep_only_bad_lines
|
||||
|
||||
if grep_remove_regex:
|
||||
analise_line += grep_remove_regex
|
||||
|
||||
if sed_bad_regex:
|
||||
analise_line += sed_bad_regex
|
||||
|
||||
if sed_good_regex:
|
||||
analise_line += sed_good_regex
|
||||
|
||||
analise_line += '; done; echo "";'
|
||||
return analise_line
|
||||
|
||||
#In case file is type "d"
|
||||
if frecord.files:
|
||||
for ffrecord in frecord.files:
|
||||
ff_real_regex = ffrecord.regex[1:] if ffrecord.regex.startswith("*") else ffrecord.regex
|
||||
ff_real_regex = ff_real_regex.replace("*",".*")
|
||||
analise_line += 'for ff in $(find "$f" -name "'+ffrecord.regex+'"); do ls -ld "$ff" | sed -${E} "s,'+ff_real_regex+',${SED_RED},"; ' + self.__construct_file_line(precord, ffrecord, init=False)
|
||||
|
||||
analise_line += 'done; echo "";'
|
||||
return analise_line
|
||||
|
||||
|
||||
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
|
3149
linPEAS/linpeas.sh
Normal file
3149
linPEAS/linpeas.sh
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user