Skip to content

Instantly share code, notes, and snippets.

@spacelatte
Last active December 2, 2016 16:57
Show Gist options
  • Save spacelatte/bf29f658a10e6259b98d362a243190b2 to your computer and use it in GitHub Desktop.
Save spacelatte/bf29f658a10e6259b98d362a243190b2 to your computer and use it in GitHub Desktop.
check whois, ssl cert and smtp from node.js
#!/usr/bin/env node
const fs = require("fs");
const tls = require("tls");
const net = require("net");
const dns = require("dns");
const whois = require("whois");
const sql = require("sql.js");
const whoistabname = "whois";
const certtabname = "cert";
const smtptabname = "smtp";
const _domain = "e.x.a.m.p.l.e.com";
const default_cooldown = 111;
const mail_user = "n0r3ply";
const def_tout_val = 999;
var db = null;
const matchtable = {
"tr": [
"expires on",
],
"com": [
"expiration date",
"expiry date",
],
"net": [
"expiration date",
],
"org": [
"expiry date",
],
"me": [
"expiry date",
],
"io": [
"expiry",
],
"co": [
"domain expiration date",
],
};
const matchfunc = {
"local": function(arg) {
return arg.split(":").slice(1).join(":").trim();
},
"space": function(arg) {
return this.local(arg.replace(/ /g,""));
},
"verisign": function(arg) {
if('\r' == arg[arg.length-1]) {
arg = arg.substring(0,arg.length-2); // removal of carriage return;
// } else if('Z' != arg[arg.length-1]) {
// arg += 'Z';
}
return matchfunc.local(arg);
},
"tr": [
function(arg) {
return matchfunc.space(arg);
},
],
"com": [
function(arg) {
return matchfunc.verisign(arg);
},
function(arg) {
return matchfunc.local(arg);
},
],
"net": [
function(arg) {
return matchfunc.verisign(arg);
},
],
"org": [
function(arg) {
return matchfunc.space(arg);
},
],
"me": [
function(arg) {
return matchfunc.space(arg);
},
],
"io": [
function(arg) {
return matchfunc.space(arg);
},
],
"co": [
function(arg) {
return matchfunc.local(arg.replace(/\s+/g," "));
},
],
};
function check(host,delay) {
// var dt = Date.now(); while(dt+delay > Date.now()) continue;
// get tld
var tld = host.split(".").pop();
whois.lookup(host, {
"server": null,
"follow": 5,
"timeout": 0,
"verbose": false,
},
function(err, data, addr) {
if(err) {
return console.log("[fail] whois network:", err.code, ":", err.errno, host);
}
data = data.split("\n");
var dates = [];
data.forEach(function(line,index,orig) {
for(i=0;i<matchtable[tld].length;i++) {
if(line.toLowerCase().indexOf(matchtable[tld][i]) > -1) {
dates.push(matchfunc[tld][i](line));
}
}
});
var str = dates.join(null);
//str = str.split("T")[0];
var d = new Date(str);
if(str == null || d.getTime().toString().indexOf("NaN") >= 0) {
return console.log("[fail] whois response:", host, [data.join("\r")]);
}
try {
db.run("insert into"
+ " '" + whoistabname + "' "
+ "values(null,:host,:time);", {
":host": host,
":time": d.getTime(),
}
);
} catch(e) {
db.run("update"
+ " '" + whoistabname + "' "
+ "set exp = "
+ " '"+d.getTime()+"' "
+ "where host = "
+ " '" + host + "' " + ";"
);
}
console.log("[ ok ] whois:", d, host);
return;
}
);
//let types = tls.getCiphers();
//types.push(null);
[null].forEach(function(ctype,ci,clist) {
var conn = tls.connect(443, host, {
"rejectUnauthorized":false,
"ciphers": ctype,
}, function() {
cert = this.getPeerCertificate(true);
cert_dates = [
new Date(cert.valid_from),
new Date(cert.valid_to),
];
// console.log(this.getProtocol(), host, cert_dates,
// cert.valid_from, cert.valid_to, cert.subjectaltname);
if(this.getProtocol === undefined) {
this.getProtocol = function() {
return null;
};
}
cert.subjectaltname = cert.subjectaltname.replace(/, /g, "\n");
try {
db.run("insert into"
+" '"+certtabname+"' "
+" values(null,:host,:cs,:ce,:dns,:prot);", {
":host": host,
":cs": cert_dates[0].getTime(),
":ce": cert_dates[1].getTime(),
":dns": cert.subjectaltname,
":prot": this.getProtocol(),
}
);
} catch(e) {
db.run("update '"+certtabname+"' set "
+ " 'cert_start' = '" + cert_dates[0].getTime() + "',"
+ " 'cert_end' = '" + cert_dates[1].getTime() + "',"
+ " 'dns' = '" + cert.subjectaltname + "',"
+ " 'prot' = '" + this.getProtocol() + "' "
+ " where "
+ " host = '" + host + "' "
+ " ;"
);
}
console.log("[ ok ] certificate:",
cert_dates[0],cert_dates[1],
this.getProtocol(), ctype, host
);
this.destroy();
return;
});
conn.on("error", function(err) {
console.log("[fail] certificate:", host, err.toString().split("\n")[0], ctype );
return;
});
setTimeout(function() {
conn.destroy();
return;
},def_tout_val);
return;
});
dns.resolveMx(host,function(err,addr) {
if(addr == null) {
return console.log("[fail] smtp n/w:", host, err);
}
var is_relay = 0;
var servers = [];
addr.forEach(function(elem,index,array) {
servers.push(elem.exchange);
var smtp = net.connect(25, elem.exchange, function(e,a) {
smtp.on("data", function(data) {
data.toString().split("\r\n").forEach(function(elem,index,array) {
if(parseInt(elem.split(" ")[0]) == 354) {
is_relay |= 1;
return;
} else if(parseInt(elem.split(" ")[0]) == 550) {
is_relay |= 0;
return;
}
return;
});
return;
});
var mc = [];
mc.push("HELO " + host + "");
mc.push("MAIL FROM: " + mail_user + "@" + host + " ");
mc.push("RCPT TO: " + mail_user + "@" + _domain + " ");
// mc.push("DATA");
// mc.push("Open Relay Test");
// mc.push(".");
mc.push("QUIT");
smtp.write(mc.join("\r\n"));
setTimeout(function() {
smtp.destroy();
return;
},def_tout_val);
// console.log(mc.join("\n"));
return;
});
smtp.on("error", function(err) {
console.log("[fail] smtp:", host, addr, err.code, ":", err.errno);
return;
});
return;
});
console.log("[ ok ] smtp:", host, servers.join(", "),
(is_relay?"RELAY DETECTED!":"")
);
try {
db.run("insert into"
+ " '" + smtptabname + "' "
+ "values(null,:host,:mx,:relay);", {
":host": host,
":mx": servers.join(",\n"),
":relay": is_relay,
}
);
} catch(e) {
db.run("update"
+ " '" + smtptabname + "' "
+ "set relay = "
+ " '" + is_relay + "', "
+ " servers = "
+ " '" + servers.join(",\n") + "' "
+ "where host = "
+ " '" + host + "' " + ";"
);
}
return;
});
return;
}
function dbinit(filename) {
try {
fs.statSync(filename);
} catch(e) {
fs.closeSync(
fs.openSync(filename,"w")
);
}
db = new sql.Database(
fs.readFileSync(
filename,{
"flag":"r",
}
)
);
db.exec("create table if not exists"
+ " '" + whoistabname + "' "
+ " ( "
+ " id integer primary key,"
+ " host text not null unique,"
+ " exp integer not null"
+ " );"
);
db.exec("create table if not exists"
+ " '" + certtabname + "' "
+ " ("
+ " id integer primary key,"
+ " host text not null unique,"
+ " cert_start int,"
+ " cert_end int,"
+ " dns text,"
+ " prot text"
+ " );"
);
db.exec("create table if not exists"
+ " '" + smtptabname + "' "
+ " ("
+ " id integer primary key,"
+ " host text not null unique,"
+ " servers text,"
+ " relay int not null"
+ " );"
);
return;
}
function dbsave(filename) {
fs.writeFileSync(filename,
new Buffer(db.export()));
return;
}
if(require.main === module) {
if(process.argv.length <= 2) {
console.log("arg missing");
return;
}
console.log("starting...");
dbinit(process.argv[2]);
process.on("beforeExit", function() {
dbsave(process.argv[2]);
});
var chost = null;
switch(process.argv[3]) {
case "update":
var res = db.exec("select host from"
+ " ( "
+ " select host from "
+ " '" + certtabname + "' "
+ " union all "
+ " select host from "
+ " '" + whoistabname + "' "
+ " union all "
+ " select host from "
+ " '" + smtptabname + "' "
+ " ) "
+ " group by host "
+ " ;"
);
if(!res || res.length < 1) {
break;
}
for(i=0;i<res[0].values.length;i++) {
chost = res[0].values[i][0];
// setTimeout(function() {
check(chost, default_cooldown);
// return;
// },i*default_cooldown);
continue;
}
break;
default:
for(var i=3;i<process.argv.length;i++) {
chost = process.argv[i];
// setTimeout(function() {
check(chost, default_cooldown);
// return;
// },i*default_cooldown);
continue;
}
break;
}
return;
}
NODE = node
FLAGS = --harmony
DBNAME = test.db
MAINFN = checker.js
SQLITE = sqlite3
%.org %.com %.net %.co %.tr %.io %.me:
$(NODE) $(FLAGS) $(MAINFN) $(DBNAME) $@
auto: init
$(NODE) $(FLAGS) $(MAINFN) $(DBNAME) $$(cat hosts.txt | tr \\n \ )
init: node_modules
npm install
node_modules:
-mkdir -p $@
update:
$(NODE) $(FLAGS) $(MAINFN) $(DBNAME) $@
%.test:
$(SQLITE) $(DBNAME) "select * from $$(basename $@ .test)";
test: whois.test cert.test smtp.test
$(SQLITE) $(DBNAME) ".tables"
.PHONY:
{
"name": "lcheck",
"version": "0.1.0",
"description": "check various net info from external sources",
"main": "main.js",
"dependencies": {
"sql.js": "^0.3.2",
"whois": "^2.1.6"
},
"devDependencies": {},
"scripts": {
"test": "node main.js save.db google.com"
},
"keywords": [
"whois",
"check",
"network",
"sqlite"
],
"author": "mert akengin",
"license": "ISC",
"repository": {
"type": "git",
"url": "http://gist.github.com/pvtmert/bf29f658a10e6259b98d362a243190b2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment