Benoit Crestey
ServiceNow Employee
ServiceNow Employee

Customer Use Case

Customer wanted to know the Windows servers candidate for PowerShell/WinRM discovery, without access to the servers.

To do this, it is possible to do an extract of 135 (WMI), 5985 (WinRM HTTP), 5986 (WinRM HTTPs) ports. The export was computed in Excel, and was used to manage the deployment status.

Problem

  • Shazzam process scans targets for a list of opened ports
  • Shazzam triggers other probes, but the result of port scanned is not stored in the CMDB
  • There is no standard way to extract this data

Solution

Script to extract this list, and be able to report on the list of status of ports

 

Possible other use case (with little script modifications)

  • Extract Windows servers having a share file port opened/reachable
  • Extract devices having SSH port opened/reachable
  • Compare the results from port reachable from 2 different MIDs
  • Extract devices having a specific opened/reachable, that could lead to security issues
    • This would require a little script modification, and the addition of the port in Shazzam process

Result

Result is in the logs, or displayed depending on execution method

 

ShazzamExtractor:192.168.XX.XX;mid.server.lan_w20qsqs01;2020-11-23 10:54:10;refused;?;timed_out
ShazzamExtractor:10.108.XX.XX;mid.server.lan_w20qsqs01;2020-11-23 16:34:56;?;?;timed_out
ShazzamExtractor:172.27.XX.XX;mid.server.lan_w20qsqs01;2020-11-25 09:03:09;open;open;io_error

 

 Technical Implementation

  • The script search for Shazzam ECC queues records, and extract the Payload
  • If the Shazzam results are in attachment, then the attachment is analyzed

Script

  • Run as a background script
  • Can be used in Fix Script or Scheduled Job
  • Should work on most serviceNow releases
  • Doesn't modify data

 

function scanEcc() {
  // Read the ECC queue table
  gr = new GlideRecord("ecc_queue");
  // Uncomment For testing purpose to test on one ECC queue record
  //gr.addQuery("sys_id", "3a0034b8db45c81024106085059619f2");
  gr.addQuery("topic", "Shazzam");
  gr.addQuery("queue", "input");
  // Uncomment to select only yestarday records
  //gr.addEncodedQuery("sys_created_onONYesterday@javascript:gs.beginningOfYesterday()@javascript:gs.endOfYesterday()");
  gr.query();
  while (gr.next()) {
    scanShazam(gr);
  }
}

function scanShazam(gr) {
  var res = "";
  var mid = gr.getValue("agent");
  var XMLUtil = GlideXMLUtil;
  var g_doc = XMLUtil.parse(getPayload(gr));
  var parent = g_doc.getDocumentElement();

  var resultList = parent.getElementsByTagName("result")

  for (var i=0; i<resultList.getLength(); i++) {

    var attribute = XMLUtil.getAttributesAsMap(resultList.item(i));
    
    var scannerList = resultList.item(i).getElementsByTagName("scanner");
    var result135 = "?";
    var result5985 = "?";
    var result5986 = "?";

    for (var j=0; j<scannerList.getLength(); j++) {
      var res3 = XMLUtil.getAttributesAsMap(scannerList.item(j));
      result135 = getResult(res3, result135, "135");
      result5985 = getResult(res3, result5985, "5985");
      result5986 = getResult(res3, result5986, "5986");
    }
    // Uncomment to extract only depending on criteria
    //if (result135 == "?" && (result5985 == "open" || result5986 == "open")) {
      res = res + attribute.get("ip_address") + ";" + gr.getValue("agent") + ";" + gr.getValue("sys_created_on") + ";" + result135  + ";" + result5985 + ";" + result5986  + "\n"; 
    //}
  } 
  gs.log(res, "ShazzamExtractor");
}

function getResult(res, before, port) {
  if (res.get("port") == port) {
    return res.get("result"); 
  }
  return before;
}

// Read the payload or attachment (when result is big)
function getPayload(gr) {
  var res = gr.getValue("payload");
  if (res == "<see_attachment/>" ) {
    res = getAttachmentContentsAsString("ecc_queue", gr.getValue("sys_id"));
  }
  return res;
}

function getAttachmentContentsAsString(tableName, recordID) {
  var gsa = new GlideSysAttachment();
  var bytesInFile = gsa.getBytes(tableName, recordID);
  var dataAsString = Packages.java.lang.String(bytesInFile);
  dataAsString = String(dataAsString);
  return dataAsString;
}

scanEcc();

 

Version history
Last update:
‎11-25-2020 01:50 AM
Updated by: