Merge pull request #145 from carlospolop/linpeasdevelop
Merge branch 'linpeasdevelop' of github.com:carlospolop/privilege-escalation-awesome-scripts-suite into linpeasdevelop
This commit is contained in:
commit
da980e49e3
56
.github/workflows/linpeas-development.yml
vendored
Normal file
56
.github/workflows/linpeas-development.yml
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# This is a basic workflow to help you get started with Actions
|
||||||
|
|
||||||
|
name: CI-linpeas-ubuntu
|
||||||
|
|
||||||
|
# Controls when the action will run.
|
||||||
|
on:
|
||||||
|
# Triggers the workflow on push or pull request events but only for the master branch
|
||||||
|
push:
|
||||||
|
branches: [ linpeasdevelop ]
|
||||||
|
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
# This workflow contains a single job called "build"
|
||||||
|
build:
|
||||||
|
# The type of runner that the job will run on
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
|
steps:
|
||||||
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Build linpeas
|
||||||
|
run: |
|
||||||
|
python3 -m pip install PyYAML
|
||||||
|
cd linPEAS
|
||||||
|
python3 -m builder.linpeas_builder
|
||||||
|
|
||||||
|
# Runs a single command using the runners shell
|
||||||
|
- name: Run linpeas
|
||||||
|
run: linPEAS/linpeas.sh -h
|
||||||
|
|
||||||
|
- name: Create local changes
|
||||||
|
run: git add linPEAS/linpeas.sh
|
||||||
|
|
||||||
|
- name: Commit results to Github
|
||||||
|
run: |
|
||||||
|
git config --local user.email ""
|
||||||
|
git config --global user.name "CI-linpeas-ubuntu"
|
||||||
|
git commit -m "linpeas.sh auto update" -a --allow-empty
|
||||||
|
|
||||||
|
- name: Push changes
|
||||||
|
uses: ad-m/github-push-action@master
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
branch: ${{ github.ref }}
|
||||||
|
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: pull-request
|
||||||
|
uses: repo-sync/pull-request@v2
|
||||||
|
with:
|
||||||
|
destination_branch: "master" #Pull request to master
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
30
.github/workflows/linpeas-macos.yml
vendored
30
.github/workflows/linpeas-macos.yml
vendored
@ -1,30 +0,0 @@
|
|||||||
# This is a basic workflow to help you get started with Actions
|
|
||||||
|
|
||||||
name: CI
|
|
||||||
|
|
||||||
# Controls when the action will run.
|
|
||||||
on:
|
|
||||||
# Triggers the workflow on push or pull request events but only for the master branch
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
|
||||||
jobs:
|
|
||||||
# This workflow contains a single job called "build"
|
|
||||||
build:
|
|
||||||
# The type of runner that the job will run on
|
|
||||||
runs-on: macos-latest
|
|
||||||
|
|
||||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
|
||||||
steps:
|
|
||||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Runs a single command using the runners shell
|
|
||||||
- name: Run linpeas
|
|
||||||
run: linPEAS/linpeas.sh
|
|
@ -1,14 +1,13 @@
|
|||||||
# This is a basic workflow to help you get started with Actions
|
# This is a basic workflow to help you get started with Actions
|
||||||
|
|
||||||
name: CI
|
name: CI-Pro
|
||||||
|
|
||||||
# Controls when the action will run.
|
# Controls when the action will run.
|
||||||
on:
|
on:
|
||||||
# Triggers the workflow on push or pull request events but only for the master branch
|
# Triggers the workflow on push or pull request events but only for the master branch
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
paths:
|
||||||
|
- 'linPEAS/linpeas.sh'
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@ -16,7 +15,7 @@ on:
|
|||||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
jobs:
|
jobs:
|
||||||
# This workflow contains a single job called "build"
|
# This workflow contains a single job called "build"
|
||||||
build:
|
Run_on_ubuntu:
|
||||||
# The type of runner that the job will run on
|
# The type of runner that the job will run on
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
@ -28,3 +27,15 @@ jobs:
|
|||||||
# Runs a single command using the runners shell
|
# Runs a single command using the runners shell
|
||||||
- name: Run linpeas
|
- name: Run linpeas
|
||||||
run: linPEAS/linpeas.sh
|
run: linPEAS/linpeas.sh
|
||||||
|
|
||||||
|
Run_on_macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
|
steps:
|
||||||
|
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Runs a single command using the runners shell
|
||||||
|
- name: Run linpeas
|
||||||
|
run: linPEAS/linpeas.sh
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -12,3 +12,6 @@ winPEAS/winPEASexe/winPEAS/bin/Debug/*
|
|||||||
obj
|
obj
|
||||||
bin
|
bin
|
||||||
packages
|
packages
|
||||||
|
*cpython*
|
||||||
|
*/*cpython*
|
||||||
|
launch.json
|
2048
build_lists/sensitive_files.yaml
Normal file
2048
build_lists/sensitive_files.yaml
Normal file
File diff suppressed because it is too large
Load Diff
0
linPEAS/builder/__init__.py
Normal file
0
linPEAS/builder/__init__.py
Normal file
BIN
linPEAS/builder/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
linPEAS/builder/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
linPEAS/builder/__pycache__/linpeas_builder.cpython-39.pyc
Normal file
BIN
linPEAS/builder/__pycache__/linpeas_builder.cpython-39.pyc
Normal file
Binary file not shown.
2904
linPEAS/builder/linpeas_base.sh
Executable file
2904
linPEAS/builder/linpeas_base.sh
Executable file
File diff suppressed because one or more lines are too long
19
linPEAS/builder/linpeas_builder.py
Normal file
19
linPEAS/builder/linpeas_builder.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from .src.peasLoaded import PEASLoaded
|
||||||
|
from .src.linpeasBuilder import LinpeasBuilder
|
||||||
|
from .src.yamlGlobals import FINAL_LINPEAS_PATH
|
||||||
|
|
||||||
|
import os
|
||||||
|
import stat
|
||||||
|
|
||||||
|
#python3 -m builder.linpeas_builder
|
||||||
|
def main():
|
||||||
|
ploaded = PEASLoaded()
|
||||||
|
lbuilder = LinpeasBuilder(ploaded)
|
||||||
|
lbuilder.build()
|
||||||
|
lbuilder.write_linpeas(FINAL_LINPEAS_PATH)
|
||||||
|
st = os.stat(FINAL_LINPEAS_PATH)
|
||||||
|
os.chmod(FINAL_LINPEAS_PATH, st.st_mode | stat.S_IEXEC)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
BIN
linPEAS/builder/src/__pycache__/fileRecord.cpython-39.pyc
Normal file
BIN
linPEAS/builder/src/__pycache__/fileRecord.cpython-39.pyc
Normal file
Binary file not shown.
BIN
linPEAS/builder/src/__pycache__/linpeasBuilder.cpython-39.pyc
Normal file
BIN
linPEAS/builder/src/__pycache__/linpeasBuilder.cpython-39.pyc
Normal file
Binary file not shown.
BIN
linPEAS/builder/src/__pycache__/peasLoaded.cpython-39.pyc
Normal file
BIN
linPEAS/builder/src/__pycache__/peasLoaded.cpython-39.pyc
Normal file
Binary file not shown.
BIN
linPEAS/builder/src/__pycache__/peassRecord.cpython-39.pyc
Normal file
BIN
linPEAS/builder/src/__pycache__/peassRecord.cpython-39.pyc
Normal file
Binary file not shown.
BIN
linPEAS/builder/src/__pycache__/yamlGlobals.cpython-39.pyc
Normal file
BIN
linPEAS/builder/src/__pycache__/yamlGlobals.cpython-39.pyc
Normal file
Binary file not shown.
51
linPEAS/builder/src/fileRecord.py
Normal file
51
linPEAS/builder/src/fileRecord.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
from .yamlGlobals import DEFAULTS, ROOT_FOLDER, COMMON_DIR_FOLDERS, COMMON_FILE_FOLDERS
|
||||||
|
|
||||||
|
class FileRecord:
|
||||||
|
def __init__(self,
|
||||||
|
regex: str,
|
||||||
|
bad_regex: str=DEFAULTS["bad_regex"],
|
||||||
|
check_extra_path: str =DEFAULTS["check_extra_path"],
|
||||||
|
files: dict={},
|
||||||
|
good_regex: str=DEFAULTS["good_regex"],
|
||||||
|
just_list_file: bool=DEFAULTS["just_list_file"],
|
||||||
|
line_grep: str=DEFAULTS["line_grep"],
|
||||||
|
only_bad_lines: bool=DEFAULTS["only_bad_lines"],
|
||||||
|
remove_empty_lines: bool=DEFAULTS["remove_empty_lines"],
|
||||||
|
remove_path: str=DEFAULTS["remove_path"],
|
||||||
|
remove_regex: str=DEFAULTS["remove_regex"],
|
||||||
|
search_in: list=DEFAULTS["search_in"],
|
||||||
|
type: str=DEFAULTS["type"],
|
||||||
|
):
|
||||||
|
|
||||||
|
self.regex = regex
|
||||||
|
self.bad_regex = bad_regex
|
||||||
|
self.check_extra_path = check_extra_path
|
||||||
|
self.files = [FileRecord(regex=regex,**fr) for regex,fr in files.items()]
|
||||||
|
self.good_regex = good_regex
|
||||||
|
self.just_list_file = just_list_file
|
||||||
|
self.line_grep = line_grep
|
||||||
|
self.only_bad_lines = only_bad_lines
|
||||||
|
self.remove_regex = remove_regex
|
||||||
|
self.remove_empty_lines = remove_empty_lines
|
||||||
|
self.remove_path = remove_path
|
||||||
|
self.type = type
|
||||||
|
self.search_in = self.__resolve_search_in(search_in)
|
||||||
|
|
||||||
|
def __resolve_search_in(self, search_in):
|
||||||
|
""" Resolve spacial values to the correct directories """
|
||||||
|
|
||||||
|
if "all" in search_in:
|
||||||
|
search_in.remove("all")
|
||||||
|
search_in = ROOT_FOLDER
|
||||||
|
|
||||||
|
if "common" in search_in:
|
||||||
|
search_in.remove("common")
|
||||||
|
if self.type == "d":
|
||||||
|
search_in = list(set(search_in + COMMON_DIR_FOLDERS))
|
||||||
|
else:
|
||||||
|
search_in = list(set(search_in + COMMON_FILE_FOLDERS))
|
||||||
|
|
||||||
|
#Check that folders to search in are specified in ROOT_FOLDER
|
||||||
|
assert all(r in ROOT_FOLDER for r in search_in)
|
||||||
|
|
||||||
|
return search_in
|
238
linPEAS/builder/src/linpeasBuilder.py
Normal file
238
linPEAS/builder/src/linpeasBuilder.py
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from .peasLoaded import PEASLoaded
|
||||||
|
from .peassRecord import PEASRecord
|
||||||
|
from .fileRecord import FileRecord
|
||||||
|
from .yamlGlobals import (
|
||||||
|
LINPEAS_BASE_PATH,
|
||||||
|
PEAS_FINDS_MARKUP,
|
||||||
|
PEAS_STORAGES_MARKUP,
|
||||||
|
PEAS_STORAGES_MARKUP,
|
||||||
|
INT_HIDDEN_FILES_MARKUP,
|
||||||
|
ROOT_FOLDER,
|
||||||
|
STORAGE_TEMPLATE,
|
||||||
|
FIND_TEMPLATE,
|
||||||
|
FIND_LINE_MARKUP,
|
||||||
|
STORAGE_LINE_MARKUP,
|
||||||
|
STORAGE_LINE_EXTRA_MARKUP,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class LinpeasBuilder:
|
||||||
|
def __init__(self, ploaded:PEASLoaded):
|
||||||
|
self.ploaded = ploaded
|
||||||
|
self.hidden_files = set()
|
||||||
|
self.bash_find_f_vars, self.bash_find_d_vars = set(), set()
|
||||||
|
self.bash_storages = set()
|
||||||
|
self.__get_files_to_search()
|
||||||
|
with open(LINPEAS_BASE_PATH, 'r') as file:
|
||||||
|
self.linpeas_sh = file.read()
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
find_calls = self.__generate_finds()
|
||||||
|
self.__replace_mark(PEAS_FINDS_MARKUP, find_calls, " ")
|
||||||
|
|
||||||
|
storage_vars = self.__generate_storages()
|
||||||
|
self.__replace_mark(PEAS_STORAGES_MARKUP, storage_vars, " ")
|
||||||
|
|
||||||
|
#Check all the expected STORAGES in linpeas have been created
|
||||||
|
for s in re.findall(r'PSTORAGE_[\w]*', self.linpeas_sh):
|
||||||
|
assert s in self.bash_storages, f"{s} isn't created"
|
||||||
|
|
||||||
|
#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)}"
|
||||||
|
|
||||||
|
|
||||||
|
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"""
|
||||||
|
self.dict_to_search = {"d": {}, "f": {}}
|
||||||
|
self.dict_to_search["d"] = {r: set() for r in ROOT_FOLDER}
|
||||||
|
self.dict_to_search["f"] = {r: set() for r in ROOT_FOLDER}
|
||||||
|
|
||||||
|
for precord in self.ploaded.peasrecords:
|
||||||
|
for frecord in precord.filerecords:
|
||||||
|
for folder in frecord.search_in:
|
||||||
|
self.dict_to_search[frecord.type][folder].add(frecord.regex)
|
||||||
|
|
||||||
|
if frecord.regex[0] == "." or frecord.regex[:2] == "*.":
|
||||||
|
self.hidden_files.add(frecord.regex.replace("*",""))
|
||||||
|
|
||||||
|
|
||||||
|
def __generate_finds(self) -> list:
|
||||||
|
"""Given the regexes to search on each root folder, generate the find command"""
|
||||||
|
finds = []
|
||||||
|
for type,searches in self.dict_to_search.items():
|
||||||
|
for r,regexes in searches.items():
|
||||||
|
if regexes:
|
||||||
|
find_line = f"{r} "
|
||||||
|
|
||||||
|
if type == "d":
|
||||||
|
find_line += "-type d "
|
||||||
|
bash_find_var = f"FIND_DIR_{r[1:].replace('.','').upper()}"
|
||||||
|
self.bash_find_d_vars.add(bash_find_var)
|
||||||
|
else:
|
||||||
|
bash_find_var = f"FIND_{r[1:].replace('.','').upper()}"
|
||||||
|
self.bash_find_f_vars.add(bash_find_var)
|
||||||
|
|
||||||
|
find_line += '-name \\"' + '\\" -o -name \\"'.join(regexes) + '\\"'
|
||||||
|
find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line)
|
||||||
|
find_line = f"{bash_find_var}={find_line}"
|
||||||
|
finds.append(find_line)
|
||||||
|
|
||||||
|
return finds
|
||||||
|
|
||||||
|
def __generate_storages(self) -> list:
|
||||||
|
"""Generate the storages to save the results per entry"""
|
||||||
|
storages = []
|
||||||
|
all_f_finds = "$" + "\\n$".join(self.bash_find_f_vars)
|
||||||
|
all_d_finds = "$" + "\\n$".join(self.bash_find_d_vars)
|
||||||
|
all_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + list(self.bash_find_d_vars))
|
||||||
|
|
||||||
|
for precord in self.ploaded.peasrecords:
|
||||||
|
bash_storage_var = f"PSTORAGE_{precord.bash_name}"
|
||||||
|
self.bash_storages.add(bash_storage_var)
|
||||||
|
|
||||||
|
#Select the FIND_ variables to search on depending on the type files
|
||||||
|
if all(frecord.type == "f" for frecord in precord.filerecords):
|
||||||
|
storage_line = STORAGE_TEMPLATE.replace(STORAGE_LINE_MARKUP, all_f_finds)
|
||||||
|
elif all(frecord.type == "d" for frecord in precord.filerecords):
|
||||||
|
storage_line = STORAGE_TEMPLATE.replace(STORAGE_LINE_MARKUP, all_d_finds)
|
||||||
|
else:
|
||||||
|
storage_line = STORAGE_TEMPLATE.replace(STORAGE_LINE_MARKUP, all_finds)
|
||||||
|
|
||||||
|
#Grep by filename regex (ended in '$')
|
||||||
|
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(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(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_folders_searched}{grep_names}")
|
||||||
|
storage_line = f"{bash_storage_var}={storage_line}"
|
||||||
|
storages.append(storage_line)
|
||||||
|
|
||||||
|
return storages
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then echo_not_found "'+frecord.regex+'"; fi; '
|
||||||
|
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):
|
||||||
|
"""Substitude the markup with the actual code"""
|
||||||
|
self.linpeas_sh = self.linpeas_sh.replace(mark, join_char.join(find_calls)) #New line char is't needed
|
||||||
|
|
||||||
|
def write_linpeas(self, path):
|
||||||
|
"""Write on disk the final linpeas"""
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.write(self.linpeas_sh)
|
26
linPEAS/builder/src/peasLoaded.py
Normal file
26
linPEAS/builder/src/peasLoaded.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from .fileRecord import FileRecord
|
||||||
|
from .peassRecord import PEASRecord
|
||||||
|
from .yamlGlobals import YAML_LOADED, DEFAULTS
|
||||||
|
|
||||||
|
class PEASLoaded:
|
||||||
|
def __init__(self):
|
||||||
|
to_search = YAML_LOADED["search"]
|
||||||
|
self.peasrecords = []
|
||||||
|
for name,peasrecord_json in to_search.items():
|
||||||
|
filerecords = []
|
||||||
|
for regex,fr in peasrecord_json["files"].items():
|
||||||
|
filerecords.append(
|
||||||
|
FileRecord(
|
||||||
|
regex=regex,
|
||||||
|
**fr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.peasrecords.append(
|
||||||
|
PEASRecord(
|
||||||
|
name=name,
|
||||||
|
auto_check=peasrecord_json["config"]["auto_check"],
|
||||||
|
exec=peasrecord_json["config"].get("exec", DEFAULTS["exec"]),
|
||||||
|
filerecords=filerecords
|
||||||
|
)
|
||||||
|
)
|
7
linPEAS/builder/src/peassRecord.py
Normal file
7
linPEAS/builder/src/peassRecord.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class PEASRecord:
|
||||||
|
def __init__(self, name, auto_check: bool, exec: list, filerecords: list):
|
||||||
|
self.name = name
|
||||||
|
self.bash_name = name.upper().replace(" ","_").replace("-","_")
|
||||||
|
self.auto_check = auto_check
|
||||||
|
self.exec = exec
|
||||||
|
self.filerecords = filerecords
|
30
linPEAS/builder/src/yamlGlobals.py
Normal file
30
linPEAS/builder/src/yamlGlobals.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
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
|
||||||
|
|
||||||
|
with open(FILES_YAML, 'r') as file:
|
||||||
|
YAML_LOADED = yaml.load(file, Loader=yaml.FullLoader)
|
||||||
|
|
||||||
|
ROOT_FOLDER = YAML_LOADED["root_folders"]
|
||||||
|
DEFAULTS = YAML_LOADED["defaults"]
|
||||||
|
COMMON_FILE_FOLDERS = YAML_LOADED["common_file_folders"]
|
||||||
|
COMMON_DIR_FOLDERS = YAML_LOADED["common_directory_folders"]
|
||||||
|
assert all(f in ROOT_FOLDER for f in COMMON_FILE_FOLDERS)
|
||||||
|
assert all(f in ROOT_FOLDER for f in COMMON_DIR_FOLDERS)
|
||||||
|
|
||||||
|
|
||||||
|
PEAS_FINDS_MARKUP = YAML_LOADED["peas_finds_markup"]
|
||||||
|
FIND_LINE_MARKUP = YAML_LOADED["find_line_markup"]
|
||||||
|
FIND_TEMPLATE = YAML_LOADED["find_template"]
|
||||||
|
|
||||||
|
PEAS_STORAGES_MARKUP = YAML_LOADED["peas_storages_markup"]
|
||||||
|
STORAGE_LINE_MARKUP = YAML_LOADED["storage_line_markup"]
|
||||||
|
STORAGE_LINE_EXTRA_MARKUP = YAML_LOADED["storage_line_extra_markup"]
|
||||||
|
STORAGE_TEMPLATE = YAML_LOADED["storage_template"]
|
||||||
|
|
||||||
|
INT_HIDDEN_FILES_MARKUP = YAML_LOADED["int_hidden_files_markup"]
|
2213
linPEAS/linpeas.sh
2213
linPEAS/linpeas.sh
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user