Armitage 05.21.12
This release improves collaboration performance and fixes a few Windows specific issues.unstable
parent
74e4812946
commit
c14a3e655e
Binary file not shown.
|
@ -1,6 +1,24 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
21 May 12
|
||||
---------
|
||||
- Added a hack to prevent the input area from flickering when the
|
||||
prompt changes.
|
||||
- Updated the color palette to something a little more subtle.
|
||||
- Added an optimization to how modules are launched. This will make
|
||||
a difference for team use in high latency situations.
|
||||
- Rewrote MSF Scans feature to use console queue. This option is more
|
||||
reliable and it makes the code easier to follow.
|
||||
- Added a hack to combine chat message writes with a read request.
|
||||
This will make the event log more responsive in a high latency
|
||||
situation (can't you tell I care about this "situation")
|
||||
- Fixed text highlights through Ctrl+F on Windows. UNIX platforms
|
||||
were always OK. Another good reason to not use these tools on
|
||||
Windows. Ever.
|
||||
- View -> Downloads Sync Files feature now works on Windows. It looks
|
||||
like leaving those pesky :'s in the file paths is bad.
|
||||
|
||||
17 May 12
|
||||
---------
|
||||
- Fixed bug with loot/download viewer breaking with a font resize.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<center><h1>Armitage 1.44-dev</h1></center>
|
||||
|
||||
<p>An attack management tool for Metasploit®
|
||||
<br />Release: 17 May 12</p>
|
||||
<br />Release: 21 May 12</p>
|
||||
<br />
|
||||
<p>Developed by:</p>
|
||||
|
||||
|
|
|
@ -41,18 +41,18 @@ armitage.show_all_commands.boolean=true
|
|||
armitage.application_title.string=Armitage
|
||||
console.color_0.color=\#ffffff
|
||||
console.color_1.color=\#000000
|
||||
console.color_2.color=\#000080
|
||||
console.color_3.color=\#009000
|
||||
console.color_4.color=\#ff0000
|
||||
console.color_5.color=\#800000
|
||||
console.color_6.color=\#a000a0
|
||||
console.color_7.color=\#ff8000
|
||||
console.color_8.color=\#ffff00
|
||||
console.color_9.color=\#00ff00
|
||||
console.color_10.color=\#009090
|
||||
console.color_11.color=\#00ffff
|
||||
console.color_12.color=\#0000ff
|
||||
console.color_13.color=\#ff00ff
|
||||
console.color_2.color=\#3465A4
|
||||
console.color_3.color=\#4E9A06
|
||||
console.color_4.color=\#EF2929
|
||||
console.color_5.color=\#CC0000
|
||||
console.color_6.color=\#75507B
|
||||
console.color_7.color=\#C4A000
|
||||
console.color_8.color=\#FCE94F
|
||||
console.color_9.color=\#8AE234
|
||||
console.color_10.color=\#069A9A
|
||||
console.color_11.color=\#34E2E2
|
||||
console.color_12.color=\#729FCF
|
||||
console.color_13.color=\#AD7FA8
|
||||
console.color_14.color=\#808080
|
||||
console.color_15.color=\#c0c0c0
|
||||
console.show_colors.boolean=true
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
^(..:..:..) \[\*\] (.*) $1 \cA[*]\o $2
|
||||
^\[\*\] (.*) \cA[*]\o $1
|
||||
^(..:..:..) \* (.*) $1 \c7*\o $2
|
||||
^(..:..:..) \[\*\] (.*) $1 \cC[*]\o $2
|
||||
^\[\*\] (.*) \cC[*]\o $1
|
||||
^(..:..:..) \* (.*) $1 \cD*\o $2
|
||||
^(\w+)> \u$1\o>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
^meterpreter > \umeterpreter\u >
|
||||
^msf > \umsf\u >
|
||||
^msf (.*?)\((.*?)\) > \umsf\u $1(\c4$2\o) >
|
||||
^\[\*\] (.*) \cA[*]\o $1
|
||||
^\[\*\] (.*) \cC[*]\o $1
|
||||
^\[\+\] (.*) \c9[+]\o $1
|
||||
^\[\-\] (.*) \c4[-]\o $1
|
||||
^ =\[ (.*) =[\c7 $1
|
||||
|
|
|
@ -150,7 +150,8 @@ sub launch_service {
|
|||
}
|
||||
|
||||
sub _launch_service {
|
||||
local('$c $key $value');
|
||||
local('$c $key $value %options');
|
||||
%options = copy($3);
|
||||
|
||||
if ('SESSION' in $3) {
|
||||
$c = createDisplayTab($1, $host => sessionToHost($3['SESSION']), $file => "post");
|
||||
|
@ -167,17 +168,15 @@ sub _launch_service {
|
|||
}
|
||||
|
||||
if ($4 eq "payload" && $format eq "multi/handler") {
|
||||
[$c addCommand: $null, "use exploit/multi/handler"];
|
||||
[$c addCommand: $null, "set PAYLOAD ". substr($2, 8)];
|
||||
[$c addCommand: $null, "set ExitOnSession false"];
|
||||
[$c addCommand: $null, "use exploit/multi/handler"];
|
||||
%options['PAYLOAD'] = substr($2, 8);
|
||||
%options['ExitOnSession'] = 'false';
|
||||
}
|
||||
else {
|
||||
[$c addCommand: $null, "use $2"];
|
||||
}
|
||||
|
||||
foreach $key => $value ($3) {
|
||||
[$c addCommand: $null, "set $key $value"];
|
||||
}
|
||||
[$c setOptions: %options];
|
||||
|
||||
if ($4 eq "exploit" || ($4 eq "payload" && $format eq "multi/handler")) {
|
||||
[$c addCommand: "x", "exploit -j"];
|
||||
|
|
|
@ -33,6 +33,7 @@ sub downloadLoot {
|
|||
local('$dest');
|
||||
#$dest = chooseFile($title => "Where shall I save these files?", $dirsonly => 1, $always => 1);
|
||||
$dest = getFileProper(dataDirectory(), $type);
|
||||
mkdir($dest);
|
||||
_downloadLoot(\$model, \$table, \$getme, \$dest, $dtype => $type);
|
||||
}, \$model, \$table, \$getme, \$type));
|
||||
}
|
||||
|
@ -48,7 +49,7 @@ sub _downloadLoot {
|
|||
# make the folder to store our downloads into
|
||||
local('$handle $data $file');
|
||||
if ($dtype eq "downloads") {
|
||||
$file = getFileProper($dest, $host, $path, $name);
|
||||
$file = getFileProper($dest, $host, strrep($path, ':', ''), $name);
|
||||
}
|
||||
else {
|
||||
$file = getFileProper($dest, $host, $name);
|
||||
|
@ -76,10 +77,10 @@ sub _postLoot {
|
|||
local('$host $location $name $type $when');
|
||||
($host, $location, $name, $type, $when) = $1;
|
||||
|
||||
[$2 append: "\c9
|
||||
#
|
||||
# $host $+ : $name
|
||||
#\n"];
|
||||
[$2 append: "
|
||||
\c9#
|
||||
\c9# $host $+ : $name
|
||||
\c9#\n"];
|
||||
|
||||
if ("*binary*" iswm $type) {
|
||||
[$2 append: "\c4This is a binary file\n"];
|
||||
|
|
|
@ -266,96 +266,88 @@ sub launch_msf_scans {
|
|||
@modules = filter({ return iff("*_version" iswm $1, $1); }, @auxiliary);
|
||||
|
||||
$hosts = iff($1 is $null, ask("Enter range (e.g., 192.168.1.0/24):"), $1);
|
||||
if ($hosts is $null) {
|
||||
return;
|
||||
}
|
||||
|
||||
thread(lambda({
|
||||
local('$scanner $index $console %ports %discover $port %o $temp');
|
||||
local('$scanner $index $queue %ports %discover $port %o $temp');
|
||||
%ports = ohash();
|
||||
%discover = ohash();
|
||||
setMissPolicy(%ports, { return @(); });
|
||||
setMissPolicy(%discover, { return @(); });
|
||||
|
||||
if ($hosts !is $null) {
|
||||
elog("launched msf scans at: $hosts");
|
||||
elog("launched msf scans at: $hosts");
|
||||
|
||||
$console = createConsoleTab("Scan", 1, $host => "all", $file => "scan");
|
||||
[$console addSessionListener: lambda({
|
||||
local('$text $host $port $hosts $modules $module @c');
|
||||
$queue = createDisplayTab("Scan", $host => "all", $file => "scan");
|
||||
|
||||
foreach $text (split("\n", $2)) {
|
||||
if ($text ismatch '... (.*?):(\d+) - TCP OPEN') {
|
||||
($host, $port) = matched();
|
||||
push(%discover[$port], $host);
|
||||
}
|
||||
else if ($text ismatch '... Scanned \d+ of \d+ hosts .100. complete.' && $start == 1) {
|
||||
$start = $null;
|
||||
[[$console getWindow] append: "[*] Starting host discovery scans\n"];
|
||||
[$queue append: "[*] Building list of scan ports and modules"];
|
||||
|
||||
foreach $port => $hosts (%discover) {
|
||||
if ($port in %ports) {
|
||||
$modules = %ports[$port];
|
||||
foreach $module ($modules) {
|
||||
@c = @("use $module");
|
||||
push(@c, "set RHOSTS " . join(", ", $hosts));
|
||||
push(@c, "set RPORT $port");
|
||||
push(@c, "set THREADS 24");
|
||||
push(@c, "run -j");
|
||||
# build up a list of scan ports
|
||||
foreach $index => $scanner (@modules) {
|
||||
if ($scanner ismatch 'scanner/(.*?)/\1_version') {
|
||||
%o = call($client, "module.options", "auxiliary", $scanner);
|
||||
if ('RPORT' in %o) {
|
||||
$port = %o['RPORT']['default'];
|
||||
push(%ports[$port], $scanner);
|
||||
}
|
||||
|
||||
push(@launch, @c);
|
||||
}
|
||||
safetyCheck();
|
||||
}
|
||||
}
|
||||
|
||||
# add these ports to our list of ports to scan.. these come from querying all of Metasploit's modules
|
||||
# for the default ports
|
||||
foreach $port (@(50000, 21, 1720, 80, 443, 143, 3306, 1521, 110, 5432, 50013, 25, 161, 22, 23, 17185, 135, 8080, 4848, 1433, 5560, 512, 513, 514, 445, 5900, 5038, 111, 139, 49, 515, 7787, 2947, 7144, 9080, 8812, 2525, 2207, 3050, 5405, 1723, 1099, 5555, 921, 10001, 123, 3690, 548, 617, 6112, 6667, 3632, 783, 10050, 38292, 12174, 2967, 5168, 3628, 7777, 6101, 10000, 6504, 41523, 41524, 2000, 1900, 10202, 6503, 6070, 6502, 6050, 2103, 41025, 44334, 2100, 5554, 12203, 26000, 4000, 1000, 8014, 5250, 34443, 8028, 8008, 7510, 9495, 1581, 8000, 18881, 57772, 9090, 9999, 81, 3000, 8300, 8800, 8090, 389, 10203, 5093, 1533, 13500, 705, 623, 4659, 20031, 16102, 6080, 6660, 11000, 19810, 3057, 6905, 1100, 10616, 10628, 5051, 1582, 65535, 105, 22222, 30000, 113, 1755, 407, 1434, 2049, 689, 3128, 20222, 20034, 7580, 7579, 38080, 12401, 910, 912, 11234, 46823, 5061, 5060, 2380, 69, 5800, 62514, 42, 5631, 902)) {
|
||||
$temp = %ports[$port];
|
||||
}
|
||||
|
||||
# add a few left out modules
|
||||
push(%ports['445'], "scanner/smb/smb_version");
|
||||
|
||||
[$queue append: "[*] Launching TCP scan"];
|
||||
[$queue addCommand: $null, "use auxiliary/scanner/portscan/tcp"];
|
||||
[$queue setOptions: %(PORTS => join(", ", keys(%ports)), RHOSTS => $hosts, THREADS => 24)];
|
||||
[$queue addCommand: "x", "run -j"];
|
||||
|
||||
[$queue addSessionListener: lambda({
|
||||
this('$start @launch');
|
||||
local('$text $host $port $hosts $modules $module $options');
|
||||
|
||||
foreach $text (split("\n", $3)) {
|
||||
if ($text ismatch '... (.*?):(\d+) - TCP OPEN') {
|
||||
($host, $port) = matched();
|
||||
push(%discover[$port], $host);
|
||||
}
|
||||
else if ($text ismatch '... Scanned \d+ of \d+ hosts .100. complete.' && $start is $null) {
|
||||
$start = 1;
|
||||
[$queue append: "\n[*] Starting host discovery scans"];
|
||||
|
||||
# gather up the list of modules that we will launch...
|
||||
foreach $port => $hosts (%discover) {
|
||||
if ($port in %ports) {
|
||||
$modules = %ports[$port];
|
||||
foreach $module ($modules) {
|
||||
push(@launch, @($module, %(RHOSTS => join(", ", $hosts), RPORT => $port, THREADS => 24)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($text ismatch '... Scanned \d+ of \d+ hosts .100. complete.' || $text ismatch '... Auxiliary failed: .*') {
|
||||
if (size(@launch) == 0) {
|
||||
$time = (ticks() - $time) / 1000.0;
|
||||
|
||||
[[$console getWindow] append: "\n[*] Scan complete in $time $+ s\n"];
|
||||
}
|
||||
else {
|
||||
[[$console getWindow] append: "\n[*] " . size(@launch) . " scan" . iff(size(@launch) != 1, "s") . " to go...\n"];
|
||||
thread(lambda({
|
||||
local('$command');
|
||||
foreach $command ($commands) {
|
||||
[$console sendString: "$command $+ \n"];
|
||||
yield 250;
|
||||
}
|
||||
}, \$console, $commands => shift(@launch)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, \$console, \%ports, \%discover, $start => 1, @launch => @(), $time => ticks())];
|
||||
|
||||
[[$console getWindow] append: "[*] Building list of scan ports and modules\n"];
|
||||
|
||||
# build up a list of scan ports
|
||||
foreach $index => $scanner (@modules) {
|
||||
if ($scanner ismatch 'scanner/(.*?)/\1_version') {
|
||||
%o = call($client, "module.options", "auxiliary", $scanner);
|
||||
if ('RPORT' in %o) {
|
||||
$port = %o['RPORT']['default'];
|
||||
push(%ports[$port], $scanner);
|
||||
}
|
||||
|
||||
safetyCheck();
|
||||
if ($text ismatch '... Scanned \d+ of \d+ hosts .100. complete.' && size(@launch) > 0) {
|
||||
[$queue append: "\n[*] " . size(@launch) . " scan" . iff(size(@launch) != 1, "s") . " to go..."];
|
||||
($module, $options) = shift(@launch);
|
||||
[$queue addCommand: $null, "use $module"];
|
||||
[$queue setOptions: $options];
|
||||
[$queue addCommand: $null, "run -j"];
|
||||
}
|
||||
else if ($text ismatch '... Scanned \d+ of \d+ hosts .100. complete.' && size(@launch) == 0) {
|
||||
$time = (ticks() - $time) / 1000.0;
|
||||
[$queue append: "\n[*] Scan complete in $time $+ s"];
|
||||
}
|
||||
}
|
||||
}, \$hosts, \%ports, \@modules, \%discover, \$queue, $time => ticks())];
|
||||
|
||||
# add these ports to our list of ports to scan.. these come from querying all of Metasploit's modules
|
||||
# for the default ports
|
||||
foreach $port (@(50000, 21, 1720, 80, 443, 143, 3306, 1521, 110, 5432, 50013, 25, 161, 22, 23, 17185, 135, 8080, 4848, 1433, 5560, 512, 513, 514, 445, 5900, 5038, 111, 139, 49, 515, 7787, 2947, 7144, 9080, 8812, 2525, 2207, 3050, 5405, 1723, 1099, 5555, 921, 10001, 123, 3690, 548, 617, 6112, 6667, 3632, 783, 10050, 38292, 12174, 2967, 5168, 3628, 7777, 6101, 10000, 6504, 41523, 41524, 2000, 1900, 10202, 6503, 6070, 6502, 6050, 2103, 41025, 44334, 2100, 5554, 12203, 26000, 4000, 1000, 8014, 5250, 34443, 8028, 8008, 7510, 9495, 1581, 8000, 18881, 57772, 9090, 9999, 81, 3000, 8300, 8800, 8090, 389, 10203, 5093, 1533, 13500, 705, 623, 4659, 20031, 16102, 6080, 6660, 11000, 19810, 3057, 6905, 1100, 10616, 10628, 5051, 1582, 65535, 105, 22222, 30000, 113, 1755, 407, 1434, 2049, 689, 3128, 20222, 20034, 7580, 7579, 38080, 12401, 910, 912, 11234, 46823, 5061, 5060, 2380, 69, 5800, 62514, 42, 5631, 902)) {
|
||||
$temp = %ports[$port];
|
||||
}
|
||||
|
||||
# add a few left out modules
|
||||
push(%ports['445'], "scanner/smb/smb_version");
|
||||
|
||||
[[$console getWindow] append: "[*] Launching TCP scan\n"];
|
||||
[$console sendString: "use auxiliary/scanner/portscan/tcp\n"];
|
||||
[$console sendString: "set PORTS " . join(", ", keys(%ports)) . "\n"];
|
||||
[$console sendString: "set RHOSTS $hosts $+ \n"];
|
||||
[$console sendString: "set THREADS 24\n"];
|
||||
[$console sendString: "run -j\n"];
|
||||
}
|
||||
[$queue start];
|
||||
}, \$hosts, \@modules));
|
||||
}
|
||||
|
|
|
@ -323,9 +323,9 @@ sub launchBruteForce {
|
|||
[$console addCommand: $null, "use $type $+ / $+ $module"];
|
||||
foreach $key => $value ($options) {
|
||||
$value = strrep($value, '\\', '\\\\');
|
||||
[$console addCommand: $null, "set $key $value"];
|
||||
}
|
||||
[$console addCommand: $null, "set REMOVE_USERPASS_FILE true"];
|
||||
$options['REMOVE_USERPASS_FILE'] = "true";
|
||||
[$console setOptions: $options];
|
||||
[$console addCommand: $null, "run -j"];
|
||||
[$console start];
|
||||
}, $type => $1, $module => $2, $options => $3, $title => $4));
|
||||
|
|
|
@ -47,8 +47,6 @@ sub client {
|
|||
%async['module.execute'] = 1;
|
||||
%async['core.setg'] = 1;
|
||||
%async['console.destroy'] = 1;
|
||||
%async['console.write'] = 1;
|
||||
%async['session.shell_write'] = 1;
|
||||
|
||||
#
|
||||
# verify the client
|
||||
|
@ -189,13 +187,15 @@ sub client {
|
|||
release($poll_lock);
|
||||
writeObject($handle, result(%()));
|
||||
}
|
||||
else if ($method eq "armitage.push") {
|
||||
($null, $data) = $args;
|
||||
event("< $+ $[10]eid $+ > " . $data);
|
||||
writeObject($handle, result(%()));
|
||||
}
|
||||
else if ($method eq "armitage.poll") {
|
||||
else if ($method eq "armitage.poll" || $method eq "armitage.push") {
|
||||
acquire($poll_lock);
|
||||
if ($method eq "armitage.push") {
|
||||
($null, $data) = $args;
|
||||
foreach $temp (split("\n", $data)) {
|
||||
push(@events, formatDate("HH:mm:ss") . " < $+ $[10]eid $+ > " . $data);
|
||||
}
|
||||
}
|
||||
|
||||
if (size(@events) > $index) {
|
||||
$rv = result(%(data => join("", sublist(@events, $index)), encoding => "base64", prompt => "$eid $+ > "));
|
||||
$index = size(@events);
|
||||
|
|
|
@ -138,9 +138,6 @@ sub createConsolePanel {
|
|||
else if ($word in @payloads) {
|
||||
[$thread sendString: "set PAYLOAD $word $+ \n"];
|
||||
}
|
||||
else if (-exists $word && !$REMOTE) {
|
||||
saveFile($word);
|
||||
}
|
||||
}, \$thread)];
|
||||
|
||||
return @($result['id'], $console, $thread);
|
||||
|
@ -159,9 +156,7 @@ sub createConsoleTab {
|
|||
logCheck($console, $host, $file);
|
||||
}
|
||||
|
||||
dispatchEvent(lambda({
|
||||
[$frame addTab: iff($title is $null, "Console", $title), $console, $thread, $host];
|
||||
}, $title => $1, \$console, \$thread, \$host));
|
||||
[$frame addTab: iff($1 is $null, "Console", $1), $console, $thread, $host];
|
||||
return $thread;
|
||||
}
|
||||
|
||||
|
@ -479,10 +474,8 @@ sub module_execute {
|
|||
$queue = createDisplayTab($1, \$host);
|
||||
|
||||
[$queue addCommand: $null, "use $1 $+ / $+ $2"];
|
||||
foreach $key => $value ($3) {
|
||||
[$queue addCommand: $null, "set $key $value"];
|
||||
}
|
||||
|
||||
[$queue setOptions: $3];
|
||||
|
||||
if ($1 eq "exploit") {
|
||||
[$queue addCommand: $null, "exploit -j"];
|
||||
}
|
||||
|
|
|
@ -143,8 +143,13 @@ public class ConsoleClient implements Runnable, ActionListener {
|
|||
}
|
||||
}
|
||||
|
||||
connection.execute(writeCommand, new Object[] { session, text });
|
||||
read = readResponse();
|
||||
if ("armitage.push".equals(writeCommand)) {
|
||||
read = (Map)connection.execute(writeCommand, new Object[] { session, text });
|
||||
}
|
||||
else {
|
||||
connection.execute(writeCommand, new Object[] { session, text });
|
||||
read = readResponse();
|
||||
}
|
||||
processRead(read);
|
||||
|
||||
fireSessionWroteEvent(text);
|
||||
|
|
|
@ -21,8 +21,9 @@ public class ConsoleQueue implements Runnable {
|
|||
protected Console display = null;
|
||||
|
||||
private static class Command {
|
||||
public Object token;
|
||||
public String text;
|
||||
public Object token = null;
|
||||
public String text = null;
|
||||
public Map assign = null;
|
||||
public long start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
@ -92,6 +93,78 @@ public class ConsoleQueue implements Runnable {
|
|||
}
|
||||
|
||||
protected void processCommand(Command c) {
|
||||
if (c.assign == null) {
|
||||
processNormalCommand(c);
|
||||
}
|
||||
else {
|
||||
processAssignCommand(c);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processAssignCommand(Command c) {
|
||||
try {
|
||||
/* absorb anything misc */
|
||||
Map read = readResponse();
|
||||
String prompt = ConsoleClient.cleanText(read.get("prompt") + "");
|
||||
|
||||
StringBuffer writeme = new StringBuffer();
|
||||
Set expected = new HashSet();
|
||||
|
||||
/* loop through our values to assign */
|
||||
Iterator i = c.assign.entrySet().iterator();
|
||||
while (i.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry)i.next();
|
||||
String key = entry.getKey() + "";
|
||||
String value = entry.getValue() + "";
|
||||
writeme.append("set " + key + " " + value + "\n");
|
||||
expected.add(key);
|
||||
}
|
||||
|
||||
/* write our command to whateverz */
|
||||
connection.execute("console.write", new Object[] { consoleid, writeme.toString() });
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
/* process through all of our values */
|
||||
while (expected.size() > 0) {
|
||||
Thread.yield();
|
||||
Map temp = (Map)(connection.execute("console.read", new Object[] { consoleid }));
|
||||
if (!isEmptyData(temp.get("data") + "")) {
|
||||
String[] lines = (temp.get("data") + "").split("\n");
|
||||
for (int x = 0; x < lines.length; x++) {
|
||||
if (lines[x].indexOf(" => ") != -1) {
|
||||
String[] kv = lines[x].split(" => ");
|
||||
|
||||
/* remove any set variables from our set of stuff */
|
||||
expected.remove(kv[0]);
|
||||
|
||||
if (display != null) {
|
||||
display.append(prompt + "set " + kv[0] + " " + kv[1] + "\n");
|
||||
display.append(lines[x] + "\n");
|
||||
}
|
||||
}
|
||||
else if (display != null) {
|
||||
display.append(lines[x] + "\n");
|
||||
}
|
||||
else {
|
||||
System.err.println("Batch read unexpected: " + lines[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((System.currentTimeMillis() - start) > 10000) {
|
||||
/* this is a safety check to keep a console from spinning waiting for one command to complete. Shouldn't trigger--unless I mess up :) */
|
||||
System.err.println("Timed out: " + c.assign + " vs. " + expected);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.err.println(consoleid + " -> " + c.text);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void processNormalCommand(Command c) {
|
||||
Map read = null;
|
||||
try {
|
||||
if (c.text.startsWith("ECHO ")) {
|
||||
|
@ -161,6 +234,20 @@ public class ConsoleQueue implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
public void append(String text) {
|
||||
addCommand(null, "ECHO " + text + "\n");
|
||||
}
|
||||
|
||||
public void setOptions(Map options) {
|
||||
synchronized (this) {
|
||||
Command temp = new Command();
|
||||
temp.token = null;
|
||||
temp.text = null;
|
||||
temp.assign = options;
|
||||
commands.add(temp);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCommand(Object token, String text) {
|
||||
synchronized (this) {
|
||||
if (text.trim().equals("")) {
|
||||
|
|
|
@ -31,19 +31,20 @@ public class Colors {
|
|||
colorTable = new Color[16];
|
||||
colorTable[0] = Color.white;
|
||||
colorTable[1] = new Color(0, 0, 0);
|
||||
colorTable[2] = new Color(0, 0, 128);
|
||||
colorTable[3] = new Color(0, 144, 0);
|
||||
colorTable[4] = new Color(255, 0, 0);
|
||||
colorTable[5] = new Color(128, 0, 0);
|
||||
colorTable[6] = new Color(160, 0, 160);
|
||||
colorTable[7] = new Color(255, 128, 0);
|
||||
colorTable[8] = new Color(255, 255, 0);
|
||||
colorTable[9] = new Color(0, 255, 0);
|
||||
colorTable[10] = new Color(0, 144, 144);
|
||||
colorTable[11] = new Color(0, 255, 255);
|
||||
colorTable[12] = new Color(0, 0, 255);
|
||||
colorTable[13] = new Color(255, 0, 255);
|
||||
colorTable[14] = new Color(128, 128, 128);
|
||||
colorTable[2] = Color.decode("#3465A4");
|
||||
colorTable[3] = Color.decode("#4E9A06");
|
||||
colorTable[4] = Color.decode("#EF2929"); //new Color(255, 0, 0);
|
||||
colorTable[5] = Color.decode("#CC0000");
|
||||
colorTable[6] = Color.decode("#75507B");
|
||||
colorTable[7] = Color.decode("#C4A000");
|
||||
colorTable[8] = Color.decode("#FCE94F");
|
||||
colorTable[9] = Color.decode("#8AE234");
|
||||
colorTable[10] = Color.decode("#06989A");
|
||||
colorTable[11] = Color.decode("#34E2E2");
|
||||
colorTable[12] = Color.decode("#729FCF");
|
||||
colorTable[13] = Color.decode("#AD7FA8");
|
||||
//colorTable[14] = Color.decode("#555753");
|
||||
colorTable[14] = Color.decode("#808080");
|
||||
colorTable[15] = Color.lightGray;
|
||||
|
||||
for (int x = 0; x < 16; x++) {
|
||||
|
@ -62,8 +63,12 @@ public class Colors {
|
|||
|
||||
/* strip format codes from the text */
|
||||
public String strip(String text) {
|
||||
StringBuffer buffer = new StringBuffer(text.length());
|
||||
Fragment f = parse(text);
|
||||
return strip(f);
|
||||
}
|
||||
|
||||
private String strip(Fragment f) {
|
||||
StringBuffer buffer = new StringBuffer(128);
|
||||
while (f != null) {
|
||||
buffer.append(f.text);
|
||||
f = f.next;
|
||||
|
@ -71,13 +76,11 @@ public class Colors {
|
|||
return buffer.toString();
|
||||
}
|
||||
|
||||
public void append(JTextPane console, String text) {
|
||||
StyledDocument doc = console.getStyledDocument();
|
||||
Fragment f = parse(text);
|
||||
private void append(StyledDocument doc, Fragment f) {
|
||||
while (f != null) {
|
||||
try {
|
||||
if (f.text.length() > 0)
|
||||
doc.insertString(doc.getLength(), f.text.toString(), showcolors ? f.attr : null);
|
||||
doc.insertString(doc.getLength(), f.text.toString(), f.attr);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
@ -86,14 +89,46 @@ public class Colors {
|
|||
}
|
||||
}
|
||||
|
||||
public void append(JTextPane console, String text) {
|
||||
StyledDocument doc = console.getStyledDocument();
|
||||
Fragment f = parse(text);
|
||||
if (showcolors) {
|
||||
append(doc, f);
|
||||
}
|
||||
else {
|
||||
append(doc, parse(strip(f)));
|
||||
}
|
||||
}
|
||||
|
||||
public void set(JTextPane console, String text) {
|
||||
console.setText("");
|
||||
append(console, text);
|
||||
/* don't update that which we do not need to update */
|
||||
Fragment f = parse(text);
|
||||
if (strip(f).equals(console.getText())) {
|
||||
return;
|
||||
}
|
||||
|
||||
StyledDocument doc = console.getStyledDocument();
|
||||
try {
|
||||
doc.remove(0, doc.getLength());
|
||||
if (showcolors)
|
||||
append(doc, f);
|
||||
else
|
||||
append(doc, parse(strip(f)));
|
||||
}
|
||||
catch (BadLocationException ex) { ex.printStackTrace(); }
|
||||
|
||||
/* this is a dumb hack to prevent the height from getting out of whack */
|
||||
console.setSize(new Dimension(1000, console.getSize().height));
|
||||
}
|
||||
|
||||
private Fragment parse(String text) {
|
||||
|
||||
Fragment current = new Fragment();
|
||||
Fragment first = current;
|
||||
|
||||
if (text == null)
|
||||
return current;
|
||||
|
||||
char[] data = text.toCharArray();
|
||||
int fore, back;
|
||||
|
||||
|
|
|
@ -271,12 +271,12 @@ public class Console extends JPanel implements FocusListener {
|
|||
|
||||
if (breakp != -1) {
|
||||
colors.append(console, _text.substring(0, breakp + 1));
|
||||
colors.set(prompt, _text.substring(breakp + 1) + " ");
|
||||
updatePrompt(_text.substring(breakp + 1) + " ");
|
||||
if (log != null)
|
||||
log.print(colors.strip(_text.substring(0, breakp + 1)));
|
||||
}
|
||||
else {
|
||||
colors.set(prompt, _text);
|
||||
updatePrompt(_text);
|
||||
}
|
||||
promptLock = true;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public class SearchPanel extends JPanel implements ActionListener {
|
|||
try {
|
||||
String text = component.getText();
|
||||
int lastIndex = -1;
|
||||
while ((lastIndex = text.indexOf(searchstr, lastIndex + 1)) != -1) {
|
||||
while ((lastIndex = text.replaceAll("\r", "").indexOf(searchstr, lastIndex + 1)) != -1) {
|
||||
component.getHighlighter().addHighlight(
|
||||
lastIndex,
|
||||
lastIndex + searchstr.length(),
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
Armitage Changelog
|
||||
==================
|
||||
|
||||
21 May 12
|
||||
---------
|
||||
- Added a hack to prevent the input area from flickering when the
|
||||
prompt changes.
|
||||
- Updated the color palette to something a little more subtle.
|
||||
- Added an optimization to how modules are launched. This will make
|
||||
a difference for team use in high latency situations.
|
||||
- Rewrote MSF Scans feature to use console queue. This option is more
|
||||
reliable and it makes the code easier to follow.
|
||||
- Added a hack to combine chat message writes with a read request.
|
||||
This will make the event log more responsive in a high latency
|
||||
situation (can't you tell I care about this "situation")
|
||||
- Fixed text highlights through Ctrl+F on Windows. UNIX platforms
|
||||
were always OK. Another good reason to not use these tools on
|
||||
Windows. Ever.
|
||||
- View -> Downloads Sync Files feature now works on Windows. It looks
|
||||
like leaving those pesky :'s in the file paths is bad.
|
||||
|
||||
17 May 12
|
||||
---------
|
||||
- Fixed bug with loot/download viewer breaking with a font resize.
|
||||
|
|
Loading…
Reference in New Issue