updating with r7-msf
commit
907983db4a
|
@ -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.6.0'
|
||||
gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.6.2'
|
||||
# Needed by msfgui and other rpc components
|
||||
gem 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
GIT
|
||||
remote: git://github.com/rapid7/metasploit_data_models.git
|
||||
revision: 0285d6e199f125b33214100dcb0f4eeb12ee765f
|
||||
tag: 0.6.0
|
||||
revision: 67d78f9ce59a74ad9d6e8d3f9e68760ff4d2ec55
|
||||
tag: 0.6.2
|
||||
specs:
|
||||
metasploit_data_models (0.6.0)
|
||||
metasploit_data_models (0.6.2)
|
||||
activerecord (>= 3.2.10)
|
||||
activesupport
|
||||
pg
|
||||
|
|
85
Rakefile
85
Rakefile
|
@ -1,52 +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',
|
||||
'LICENSE',
|
||||
'CONTRIBUTING.md',
|
||||
]
|
||||
yard_options = [
|
||||
# include documentation for protected methods for developers extending the code.
|
||||
'--protected',
|
||||
# Don't bother with files meant to be examples
|
||||
'--exclude', 'samples/',
|
||||
'--exclude', '\.ut\.rb/',
|
||||
'--exclude', '\.ts\.rb/',
|
||||
]
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env rake
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
||||
end
|
||||
|
||||
APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
|
||||
load 'rails/tasks/engine.rake'
|
||||
|
||||
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
|
||||
|
||||
require 'rspec/core'
|
||||
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
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
require 'rails'
|
||||
|
||||
module MetasploitDataModels
|
||||
class Engine < Rails::Engine
|
||||
|
||||
# @see http://viget.com/extend/rails-engine-testing-with-rspec-capybara-and-factorygirl
|
||||
config.generators do |g|
|
||||
g.assets false
|
||||
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
||||
g.helper false
|
||||
g.test_framework :rspec, :fixture => false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,27 +0,0 @@
|
|||
# @note All options not specific to any given rake task should go in the .yardopts file so they are available to both
|
||||
# the below rake tasks and when invoking `yard` from the command line
|
||||
|
||||
require 'yard'
|
||||
require 'yard/rake/yardoc_task'
|
||||
|
||||
namespace :yard do
|
||||
YARD::Rake::YardocTask.new(:doc) do |t|
|
||||
# --no-stats here as 'stats' task called after will print fuller stats
|
||||
t.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
|
||||
stats.run('--compact', '--list-undoc')
|
||||
end
|
||||
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']
|
|
@ -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
|
|
@ -15,9 +15,8 @@ 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
|
||||
# A percentage {#confidence} that the vulnerability is real and not a false positive.
|
||||
CONFIDENCE_RANGE = 0 .. 100
|
||||
|
||||
# Default value for {#params}
|
||||
DEFAULT_PARAMS = []
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue