📄 nessusscan.java
字号:
//// This file is part of the OpenNMS(R) Application.//// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved.// OpenNMS(R) is a derivative work, containing both original code, included code and modified// code that was published under the GNU General Public License. Copyrights for modified // and included code are below.//// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.//// Copyright (C) 1999-2001 Oculan Corp. All rights reserved.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details. //// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // For more information contact: // OpenNMS Licensing <license@opennms.org>// http://www.opennms.org/// http://www.opennms.com///package org.opennms.netmgt.vulnscand;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Timestamp;import java.sql.Types;import java.util.HashSet;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.Set;import java.util.StringTokenizer;import org.apache.log4j.Category;import org.apache.regexp.RE;import org.opennms.core.queue.FifoQueue;import org.opennms.core.queue.FifoQueueException;import org.opennms.core.queue.FifoQueueImpl;import org.opennms.core.utils.ThreadCategory;import org.opennms.netmgt.config.DatabaseConnectionFactory;import org.opennms.netmgt.config.VulnscandConfigFactory;import org.opennms.netmgt.eventd.db.Constants;/** * <p> * This class is a proxy for communications with the Nessus security scanner * daemon, nessusd. It has been designed to: * </p> * <ul> * <li>Initiate scans against a single target IP</li> * <li>Use prepackaged "levels" of security scanning: * <ul> * <li>Level 1: Portscanning</li> * <li>Level 2: Profiling</li> * <li>Level 3: Intrusions</li> * <li>Level 4: Destructive Intrusions</li> * </ul> * </li> * <li>Communicate with the daemon using username and and password, instead of * SSL key exchange</li> * </ul> * * <p> * Other functions (arbitrary plugin selection, SSL support) may be added in the * future. * </p> * */class NessusScan implements Runnable { // Put the md5_caching directive in to prevent the server // from sending the entire plugin list at startup private static final String NTP_VERSION_STRING = "< NTP/1.2 >< md5_caching plugins_cve_id plugins_version>"; private static final String NTP_CLIENT_ENTITY = "CLIENT"; private static final String NTP_SERVER_ENTITY = "SERVER"; private static final String NTP_USERNAME_PROMPT = "User : "; private static final String NTP_PASSWORD_PROMPT = "Password : "; private static final String NTP_SEP = " <|> "; private static final int PORTSCAN_PLUGIN_ID = 0; public static final int SCAN_SUCCESS = 0; public static final int SCAN_HOST_DOWN = 1; public static final int SCAN_FATAL_ERROR = 2; public static final int SCAN_NON_FATAL_ERROR = 4; public static final int SCAN_COMPLETE = 8; /** * Select the next vulnerabilityID from the sequence */ private static final String SELECT_NEXT_ID = "SELECT NEXTVAL('vulnNxtId')"; /** * Get all unresolved vulnerabilities for a given ipaddr. */ private static final String SELECT_ALL_VULNERABILITIES = "SELECT vulnerabilityid FROM vulnerabilities " + "WHERE ipaddr = ? AND resolvedtime IS NULL"; /** * This query retrieves the name and summary of a plugin out of the database * so that we can construct the logmsg of the vulnerability with the fields. */ private static final String SELECT_PLUGIN_INFO = "SELECT name, summary FROM vulnplugins " + "WHERE pluginid = ? AND pluginsubid = ?"; /** * Insert a new vulnerability into the "vulnerabilities" table */ private static final String INSERT_NEW_VULNERABILITY = "INSERT INTO vulnerabilities " + "(vulnerabilityid, nodeid, ipaddr, serviceid, creationtime, lastattempttime, lastscantime, " + "severity, pluginid, pluginsubid, logmsg, descr, port, protocol, cveentry) " + "VALUES (?,?,?,?, ?,?,?, ?, ?,?, ?,?, ?,?, ?)"; /** * Find an open vulnerability ID in the database. The combination of ipaddr, * port, protocol, pluginID, and pluginSubID is used as the key for * vulnerability uniqueness. */ private static final String SELECT_OPEN_VULNERABILITY = "SELECT vulnerabilityid FROM vulnerabilities " + "WHERE ipaddr = ? AND port = ? AND protocol = ? AND pluginid = ? AND pluginsubid = ? AND resolvedtime IS NULL"; /** * Update the timestamps in an open vulnerability that was rescanned and * still exists. */ private static final String VULNERABILITY_SCANNED = "UPDATE vulnerabilities SET lastattempttime = ?, lastscantime = ? " + "WHERE vulnerabilityid = ?"; /** * Update the timestamps in an open vulnerability for which the rescan * failed. */ private static final String VULNERABILITY_SCAN_ATTEMPTED = "UPDATE vulnerabilities SET lastattempttime = ? " + "WHERE vulnerabilityid = ?"; /** * Resolve a given vulnerability by its unique ID number. */ private static final String RESOLVE_VULNERABILITY = "UPDATE vulnerabilities SET lastattempttime = ?, resolvedtime = ? " + "WHERE vulnerabilityid = ?"; /** * Nessus configuration that is used to perform the current scan. */ private NessusScanConfiguration config; /** * Regex expression that is used to tokenize the messages from Nessus. */ private RE ntpTokenizer = null; /** * List of the open vulnerabilities on an IP address */ private Set openVulnerabilities = new HashSet(); /** * Array that holds the plugin lists for each scanning level. */ private String[] pluginLists = null; /** * Array that holds the safe-checks settings for each scanning level. */ private boolean[] safeChecks = null; /** * Integer of the ordinal of the last plugin that was executed against the * target. This number is used to ensure that if the scan is terminated * prematurely because of an unreachable host in the list, the * vulnerabilities are not marked resolved. */ private int lastPlugin; /** * Counter of the total number of plugins that will be executed against this * host. */ private int totalPlugins; /** * Create a new scan that will scan the target specified in the * configuration and insert the results of the scan into the database. */ public NessusScan(NessusScanConfiguration newConfig) throws IllegalArgumentException { if (newConfig.isValid()) config = newConfig; else throw new IllegalArgumentException("NessusScanConfiguration was invalid"); try { ntpTokenizer = new RE(" <\\|> "); } catch (org.apache.regexp.RESyntaxException ex) { ThreadCategory.getInstance(NessusScan.class).error("FATAL ERROR in regex in NessusScan.java. Correct this error and rebuild.", ex); } init(); } private void init() { pluginLists = VulnscandConfigFactory.getInstance().getPluginLists(); safeChecks = VulnscandConfigFactory.getInstance().getSafeChecks(); lastPlugin = -1; totalPlugins = -1; } public void run() { Category log = ThreadCategory.getInstance(getClass()); // Queue of the lines that are read from the Nessus socket FifoQueue lines = null; // Flag that lets us know if we've found what we're looking for boolean found = false; // DB connection; is connected and disconnected as necessary Connection conn = null; // Grab the list of all current open vulnerabilities for the IP address. // We'll use this list to resolve vulnerabilities that are not // redetected. try { conn = DatabaseConnectionFactory.getInstance().getConnection(); } catch (SQLException ex) { log.error("Could not open DB connection", ex); return; } try { PreparedStatement stmt = conn.prepareStatement(SELECT_ALL_VULNERABILITIES); stmt.setString(1, config.targetAddress.getHostAddress()); ResultSet openVulnerabilitiesRS = stmt.executeQuery(); while (openVulnerabilitiesRS.next()) { openVulnerabilities.add(new Integer(openVulnerabilitiesRS.getInt("vulnerabilityid"))); } } catch (SQLException ex) { log.error("Error when querying database for open vulnerabilities."); log.error(ex.getLocalizedMessage(), ex); return; } finally { try { conn.close(); } catch (SQLException ex) { log.error("Could not close DB connection", ex); } } /* * Perform a Nessus scan of the target IP address. As each * vulnerability is found, a new entry is put into the database * or the existing entry is updated. */ Socket nessusSocket = null; try { nessusSocket = NessusConnectionFactory.getConnection(config.hostname, config.hostport); if (nessusSocket == null) { throw new IOException("Factory returned null connection"); } InputStream in = nessusSocket.getInputStream(); OutputStream out = nessusSocket.getOutputStream(); log.debug("Attached streams to the Nessus socket."); // Login to the server out.write((NTP_VERSION_STRING + "\n").getBytes()); log.debug("Sent NTP version string."); lines = readLines(in); // Strip off the protocol/username prompt found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); log.debug("NTP string response: " + line); if (line.indexOf(NTP_USERNAME_PROMPT) != -1) { found = true; break; } } if (!found) lines = readLines(in); } // Login to the server out.write((config.username + "\n").getBytes()); log.debug("Sent username string."); // Strip off the password prompt found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); log.debug("Username response: " + line); if (line.indexOf(NTP_PASSWORD_PROMPT) != -1) { found = true; break; } } if (!found) lines = readLines(in); } // Login to the server out.write((config.password + "\n").getBytes()); log.debug("Sent password string."); // Strip off the rules list found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); // Do any necessary parsing log.debug("Password response: " + line); if (line.indexOf((NTP_SEP + NTP_SERVER_ENTITY).trim()) != -1) { found = true; break; } } if (!found) lines = readLines(in); } // Strip off the preferences list found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); // Do any necessary parsing log.debug("Preferences: " + line); if (line.indexOf((NTP_SEP + NTP_SERVER_ENTITY).trim()) != -1) { found = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -