static void ScanHttp(IPAddress ip, IpReport report) { try { HttpWebResponse resp = null; try { var req = (HttpWebRequest)WebRequest.Create(string.Format("http://{0}:{1}", ip, 80)); req.UserAgent = "Crawler"; req.AllowAutoRedirect = false; req.ServicePoint.Expect100Continue = false; req.KeepAlive = false; var ar = req.BeginGetResponse(null, null); using (ar.AsyncWaitHandle) { if (ar.AsyncWaitHandle.WaitOne(Settings.Default.HttpTimeout)) { resp = (HttpWebResponse)req.EndGetResponse(ar); } } } catch (WebException we) { resp = we.Response as HttpWebResponse; } if (resp == null) return; using (resp) { var http = new HttpReport(); if (resp.ContentLength > 0) { using (var sr = new StreamReader(resp.GetResponseStream())) http.Body = sr.ReadToEnd(); } http.Headers = new List<string>(resp.Headers.AllKeys.Select(k => k + ": " + resp.Headers[k])); http.Server = resp.Headers["Server"]; http.StatusCode = (int)resp.StatusCode; var match = Regex.Match(http.Body, "<title>(.*?)</title>", RegexOptions.IgnoreCase); if (match.Success) http.Title = match.Groups[1].Value; if (resp.StatusCode == HttpStatusCode.Unauthorized) { var auth = resp.Headers["WWW-Authenticate"]; if (!string.IsNullOrEmpty(auth) && auth.Trim().Length > 0) http.Title = resp.Headers["WWW-Authenticate"]; } report.Protocols["Http"] = http; } } catch (Exception ex) { } }
static void ScanLoop() { while (true) { var ip = GetNextIp(); var ipaddr = IpUtil.IntToIp(ip); var found = new List<int>(); for (int i = 0; i < Ports.Count; i++) { try { using (var tcp = new TcpClient()) { var ar = tcp.BeginConnect(ipaddr, Ports[i], null, null); using (ar.AsyncWaitHandle) { if (ar.AsyncWaitHandle.WaitOne(Settings.Default.ConnectTimeout)) { tcp.EndConnect(ar); found.Add(Ports[i]); } } } } catch (Exception ex) { StaticLogger.Trace(ex); } } IpsScanned++; if (found.Count < 1) { continue; } IpsFound++; StaticLogger.Trace(string.Format("Found IP {0}", ipaddr)); var report = new IpReport(); report.Ip = ipaddr.ToString(); report.HostName = GetHostName(ipaddr); report.Ports = found; if (Settings.Default.ScanSubnets) { lock (IpQueue) { uint lrange = ip >> 8; uint range = ip & 0xFFFFFF00; if (!RangesScanned[lrange]) { StaticLogger.Info(string.Format("Scanning Range {0}", IpUtil.IntToIp(range))); for (long i = range; i < range + 0x100; i++) { if (i != ip) { IpQueue.Enqueue((uint)i); } } RangesScanned[lrange] = true; } } } for (int i = 0; i < found.Count; i++) { Action<IPAddress, IpReport> func; if (ScanMethods.TryGetValue(found[i], out func)) func(ipaddr, report); } lock (ReportQueue) ReportQueue.Add(report); } }
static void Report() { var mindelay = Settings.Default.ReportsMinDelay; var maxdelay = Settings.Default.ReportsMaxDelay; var percall = Settings.Default.ReportsPerCall; var reports = new IpReport[percall]; while (true) { var lastreport = DateTime.UtcNow; while (true) { var span = (DateTime.UtcNow - lastreport); if (span >= mindelay && ReportQueue.Count >= percall) break; if (span >= maxdelay) break; Thread.Sleep(100); } if (ReportQueue.Count < 1) continue; int processing; //The number of reports being processed this round. lock (ReportQueue) { processing = Math.Min(ReportQueue.Count, percall); ReportQueue.CopyTo(0, reports, 0, processing); } try { var http = (HttpWebRequest)WebRequest.Create(Settings.Default.ApiUrl); http.Method = WebRequestMethods.Http.Post; http.KeepAlive = false; http.ServicePoint.Expect100Continue = false; http.ContentType = "application/octet-stream"; var dict = new Dictionary<string, object>(); dict["do"] = "reports"; dict["key"] = Settings.Default.ApiKey; dict["reports"] = reports.Take(processing); var sdata = JsonConvert.SerializeObject(dict); var data = CompressString(sdata); StaticLogger.Info(new ConsoleOutput(ConsoleColor.DarkCyan, "Sending {0} reports, {1}KB ({2}KB)", processing, data.Length / 1024, sdata.Length / 1024)); using (var s = http.GetRequestStream()) s.Write(data, 0, data.Length); using (var resp = http.GetResponseNoException()) { using (var sr = new StreamReader(resp.GetResponseStream())) { if (resp.StatusCode != HttpStatusCode.OK) StaticLogger.Warning("Failed to report discovered hosts"); StaticLogger.Info(new ConsoleOutput(ConsoleColor.Cyan, sr.ReadToEnd())); IpsReported += processing; } } //Remove reports only if it was successful. lock (ReportQueue) ReportQueue.RemoveRange(0, processing); } catch (Exception ex) { StaticLogger.Warning("Failed to report discovered hosts"); StaticLogger.Error(ex); } } }