Merge remote branch 'rsmudge/armitage'

unstable
Tod Beardsley 2012-11-26 10:52:06 -06:00
commit 8d6289d8d6
16 changed files with 196 additions and 45 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,29 @@
Armitage Changelog
==================
26 Nov 12 (tested against msf 16114)
---------
- Windows command shell tab is now friendlier to commands that prompt
for input (e.g., time command)
- [host] -> Meterpreter -> Access -> Escalate Privileges now shows all
the framework's new exploit/windows/local modules too
- [host] -> Shell -> Post Modules now shows the framework's unix/local
and exploit/linux/local modules
- Added Ctrl+I shortcut. Lets you choose a session to interact with.
- Added Steal Token button to Processes dialog.
- Armitage now asks Metasploit for a non-expiring authentication token.
This will prevent Armitage from losing its access to msfrpcd when you
put your computer to sleep or pause the VM running Metasploit.
- add_user and add_[local]group_user now show all of their output when
the -h flag is used to operate on a remote host.
- added a Delete menu to creds table. Right-click a cred to delete it
Cortana Updates (for scripters)
--------
- aliased &data_delete to &data_clear to match the documentation.
- &file_get, &loot_get, and &file_content no longer delete the remote
file when connected to a teamserver.
16 Oct 12 (tested against msf 15972)
---------
- Added port 5985 to MSF Scans list.

View File

@ -3,7 +3,7 @@
<center><h1>Armitage 1.44</h1></center>
<p>An attack management tool for Metasploit&reg;
<br />Release: 16 Oct 12</p>
<br />Release: 26 Nov 12</p>
<br />
<p>Developed by:</p>

View File

@ -550,6 +550,11 @@ sub data_delete {
call("db.key_clear", $1);
}
# data_clear('key') -- clears all data associated with the specified key
sub data_clear {
data_delete($1);
}
# data_add('key', $object) -- appends value into the database...
sub data_add {
local('$buffer $data');
@ -860,7 +865,7 @@ sub file_content {
}
else {
local('%r');
%r = call("armitage.download", $1);
%r = call("armitage.download_nodelete", $1);
return %r['data'];
}
}

View File

@ -623,6 +623,34 @@ sub host_attack_items {
}
}
sub chooseSession {
local('@data $sid $data $host $hdata $temp $tablef');
# obtain a list of sessions
foreach $host (keys(%hosts)) {
foreach $sid => $data (getSessions($host)) {
$temp = copy($data);
$temp['sid'] = $sid;
push(@data, $temp);
}
}
# sort the session data
@data = sort({ return $1['sid'] <=> $2['sid']; }, @data);
# update the table widths
$tablef = {
[[$1 getColumn: "sid"] setPreferredWidth: 100];
[[$1 getColumn: "session_host"] setPreferredWidth: 300];
[[$1 getColumn: "info"] setPreferredWidth: 1024];
};
# let the user choose a session
quickListDialog("Choose a session", "Select", @("sid", "sid", "session_host", "info"), @data, $width => 640, $height => 240, lambda({
[$call : $1];
}, $call => $4), \$tablef);
}
sub addFileListener {
local('$table $model $actions');
($table, $model, $actions) = @_;
@ -652,33 +680,7 @@ sub addFileListener {
$actions["WORDLIST"] = $actions["*FILE*"];
# set up an action to choose a session
$actions["SESSION"] = {
local('@data $sid $data $host $hdata $temp $tablef');
# obtain a list of sessions
foreach $host (keys(%hosts)) {
foreach $sid => $data (getSessions($host)) {
$temp = copy($data);
$temp['sid'] = $sid;
push(@data, $temp);
}
}
# sort the session data
@data = sort({ return $1['sid'] <=> $2['sid']; }, @data);
# update the table widths
$tablef = {
[[$1 getColumn: "sid"] setPreferredWidth: 100];
[[$1 getColumn: "session_host"] setPreferredWidth: 300];
[[$1 getColumn: "info"] setPreferredWidth: 1024];
};
# let the user choose a session
quickListDialog("Choose a session", "Select", @("sid", "sid", "session_host", "info"), @data, $width => 640, $height => 240, lambda({
[$call : $1];
}, $call => $4), \$tablef);
};
$actions["SESSION"] = lambda(&chooseSession);
# set up an action to pop up a file chooser for different file type values.
$actions["RHOST"] = {

View File

@ -239,6 +239,23 @@ sub init_menus {
dynmenu($top, "Help", 'H', &help_items);
# setup some global keyboard shortcuts...
[$frame bindKey: "Ctrl+I", {
thread({
chooseSession($null, $null, $null, {
local('$session');
$session = sessionData($1);
if ($session is $null) {
showError("Session $1 does not exist");
}
else if ($session['desc'] eq "Meterpreter") {
createMeterpreterTab($1);
}
else {
createShellSessionTab(\$session, $sid => $1);
}
});
});
}];
[$frame bindKey: "Ctrl+N", { thread(&createConsoleTab); }];
[$frame bindKey: "Ctrl+W", { [$frame openActiveTab]; }];
[$frame bindKey: "Ctrl+D", { [$frame closeActiveTab]; }];

View File

@ -104,13 +104,16 @@ sub parseMeterpreter {
}
sub interpretMeterpreterCommand {
if ([$1 getActionCommand] eq "shell") {
local('$c');
$c = [lc([$1 getActionCommand] . "") trim];
if ($c eq "shell") {
createShellTab($sid);
}
else if ([$1 getActionCommand] eq "screenshot") {
else if ($c eq "screenshot") {
[createScreenshotViewer($sid)];
}
else if ([$1 getActionCommand] eq "webcam_snap") {
else if ($c eq "webcam_snap") {
[createWebcamViewer($sid)];
}
}
@ -168,7 +171,9 @@ sub showMeterpreterMenu {
}, $sid => "$sid"));
item($j, "Escalate Privileges", 'E', lambda({
showPostModules($sid, "*escalate*");
showPostModules($sid, "*escalate*",
ohash(exploit => buildTree(filter({ return iff("*windows/local/*" iswm $1, $1); }, @exploits)))
);
}, $sid => "$sid"));
item($j, "Steal Token" , "S", lambda({

View File

@ -251,7 +251,7 @@ sub showExploitModules {
# shows the post modules compatible with a session... for this to work, the
# code that creates the module browser must call: let(&showPostModules, $tree => ..., $search => ...)
sub showPostModules {
local('@allowed $2');
local('@allowed $2 $3');
@allowed = getOS(sessionToOS($1));
fork({
local('$modules %list $model');
@ -270,7 +270,13 @@ sub showPostModules {
$modules = filter(lambda({ return iff($filter iswm $1, $1); }, \$filter), $modules);
}
%list = ohash(post => buildTree($modules));
if ($base is $null) {
%list = ohash(post => buildTree($modules));
}
else {
%list = $base;
%list['post'] = buildTree($modules);
}
$model = treeNodes($null, %list);
dispatchEvent(lambda({
@ -282,7 +288,7 @@ sub showPostModules {
}
[$search setText: ""];
}, \$search, \$tree, \$model));
}, \$tree, \$search, $sid => $1, \$client, \@allowed, $filter => $2);
}, \$tree, \$search, $sid => $1, \$client, \@allowed, $filter => $2, $base => $3);
}
sub createModuleBrowserTab {

View File

@ -96,6 +96,33 @@ sub createCredentialsTab {
($dialog, $table, $model) = show_hashes("", 320);
[$dialog removeAll];
addMouseListener($table, lambda({
if ([$1 isPopupTrigger]) {
local('$popup $entries');
$popup = [new JPopupMenu];
$entries = [$model getSelectedValuesFromColumns: $table, @("user", "pass", "host")];
item($popup, "Delete", 'D', lambda({
local('$queue $entry $user $pass $host');
$queue = [new armitage.ConsoleQueue: $client];
foreach $entry ($entries) {
($user, $pass, $host) = $entry;
[$queue addCommand: $null, "creds -d $host -u $user -P $pass"];
}
[$queue addCommand: "x", "creds -h"];
[$queue addListener: lambda({
[$queue stop];
refreshCredsTable($model, $null);
}, \$model, \$queue)];
[$queue start];
[$queue stop];
}, \$table, \$model, \$entries));
[$popup show: [$1 getSource], [$1 getX], [$1 getY]];
}
}, \$table, \$model));
$panel = [new JPanel];
[$panel setLayout: [new BorderLayout]];
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];

View File

@ -75,7 +75,7 @@ sub createProcessBrowser {
[$panel add: [new JScrollPane: $table], [BorderLayout CENTER]];
local('$a $b $bb $c');
local('$a $b $bb $bbb $c');
$a = [new JButton: "Kill"];
[$a addActionListener: lambda({
local('$procs $v');
@ -105,6 +105,15 @@ sub createProcessBrowser {
}
}, $m => $1, \$table, \$model)];
$bbb = [new JButton: "Steal Token"];
[$bbb addActionListener: lambda({
local('$v');
$v = [$model getSelectedValue: $table];
if ($v !is $null) {
m_cmd_callback($m, "steal_token $v", { if ($0 eq "end") { showError(["$2" trim]); } });
}
}, $m => $1, \$table, \$model)];
$c = [new JButton: "Refresh"];
[$c addActionListener:
lambda({
@ -112,7 +121,7 @@ sub createProcessBrowser {
}, $m => $1)
];
[$panel add: center($a, $b, $bb, $c), [BorderLayout SOUTH]];
[$panel add: center($a, $b, $bb, $bbb, $c), [BorderLayout SOUTH]];
[$frame addTab: "Processes $1", $panel, $null, "Processes " . sessionToHost($1)];
m_cmd($1, "ps");

View File

@ -163,6 +163,10 @@ global('%shells $ashell $achannel %maxq %wait');
# make our shell heuristic tolerant of prompts like this.
%wait[$achannel] = $null;
}
else if (size($v) > 0 && $v[-1] ismatch '.*?:') {
# make our shell heuristic tolerant of more prompts... this is from the time command
%wait[$achannel] = $null;
}
else if (size($v) > 0 && $v[-1] !ismatch '(.*?):\\\\.*?\\>') {
m_cmd($1, "read $achannel");
}
@ -254,7 +258,14 @@ sub showShellMenu {
}
item($1, "Post Modules", 'P', lambda({
showPostModules($sid);
if ("*Windows*" iswm sessionToOS($sid)) {
showPostModules($sid);
}
else {
showPostModules($sid, "*",
ohash(exploit => buildTree(filter({ return iff("*u*x/local/*" iswm $1, $1); }, @exploits)))
);
}
}, \$sid));
separator($1);

View File

@ -164,6 +164,21 @@ public class MeterpreterSession implements Runnable {
readUntilSuccessful(c, false);
return;
}
else if (c.text.startsWith("add_user") && !teammode) {
/* when -h [host] is specified, attempts to add a user on another
host. In this case, output is split into multiple chunks.
This applies to add_localgroup_user and add_group_user too. */
readUntilSuccessful(c, false);
return;
}
else if (c.text.startsWith("add_localgroup_user") && !teammode) {
readUntilSuccessful(c, false);
return;
}
else if (c.text.startsWith("add_group_user") && !teammode) {
readUntilSuccessful(c, false);
return;
}
//System.err.println("(" + session + ") latency: " + (System.currentTimeMillis() - c.start) + " -- " + c.text);

View File

@ -57,6 +57,13 @@ public class MsgRpcImpl extends RpcConnectionImpl {
/* login to msf server */
Object[] params = new Object[]{ username, password };
Map results = exec("auth.login",params);
/* save the temp token (lasts for 5 minutes of inactivity) */
rpcToken = results.get("token").toString();
/* generate a non-expiring token and use that */
params = new Object[]{ rpcToken };
results = exec("auth.token_generate", params);
rpcToken = results.get("token").toString();
}

View File

@ -33,10 +33,6 @@ public class KeyBindings implements KeyEventDispatcher {
}
public boolean dispatchKeyEvent(KeyEvent ev) {
if (ev.getID() != KeyEvent.KEY_PRESSED) {
return false;
}
StringBuffer description = new StringBuffer();
if (ev.getModifiers() != 0) {
description.append(getKeyModifiers(ev));
@ -46,9 +42,14 @@ public class KeyBindings implements KeyEventDispatcher {
synchronized (this) {
if (bindings.containsKey(description.toString())) {
SwingUtilities.invokeLater(new ExecuteBinding(description.toString(), (KeyHandler)bindings.get(description.toString())));
ev.consume();
return true;
if (ev.getID() != KeyEvent.KEY_PRESSED) {
return false;
}
else {
SwingUtilities.invokeLater(new ExecuteBinding(description.toString(), (KeyHandler)bindings.get(description.toString())));
return true;
}
}
}

View File

@ -1,6 +1,29 @@
Armitage Changelog
==================
26 Nov 12 (tested against msf 16114)
---------
- Windows command shell tab is now friendlier to commands that prompt
for input (e.g., time command)
- [host] -> Meterpreter -> Access -> Escalate Privileges now shows all
the framework's new exploit/windows/local modules too
- [host] -> Shell -> Post Modules now shows the framework's unix/local
and exploit/linux/local modules
- Added Ctrl+I shortcut. Lets you choose a session to interact with.
- Added Steal Token button to Processes dialog.
- Armitage now asks Metasploit for a non-expiring authentication token.
This will prevent Armitage from losing its access to msfrpcd when you
put your computer to sleep or pause the VM running Metasploit.
- add_user and add_[local]group_user now show all of their output when
the -h flag is used to operate on a remote host.
- added a Delete menu to creds table. Right-click a cred to delete it
Cortana Updates (for scripters)
--------
- aliased &data_delete to &data_clear to match the documentation.
- &file_get, &loot_get, and &file_content no longer delete the remote
file when connected to a teamserver.
16 Oct 12 (tested against msf 15972)
---------
- Added port 5985 to MSF Scans list.