313 lines
10 KiB
C#
313 lines
10 KiB
C#
// /**
|
|
// * File: CrawlHost.cs
|
|
// * Author: haraldwolff
|
|
// *
|
|
// * This file and it's content is copyrighted by the Author and / or copyright holder.
|
|
// * Any use wihtout proper permission is illegal and may lead to legal actions.
|
|
// *
|
|
// *
|
|
// **/
|
|
using System;
|
|
using ln.types.threads;
|
|
using ln.logging;
|
|
using System.Net.NetworkInformation;
|
|
using ln.snmp.endpoint;
|
|
using ln.snmp;
|
|
using System.Net;
|
|
using ln.snmp.types;
|
|
using System.Collections.Generic;
|
|
using ln.snmp.rfc1213;
|
|
using ln.types;
|
|
using Newtonsoft.Json;
|
|
namespace ln.skyscanner.crawl
|
|
{
|
|
public class CrawlHost : PoolJob
|
|
{
|
|
[JsonIgnore]
|
|
public Crawler Crawler { get; }
|
|
[JsonIgnore]
|
|
public CrawledHost CrawledHost { get; }
|
|
|
|
public CrawlHost(Crawler crawler,CrawledHost crawledHost)
|
|
{
|
|
Crawler = crawler;
|
|
CrawledHost = crawledHost;
|
|
|
|
Name = String.Format("Host crawl {0} [ {1} ]", crawledHost.Name, crawledHost.PrimaryIP);
|
|
}
|
|
|
|
public override void RunJob()
|
|
{
|
|
DateTime dateTime = DateTime.Now;
|
|
|
|
if (crawlPing(CrawledHost))
|
|
{
|
|
if (CrawledHost.FirstSeen.Equals(DateTime.MinValue))
|
|
CrawledHost.FirstSeen = DateTime.Now;
|
|
|
|
CrawledHost.LastSeen = DateTime.Now;
|
|
|
|
try
|
|
{
|
|
|
|
CrawlSNMP(CrawledHost);
|
|
|
|
|
|
} catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "CrawlHost: {0}: caught exception",CrawledHost.PrimaryIP);
|
|
Logging.Log(e);
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
CrawledHost.LastCheck = dateTime;
|
|
CrawledHost.NextCheck = dateTime + TimeSpan.FromHours(1);
|
|
}
|
|
|
|
public bool crawlPing(CrawledHost crawledHost)
|
|
{
|
|
using (Ping ping = new Ping())
|
|
{
|
|
setState("ICMP check");
|
|
|
|
int nSuccess = 0;
|
|
long roundTripTime = 0;
|
|
|
|
for (int n = 0; n < 10; n++)
|
|
{
|
|
setState("ICMP check [{0}/10]",n);
|
|
|
|
PingReply pingReply = ping.Send(crawledHost.PrimaryIP, 500);
|
|
if (pingReply.Status == IPStatus.Success)
|
|
{
|
|
nSuccess++;
|
|
roundTripTime += pingReply.RoundtripTime;
|
|
}
|
|
else if ((n > 3) && (nSuccess == 0))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (nSuccess > 0)
|
|
{
|
|
roundTripTime /= nSuccess;
|
|
|
|
crawledHost.SetHint("ping.success", true);
|
|
crawledHost.SetHint("ping.rta", (int)roundTripTime);
|
|
crawledHost.SetHint("ping.out_of_ten", nSuccess);
|
|
Logging.Log(LogLevel.INFO, "Host is reachable: {0} RTA={1}ms", crawledHost.PrimaryIP, roundTripTime);
|
|
}
|
|
else
|
|
{
|
|
crawledHost.SetHint("ping.success", false);
|
|
crawledHost.SetHint("ping.rta", null);
|
|
crawledHost.SetHint("ping.out_of_ten", 0);
|
|
|
|
Logging.Log(LogLevel.INFO, "Host is unreachable: {0}", crawledHost.PrimaryIP);
|
|
}
|
|
return crawledHost.GetHint<bool>("ping.success");
|
|
}
|
|
}
|
|
|
|
public void CrawlSNMP(CrawledHost crawledHost)
|
|
{
|
|
string[] communities = new string[] { "VhclfC7lfIojYZ", "Vhclf(C7$lfIojYZ", "ByFR4oW98hap", "qVy3hnZJ2fov" };
|
|
|
|
bool snmpDetected = false;
|
|
|
|
using (USMEndpoint v3endpoint = new USMEndpoint(Crawler.SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
|
|
{
|
|
setState("SNMPv3 check");
|
|
try
|
|
{
|
|
v3endpoint.QueryEngineID();
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
}
|
|
|
|
if (v3endpoint.RemoteEngineID != null)
|
|
{
|
|
crawledHost.SetHint("snmp.version", 3);
|
|
Logging.Log(LogLevel.INFO, "{0}: SNMPv3 support detected", crawledHost.PrimaryIP);
|
|
|
|
bool replied = false;
|
|
int c = 0;
|
|
|
|
foreach (string community in communities)
|
|
{
|
|
c++;
|
|
setState("SNMPv3 check [{0}/{1}]",c,communities.Length);
|
|
|
|
v3endpoint.Username = "skytron";
|
|
v3endpoint.AuthMethod = SnmpV3AuthMethod.SHA;
|
|
v3endpoint.AuthKeyPhrase = community;
|
|
|
|
try
|
|
{
|
|
Variable prID = v3endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
|
|
crawledHost.SetHint("snmp.username", "skytron");
|
|
crawledHost.SetHint("snmp.authkey", community);
|
|
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
|
|
|
|
replied = true;
|
|
break;
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
}
|
|
}
|
|
|
|
if (replied)
|
|
{
|
|
snmpDetected = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (!snmpDetected)
|
|
{
|
|
using (SnmpV2Endpoint v2endpoint = new SnmpV2Endpoint(Crawler.SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
|
|
{
|
|
setState("SNMPv2c check");
|
|
|
|
foreach (String community in communities)
|
|
{
|
|
v2endpoint.CommunityString = community;
|
|
try
|
|
{
|
|
Variable prID = v2endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
|
|
|
|
crawledHost.SetHint("snmp.version", 2);
|
|
crawledHost.SetHint("snmp.community", community);
|
|
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
|
|
|
|
snmpDetected = true;
|
|
break;
|
|
}
|
|
catch (SnmpError)
|
|
{
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!snmpDetected)
|
|
{
|
|
using (SnmpV1Endpoint v1endpoint = new SnmpV1Endpoint(Crawler.SNMPEngine, new IPEndPoint(crawledHost.PrimaryIP, 161)))
|
|
{
|
|
setState("SNMPv1 check");
|
|
|
|
foreach (String community in communities)
|
|
{
|
|
v1endpoint.CommunityString = community;
|
|
try
|
|
{
|
|
Variable prID = v1endpoint.snmpGet("1.3.6.1.2.1.1.2.0");
|
|
|
|
crawledHost.SetHint("snmp.version", 1);
|
|
crawledHost.SetHint("snmp.community", community);
|
|
crawledHost.SetHint("snmp.sysObjectID", (prID as ObjectIdentifier).AsString);
|
|
|
|
snmpDetected = true;
|
|
break;
|
|
}
|
|
catch (SnmpError)
|
|
{
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!snmpDetected)
|
|
{
|
|
crawledHost.SetHint("snmp.version", null);
|
|
crawledHost.SetHint("snmp.username", null);
|
|
crawledHost.SetHint("snmp.authkey", null);
|
|
crawledHost.SetHint("snmp.community", null);
|
|
crawledHost.SetHint("snmp.sysObjectID", null);
|
|
}
|
|
else
|
|
{
|
|
setState("SNMP crawl");
|
|
try
|
|
{
|
|
using (SnmpEndpoint endpoint = crawledHost.GetSnmpEndpoint(Crawler.SNMPEngine))
|
|
{
|
|
try
|
|
{
|
|
Sequence[] VorIDs = endpoint.snmpWalk("1.3.6.1.2.1.1.9.1.2").ToArray();
|
|
string[] orids = new string[VorIDs.Length];
|
|
|
|
for (int n = 0; n < orids.Length; n++)
|
|
{
|
|
orids[n] = (VorIDs[n].Items[1] as ObjectIdentifier).AsString;
|
|
}
|
|
|
|
crawledHost.SetHint("snmp.orids", orids);
|
|
}
|
|
catch (TimeoutException)
|
|
{ }
|
|
|
|
List<String> ids = new List<string>(crawledHost.GetHint<String[]>("snmp.orids", new string[0]));
|
|
|
|
if (ids.Contains("1.3.6.1.2.1.31") || crawledHost.GetHint<string>("snmp.sysObjectID", "").Equals("1.3.6.1.4.1.14988.1"))
|
|
{
|
|
CrawlRFC1213(crawledHost, endpoint);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "CrawlHost {0} caught exception: {1}", CrawledHost, e);
|
|
Logging.Log(e);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void CrawlRFC1213(CrawledHost crawledHost, SnmpEndpoint endpoint)
|
|
{
|
|
RFC1213.Interface[] interfaces = RFC1213.GetInterfaces(endpoint);
|
|
crawledHost.Interfaces = interfaces;
|
|
|
|
foreach (CIDR ip in crawledHost.IPAddresses)
|
|
{
|
|
if (ip.MaskWidth != 32)
|
|
Crawler.CrawlPool.GetSubnet(ip.Network);
|
|
}
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return CrawledHost.GetHashCode();
|
|
}
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is CrawlHost)
|
|
{
|
|
CrawlHost you = obj as CrawlHost;
|
|
return Crawler.Equals(you.Crawler) && CrawledHost.Equals(you.CrawledHost);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|