Forerunner:一款支持多线程、Ping探测和数据提取的快速可扩展网络扫描库

摘要

Forerunner

Forerunner是一个快速的、轻量级的并且可扩展的网络库,它可以帮助研究人员开发一个以网络为中心的健壮的应用程序,比如说IP扫描器、端口扫描器、客户端以及服务器等等。当前版本的Forerunner,能够支持针对端口和IP地址进行同步或异步扫描,并收集关于目标设备的地理位置信息和终端信息,比如说IP地址是否在线以及设备的物理MAC地址等等。这个库是一个完全面向对象和基于事件的库,这意味着扫描数据都将包含在精心编制的“scan”对象之中,而这些对象旨在处理涵盖从结果到异常的所有数据。

工具依赖

1、.NET Framework v4.6.1

功能介绍

方法名 描述 使用样例
Scan 扫描IP地址并收集信息 Scan("192.168.1.1");
ScanRange 扫描IP地址范围并收集信息 ScanRange("192.168.1.1", "192.168.1.255")
ScanList 扫描IP地址列表并收集信息 ScanList("192.168.1.1, 192.168.1.2, 192.168.1.3")
PortKnock 扫描单个IP地址的所有端口 PortKnock("192.168.1.1");
PortKnockRange 扫描IP地址范围内的所有端口 PortKnockRange("192.168.1.1", "192.168.1.255");
PortKnockList 扫描IP地址列表中的所有端口 PortKnockList("192.198.1.1, 192.168.1.2, 192.168.1.3");
IsHostAlive 多少毫秒扫描主机N次 IsHostAlive("192.168.1.1", 5, 1000);
GetAveragePingResponse 获取目标主机平均ping响应 GetAveragePingResponse("192.168.1.1", 5, 1000);
IsPortOpen 通过TCP&UDP来ping单个端口 IsPortOpen("192.168.1.1", 45000, new TimeSpan(1000), false);

工具下载

广大研究人员可以使用下列命令将项目源码克隆至本地:

git clone https://github.com/jasondrawdy/Forerunner.git

工具使用样例

IP扫描

在网络安全研究过程中,扫描一个网络是一种非常常见的任务了,因此我们应该通过尽可能简单的方法来实现这个目标,以方便未来的安全研究人员去做同样的事情。Forerunner是一个完全面向对象的功能库,因此非常适合所谓“即插即用”的情况。其中,用于IP扫描的对象被称之为IPScanObject,这个对象包含了下列几种参数属性:

Address (String)

IP (IPAddress)

Ping (Long)

Hostname (String)

MAC (String)

isOnline (Bool)

Errors (Exception)

有了对象的概念之后,我们可以尝试创建一个新的对象,并使用它来执行一次扫描任务。最简单的方法就是先创建一个新的Scanner对象,并通过它来访问我们的扫描方法。接下来,创建一个IPScanObject对象,并使用目标IP地址来设置其Scan方法。

同步扫描:


using System;

using Forerunner; // Remember to import our library.

namespace Example

{

    class Program

    {

        static void Main(string[] args)

        {

            // Our IP we would like to scan.

            string ip = "192.168.1.1";

            // Create a new scanner object.

            Scanner s = new Scanner();

            // Create a new scan object and perform a scan.

            IPScanObject result = s.Scan(ip);

            // Output that we have finished the scan.

            if (result.Errors != null)

                Console.WriteLine("[x] An error occurred during the scan.");

            else

                Console.WriteLine("[+] " + ip + " has been successfully scanned!")

            // Allow the user to exit at any time.

            Console.Read();

        }

    }

}

另一种方法是创建Scanner对象并订阅ScanAsyncProgressChangedScanAsyncComplete之类的事件处理程序,这样我可以完全控制异步方法,我可以控制它们影响应用程序的进度状态等等。

异步扫描:


using System;

using System.Threading.Tasks;

using Forerunner; // Remember to import our library.

namespace Example

{

    class Program

    {

        static void Main(string[] args)

        {

            // Our IP we would like to scan.

            string ip = "192.168.1.1";

            // Setup our scanner object.

            Scanner s = new Scanner();

            s.ScanAsyncProgressChanged += new ScanAsyncProgressChangedHandler(ScanAsyncProgressChanged);

            s.ScanAsyncComplete += new ScanAsyncCompleteHandler(ScanAsyncComplete);

            // Start a new scan task with our ip.

            TaskFactory task = new TaskFactory();

            task.StartNew(() => s.ScanAsync(ip));

            // Allow the user to exit at any time.

            Console.Read();

        }

        static void ScanAsyncProgressChanged(object sender, ScanAsyncProgressChangedEventArgs e)

        {

            // Do something here with e.Progress, or you could leave this event

            // unsubscribed so you wouldn't have to do anything.

        }

        static void ScanAsyncComplete(object sender, ScanAsyncCompleteEventArgs e)

        {

           // Do something with the IPScanObject aka e.Result.

            if (e.Result.Errors != null)

                Console.WriteLine("[x] An error occurred during the scan.");

            else

                Console.WriteLine("[+] " + e.Result.IP + " has been successfully scanned!")

        }

    }

}

端口扫描

跟IP地址扫描一样,端口扫描可以通过一组预定义的端口来尝试进行端口连接,并检查目标端口是否真正开启。它将尝试通过与每个端口进行连接并发送数据包来进行端口探测。这个功能同样是通过一个自定义对象来实现的,即"Port Knock Scan Object",简称为“PKScanObject”。 PKScanObject对象实际上包含一个PKServiceObjects列表,该列表将保存返回的全部端口数据,该服务对象包含下列参数属性:

IP (String)

Port (Int)

Protocol (PortType)

Status (Bool)

首先,我们需要创建一个Scanner对象,然后创建一个新的PKScanObject对象并使用目标IP来设置PortKnock方法,然后工具将显示扫描结果给我们。

同步扫描:


using System;

using Forerunner; // Remember to import our library.

namespace Example

{

    class Program

    {

        static void Main(string[] args)

        {

            // Our IP we would like to scan.

            string ip = "192.168.1.1";

            // Create a new scanner object.

            Scanner s = new Scanner();

            // Create a new scan object and perform a scan.

            PKScanObject result = s.PortKnock(ip);

            // Output that we have finished the scan.

            if (result.Errors != null)

                Console.WriteLine("[x] An error occurred during the scan.");

            else

                Console.WriteLine("[+] " + ip + " has been successfully scanned!")

           // Display our results.

           foreach (PKServiceObject port in result.Services)

           {

                Console.WriteLine("[+] IP: " + port.IP + " | " +

                                  "Port: " + port.Port.ToString() + " | " +

                                  "Protocol: " + port.Protocol.ToString() + " | " +

                                  "Status: " + port.Status.ToString());

           }

           // Allow the user to exit at any time.

           Console.Read();

        }

    }

}

异步扫描:


using System;

using System.Threading.Tasks;

using Forerunner; // Remember to import our library.

namespace Example

{

    class Program

    {

        static void Main(string[] args)

        {

            // Our IP we would like to scan.

            string ip = "192.168.1.1";

            // Setup our scanner object.

            Scanner s = new Scanner();

            s.PortKnockAsyncProgressChanged += new PortKnockAsyncProgressChangedHandler(PortKnockAsyncProgressChanged);

            s.PortKnockAsyncComplete += new PortKnockAsyncCompleteHandler(PortKnockAsyncComplete);

            // Start a new scan task with our ip.

            TaskFactory task = new TaskFactory();

            task.StartNew(() => s.PortKnockAsync(ip));

            // Allow the user to exit at any time.

            Console.Read();

        }

        static void PortKnockAsyncProgressChanged(object sender, PortKnockAsyncProgressChangedEventArgs e)

        {

            // Display our progress so we know the ETA.

            if (e.Progress == 99)

            {

                Console.Write(e.Progress.ToString() + "%...");

                Console.WriteLine("100%!");

            }

            else

                Console.Write(e.Progress.ToString() + "%...");

        }

        static void PortKnockAsyncComplete(object sender, PortKnockAsyncCompleteEventArgs e)

        {

            // Tell the user that the port knock was complete.

            Console.WriteLine("[+] Port Knock Complete!");

            // Check if we resolved an error.

            if (e.Result == null)

                Console.WriteLine("[X] The port knock did not return any data!");

            else

            {

                // Check if we have any ports recorded.

                if (e.Result.Services.Count == 0)

                    Console.WriteLine("[!] No ports were open during the knock.");

                else

                {

                    // Display our ports and their details.

                    foreach (PKServiceObject port in e.Result.Services)

                    { 

                        Console.WriteLine("[+] IP: " + port.IP + " | " +

                                          "Port: " + port.Port.ToString() + " | " +

                                          "Protocol: " + port.Protocol.ToString() + " | " +

                                          "Status: " + port.Status.ToString());

                    }

                }

            }

        }

    }

}

许可证协议

Forerunner项目的开发和发布遵循MIT开源许可证协议。

项目地址

Forerunner:【GitHub传送门

参考来源

jasondrawdy

目前评论:0 条

发表评论