Skip to content

Instantly share code, notes, and snippets.

@DavidRies
Last active February 25, 2016 21:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidRies/ed86e6f0d6f245c23d98 to your computer and use it in GitHub Desktop.
Save DavidRies/ed86e6f0d6f245c23d98 to your computer and use it in GitHub Desktop.
A Windows Script Host script to retrieve OVAL definitions from the Cisco OVAL Repository
/***************************************************************************************************************
* cisco-repo-get-oval-zip.js
* 2014-05-11
*
* Public Domain
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*
*
* This file contains a Windows Script Host script to retrieve OVAL definitions from the Cisco OVAL Repository
* add them to a zip file.
*
* Usage: cscript cisco-repo-get-oval-zip.js FILENAME.ZIP [LIMIT]
* FILENAME.ZIP : the file name of the zip that will be created
* LIMIT : optional limit to the number of definitions that will be retrieved (integer)
*
* Example: cscript cisco-repo-get-oval-zip.js cisco.oval.zip
*
***************************************************************************************************************/
// Configuration
var sCiscoRepositoryURL = 'https://tools.cisco.com/security/center/ovalListing.x';
// Globals
var oFSO = new ActiveXObject('Scripting.FileSystemObject');
var oStream = new ActiveXObject("ADODB.Stream");
// Include JSON Support using Douglas Crockford's json2.js (https://github.com/douglascrockford/JSON-js)
"object"!=typeof JSON&&(JSON={}),function(){"use strict"
function f(t){return 10>t?"0"+t:t}function quote(t){return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta[t]
return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}function str(t,e){var r,n,o,f,u,p=gap,i=e[t]
switch(i&&"object"==typeof i&&"function"==typeof i.toJSON&&(i=i.toJSON(t)),"function"==typeof rep&&(i=rep.call(e,t,i)),typeof i){case"string":return quote(i)
case"number":return isFinite(i)?i+"":"null"
case"boolean":case"null":return i+""
case"object":if(!i)return"null"
if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(i)){for(f=i.length,r=0;f>r;r+=1)u[r]=str(r,i)||"null"
return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+p+"]":"["+u.join(",")+"]",gap=p,o}if(rep&&"object"==typeof rep)for(f=rep.length,r=0;f>r;r+=1)"string"==typeof rep[r]&&(n=rep[r],o=str(n,i),o&&u.push(quote(n)+(gap?": ":":")+o))
else for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o=str(n,i),o&&u.push(quote(n)+(gap?": ":":")+o))
return o=0===u.length?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+p+"}":"{"+u.join(",")+"}",gap=p,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()})
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep
"function"!=typeof JSON.stringify&&(JSON.stringify=function(t,e,r){var n
if(gap="",indent="","number"==typeof r)for(n=0;r>n;n+=1)indent+=" "
else"string"==typeof r&&(indent=r)
if(rep=e,e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw Error("JSON.stringify")
return str("",{"":t})}),"function"!=typeof JSON.parse&&(JSON.parse=function(text,reviver){function walk(t,e){var r,n,o=t[e]
if(o&&"object"==typeof o)for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(n=walk(o,r),void 0!==n?o[r]=n:delete o[r])
return reviver.call(t,e,o)}var j
if(text+="",cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j
throw new SyntaxError("JSON.parse")})}()
// Helper functions/objects
function getOvalDefinitions(oTargetFolder, iResultLimit) {
// get repo html page
WScript.echo('Retrieving repository listing');
var sRepoHTML = getRemoteFileContent(sCiscoRepositoryURL);
if (sRepoHTML === false) return 0;
// extract all urls from source
var rxAllUrls = /['"]http[^'"]+['"]/gi;
var arAllUrls = sRepoHTML.match(rxAllUrls);
if (!arAllUrls || !arAllUrls.length || arAllUrls.length < 1) return 0;
// filter urls to oval document urls
var sUrl, arMatches, arOvalUrls = [];
var rxOVALUrl = /^https?:\/\/[^\/]*cisco\.com\/.*contentxml.*\.xml$/i;
for (var i=0; i<arAllUrls.length; i++){
sUrl = arAllUrls[i].replace(/[\s'"]/gi,'');
//WScript.echo('-------------------');WScript.echo(sUrl);
arMatches = sUrl.match(rxOVALUrl);
if (!arMatches || !arMatches.length || arMatches.length < 1) continue;
arOvalUrls.push(sUrl);
}
WScript.echo('Found '+arOvalUrls.length+' OVAL definitions:');
// iterate through oval document urls
var sOvalXML='', iFailed=0, iFound=0, sFilename, arFilename;
for (var i=0; i < arOvalUrls.length; i++) {
sUrl = arOvalUrls[i];
arFilename = sUrl.split('/');
sFilename = arFilename[arFilename.length-1].toLowerCase().replace(/\W+/g,'.');
// download file content
WScript.echo(' - downloading: '+ sFilename);
sOvalXML = getRemoteFileContent(sUrl);
// remove invalid attribute value (note CISCO PSIRT is working to fix in source content)
sOvalXML = sOvalXML.replace('ref_url="http://"', '');
if (sOvalXML === false) {
iFailed++;
continue;
}
// save to file
oStream.Open();
oStream.CharSet = "UTF-8";
oStream.WriteText(sOvalXML);
oStream.SaveToFile(oTargetFolder.Path + "\\" + sFilename);
oStream.Close();
iFound++;
if (iResultLimit > 0 && iFound >= iResultLimit) break;
}
if (iResultLimit > 0 && iFound >= iResultLimit) {
WScript.echo("\nSearch stopped at limit of "+ iFound +" OVAL definitions.");
} else {
WScript.echo("\nSearch complete. Retrieved "+ iFound +" OVAL definitions.");
}
if (iFailed > 0) WScript.echo("Unable to retrieve "+ iFailed +" definitions.");
return iFound;
}
function getRemoteFileContent(sUrl) {
var oXHR = new ActiveXObject("Msxml2.XMLHttp.6.0");
oXHR.open("GET", sUrl, false);
oXHR.send();
if (oXHR.readyState != 4) { WScript.echo(" Error: request did not complete."); return false; }
if (oXHR.status != 200) { WScript.echo(" Error: API returned HTTP code: "+ oXHR.status +"."); return false; }
return oXHR.responseText;
}
function waitASecond(iSeconds) {
if (!iSeconds) iSeconds = 1;
var iStop = new Date().getTime() + (iSeconds * 1000);
while (new Date().getTime() < iStop) {
runLittleMan();
}
}
function runLittleMan() {
var sDel = String.fromCharCode(8);
for (var i=0; i<=17; i++) {
switch (i) {
case 1: WScript.stdout.write(' |'); break;
case 2: WScript.stdout.write(sDel + ' /'); break;
case 3: WScript.stdout.write(sDel + ' -'); break;
case 4: WScript.stdout.write(sDel + ' \\'); break;
case 5: WScript.stdout.write(sDel + ' |'); break;
case 6: WScript.stdout.write(sDel + ' /'); break;
case 7: WScript.stdout.write(sDel + ' -'); break;
case 8: WScript.stdout.write(sDel + ' \\'); break;
case 9: WScript.stdout.write(sDel + ' |'); break;
case 10: WScript.stdout.write(sDel+' '+sDel+sDel+sDel + '\\ '); break;
case 11: WScript.stdout.write(sDel+sDel+sDel+ '- '); break;
case 12: WScript.stdout.write(sDel+sDel+sDel+ '/ '); break;
case 13: WScript.stdout.write(sDel+sDel+sDel+ '| '); break;
case 14: WScript.stdout.write(sDel+sDel+sDel+ '\\ '); break;
case 15: WScript.stdout.write(sDel+sDel+sDel+ '- '); break;
case 16: WScript.stdout.write(sDel+sDel+sDel+ '/ '); break;
case 17: WScript.stdout.write(sDel+sDel+sDel+sDel+ '. '); break;
}
WScript.Sleep(100);
}
WScript.stdout.write(sDel+sDel+sDel+sDel+sDel+sDel+ ' '+sDel);
}
function getTempFolder(){
// create temp folder in temp
var oTempFolder = oFSO.GetSpecialFolder(2);
var sFolderName = oTempFolder.path + "\\" + oFSO.GetTempName();
var oFolder = oFSO.CreateFolder(sFolderName);
return oFolder;
}
function createZip(oSourceFolder, sTargetFile) {
sTargetFile = oFSO.GetAbsolutePathName(sTargetFile);
var oFile = oFSO.CreateTextFile(sTargetFile, true);
oFile.write("PK");
oFile.write(String.fromCharCode(5));
oFile.write(String.fromCharCode(6));
oFile.write('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0');
oFile.close();
var oShell = new ActiveXObject("shell.application");
var oZip = oShell.NameSpace(sTargetFile);
var oItems = oShell.NameSpace(oSourceFolder.path).Items();
WScript.echo("Zipping "+ oItems.Count +" definitions.");
if (oZip != null) {
oZip.CopyHere(oItems);
}
while (true) {
waitASecond(10);
try {
oFile = oFSO.OpenTextFile(sTargetFile,8);
break;
} catch(e) { }
}
oFile.close();
}
var iStartTime = new Date().getTime();
if (WScript.Arguments.length < 1) {
WScript.Echo("\nDESCRIPTION\nThis is a Windows Script Host script to retrieve OVAL definitions from the Cisco OVAL Repository add them to a zip file.\n\n"+
"USAGE\n cscript cisco-repo-get-oval-zip.js FILENAME.ZIP [LIMIT]\n\n"+
"PARAMETERS\n"+
" FILENAME.ZIP: the file name of the zip that will be created\n"+
" LIMIT: optional limit to the number of definitions that will be retrieved (integer)\n\n"+
"EXAMPLE\n cscript cisco-repo-get-oval-zip.js cisco.oval.zip\n");
WScript.Quit();
} else {
var sOutputFileName = WScript.Arguments.Item(0);
var iResultLimit = (WScript.Arguments.length > 1) ? WScript.Arguments.Item(1) : 0;
}
// create a temp folder to store definitions in
var oTargetFolder = getTempFolder();
// intitiate search and retrieval of OVAL Definitions from SCAP Sync
var iDefinitionsFound = getOvalDefinitions(oTargetFolder, iResultLimit);
if (iDefinitionsFound < 1) {
WScript.echo("Error: no OVAL found in repository at: '"+ sCiscoRepositoryURL +"'.");
WScript.Quit();
}
// create zip
createZip(oTargetFolder,sOutputFileName);
var iSecondsTimeElapsed = (new Date().getTime() - iStartTime) / 1000;
WScript.echo("\nDone in "+ Math.floor(iSecondsTimeElapsed/60) +" minutes and "+ Math.round(iSecondsTimeElapsed % 60) +" seconds!");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment