Last active
February 25, 2016 21:30
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************************************************************************** | |
* 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