📄 nessusscan.java
字号:
break; } } if (!found) lines = readLines(in); } // Strip off the rules list found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); // Do any necessary parsing log.debug("Rules: " + line); if (line.indexOf((NTP_SEP + NTP_SERVER_ENTITY).trim()) != -1) { found = true; break; } } if (!found) lines = readLines(in); } // Write the preferences list for the scan // (which includes the list of plugins to execute // against the target) out.write(buildPreferencesString().getBytes()); log.debug("Sent preferences string."); // Strip off the PREFERENCES_ERRORS found = false; while (!found) { while (lines.size() > 0) { String line = (String) lines.remove(); // Do any necessary parsing log.debug("Preferences response: " + line); if (line.indexOf((NTP_SEP + NTP_SERVER_ENTITY).trim()) != -1) { found = true; break; } } if (!found) lines = readLines(in); } /* * I'm using the NEW_ATTACK directive, since I don't * care about command strings getting too long (which * you would use the LONG_ATTACK directive for). */ out.write((NTP_CLIENT_ENTITY + NTP_SEP + "NEW_ATTACK" + NTP_SEP + config.targetAddress.toString().replaceAll("/", "") + NTP_SEP + NTP_CLIENT_ENTITY + "\n").getBytes()); log.debug("Sent NEW_ATTACK directive against target: " + config.targetAddress.toString()); // Read the response to the NEW_ATTACK int returnCode = SCAN_SUCCESS; while ((returnCode == SCAN_SUCCESS) || (returnCode == SCAN_NON_FATAL_ERROR)) { while (lines.size() > 0) { String line = (String) lines.remove(); log.debug("Nessus attack response: " + line.replace('\n', ' ')); // Grep out any inappropriate messages if ((line.indexOf("the server killed it") == -1)) { // This processing will update existing vulnerabilities // in the database // and add new vulnerability entries as the // vulnerabilities are detected returnCode = processScanMessage(line); } else { log.error("Discarded inappropriate Nessus message: " + line); } } // If the last read was successful, get more lines if ((returnCode == SCAN_SUCCESS) || (returnCode == SCAN_NON_FATAL_ERROR)) { lines = readLines(in); } } out.write(buildStopWholeTestString().getBytes()); // If there were open vulnerabilities that were not reconfirmed // during this // scanning cycle, then mark them as resolved. if (openVulnerabilities.size() > 0) { try { conn = DatabaseConnectionFactory.getInstance().getConnection(); } catch (SQLException ex) { log.error("Could not open DB connection", ex); return; } try { PreparedStatement stmt = conn.prepareStatement(RESOLVE_VULNERABILITY); Timestamp currentTime = new Timestamp(new java.util.Date().getTime()); Iterator vuln = openVulnerabilities.iterator(); while (vuln.hasNext()) { stmt.setTimestamp(1, currentTime); // If the scan ended because of a successful completion // and all plugins were executed (indicating that the // host WAS accessible), resolve the bug if ((returnCode == SCAN_COMPLETE) && (lastPlugin == totalPlugins)) { stmt.setTimestamp(2, currentTime); } // Otherwise, just leave the resolved field NULL else { stmt.setNull(2, Types.TIMESTAMP); } stmt.setInt(3, ((Integer) vuln.next()).intValue()); stmt.executeUpdate(); } } 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); } } } log.debug("Sent STOP_WHOLE_TEST directive against target " + config.targetAddress.toString()); } catch (FifoQueueException ex) { log.warn(ex, ex); } catch (InterruptedException ex) { log.warn(ex, ex); } catch (IOException ex) { log.warn(ex, ex); } finally { log.info("Releasing Nessus socket connection"); if (nessusSocket != null) NessusConnectionFactory.releaseConnection(nessusSocket); } // Update the scheduler flags for this configuration config.setScheduled(false); config.setLastScanned(new java.util.Date()); } private String buildStopWholeTestString() { return (NTP_CLIENT_ENTITY + NTP_SEP + "STOP_WHOLE_TEST" + NTP_SEP + NTP_CLIENT_ENTITY + "\n"); } private String buildStopScanString() { return (NTP_CLIENT_ENTITY + NTP_SEP + "STOP_ATTACK" + config.targetAddress.toString() + NTP_SEP + NTP_CLIENT_ENTITY + "\n"); } /** * Build the preferences string with the appropriate plugins and safe_checks * settings from the config file. */ private String buildPreferencesString() { String retval = NTP_CLIENT_ENTITY + NTP_SEP + "PREFERENCES" + NTP_SEP + "\n" + "plugin_set" + NTP_SEP + pluginLists[config.scanLevel] + "\n" + "safe_checks" + NTP_SEP; if (safeChecks[config.scanLevel]) retval += "yes"; else retval += "no"; retval += "\nmax_hosts" + NTP_SEP + "1\n" + "ntp_short_status" + NTP_SEP + "yes\n" + NTP_SEP + NTP_CLIENT_ENTITY; return retval; } /** * Process a scan message. * <p> * This function is designed to parse any messages that come from Nessus * during a scan session (eg. after the NEW_ATTACK directive has been sent) * </p> * * <p> * The following types of events are handled: * <ul> * <li>Abbreviated STATUS messages</li> * <li>PORT</li> * <li>INFO</li> * <li>HOLE</li> * <li>BYE (as in BYE BYE)</li> * </ul> * </p> * */ private int processScanMessage(String message) { Category log = ThreadCategory.getInstance(getClass()); int vulnerabilityId = -1; // DB connection; is connected and disconnected as necessary Connection conn = null; // Normal NTP messages if (message.startsWith((NTP_SERVER_ENTITY + NTP_SEP).trim())) { int i = 0; message = message.substring((NTP_SERVER_ENTITY + NTP_SEP).length()).trim(); String tokens[] = ntpTokenizer.split(message); String next = tokens[i++]; // Indicates information about the target system or // that a security hole has been located if (next.equals("INFO") || next.equals("HOLE")) { NessusParser parser = NessusParser.getInstance(); PortValues portvals = null; DescrValues descrvals = null; int pluginId = -1, pluginSubId = -1; String pluginLogmsg = ""; String hostname = tokens[i++]; String portString = tokens[i++]; try { // Parse the service, port, and protocol of the hole portvals = parser.parsePort(portString); } catch (IllegalArgumentException ex) { log.error("Could not parse the port and protocol information out of this string: " + portString); portvals = NessusParser.getDefaultPortValues(); } String descrString = tokens[i++]; try { // Parse the descr of the event descrvals = parser.parseDescr(descrString); } catch (IllegalArgumentException ex) { log.error("Could not parse the severity, descr, and/or CVE entry information out of this string: \n" + descrString); descrvals = NessusParser.getDefaultDescrValues(); } String pluginIdString = tokens[i++]; try { pluginId = Integer.parseInt(pluginIdString); } catch (NumberFormatException ex) { log.error("Could not parse the plugin ID out of the string: " + pluginIdString, ex); } // Change this, once we get a way to break the // plugins down into separate vulnerabilities pluginSubId = 0; // try { conn = DatabaseConnectionFactory.getInstance().getConnection(); } catch (SQLException ex) { log.error("Could not open DB connection", ex); return SCAN_FATAL_ERROR; } try { PreparedStatement stmt = conn.prepareStatement(SELECT_OPEN_VULNERABILITY); // ipaddr stmt.setString(1, config.targetAddress.getHostAddress()); // port if (portvals.port > 0) stmt.setInt(2, portvals.port); else stmt.setNull(2, Types.INTEGER); // protocol if (portvals.protocol != null) stmt.setString(3, portvals.protocol); else stmt.setNull(2, Types.VARCHAR); // pluginid and pluginsubid stmt.setInt(4, pluginId); stmt.setInt(5, pluginSubId); ResultSet openVuln = stmt.executeQuery(); // Update the timestamps on the existing events if (openVuln.first()) { stmt = conn.prepareStatement(VULNERABILITY_SCANNED); Timestamp currentTime = new Timestamp(new java.util.Date().getTime()); stmt.setTimestamp(1, currentTime); stmt.setTimestamp(2, currentTime); stmt.setInt(3, openVuln.getInt("vulnerabilityid")); int rowCount = stmt.executeUpdate(); if (rowCount != 1) { log.error("UNEXPECTED CONDITION: " + rowCount + " row(s) updated during last scan successful UPDATE call"); } else { openVulnerabilities.remove(new Integer(openVuln.getInt("vulnerabilityid"))); } if (openVuln.next()) { log.error("UNEXPECTED CONDITION: There are multiple rows that match this vulnerability, ignoring subsequent rows."); } } // Insert a new vulnerability row into the database else { stmt = conn.prepareStatement(SELECT_NEXT_ID); ResultSet idRS = stmt.executeQuery(); idRS.next(); int vulnId = idRS.getInt(1); idRS.close(); idRS = null; stmt = conn.prepareStatement(INSERT_NEW_VULNERABILITY); stmt.setInt(1, vulnId); // Match the interface to a node in the database int nodeId = VulnscandConfigFactory.getInterfaceDbNodeId(conn, config.targetAddress); if (nodeId > 0) stmt.setInt(2, nodeId); else stmt.setNull(2, Types.INTEGER); stmt.setString(3, config.targetAddress.getHostAddress()); // ADD SERVICE CORRELATION // Punt this for now also... not necessary // stmt.setInt(4, serviceId); stmt.setNull(4, Types.INTEGER); Timestamp currentTime = new Timestamp(new java.util.Date().getTime()); stmt.setTimestamp(5, currentTime); stmt.setTimestamp(6, currentTime); stmt.setTimestamp(7, currentTime); stmt.setInt(8, descrvals.severity); stmt.setInt(9, pluginId); stmt.setInt(10, pluginSubId); PreparedStatement pluginStmt = conn.prepareStatement(SELECT_PLUGIN_INFO); pluginStmt.setInt(1, pluginId); pluginStmt.setInt(2, pluginSubId); ResultSet plugRS = pluginStmt.executeQuery(); if (plugRS.next()) { if (plugRS.getString("name") != null && plugRS.getString("name").length() > 0) { pluginLogmsg = plugRS.getString("name"); } if (plugRS.getString("summary") != null && plugRS.getString("summary").length() > 0) { if (!pluginLogmsg.equals("")) pluginLogmsg += ": "; pluginLogmsg += plugRS.getString("summary"); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -