Compare commits

...

22 Commits

Author SHA1 Message Date
HackTricks News Bot
aaecb3e728 Add linpeas privilege escalation checks from: HTB Eureka: From Actuator HeapDump to SSH, credential capture via Gateway, and r 2025-08-30 18:41:38 +00:00
SirBroccoli
cc5ab76991 Merge pull request #486 from soobinrho/fix-typo-on-color-explanations
docs: fix typo (conten -> content)
2025-08-27 12:12:28 +02:00
carlospolop
36001d644e Merge branch 'master' of github.com:peass-ng/PEASS-ng 2025-08-25 11:18:18 +02:00
carlospolop
fdd414f4aa new workflow 2025-08-25 11:18:16 +02:00
Soobin Rho
c3e50dbdbf docs: fix typo (conten -> content) 2025-08-08 17:56:41 -05:00
SirBroccoli
41128808a6 Merge pull request #483 from securitytime/patch-1
Update Beaprint.cs
2025-07-01 16:23:13 +02:00
carlospolop
6fd96f4bdb f 2025-07-01 12:12:01 +02:00
carlospolop
a745f00dd7 fix 2025-07-01 11:10:21 +02:00
securitytime
933e12d7f1 Update Beaprint.cs
A space character is missing here:
"... educational purposes only.Any misuse of this software  ..."
2025-06-28 09:12:40 +02:00
SirBroccoli
4061cef7e8 Merge pull request #476 from peass-ng/codex/fix-url-reference-in-linpeasbuilder.py
Fix url variable reference in linpeasBuilder
2025-06-25 01:59:43 +02:00
SirBroccoli
b66ced3c63 Merge pull request #475 from peass-ng/codex/find-and-fix-a-bug
Fix parser global state reuse
2025-06-25 01:59:03 +02:00
SirBroccoli
cde725dacc Merge pull request #477 from peass-ng/codex/update-docstring-and-fix-typo
Fix docstring and comment in linpeasBuilder
2025-06-25 01:57:58 +02:00
SirBroccoli
f0f829890c Merge pull request #479 from peass-ng/codex/replace--parth--with--path--in-argparse
Fix typo in linpeas builder arg help
2025-06-25 01:57:11 +02:00
SirBroccoli
99c36b8562 Merge pull request #480 from Signum21/master
Fixed multiple bugs in Vulnerable Leaked Handlers
2025-06-25 01:56:58 +02:00
SirBroccoli
a74c6c820f Merge pull request #482 from Aarav-Juneja/builder-exclude-fix
Fix exclude modules on linPEASS
2025-06-25 01:55:48 +02:00
SirBroccoli
53fd4d8dc8 Merge pull request #481 from ertaku12/master
Added a privilege escalation vulnerability for MySQL 4.x/5.x versions.
2025-06-25 01:55:25 +02:00
Aarav Juneja
9b37fd4ef4 Fix exclude modules on linPEASS 2025-06-24 13:05:10 -07:00
John Doe
f27b1d4816 Added a privilege escalation vulnerability for MySQL 4.x/5.x versions. 2025-06-23 22:37:44 +03:00
Signum21
d335b9254f Fixed multiple bugs in Vulnerable Leaked Handlers 2025-06-15 20:59:20 +02:00
SirBroccoli
d5e3c2a885 Fix typo in linpeas builder output argument 2025-06-06 00:38:05 +02:00
SirBroccoli
4af321d138 Fix docstring and comment typo 2025-06-06 00:01:29 +02:00
SirBroccoli
39066f6867 Fix leftover debug code and reset state in parser 2025-06-06 00:00:39 +02:00
11 changed files with 516 additions and 27 deletions

201
.github/workflows/PR-tests.yml vendored Normal file
View File

@@ -0,0 +1,201 @@
name: PR-tests
on:
pull_request:
branches:
- master
- main
paths-ignore:
- '.github/**'
jobs:
Build_and_test_winpeas_pr:
runs-on: windows-latest
# environment variables
env:
Solution_Path: 'winPEAS\winPEASexe\winPEAS.sln'
Configuration: 'Release'
steps:
# checkout
- name: Checkout
uses: actions/checkout@master
with:
ref: ${{ github.head_ref }}
- name: Download regexes
run: |
powershell.exe -ExecutionPolicy Bypass -File build_lists/download_regexes.ps1
# Add MSBuild to the PATH
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2
# Setup NuGet
- name: Setup NuGet.exe
uses: nuget/setup-nuget@v1
# Restore the packages for testing
- name: Restore the application
run: nuget restore $env:Solution_Path
# build
- name: run MSBuild
run: msbuild $env:Solution_Path
# Build all versions
- name: Build all versions
run: |
echo "build x64"
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="x64"
echo "build x86"
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="x86"
echo "build Any CPU"
msbuild -m $env:Solution_Path /t:Rebuild /p:Configuration=$env:Configuration /p:Platform="Any CPU"
- name: Execute winPEAS -h
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (Test-Path $exePath) {
& $exePath -h
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
- name: Execute winPEAS cloudinfo
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (Test-Path $exePath) {
& $exePath cloudinfo
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
- name: Execute winPEAS systeminfo
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (Test-Path $exePath) {
& $exePath systeminfo
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
- name: Execute winPEAS networkinfo
shell: pwsh
run: |
$Configuration = "Release"
$exePath = "winPEAS/winPEASexe/winPEAS/bin/$Configuration/winPEAS.exe"
if (Test-Path $exePath) {
& $exePath networkinfo
} else {
Write-Error "winPEAS.exe not found at $exePath"
}
Build_and_test_linpeas_pr:
runs-on: ubuntu-latest
steps:
# Download repo
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
# Setup go
- uses: actions/setup-go@v2
with:
go-version: 1.17.0-rc1
stable: false
- run: go version
# Build linpeas
- name: Build linpeas
run: |
python3 -m pip install PyYAML
cd linPEAS
python3 -m builder.linpeas_builder --all --output linpeas_fat.sh
python3 -m builder.linpeas_builder --all-no-fat --output linpeas.sh
python3 -m builder.linpeas_builder --small --output linpeas_small.sh
# Run linpeas help as quick test
- name: Run linpeas help
run: linPEAS/linpeas_fat.sh -h && linPEAS/linpeas.sh -h && linPEAS/linpeas_small.sh -h
# Run linpeas as a test
- name: Run linpeas system_information
run: linPEAS/linpeas_fat.sh -o system_information -a
- name: Run linpeas container
run: linPEAS/linpeas_fat.sh -o container -a
- name: Run linpeas cloud
run: linPEAS/linpeas_fat.sh -o cloud -a
- name: Run linpeas procs_crons_timers_srvcs_sockets
run: linPEAS/linpeas_fat.sh -o procs_crons_timers_srvcs_sockets -a
- name: Run linpeas network_information
run: linPEAS/linpeas_fat.sh -o network_information -t -a
- name: Run linpeas users_information
run: linPEAS/linpeas_fat.sh -o users_information -a
- name: Run linpeas software_information
run: linPEAS/linpeas_fat.sh -o software_information -a
- name: Run linpeas interesting_perms_files
run: linPEAS/linpeas_fat.sh -o interesting_perms_files -a
- name: Run linpeas interesting_files
run: linPEAS/linpeas_fat.sh -o interesting_files -a
Build_and_test_macpeas_pr:
runs-on: macos-latest
steps:
# Download repo
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
# Build linpeas (macpeas)
- name: Build macpeas
run: |
python3 -m pip install PyYAML --break-system-packages
python3 -m pip install requests --break-system-packages
cd linPEAS
python3 -m builder.linpeas_builder --all --output linpeas_fat.sh
# Run linpeas help as quick test
- name: Run macpeas help
run: linPEAS/linpeas_fat.sh -h
# Run macpeas parts to test it
- name: Run macpeas system_information
run: linPEAS/linpeas_fat.sh -o system_information -a
- name: Run macpeas container
run: linPEAS/linpeas_fat.sh -o container -a
- name: Run macpeas cloud
run: linPEAS/linpeas_fat.sh -o cloud -a
- name: Run macpeas procs_crons_timers_srvcs_sockets
run: linPEAS/linpeas_fat.sh -o procs_crons_timers_srvcs_sockets -a
- name: Run macpeas network_information
run: linPEAS/linpeas_fat.sh -o network_information -t -a
- name: Run macpeas users_information
run: linPEAS/linpeas_fat.sh -o users_information -a
- name: Run macpeas software_information
run: linPEAS/linpeas_fat.sh -o software_information -a

View File

@@ -22,6 +22,10 @@ Check how to **select the checks you want to build [in your own linpeas followin
Note that by default, in the releases pages of this repository, you will find a **linpeas with all the checks**.
### New in Aug 2025
- Added heuristic detection for Bash arithmetic injection in root-run periodic parsers (cron/timers). LinPEAS now inspects root cron entries and systemd timers to find shell scripts that parse logs and use arithmetic contexts like (( ... )), let, or declare -i with untrusted variables. This may reveal dangerous patterns where attacker-controlled log lines can trigger command substitution inside arithmetic evaluation.
## Differences between `linpeas_fat.sh`, `linpeas.sh` and `linpeas_small.sh`:
- **linpeas_fat.sh**: Contains all checks, even third party applications in base64 embedded.
@@ -170,7 +174,7 @@ LinPEAS uses colors to indicate where does each section begin. But **it also use
- The ![](https://placehold.it/15/b32400/000000?text=+) **Red** color is used for identifing suspicious configurations that could lead to privilege escalation.
- The ![](https://placehold.it/15/66ff33/000000?text=+) **Green** color is used for known good configurations (based on the name not on the conten!)
- The ![](https://placehold.it/15/66ff33/000000?text=+) **Green** color is used for known good configurations (based on the name not on the content!)
- The ![](https://placehold.it/15/0066ff/000000?text=+) **Blue** color is used for: Users without shell & Mounted devices

View File

@@ -33,7 +33,7 @@ if __name__ == "__main__":
parser.add_argument('--small', action='store_true', help='Build small version of linpeas.')
parser.add_argument('--include', type=str, help='Build linpeas only with the modules indicated you can indicate section names or module IDs).')
parser.add_argument('--exclude', type=str, help='Exclude the given modules (you can indicate section names or module IDs).')
parser.add_argument('--output', required=True, type=str, help='Parth to write the final linpeas file to.')
parser.add_argument('--output', required=True, type=str, help='Path to write the final linpeas file to.')
args = parser.parse_args()
all_modules = args.all

View File

@@ -0,0 +1,215 @@
# Title: Processes & Cron & Services & Timers - Bash arithmetic on untrusted logs
# ID: PR_Bash_arithmetic_untrusted_logs
# Author: HT Bot
# Last Update: 2025-08-30
# Description: Heuristic detection of root-run periodic scripts (cron/timers) that perform Bash arithmetic on variables sourced from logs or user-controlled files. Flags common patterns that enable command substitution inside arithmetic ((...)), let, or declare -i when parsing log lines/arguments.
# License: GNU GPL
# Version: 1.0
# Functions Used: print_2title, print_3title, print_info
# Global Variables: $SEARCH_IN_FOLDER
# Initial Functions:
# Generated Global Variables: $cron_file, $line, $tok, $script, $args, $arg, $timer_unit, $service_unit, $exec_line, $user_field, $cand, $match_lines, $severity, $msg, $file, $sev_and_lines, $candidates_tmp
# Fat linpeas: 0
# Small linpeas: 1
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Potential Bash arithmetic injection in root-run parsers (cron/timers)"
print_info "https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#scheduledcron-jobs"
# Small helpers -----------------------------------------------------------
uniq_print_cand() {
# de-duplicate candidate scripts
# usage: uniq_print_cand <path>
cand="$1"
[ -z "$cand" ] && return
[ ! -f "$cand" ] && return
# only consider text-ish files to keep it fast
if grep -Iq . "$cand" 2>/dev/null; then
printf '%s\n' "$cand"
fi
}
is_shell_script() {
# returns 0 if file looks like a shell script (shebang or .sh), else 1
[ ! -f "$1" ] && return 1
head -n1 "$1" 2>/dev/null | grep -Eq '(/bash|/sh|/dash|/zsh|/ksh)' && return 0
printf '%s' "$1" | grep -qE '\\.sh(\\.|$)' && return 0
return 1
}
find_arith_patterns() {
# echo severity and matched lines for arithmetic patterns
# severity: STRONG if command substitution inside arithmetic, WEAK if variable arithmetic
file="$1"
# Strong: command substitution inside arithmetic context
if grep -nE '\\(\\(.*\\$\\(.*\\).*\\)\\)|\\blet\\b[^#]*\\$\\(.*\\)|declare[[:space:]]+-i[[:space:]]+[A-Za-z_][A-Za-z0-9_]*=[^#]*\\$\\(.*\\)' "$file" 2>/dev/null | head -n 3 | sed 's/^/ /' ; then
severity="STRONG"
match_lines=$(grep -nE '\\(\\(.*\\$\\(.*\\).*\\)\\)|\\blet\\b[^#]*\\$\\(.*\\)|declare[[:space:]]+-i[[:space:]]+[A-Za-z_][A-Za-z0-9_]*=[^#]*\\$\\(.*\\)' "$file" 2>/dev/null | head -n 3)
printf 'STRONG\n'; printf '%s\n' "$match_lines"
return 0
fi
# Weak: arithmetic with unquoted variables that could be attacker-controlled
if grep -nE '\\(\\([^#]*\\$[A-Za-z_][A-Za-z0-9_]*[^#]*\\)\\)|\\blet\\b[^#]*\\$[A-Za-z_][A-Za-z0-9_]*|declare[[:space:]]+-i[[:space:]]+[A-Za-z_][A-Za-z0-9_]*=[^#]*\\$[A-Za-z_][A-Za-z0-9_]*' "$file" 2>/dev/null | head -n 3 | sed 's/^/ /' ; then
severity="WEAK"
match_lines=$(grep -nE '\\(\\([^#]*\\$[A-Za-z_][A-Za-z0-9_]*[^#]*\\)\\)|\\blet\\b[^#]*\\$[A-Za-z_][A-Za-z0-9_]*|declare[[:space:]]+-i[[:space:]]+[A-Za-z_][A-Za-z0-9_]*=[^#]*\\$[A-Za-z_][A-Za-z0-9_]*' "$file" 2>/dev/null | head -n 3)
printf 'WEAK\n'; printf '%s\n' "$match_lines"
return 0
fi
return 1
}
looks_like_log_parsing() {
# heuristics: script references logs/WWW logs/tmp or uses variables LOG/FILE in pipelines/process substitution
file="$1"
# explicit log-like paths
if grep -qE '/var/log|/var/www/.*/log|/tmp/' "$file" 2>/dev/null; then
return 0
fi
# log-ish variables used in pipelines or redirections
if grep -qE '(LOG_FILE|LOG|FILE)=' "$file" 2>/dev/null && \
grep -qE '(grep|awk|sed|cut|tail|head)[^\n]*\\$[A-Za-z_][A-Za-z0-9_]*' "$file" 2>/dev/null; then
return 0
fi
# process substitution with grep/cat reading from variable
grep -qE '(<\\(|<\\s*[^<])' "$file" 2>/dev/null && \
grep -qE 'grep[^\n]*\\$[A-Za-z_][A-Za-z0-9_]*' "$file" 2>/dev/null && return 0
return 1
}
print_writable_arg_info() {
# Given an argument path, print if current user can write the file or its parent dir
arg="$1"
[ -z "$arg" ] && return
case "$arg" in
/*)
if [ -e "$arg" ]; then
if [ -w "$arg" ]; then
echo " Writable argument file: $arg"; ls -l "$arg" 2>/dev/null | sed 's/^/ /'
fi
else
d=$(dirname -- "$arg")
if [ -d "$d" ] && [ -w "$d" ]; then
echo " Parent dir writable: $d (arg $arg does not exist)"
ls -ld "$d" 2>/dev/null | sed 's/^/ /'
fi
fi
;;
esac
}
# Collect candidate scripts from cron ------------------------------------------------
candidates_tmp=$(mktemp 2>/dev/null || echo "/tmp/.lp.cand.$$")
: > "$candidates_tmp"
# Root crontabs and system cron files
for cron_file in /etc/crontab /var/spool/cron/crontabs/root /etc/cron.d/*; do
[ -r "$cron_file" ] || continue
# Iterate non-comment lines
while IFS= read -r line || [ -n "$line" ]; do
case "$line" in
\#*|"") continue ;;
esac
# Extract absolute paths from the line
# First token that is an absolute path is likely the script/binary
script=""
args=""
# Get all absolute-like tokens
for tok in $(printf '%s\n' "$line" | grep -oE '/[^[:space:]]+'); do
if [ -z "$script" ]; then
script="$tok"
else
args="$args $tok"
fi
done
if [ -n "$script" ]; then
uniq_print_cand "$script" >> "$candidates_tmp"
# If script is run by root (likely in these files), show writable argument hints now
if [ -n "$args" ]; then
echo "Root cron entry: $script$args"
for arg in $args; do
print_writable_arg_info "$arg"
done
fi
fi
done < "$cron_file"
done
# run-parts style cron directories (executed as root by system crond/anacron)
for d in /etc/cron.daily /etc/cron.hourly /etc/cron.weekly /etc/cron.monthly; do
[ -d "$d" ] || continue
for f in "$d"/*; do
[ -f "$f" ] || continue
uniq_print_cand "$f" >> "$candidates_tmp"
done
done
# Collect candidate scripts from systemd timers --------------------------------------
if command -v systemctl >/dev/null 2>&1; then
systemctl list-timers --all 2>/dev/null | awk 'NR>1 {print $1}' | grep -E '\\.timer$' | while read -r timer_unit; do
[ -z "$timer_unit" ] && continue
service_unit=$(systemctl show "$timer_unit" -p Unit 2>/dev/null | cut -d= -f2)
[ -z "$service_unit" ] && continue
user_field=$(systemctl show "$service_unit" -p User 2>/dev/null | cut -d= -f2)
# Default user for services without User= is root; include both empty and root
if [ -z "$user_field" ] || [ "$user_field" = "root" ]; then
exec_line=$(systemctl show "$service_unit" -p ExecStart 2>/dev/null | cut -d= -f2)
# Extract first absolute path as executable/script and any absolute path args
script=""
args=""
for tok in $(printf '%s\n' "$exec_line" | grep -oE '/[^[:space:]]+'); do
if [ -z "$script" ]; then
script="$tok"
else
args="$args $tok"
fi
done
if [ -n "$script" ]; then
uniq_print_cand "$script" >> "$candidates_tmp"
if [ -n "$args" ]; then
echo "Root timer entry: $script$args"
for arg in $args; do
print_writable_arg_info "$arg"
done
fi
fi
fi
done
fi
# Evaluate candidates ---------------------------------------------------------------
if [ -s "$candidates_tmp" ]; then
print_3title "Reviewing root-run scripts for arithmetic on untrusted input"
sort -u "$candidates_tmp" | while read -r script; do
[ -z "$script" ] && continue
[ -r "$script" ] || continue
is_shell_script "$script" || continue
sev_and_lines=$(find_arith_patterns "$script")
if [ $? -eq 0 ]; then
severity=$(printf '%s' "$sev_and_lines" | head -n1)
match_lines=$(printf '%s' "$sev_and_lines" | tail -n +2)
if looks_like_log_parsing "$script"; then
echo "[!] $severity risk: arithmetic evaluation with variables in $script"
printf '%s\n' "$match_lines" | sed 's/^/ /'
# Bonus: try to spot obvious log file variables
if grep -qE 'LOG_FILE|LOG_PATH|LOG' "$script" 2>/dev/null; then
msg=$(grep -nE 'LOG_FILE|LOG_PATH|LOG' "$script" 2>/dev/null | head -n 2)
printf '%s\n' "$msg" | sed 's/^/ hint: /'
fi
fi
fi
done
fi
rm -f "$candidates_tmp" 2>/dev/null
echo ""
else
# Folder analysis mode: just list potential log-parsing shell scripts under the target folder
print_2title "Potential Bash arithmetic/log-parsing scripts in folder"
find "$SEARCH_IN_FOLDER" -type f -name "*.sh" -maxdepth 6 2>/dev/null \
-exec sh -c 'head -n1 "$1" 2>/dev/null | grep -Eq "(/bash|/sh|/dash|/zsh|/ksh)" || exit 1' _ {} \; \
-exec grep -Ilq . {} \; \
-exec grep -qE "\\(\\(|\\blet\\b|declare[[:space:]]+-i" {} \; \
-print
echo ""
fi

View File

@@ -8,7 +8,7 @@
# Functions Used: print_2title
# Global Variables: $DEBUG, $knw_usrs, $nosh_usrs, $sh_usrs, $DEBUG, $USER, $STRINGS
# Initial Functions:
# Generated Global Variables: $mysqluser, $mysqlexec, $mysqlconnect, $mysqlconnectnopass
# Generated Global Variables: $mysqluser, $mysqlexec, $mysqlconnect, $mysqlconnectnopass, $mysqluser, $version_output, $major_version, $version, $process_info
# Fat linpeas: 0
# Small linpeas: 1
@@ -102,4 +102,42 @@ if [ "$(command -v mysql || echo -n '')" ] || [ "$(command -v mysqladmin || echo
else echo_no
fi
echo ""
fi
### This section checks if MySQL (mysqld) is running as root and if its version is 4.x or 5.x to refer a known local privilege escalation exploit! ###
# Find the mysqld process
process_info=$(ps aux | grep '[m]ysqld' | head -n1)
if [ -z "$process_info" ]; then
echo "MySQL process not found." | sed -${E} "s,.*,${SED_GREEN},"
else
# Extract the process user
mysqluser=$(echo "$process_info" | awk '{print $1}')
# Get the MySQL version string
version_output=$(mysqld --version 2>&1)
# Extract the version number (expects format like X.Y.Z)
version=$(echo "$version_output" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)
if [ -z "$version" ]; then
echo "Unable to determine MySQL version." | sed -${E} "s,.*,${SED_GREEN},"
else
# Extract the major version number (X from X.Y.Z)
major_version=$(echo "$version" | cut -d. -f1)
# Check if MySQL is running as root and if the version is either 4.x or 5.x
if [ "$mysqluser" = "root" ] && { [ "$major_version" -eq 4 ] || [ "$major_version" -eq 5 ]; }; then
echo "MySQL is running as root with version $version. This is a potential local privilege escalation vulnerability!" | sed -${E} "s,.*,${SED_RED},"
echo "\tRefer to: https://www.exploit-db.com/exploits/1518" | sed -${E} "s,.*,${SED_YELLOW},"
echo "\tRefer to: https://medium.com/r3d-buck3t/privilege-escalation-with-mysql-user-defined-functions-996ef7d5ceaf" | sed -${E} "s,.*,${SED_YELLOW},"
else
echo "MySQL is running as user '$mysqluser' with version $version." | sed -${E} "s,.*,${SED_GREEN},"
fi
### ------------------------------------------------------------------------------------------------------------------------------------------------ ###
fi
fi

View File

@@ -292,9 +292,12 @@ class LinpeasBaseBuilder:
all_module_paths += self.enumerate_directory(LINPEAS_PARTS["variables"])
for module in LINPEAS_PARTS["modules"]:
exclude = False
for ex_module in exclude_modules:
if ex_module in module["folder_path"] or ex_module in [module["name"], module["name_check"]]:
continue
exclude = True
break
if exclude: continue
all_module_paths += self.enumerate_directory(module["folder_path"])
for module in all_module_paths:

View File

@@ -402,9 +402,9 @@ class LinpeasBuilder:
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
"""Substitude the markup with the actual code"""
self.linpeas_sh = self.linpeas_sh.replace(mark, join_char.join(find_calls)) #New line char is't needed
"""Substitute the markup with the actual code"""
self.linpeas_sh = self.linpeas_sh.replace(mark, join_char.join(find_calls)) #New line char isn't needed
def write_linpeas(self, path):
"""Write on disk the final linpeas"""

View File

@@ -106,8 +106,6 @@ def parse_line(line: str):
global FINAL_JSON, C_SECTION, C_MAIN_SECTION, C_2_SECTION, C_3_SECTION
if "Cron jobs" in line:
a=1
if is_section(line, TITLE1_PATTERN):
title = parse_title(line)
@@ -145,17 +143,26 @@ def parse_line(line: str):
def parse_peass(outputpath: str, jsonpath: str = ""):
global OUTPUT_PATH, JSON_PATH
global OUTPUT_PATH, JSON_PATH, FINAL_JSON, C_SECTION, C_MAIN_SECTION, C_2_SECTION, C_3_SECTION
OUTPUT_PATH = outputpath
JSON_PATH = jsonpath
for line in open(OUTPUT_PATH, 'r', encoding="utf8").readlines():
line = line.strip()
if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex
continue
# Reset globals to avoid data leaking between executions
FINAL_JSON = {}
C_SECTION = FINAL_JSON
C_MAIN_SECTION = FINAL_JSON
C_2_SECTION = FINAL_JSON
C_3_SECTION = FINAL_JSON
parse_line(line)
with open(OUTPUT_PATH, 'r', encoding="utf8") as f:
for line in f.readlines():
line = line.strip()
# Remove empty lines or lines containing only color codes
if not line or not clean_colors(line):
continue
parse_line(line)
if JSON_PATH:
with open(JSON_PATH, "w") as f:

View File

@@ -102,17 +102,15 @@ namespace winPEAS.Checks
{
vulnHandlers = ProcessesInfo.GetVulnHandlers(progress);
}
Dictionary<string, string> colors = new Dictionary<string, string>();
colors[Checks.CurrentUserName] = Beaprint.ansi_color_bad;
colors[HandlesHelper.elevatedProcess] = Beaprint.ansi_color_bad;
foreach (Dictionary<string, string> handler in vulnHandlers)
{
Dictionary<string, string> colors = new Dictionary<string, string>()
{
{ Checks.CurrentUserName, Beaprint.ansi_color_bad },
{ handler["Reason"], Beaprint.ansi_color_bad },
};
Beaprint.DictPrint(vulnHandlers, colors, true);
colors[handler["Reason"]] = Beaprint.ansi_color_bad;
}
Beaprint.DictPrint(vulnHandlers, colors, true);
}
catch (Exception ex)
{

View File

@@ -31,7 +31,7 @@ namespace winPEAS.Helpers
public static string ansi_current_user = MAGENTA;
private static string Advisory =
"winpeas should be used for authorized penetration testing and/or educational purposes only." +
"winpeas should be used for authorized penetration testing and/or educational purposes only. " +
"Any misuse of this software will not be the responsibility of the author or of any other collaborator. " +
"Use it at your own devices and/or with the device owner's permission.";

View File

@@ -12,6 +12,7 @@ namespace winPEAS.Helpers
private const int CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION = 64;
public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
public const int DUPLICATE_SAME_ACCESS = 0x2;
public const string elevatedProcess = "Access denied, process is probably elevated";
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FILE_NAME_INFO
@@ -171,7 +172,7 @@ namespace winPEAS.Helpers
// Hex perms from https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights and https://github.com/buffer/maltracer/blob/master/defines.py
//PROCESS_ALL_ACCESS
if ((h.GrantedAccess & 0x001F0FFF) == h.GrantedAccess)
if ((h.GrantedAccess & 0x001F0FFF) == h.GrantedAccess || (h.GrantedAccess & 0x1FFFFF) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_ALL_ACCESS";
@@ -454,6 +455,8 @@ namespace winPEAS.Helpers
}
catch
{
data["name"] = elevatedProcess;
data["sid"] = elevatedProcess;
return data;
}
finally
@@ -469,12 +472,32 @@ namespace winPEAS.Helpers
public static PT_RELEVANT_INFO getProcInfoById(int pid)
{
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
Process proc;
Process proc = Process.GetProcessById(pid);
try
{
proc = Process.GetProcessById(pid);
}
catch
{
pri.pid = pid;
pri.name = "Error, process may not exist";
pri.userName = "Error, process may not exist";
pri.userSid = "Error, process may not exist";
pri.imagePath = "Error, process may not exist";
return pri;
}
Dictionary<string, string> user = GetProcU(proc);
StringBuilder fileName = new StringBuilder(2000);
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
try
{
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
}
catch
{
fileName = new StringBuilder(elevatedProcess);
}
pri.pid = pid;
pri.name = proc.ProcessName;