diff --git a/data/gui/msfgui.jar b/data/gui/msfgui.jar
index 903a90ac92..42ae6d84e4 100644
Binary files a/data/gui/msfgui.jar and b/data/gui/msfgui.jar differ
diff --git a/external/source/gui/msfguijava/src/msfgui/MainFrame.form b/external/source/gui/msfguijava/src/msfgui/MainFrame.form
index d447959092..94e5b89cb1 100644
--- a/external/source/gui/msfguijava/src/msfgui/MainFrame.form
+++ b/external/source/gui/msfguijava/src/msfgui/MainFrame.form
@@ -131,7 +131,7 @@
-
+
@@ -161,7 +161,7 @@
-
+
@@ -191,7 +191,7 @@
-
+
@@ -221,7 +221,7 @@
-
+
@@ -251,7 +251,7 @@
-
+
@@ -281,7 +281,7 @@
-
+
@@ -308,7 +308,7 @@
-
+
diff --git a/external/source/gui/msfguijava/src/msfgui/MainFrame.java b/external/source/gui/msfguijava/src/msfgui/MainFrame.java
index c6e30fbcbf..8df848821e 100644
--- a/external/source/gui/msfguijava/src/msfgui/MainFrame.java
+++ b/external/source/gui/msfguijava/src/msfgui/MainFrame.java
@@ -5,7 +5,6 @@ package msfgui;
import java.awt.Component;
import java.awt.HeadlessException;
-import javax.swing.JTable;
import org.jdesktop.application.*;
import java.awt.event.*;
import java.io.*;
@@ -26,7 +25,6 @@ import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
-import javax.swing.table.DefaultTableModel;
import org.jdesktop.application.Task;
import org.jdesktop.swingworker.SwingWorker;
@@ -48,14 +46,8 @@ public class MainFrame extends FrameView {
public MainFrame(SingleFrameApplication app) {
super(app);
MsfFrame.setLnF();
+ connectRpc(); // Connect to RPC daemon
initComponents();
- eventsPane = new javax.swing.JScrollPane();
- eventsTable = new MsfTable(new String [] {
- "Host", "Created", "Updated", "Name", "Critical", "Username", "Info"
- });
- eventsTable.setName("eventsTable"); // NOI18N
- eventsPane.setViewportView(eventsTable);
- tabbedPane.addTab("Events", eventsPane); // NOI18N
sessionsTableModel = null;
sessionWindowMap = new HashMap();
@@ -121,14 +113,22 @@ public class MainFrame extends FrameView {
//Set up GUI, RPC connection, and recent modules
setupSessionsPollTimer();
setupPopupMenus();
+ if(rpcConn != null)
+ getModules();
MsfguiApp.fileChooser = new JFileChooser();
- connectRpc();
getFrame().addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
if(!MsfguiApp.shuttingDown && !confirmStop())
throw new RuntimeException("Closing aborted.");
}
});
+ //Events pane
+ eventsPane = new javax.swing.JScrollPane();
+ eventsTable = new MsfTable(rpcConn, new String [] {"Host", "Created", "Updated", "Name", "Critical", "Username", "Info"
+ }, "events", new String[]{"host","created_at","updated_at","name","critical","username", "info"});
+ eventsTable.setName("eventsTable"); // NOI18N
+ eventsPane.setViewportView(eventsTable);// Create a scrollable text area
+ tabbedPane.addTab("Events", eventsPane); // NOI18N
//Setup icon
this.getFrame().setIconImage( resourceMap.getImageIcon("main.icon").getImage());
//Disable tabs by default
@@ -147,6 +147,15 @@ public class MainFrame extends FrameView {
}
}
MsfFrame.updateSizes(getFrame());
+ // Setup table autoquery code
+ ((MsfTable)eventsTable).addAutoAdjuster(eventsPane);
+ ((MsfTable)hostsTable).addAutoAdjuster(hostsPane);
+ ((MsfTable)clientsTable).addAutoAdjuster(clientsPane);
+ ((MsfTable)servicesTable).addAutoAdjuster(servicesPane);
+ ((MsfTable)vulnsTable).addAutoAdjuster(vulnsPane);
+ ((MsfTable)notesTable).addAutoAdjuster(notesPane);
+ ((MsfTable)lootsTable).addAutoAdjuster(lootsPane);
+ ((MsfTable)credsTable).addAutoAdjuster(credsPane);
}
/** Before exit, check whether the daemon should be stopped or just the session terminated */
private boolean confirmStop() {
@@ -490,33 +499,26 @@ nameloop: for (int i = 0; i < names.length; i++) {
sessionsPane = new javax.swing.JScrollPane();
sessionsTable = new javax.swing.JTable();
hostsPane = new javax.swing.JScrollPane();
- hostsTable = new MsfTable(new String [] {
- "Created", "Address", "Address6", "MAC", "Name", "State", "OS name", "OS flavor", "OS SP", "OS lang", "Updated", "Purpose", "Info"
- });
+ hostsTable = new MsfTable(rpcConn, new String [] {"Created", "Address", "Address6", "MAC", "Name", "State", "OS name", "OS flavor", "OS SP", "OS lang", "Updated", "Purpose", "Info"}
+ , "hosts",new String[]{"created_at", "address", "address6", "mac", "name", "state", "os_name", "os_flavor", "os_sp", "os_lang", "updated_at", "purpose", "info"});
clientsPane = new javax.swing.JScrollPane();
- clientsTable = new MsfTable(new String [] {
- "Host", "UA String", "UA Name", "UA Ver", "Created", "Updated"
- });
+ clientsTable = new MsfTable(rpcConn, new String [] {"Host", "UA String", "UA Name", "UA Ver", "Created", "Updated"}
+ , "clients", new String[]{"host", "ua_string", "ua_name", "ua_ver", "created_at", "updated_at"});
servicesPane = new javax.swing.JScrollPane();
- servicesTable = new MsfTable(new String [] {
- "Host", "Created", "Updated", "Port", "Proto", "State", "Name", "Info"
- });
+ servicesTable = new MsfTable(rpcConn, new String [] {"Host", "Created", "Updated", "Port", "Proto", "State", "Name", "Info"}
+ , "services", new String[]{"host", "created_at", "updated_at", "port", "proto", "state", "name", "info"});
vulnsPane = new javax.swing.JScrollPane();
- vulnsTable = new MsfTable(new String [] {
- "Port", "Proto", "Time", "Host", "Name", "Refs"
- });
+ vulnsTable = new MsfTable(rpcConn, new String [] {"Port", "Proto", "Time", "Host", "Name", "Refs"
+ }, "vulns", new String[]{"port", "proto", "time", "host", "name", "refs"});
notesPane = new javax.swing.JScrollPane();
- notesTable = new MsfTable(new String [] {
- "Time", "Host", "Service", "Type", "Data"
- });
+ notesTable = new MsfTable(rpcConn, new String [] {"Time", "Host", "Service", "Type", "Data"
+ }, "notes", new String[]{"time", "host", "service", "type", "data"});
lootsPane = new javax.swing.JScrollPane();
- lootsTable = new MsfTable(new String [] {
- "Host", "Service", "Ltype", "Ctype", "Data", "Created", "Updated", "Name", "Info"
- });
+ lootsTable = new MsfTable(rpcConn,new String [] {"Host", "Service", "Ltype", "Ctype", "Data", "Created", "Updated", "Name", "Info"
+ }, "loots", new String[]{"host", "service", "ltype", "ctype", "data", "created_at", "updated_at", "name", "info"});
credsPane = new javax.swing.JScrollPane();
- credsTable = new MsfTable(new String [] {
- "Host", "Time", "Port", "Proto", "Sname", "Type", "User", "Pass", "Active"
- });
+ credsTable = new MsfTable(rpcConn, new String [] {"Host", "Time", "Port", "Proto", "Sname", "Type", "User", "Pass", "Active"
+ }, "creds", new String[]{"host", "time", "port", "proto", "sname", "type", "user", "pass", "active"});
menuBar = new javax.swing.JMenuBar();
javax.swing.JMenu fileMenu = new javax.swing.JMenu();
connectRpcMenuItem = new javax.swing.JMenuItem();
@@ -1191,7 +1193,6 @@ nameloop: for (int i = 0; i < names.length; i++) {
helpMenu.add(onlineHelpMenu);
aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
- aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
aboutMenuItem.setName("aboutMenuItem"); // NOI18N
helpMenu.add(aboutMenuItem);
@@ -1242,6 +1243,8 @@ nameloop: for (int i = 0; i < names.length; i++) {
private void connectRpcMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectRpcMenuItemActionPerformed
connectRpc();
+ if(rpcConn != null)
+ getModules();
}//GEN-LAST:event_connectRpcMenuItemActionPerformed
private void clearHistoryItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearHistoryItemActionPerformed
@@ -1318,19 +1321,14 @@ nameloop: for (int i = 0; i < names.length; i++) {
}
try { //Now load data out of current workspace
MsfguiApp.workspace = ((Map) rpcConn.execute("db.current_workspace")).get("workspace").toString();
- if(DraggableTabbedPane.isVisible(eventsTable))
- reAdd(eventsTable,(List) ((Map)rpcConn.execute("db.events",MsfguiApp.workspace)).get("events"),
- new String[]{"host","created_at","updated_at","name","critical","username","info"});
- if(all || DraggableTabbedPane.isVisible(lootsTable))
- reAdd(lootsTable,(List) ((Map)rpcConn.execute("db.loots",MsfguiApp.workspace)).get("loots"),
- new String[]{"host","service","ltype","ctype","data","created_at","updated_at","name","info"});
- reAddQuery(hostsTable,"hosts",new String[]{"created_at","address","address6","mac","name","state","os_name",
- "os_flavor","os_sp","os_lang","updated_at","purpose","info"}, all);
- reAddQuery(clientsTable,"clients",new String[]{"host","ua_string","ua_name","ua_ver","created_at","updated_at"}, all);
- reAddQuery(servicesTable, "services", new String[]{"host","created_at","updated_at","port","proto","state","name","info"}, all);
- reAddQuery(vulnsTable,"vulns",new String[]{"port","proto","time","host","name","refs"}, all);
- reAddQuery(notesTable,"notes",new String[]{"time", "host", "service", "type", "data"}, all);
- reAddQuery(credsTable,"creds",new String[]{"host", "time", "port", "proto", "sname", "type", "user", "pass", "active"}, all);
+ ((MsfTable)eventsTable).reAddQuery(all, 0);
+ ((MsfTable)lootsTable).reAddQuery(all, 0);
+ ((MsfTable)hostsTable).reAddQuery(all, 0);
+ ((MsfTable)clientsTable).reAddQuery(all, 0);
+ ((MsfTable)servicesTable).reAddQuery(all, 0);
+ ((MsfTable)vulnsTable).reAddQuery(all, 0);
+ ((MsfTable)notesTable).reAddQuery(all, 0);
+ ((MsfTable)credsTable).reAddQuery(all, 0);
} catch (MsfException mex) {
if(!mex.getMessage().equals("database not loaded"))
mex.printStackTrace();
@@ -1440,7 +1438,7 @@ nameloop: for (int i = 0; i < names.length; i++) {
reloadDb(false);
if(evt.getKeyCode() != KeyEvent.VK_DELETE)
return;
- JTable tab = (JTable)evt.getSource();
+ MsfTable tab = (MsfTable)evt.getSource();
for(int row : tab.getSelectedRows()){
try {
HashMap map = new HashMap();
@@ -1451,7 +1449,7 @@ nameloop: for (int i = 0; i < names.length; i++) {
MsfguiApp.showMessage(getFrame(), mex);
}
}//delete then readd
- reAddQuery(tab,name+"s",colNames, true);
+ tab.reAddQuery(true, 0);
}
private void hostsTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_hostsTableKeyReleased
tableDelCheck(evt,"host",new String[]{"created_at","address","address6","mac","name","state","os_name",
@@ -1471,7 +1469,7 @@ nameloop: for (int i = 0; i < names.length; i++) {
}//GEN-LAST:event_notesTableKeyReleased
private void lootsTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_lootsTableKeyReleased
- reAddQuery(lootsTable,"loots",new String[]{"host","service","ltype","ctype","data","created_at","updated_at","name","info"}, true);
+ ((MsfTable)lootsTable).reAddQuery(true, 0);
}//GEN-LAST:event_lootsTableKeyReleased
private void clientsTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_clientsTableKeyReleased
@@ -1623,8 +1621,6 @@ nameloop: for (int i = 0; i < names.length; i++) {
private void connectRpc() {
//make new rpcConnection
rpcConn = OpenConnectionDialog.getConnection(this);
- if(rpcConn != null)
- getModules();
}
/** Attempts to start msfrpcd and connect to it.*/
@@ -1974,35 +1970,4 @@ nameloop: for (int i = 0; i < names.length; i++) {
private final Icon[] busyIcons = new Icon[15];
private int busyIconIndex = 0;
private JDialog aboutBox;
-
- /** Clear a table's contents, reenabling the tab, and replace with contents of data returned from a db call */
- private void reAddQuery(JTable table, String call, String[] cols, boolean force) {
- if(!force && !DraggableTabbedPane.isVisible(table))
- return; //Don't re-add if not visible
- try {
- HashMap arg = new HashMap();
- arg.put("workspace", MsfguiApp.workspace);
- List data = (List) ((Map)rpcConn.execute("db."+call,arg)).get(call);
- if(data == null)
- return;
- reAdd(table, data, cols);
- } catch (MsfException mex) {
- mex.printStackTrace();
- if(mex.getMessage().equals("database not loaded"))
- throw mex;
- }
- }
- private void reAdd(JTable table, List data, String[] cols) throws MsfException {
- DefaultTableModel mod = (DefaultTableModel) table.getModel();
- while (mod.getRowCount() > 0)
- mod.removeRow(0);
- for (Object dataObj : data) {
- Object[] row = new Object[cols.length];
- for (int i = 0; i < cols.length; i++)
- row[i] = ((Map) dataObj).get(cols[i]);
- mod.addRow(row);
- }
- TableHelper.fitColumnWidths(mod, table);
- DraggableTabbedPane.setTabComponentEnabled(table, true);
- }
}
diff --git a/external/source/gui/msfguijava/src/msfgui/MsfTable.java b/external/source/gui/msfguijava/src/msfgui/MsfTable.java
index 31fcabc7ed..78c748a8c8 100644
--- a/external/source/gui/msfguijava/src/msfgui/MsfTable.java
+++ b/external/source/gui/msfguijava/src/msfgui/MsfTable.java
@@ -1,12 +1,19 @@
package msfgui;
+import java.awt.Component;
import java.awt.Dimension;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
+import javax.swing.table.DefaultTableModel;
/**
* Table customization defaults to non-editable, autosorted table with some preferences
@@ -16,11 +23,17 @@ import javax.swing.ScrollPaneConstants;
* @author scriptjunkie
*/
public class MsfTable extends javax.swing.JTable {
+ private final String[] dbNames;
+ private final String dbTable;
+ private final RpcConnection rpcConn;
/**
* Default constructor just takes column names
* @param colnames The names of the columns in the table
*/
- public MsfTable(String[] colnames){
+ public MsfTable(final RpcConnection rpcConn, String[] colnames, String dbTable, String[] dbNames){
+ this.dbNames = dbNames;
+ this.dbTable = dbTable;
+ this.rpcConn = rpcConn;
setModel(new javax.swing.table.DefaultTableModel(new Object [][] {}, colnames) {
public Class getColumnClass(int columnIndex) {
try{
@@ -60,4 +73,54 @@ public class MsfTable extends javax.swing.JTable {
}
} );
}
+ /** Automatically query more info on new data */
+ public void addAutoAdjuster(final JScrollPane pane){
+ //Add autoadjuster to get more DB info
+ pane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener(){
+ public void adjustmentValueChanged(AdjustmentEvent evt) {
+ java.awt.Adjustable adj = evt.getAdjustable();
+ if(evt.getValueIsAdjusting() || adj.getValue() + adj.getVisibleAmount() != adj.getMaximum())
+ return;
+ Component source = ((Component)evt.getSource());
+ while(!(source instanceof JScrollPane))
+ source = source.getParent();
+ int rowCount = getRowCount();
+ if(rowCount == 0 || (getRowCount() % 100) != 0)
+ return;
+ reAddQuery(false, rowCount);
+ }
+ });
+ }
+
+ /** Clear a table's contents, reenabling the tab, and replace with contents of data returned from a db call */
+ public void reAddQuery(boolean force, int offset) {
+ if(!force && !DraggableTabbedPane.isVisible(this))
+ return; //Don't re-add if not visible
+ try {
+ HashMap arg = new HashMap(10);
+ arg.put("workspace", MsfguiApp.workspace);
+ arg.put("offset", offset);
+ List data = (List) ((Map)rpcConn.execute("db."+dbTable, arg)).get(dbTable);
+ if(data == null)
+ return;
+ DefaultTableModel mod = (DefaultTableModel) getModel();
+ while (mod.getRowCount() > offset)
+ mod.removeRow(mod.getRowCount() - 1);
+ for (Object dataObj : data) {
+ Object[] row = new Object[dbNames.length];
+ for (int i = 0; i < dbNames.length; i++){
+ row[i] = ((Map) dataObj).get(dbNames[i]);
+ if(dbNames[i].endsWith("_at"))
+ row[i] = new java.util.Date(Long.parseLong(row[i].toString()) * 1000);
+ }
+ mod.addRow(row);
+ }
+ TableHelper.fitColumnWidths(mod, this);
+ DraggableTabbedPane.setTabComponentEnabled(this, true);
+ } catch (MsfException mex) {
+ mex.printStackTrace();
+ if(mex.getMessage().equals("database not loaded"))
+ throw mex;
+ }
+ }
}
diff --git a/lib/msf/core/rpc/v10/rpc_db.rb b/lib/msf/core/rpc/v10/rpc_db.rb
index e96380e432..e904a44808 100644
--- a/lib/msf/core/rpc/v10/rpc_db.rb
+++ b/lib/msf/core/rpc/v10/rpc_db.rb
@@ -9,7 +9,7 @@ private
def find_workspace(wspace = nil)
if(wspace and wspace != "")
- return self.framework.db.find_workspace(wspace)
+ return self.framework.db.find_workspace(wspace) || error(500, "Invalid workspace")
end
self.framework.db.workspace
end
@@ -74,23 +74,29 @@ private
error(500, "Database Not Loaded") if not db
end
+ def init_db_opts_workspace(xopts)
+ db_check
+ opts = fix_options(xopts)
+ opts[:workspace] = find_workspace(opts[:workspace])
+ return opts, opts[:workspace]
+ end
+
public
def rpc_hosts(xopts)
-
- db_check
-
- opts = fix_options(xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
conditions = {}
conditions[:state] = [Msf::HostState::Alive, Msf::HostState::Unknown] if opts[:only_up]
conditions[:address] = opts[:addresses] if opts[:addresses]
- wspace = find_workspace(opts[:workspace])
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
ret = {}
ret[:hosts] = []
- wspace.hosts.all(:conditions => conditions, :order => :address).each do |h|
+ wspace.hosts.all(:conditions => conditions, :order => :address,
+ :limit => limit, :offset => offset).each do |h|
host = {}
host[:created_at] = h.created_at.to_i
host[:address] = h.address.to_s
@@ -111,48 +117,22 @@ public
end
def rpc_services( xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
- db_check
-
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
- opts[:workspace] = wspace if opts[:workspace]
- hosts = []
-
- if opts[:addresses]
- conditions = {}
- conditions[:address] = opts[:addresses] if opts[:addresses]
- hosts = wspace.hosts.all(:conditions => conditions, :order => :address)
- elsif opts[:host] || opts[:address]
- host = self.framework.db.get_host(opts)
- hosts << host
- end
+ conditions = {}
+ conditions[:state] = [ServiceState::Open] if opts[:only_up]
+ conditions[:proto] = opts[:proto] if opts[:proto]
+ conditions["hosts.address"] = opts[:addresses] if opts[:addresses]
+ conditions[:port] = Rex::Socket.portspec_to_portlist(opts[:ports]) if opts[:ports]
+ conditions[:name] = opts[:names].strip().split(",") if opts[:names]
ret = {}
ret[:services] = []
- a = self.framework.db.get_host(opts)
-
- services = []
- if opts[:host] || opts[:address] || opts[:addresses]
- hosts.each do |host|
- sret = nil
- if(opts[:proto] && opts[:port])
- sret = host.services.find_by_proto_and_port(opts[:proto], opts[:port])
- else
- sret = host.services
- end
- next if sret == nil
- services << sret if sret.class == Msf::DBManager::Service
- services |= sret if sret.class == Array
- end
- else
- services = wspace.services
- end
-
- return ret if (not services)
-
- services.each do |s|
+ wspace.services.all(:include => :host, :conditions => conditions,
+ :limit => limit, :offset => offset).each do |s|
service = {}
host = s.host
service[:host] = host.address || host.address6 || "unknown"
@@ -168,79 +148,20 @@ public
ret
end
-
def rpc_vulns(xopts)
-
- db_check
-
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
- opts[:workspace] = wspace if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
+
+ conditions = {}
+ conditions["hosts.address"] = opts[:addresses] if opts[:addresses]
+ conditions[:name] = opts[:names].strip().split(",") if opts[:names]
+ conditions["services.port"] = Rex::Socket.portspec_to_portlist(opts[:ports]) if opts[:port]
+ conditions["services.proto"] = opts[:proto] if opts[:proto]
ret = {}
ret[:vulns] = []
- hosts = []
- services = []
- vulns = []
- # Get Matching Hosts
- if opts[:addresses]
- conditions = {}
- conditions[:address] = opts[:addresses] if opts[:addresses]
- hosts = wspace.hosts.all(:conditions => conditions, :order => :address)
- elsif opts[:host] || opts[:address]
- host = self.framework.db.get_host(opts)
- hosts << host
- end
-
- #Get Matching Services
- if opts[:host] || opts[:address] || opts[:addresses]
- hosts.each do |host|
- sret = nil
- if(opts[:proto] && opts[:port])
- sret = host.services.find_by_proto_and_port(opts[:proto], opts[:port])
- else
- sret = host.services
- end
- next if sret == nil
- services << sret if sret.class == Msf::DBManager::Service
- services |= sret if sret.class == Array
- end
- elsif opts[:port] && opts[:proto]
- sret = wspace.services.find_by_proto_and_port(opts[:proto],opts[:port])
- services << sret if sret.class == Msf::DBManager::Service
- services |= sret if sret.class == Array
- end
-
- #get list of vulns
- if services.count > 0
- services.each do |s|
- if opts[:name]
- nret = s.vulns.find_by_name(opts[:name])
- else
- nret = s.vulns
- end
- next if nret == nil
- vulns << nret if nret.class == Msf::DBManager::Vuln
- vulns |= nret if nret.class == Array
- end
- elsif hosts.count > 0
- hosts.each do |h|
- if opts[:name]
- nret = h.vulns.find_by_name(opts[:name])
- else
- nret = h.vulns
- end
- next if nret == nil
- vulns << nret if nret.class == Msf::DBManager::Vuln
- vulns |= nret if nret.class == Array
- end
- else
- nret = wspace.vulns
- vulns << nret if nret.class == Msf::DBManager::Vuln
- vulns |= nret if nret.class == Array
- end
-
- vulns.each do |v|
+ wspace.vulns.all(:include => :service, :conditions => conditions, :limit => limit, :offset => offset).each do |v|
vuln = {}
reflist = v.refs.map { |r| r.name }
if(v.service)
@@ -330,12 +251,11 @@ public
end
def rpc_get_host(xopts)
- db_check
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:host] = []
opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
h = self.framework.db.get_host(opts)
if(h)
host = {}
@@ -358,9 +278,7 @@ public
end
def rpc_report_host(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
res = self.framework.db.report_host(opts)
return { :result => 'success' } if(res)
@@ -369,19 +287,14 @@ public
end
def rpc_report_service(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
res = self.framework.db.report_service(opts)
return { :result => 'success' } if(res)
{ :result => 'failed' }
end
def rpc_get_service(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
- opts[:workspace] = wspace if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:service] = []
@@ -425,10 +338,7 @@ public
end
def rpc_get_note(xopts)
- db_check
-
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:note] = []
@@ -478,9 +388,7 @@ public
end
def rpc_get_client(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:client] = []
c = self.framework.db.get_client(opts)
@@ -499,9 +407,7 @@ public
end
def rpc_report_client(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
res = self.framework.db.report_client(opts)
return { :result => 'success' } if(res)
{ :result => 'failed' }
@@ -509,9 +415,7 @@ public
#DOC NOTE: :data and :ntype are REQUIRED
def rpc_report_note(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
if (opts[:host] or opts[:address]) and opts[:port] and opts[:proto]
addr = opts[:host] || opts[:address]
wspace = opts[:workspace] || self.framework.db.workspace
@@ -526,76 +430,21 @@ public
end
def rpc_notes(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace]) if opts[:workspace]
- opts[:workspace] = wspace
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
+
+ conditions = {}
+ conditions["hosts.address"] = opts[:addresses] if opts[:addresses]
+ conditions[:name] = opts[:names].strip().split(",") if opts[:names]
+ conditions[:ntype] = opts[:ntype] if opts[:ntype]
+ conditions["services.port"] = Rex::Socket.portspec_to_portlist(opts[:ports]) if opts[:port]
+ conditions["services.proto"] = opts[:proto] if opts[:proto]
ret = {}
ret[:notes] = []
- hosts = []
- services = []
- notes = []
-
- # Get Matching Hosts
- if opts[:addresses]
- conditions = {}
- conditions[:address] = opts[:addresses] if opts[:addresses]
- hosts = wspace.hosts.all(:conditions => conditions, :order => :address)
- elsif opts[:host] || opts[:address]
- host = self.framework.db.get_host(opts)
- hosts << host
- end
-
- #Get Matching Services
- if opts[:host] || opts[:address] || opts[:addresses]
- hosts.each do |host|
- sret = nil
- if(opts[:proto] && opts[:port])
- sret = host.services.find_by_proto_and_port(opts[:proto], opts[:port])
- else
- sret = host.services
- end
- next if sret == nil
- services << sret if sret.class == Msf::DBManager::Service
- services |= sret if sret.class == Array
- end
- elsif opts[:port] && opts[:proto]
- sret = wspace.services.find_by_proto_and_port(opts[:proto],opts[:port])
- services << sret if sret.class == Msf::DBManager::Service
- services |= sret if sret.class == Array
- end
-
- #get list of notes
- if services.count > 0
- services.each do |s|
- if opts[:ntype]
- nret = s.notes.find_by_ntype(opts[:ntype])
- else
- nret = s.notes
- end
- next if nret == nil
- notes << nret if nret.class == Msf::DBManager::Note
- notes |= nret if nret.class == Array
- end
- elsif hosts.count > 0
- hosts.each do |h|
- if opts[:ntype]
- nret = h.notes.find_by_ntype(opts[:ntype])
- else
- nret = h.notes
- end
- next if nret == nil
- notes << nret if nret.class == Msf::DBManager::Note
- notes |= nret if nret.class == Array
- end
- else
- nret = wspace.notes
- notes << nret if nret.class == Msf::DBManager::Note
- notes |= nret if nret.class == Array
- end
-
- notes.each do |n|
+ wspace.notes.all(:include => [:host, :service], :conditions => conditions,
+ :limit => limit, :offset => offset).each do |n|
note = {}
note[:time] = n.created_at.to_i
note[:host] = ""
@@ -610,18 +459,14 @@ public
end
def rpc_report_auth_info(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
res = self.framework.db.report_auth_info(opts)
return { :result => 'success' } if(res)
{ :result => 'failed' }
end
def rpc_get_auth_info(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:auth_info] = []
ai = self.framework.db.get_auth_info(opts)
@@ -641,9 +486,7 @@ public
end
def rpc_del_vuln(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
+ opts, wspace = init_db_opts_workspace(xopts)
hosts = []
services = []
vulns = []
@@ -710,9 +553,7 @@ public
end
def rpc_del_note(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
+ opts, wspace = init_db_opts_workspace(xopts)
hosts = []
services = []
notes = []
@@ -778,9 +619,7 @@ public
end
def rpc_del_service(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
+ opts, wspace = init_db_opts_workspace(xopts)
hosts = []
services = []
if opts[:host] or opts[:address]
@@ -860,7 +699,6 @@ public
return { :result => 'success', :deleted => deleted }
end
-
def rpc_report_vuln(xopts)
db_check
opts = fix_options(xopts)
@@ -870,15 +708,15 @@ public
{ :result => 'failed' }
end
+ def rpc_events(xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
- def rpc_events(wspace = nil)
- db_check
- wspace = find_workspace(wspace)
- error(500, "Unknown Workspace") if(not wspace)
ret = {}
ret[:events] = []
- self.framework.db.events(wspace).each do |e|
+ wspace.events.all(:limit => limit, :offset => offset).each do |e|
event = {}
event[:host] = e.host.address || e.host.address6 if(e.host)
event[:created_at] = e.created_at.to_i
@@ -893,9 +731,7 @@ public
end
def rpc_report_event(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
res = self.framework.db.report_event(opts)
{ :result => 'success' } if(res)
end
@@ -903,8 +739,7 @@ public
#NOTE Path is required
#NOTE To match a service need host, port, proto
def rpc_report_loot(xopts)
- db_check
- opts = fix_options(xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
if opts[:host] && opts[:port] && opts[:proto]
opts[:service] = self.framework.db.find_or_create_service(opts)
end
@@ -913,14 +748,14 @@ public
{ :result => 'success' } if(res)
end
- def rpc_loots(wspace=nil)
- db_check
- wspace = find_workspace(wspace)
- error(500, "Unknown Workspace") if(not wspace)
-
+ def rpc_loots(xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
+
ret = {}
ret[:loots] = []
- self.framework.db.loots(wspace).each do |l|
+ wspace.loots.all(:limit => limit, :offset => offset).each do |l|
loot = {}
loot[:host] = l.host.address || l.host.address6 if(l.host)
loot[:service] = l.service.name || n.service.port if(n.service)
@@ -938,8 +773,7 @@ public
# requires host, port, user, pass, ptype, and active
def rpc_report_cred(xopts)
- db_check
- opts = fix_options(xopts)
+ opts, wspace = init_db_opts_workspace(xopts)
res = framework.db.find_or_create_cred(opts)
return { :result => 'success' } if res
{ :result => 'failed' }
@@ -947,15 +781,17 @@ public
#right now workspace is the only option supported
def rpc_creds(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
+
ret = {}
ret[:creds] = []
- self.framework.db.creds(wspace).each do |c|
+ DBManager::Cred.find(:all, :include => {:service => :host}, :conditions => ["hosts.workspace_id = ?",
+ framework.db.workspace.id ], :limit => limit, :offset => offset).each do |c|
cred = {}
cred[:host] = c.service.host.address || c.service.host.address6 if(c.service.host)
- cred[:time] = c.updated_at
+ cred[:updated_at] = c.updated_at.to_i
cred[:port] = c.service.port
cred[:proto] = c.service.proto
cred[:sname] = c.service.name
@@ -969,17 +805,13 @@ public
end
def rpc_import_data(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
self.framework.db.import(opts)
return { :result => 'success' }
end
def rpc_get_vuln(xopts)
- db_check
- opts = fix_options(xopts)
- opts[:workspace] = find_workspace(opts[:workspace]) if opts[:workspace]
+ opts, wspace = init_db_opts_workspace(xopts)
ret = {}
ret[:vuln] = []
@@ -1027,35 +859,20 @@ public
end
def rpc_clients(xopts)
- db_check
- opts = fix_options(xopts)
- wspace = find_workspace(opts[:workspace])
- hosts = []
- clients = []
+ opts, wspace = init_db_opts_workspace(xopts)
+ limit = opts.delete(:limit) || 100
+ offset = opts.delete(:offset) || 0
+
+ conditions = {}
+ conditions[:ua_name] = opts[:ua_name] if opts[:ua_name]
+ conditions[:ua_ver] = opts[:ua_ver] if opts[:ua_ver]
+ conditions["hosts.address"] = opts[:addresses] if opts[:addresses]
+
ret = {}
ret[:clients] = []
- if opts[:host] or opts[:address] or opts[:addresses]
- hosts = opts_to_hosts(opts)
- else
- hosts = wspace.hosts
- end
-
- hosts.each do |h|
- cret = nil
- if opts[:ua_name] or opts[:ua_ver]
- conditions = {}
- conditions[:ua_name] = opts[:ua_name] if opts[:ua_name]
- conditions[:ua_ver] = opts[:ua_ver] if opts[:ua_ver]
- cret = h.clients.all(:conditions => conditions)
- else
- cret = h.clients
- end
- next if cret == nil
- clients << cret if cret.class == Msf::DBManager::Client
- clients |= cret if cret.class == Array
- end
- clients.each do |c|
+ wspace.clients.all(:include => :host, :conditions => conditions,
+ :limit => limit, :offset => offset).each do |c|
client = {}
client[:host] = c.host.address.to_s if c.host
client[:ua_string] = c.ua_string