亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++ Boost實(shí)現(xiàn)異步端口掃描器詳解

 更新時(shí)間:2023年11月21日 10:08:40   作者:lyshark  
端口掃描是一種用于識別目標(biāo)系統(tǒng)上哪些網(wǎng)絡(luò)端口處于開放、關(guān)閉或監(jiān)聽狀態(tài)的網(wǎng)絡(luò)活動,本文將運(yùn)用Boost框架實(shí)現(xiàn)一個(gè)基于TCP的掃描工具,有需要的小伙伴可以參考下

端口掃描是一種用于識別目標(biāo)系統(tǒng)上哪些網(wǎng)絡(luò)端口處于開放、關(guān)閉或監(jiān)聽狀態(tài)的網(wǎng)絡(luò)活動。在計(jì)算機(jī)網(wǎng)絡(luò)中,端口是一個(gè)虛擬的通信端點(diǎn),用于在計(jì)算機(jī)之間傳輸數(shù)據(jù)。每個(gè)端口都關(guān)聯(lián)著特定類型的網(wǎng)絡(luò)服務(wù)或應(yīng)用程序。端口掃描通常是網(wǎng)絡(luò)管理員、安全專業(yè)人員或黑客用來評估網(wǎng)絡(luò)安全的一種方法。通過掃描目標(biāo)系統(tǒng)的端口,可以了解系統(tǒng)上哪些服務(wù)在運(yùn)行、哪些端口是開放的,從而評估系統(tǒng)的安全性。

常見的端口掃描技術(shù)包括:

  • TCP端口掃描: 通過發(fā)送TCP連接請求來確定目標(biāo)系統(tǒng)上的端口是否開放。常見的TCP掃描包括全連接掃描(Connect Scan)、半開放掃描(SYN Scan)等。
  • UDP端口掃描: 通過向目標(biāo)系統(tǒng)發(fā)送UDP數(shù)據(jù)包,觀察是否收到相應(yīng)來判斷UDP端口是否開放。UDP掃描較為復(fù)雜,因?yàn)閁DP是一種無連接的協(xié)議,難以確定是否因?yàn)槎丝陉P(guān)閉而未響應(yīng)。
  • NULL、FIN和Xmas Tree掃描: 這些掃描技術(shù)利用TCP協(xié)議的特殊性質(zhì),嘗試向目標(biāo)系統(tǒng)發(fā)送非法或異常的TCP數(shù)據(jù)包,觀察目標(biāo)系統(tǒng)的響應(yīng)。
  • IDLE掃描: 利用一個(gè)第三方系統(tǒng)(通常是僵尸主機(jī))發(fā)送探測包,通過觀察目標(biāo)系統(tǒng)的響應(yīng)來判斷端口狀態(tài)。這種掃描方法更難被目標(biāo)系統(tǒng)檢測到。

本章我們將運(yùn)用Boost框架實(shí)現(xiàn)一個(gè)基于TCP的掃描工具,TCP端口掃描是一種常見的網(wǎng)絡(luò)掃描技術(shù),通過發(fā)送TCP連接請求來確定目標(biāo)系統(tǒng)上的端口是否開放,其本質(zhì)上是通過調(diào)用Socket套接字中的connect()嘗試連接對應(yīng)的端口,如果該端口開放則連接將被建立,由此我們就可以得出該端口是存活的,利用這一特性我們就可以實(shí)現(xiàn)批量的端口探測功能。

生成C段地址

C段地址通常指的是IPv4地址中的子網(wǎng)地址,其中C表示了地址的網(wǎng)絡(luò)前綴的類別。IPv4地址按照其前綴的長度被分為A、B、C、D和E五個(gè)類別,每個(gè)類別用于不同規(guī)模的網(wǎng)絡(luò)。

在IPv4地址中,每個(gè)地址由32位二進(jìn)制數(shù)字組成,通常以點(diǎn)分十進(jìn)制(Dotted-Decimal Notation)的形式表示,例如,192.168.0.1。IPv4地址的前面的一部分被分配給網(wǎng)絡(luò),而后面的部分則分配給主機(jī)。

  • A類地址: 以0開頭,用于大型網(wǎng)絡(luò),例如1.0.0.0到126.0.0.0。
  • B類地址: 以10開頭,用于中型網(wǎng)絡(luò),例如128.0.0.0到191.255.0.0。
  • C類地址: 以110開頭,用于小型網(wǎng)絡(luò),例如192.0.0.0到223.255.255.0。

因此,當(dāng)我們說一個(gè)IPv4地址屬于C段地址時(shí),通常指的是這個(gè)地址的前綴是C類地址的范圍,即以192.x.x.x223.x.x.x的范圍。例如,192.168.1.1是一個(gè)C段地址,因?yàn)樗那熬Y是192。在這樣的地址中,最后三個(gè)字節(jié)通常用于主機(jī)標(biāo)識。

同樣我們在實(shí)現(xiàn)端口掃描之前需要生成一個(gè)C段地址中所有的主機(jī)IP,這里我們可以通過Boost庫中的字符串拼接功能來實(shí)現(xiàn)生成特定主機(jī)網(wǎng)段,具體實(shí)現(xiàn)細(xì)節(jié)如下所示;

例如192.168.1.1/100則代表要枚舉出這個(gè)網(wǎng)段中所有的地址,并將其存儲到std::vector<std::string>容器中。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <vector>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

// 傳遞IP地址范圍,自動生成IP地址表
bool CalculationAddress(std::string address, std::vector<std::string> &ref)
{
  std::vector<std::string> vect;
  try
  {
    // 以/,兩個(gè)下劃線作為切割符號,切割后放入vect容器中
    boost::split(vect, address, boost::is_any_of("/") || boost::is_any_of("."), boost::token_compress_on);

    // 將開始和結(jié)束地址取出來
    int start_count = lexical_cast<int>(vect[3]);
    int end_count = lexical_cast<int>(vect[4]);

    // IP地址中的C段必須小于255
    if (end_count <= 255)
    {
      for (int x = start_count; x <= end_count; x++)
      {
        std::string this_address = boost::str(boost::format("%s.%s.%s.%s") % vect[0] % vect[1] % vect[2] % x);
        ref.push_back(this_address);
      }
    }
    else
    {
      return false;
    }
  }
  catch (...)
  {
    return false;
  }
  return true;
}

int main(int argc, char * argv[])
{
  // 生成 192.168.1.1/100 這個(gè)范圍內(nèi)的地址表
  std::vector<std::string> address_ref;
  bool flag = CalculationAddress("192.168.1.1/255", address_ref);

  if (flag == true)
  {
    // 輸出地址表
    for (int x = 0; x < address_ref.size(); x++)
    {
      std::cout << "地址表: " << address_ref[x] << std::endl;
    }
  }

  std::system("pause");
  return 0;
}

上述函數(shù)CalculationAddress通過傳入范圍192.168.1.1/100即可實(shí)現(xiàn)生成1-100以內(nèi)的所有IP地址字符串,并將其存儲到address_ref容器內(nèi),輸出效果如下圖所示;

端口字符串提取

接著我們還需要實(shí)現(xiàn)一個(gè)提取端口字符串的功能,例如當(dāng)使用者傳入22,23,135,139時(shí),我們將其解析成獨(dú)立的整數(shù)類型,并將其存儲到std::vector<int>容器內(nèi)保存,該功能的實(shí)現(xiàn)只需要使用boost::split函數(shù)切割并循環(huán)將數(shù)據(jù)放入到整數(shù)容器內(nèi)即可,如下所示;

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <vector>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

// 傳遞端口字符串,解析為vector容器
bool CalculationPort(std::string port_string, std::vector<int> &ref)
{
  std::vector<std::string> vect;
  try
  {
    boost::split(vect, port_string, boost::is_any_of(","), boost::token_compress_on);

    for (int x = 0; x < vect.size(); x++)
    {
      ref.push_back(lexical_cast<int>(vect[x]));
    }
    return true;
  }
  catch (...)
  {
    return false;
  }
  return true;
}

int main(int argc, char * argv[])
{
  // 傳入字符串端口,自動解析為vector容器
  std::vector<int> port_ref;
  bool flag = CalculationPort("22,23,55,135", port_ref);

  if (flag == true)
  {
    // 輸出地址表
    for (int x = 0; x < port_ref.size(); x++)
    {
      std::cout << "端口表: " << port_ref[x] << std::endl;
    }
  }

  std::system("pause");
  return 0;
}

通過boost中的函數(shù)可以很容易實(shí)現(xiàn)字符串的切割,運(yùn)行后可看到字符串被解析成了獨(dú)立的整數(shù),如下圖所示;

異步端口探測

Boost.Asio是一個(gè)強(qiáng)大的C++庫,提供了異步I/O和網(wǎng)絡(luò)編程的支持。本文將介紹如何使用Boost.Asio實(shí)現(xiàn)異步連接,以及如何設(shè)置超時(shí)機(jī)制,確保連接在規(guī)定的時(shí)間內(nèi)建立。Asio是Boost庫中的一個(gè)模塊,用于異步I/O和網(wǎng)絡(luò)編程。它提供了一種靈活的方式來處理異步操作,使得程序能夠更高效地利用系統(tǒng)資源。Boost.Asio支持TCP、UDP、SSL等協(xié)議,使得開發(fā)者能夠輕松實(shí)現(xiàn)異步網(wǎng)絡(luò)通信。

異步連接實(shí)現(xiàn)

在本文的代碼示例中,我們使用Boost.Asio創(chuàng)建了一個(gè)AsyncConnect類,用于執(zhí)行異步連接。這個(gè)類包含了異步連接的主要邏輯,其中使用了tcp::socketdeadline_timer來處理異步操作和超時(shí)。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/date_time/posix_time/posix_time_types.hpp>  

using namespace std;
using boost::asio::ip::tcp;

// 異步連接地址與端口
class AsyncConnect
{
public:
  AsyncConnect(boost::asio::io_service& ios, tcp::socket &s)
    :io_service_(ios), timer_(ios), socket_(s) {}

  // 異步連接
  bool aysnc_connect(const tcp::endpoint &ep, int million_seconds)
  {
    bool connect_success = false;

    // 異步連接,當(dāng)連接成功后將觸發(fā) connect_handle 函數(shù)
    socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success)));

    // 設(shè)置一個(gè)定時(shí)器  million_seconds 
    timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds));
    bool timeout = false;

    // 異步等待 如果超時(shí)則執(zhí)行 timer_handle
    timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout)));
    do
    {
      // 等待異步操作完成
      io_service_.run_one();
      // 判斷如果timeout沒超時(shí),或者是連接建立了,則不再等待
    } while (!timeout && !connect_success);
    timer_.cancel();
    return connect_success;
  }

private:
  // 如果連接成功了,則 connect_success = true
  void connect_handle(boost::system::error_code ec, bool &connect_success)
  {
    if (!ec)
    {
      connect_success = true;
    }
  }

  // 定時(shí)器超時(shí)timeout = true
  void timer_handle(boost::system::error_code ec, bool &timeout)
  {
    if (!ec)
    {
      socket_.close();
      timeout = true;
    }
  }
  boost::asio::io_service &io_service_;
  boost::asio::deadline_timer timer_;
  tcp::socket &socket_;
};

探測主函數(shù)

在主函數(shù)中,我們創(chuàng)建了一個(gè)AsyncConnect對象,并使用它進(jìn)行異步連接。這個(gè)例子中,我們嘗試連接到IP地址為"202.89.233.101",端口號為80的服務(wù)器,并設(shè)置了連接超時(shí)時(shí)間為300毫秒。

int main(int argc, char * argv[])
{
  try
  {
    boost::asio::io_service io;
    tcp::socket socket(io);
    AsyncConnect hander(io, socket);
    tcp::endpoint ep(boost::asio::ip::address::from_string("8.141.58.64"), 80);

    // 傳遞掃描ep地址結(jié)構(gòu),以及超時(shí)時(shí)間
    if (hander.aysnc_connect(ep, 300))
    {
      std::cout << "連通了" << std::endl;
      io.run();
    }
    else
    {
      std::cout << "連接失敗" << std::endl;
    }

  }
  catch (...)
  {
    return false;
  }

  std::system("pause");
  return 0;
}

通過本文的示例,我們展示了如何使用Boost.Asio創(chuàng)建異步連接,并設(shè)置連接超時(shí)。異步連接的實(shí)現(xiàn)可以提高程序的性能和效率,特別適用于需要處理大量并發(fā)連接的網(wǎng)絡(luò)應(yīng)用場景。Boost.Asio的靈活性使得開發(fā)者能夠更方便地處理異步I/O操作,提高程序的健壯性和可維護(hù)性。

當(dāng)代碼被運(yùn)行時(shí),則自動探測特定地址的特定端口是否開放,如果開放則返回如下圖所示;

端口掃描封裝

實(shí)現(xiàn)端口掃描

首先增加PortScan函數(shù)該函數(shù)傳入地址端口號以及超時(shí)時(shí)間,自動掃描端口開放狀態(tài),這里我們就以掃描192.168.1.1端口從78-100掃描后將結(jié)果輸出到屏幕上。

// 封裝端口掃描函數(shù)
bool PortScan(std::string address, int port, int timeout)
{
  try
  {
    boost::asio::io_service io;
    tcp::socket socket(io);
    AsyncConnect hander(io, socket);
    tcp::endpoint ep(boost::asio::ip::address::from_string(address), port);

    // 傳遞掃描ep地址結(jié)構(gòu),以及超時(shí)時(shí)間
    if (hander.aysnc_connect(ep, timeout))
    {
      io.run();
      return true;
    }
    else
    {
      return false;
    }

  }
  catch (...)
  {
    return false;
  }
}

int main(int argc, char * argv[])
{
  for (int x = 78; x < 100; x++)
  {
    bool is_open = PortScan("192.168.1.1", x, 1000);
    std::cout << "掃描端口: " << x << " 狀態(tài): " << is_open << std::endl;
  }

  std::system("pause");
  return 0;
}

運(yùn)行上述代碼即可掃描特定的端口是否開放,輸出效果如下圖所示;

實(shí)現(xiàn)特定端口掃描

實(shí)現(xiàn)CalculationPort函數(shù),用戶傳入一串字符串自動解析為端口號,并調(diào)用掃描功能對特定端口進(jìn)行掃描。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/date_time/posix_time/posix_time_types.hpp>

#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;
using boost::asio::ip::tcp;

// 傳遞端口字符串,解析為vector容器
bool CalculationPort(std::string port_string, std::vector<int> &ref)
{
	std::vector<std::string> vect;
	try
	{
		boost::split(vect, port_string, boost::is_any_of(","), boost::token_compress_on);

		for (int x = 0; x < vect.size(); x++)
		{
			ref.push_back(lexical_cast<int>(vect[x]));
		}
		return true;
	}
	catch (...)
	{
		return false;
	}
	return true;
}

int main(int argc, char * argv[])
{
	std::string scan_address = "192.168.1.1";
	std::vector<int> scan_port_list;

	bool scan_ref = CalculationPort("80,443,445,135,139", scan_port_list);
	if (scan_ref == true)
	{
		// 循環(huán)取出需要掃描的端口對目標(biāo)進(jìn)行掃描
		for (int x = 0; x < scan_port_list.size(); x++)
		{
			bool is_open = PortScan(scan_address, scan_port_list[x], 1000);
			if (is_open == true)
			{
				std::cout << "掃描地址: " << scan_address << " 掃描端口: " << scan_port_list[x] << " 掃描狀態(tài): 端口開放" << std::endl;
			}
			else
			{
				std::cout << "掃描地址: " << scan_address << " 掃描端口: " << scan_port_list[x] << " 掃描狀態(tài): 端口關(guān)閉" << std::endl;
			}
		}
	}
	std::system("pause");
	return 0;
}

運(yùn)行上述代碼即可掃描地址192.168.1.1下的80,443,445,135,139端口開放狀態(tài),如下圖所示;

增加參數(shù)解析

Boost Program Options 是Boost庫中的一個(gè)模塊,用于處理程序的命令行選項(xiàng)。它提供了一個(gè)靈活的框架,使得開發(fā)者能夠輕松地解析和處理命令行參數(shù)。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/date_time/posix_time/posix_time_types.hpp>

#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include <boost/program_options.hpp>

using namespace std;
using namespace boost;
using boost::asio::ip::tcp;
namespace opt = boost::program_options;

int main(int argc, char * argv[])
{
  opt::options_description des_cmd("\n Usage: LyShark 端口掃描器 Ver:1.0 \n\n Options");
  des_cmd.add_options()
    ("address,a", opt::value<std::string>()->default_value("127.0.0.1"), "指定掃描地址")
    ("set_port,s", opt::value<std::string>()->default_value("none"), "設(shè)置掃描端口")
    ("help,h", "幫助菜單");

  opt::variables_map virtual_map;
  try
  {
    opt::store(opt::parse_command_line(argc, argv, des_cmd), virtual_map);
  }
  catch (...){ return 0; }

  // 定義消息
  opt::notify(virtual_map);

  // 無參數(shù)直接返回
  if (virtual_map.empty())
  {
    return 0;
  }
  else if (virtual_map.count("help") || virtual_map.count("h"))
  {
    std::cout << des_cmd << std::endl;
    return 0;
  }
  else if (virtual_map.count("address") && virtual_map.count("set_port"))
  {
    std::string address = virtual_map["address"].as<std::string>();
    std::string set_port = virtual_map["set_port"].as<std::string>();

    // 判斷是不是默認(rèn)參數(shù)
    if (address == "127.0.0.1" || set_port == "none")
    {
      std::cout << des_cmd << std::endl;
    }
    else
    {
      // 執(zhí)行掃描流程
      std::vector<int> scan_port_list;

      bool scan_ref = CalculationPort(set_port, scan_port_list);
      if (scan_ref == true)
      {
        // 循環(huán)取出需要掃描的端口對目標(biāo)進(jìn)行掃描
        for (int x = 0; x < scan_port_list.size(); x++)
        {
          bool is_open = PortScan(address, scan_port_list[x], 1000);
          if (is_open == true)
          {
            std::cout << "掃描地址: " << address << " 掃描端口: " << scan_port_list[x] << " 掃描狀態(tài): 端口開放" << std::endl;
          }
          else
          {
            std::cout << "掃描地址: " << address << " 掃描端口: " << scan_port_list[x] << " 掃描狀態(tài): 端口關(guān)閉" << std::endl;
          }
        }
      }
    }
  }
  else
  {
    std::cout << "參數(shù)錯(cuò)誤" << std::endl;
  }
  return 0;

  std::system("pause");
  return 0;
}

當(dāng)有了命令解析功能,我們就可以向程序內(nèi)傳入?yún)?shù),如下所示;

多線程掃描

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/date_time/posix_time/posix_time_types.hpp>

#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include <boost/program_options.hpp>

#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/thread_guard.hpp>

using namespace std;
using namespace boost;
using boost::asio::ip::tcp;
namespace opt = boost::program_options;

boost::mutex io_mutex;

// 實(shí)現(xiàn)多線程掃描
void MyThread(std::string address, int port)
{
  bool is_open = PortScan(address, port, 1000);
  // boost::mutex::scoped_lock lock(io_mutex);

  boost::lock_guard<boost::mutex> global_mutex(io_mutex);
  if (is_open == true)
  {
    std::cout << "掃描地址: " << address << " 掃描端口: " << port << " 掃描狀態(tài): 開放" << std::endl;
  }
  else
  {
    std::cout << "掃描地址: " << address << " 掃描端口: " << port << " 掃描狀態(tài): 關(guān)閉" << std::endl;
  }
}

int main(int argc, char * argv[])
{
  opt::options_description des_cmd("\n Usage: LyShark 端口掃描器 Ver:1.0 \n\n Options");
  des_cmd.add_options()
    ("address,a", opt::value<std::string>()->default_value("127.0.0.1"), "指定掃描地址")
    ("set_port,s", opt::value<std::string>()->default_value("none"), "設(shè)置掃描端口")
    ("help,h", "幫助菜單");

  opt::variables_map virtual_map;
  try
  {
    opt::store(opt::parse_command_line(argc, argv, des_cmd), virtual_map);
  }
  catch (...){ return 0; }

  // 定義消息
  opt::notify(virtual_map);

  // 無參數(shù)直接返回
  if (virtual_map.empty())
  {
    return 0;
  }
  else if (virtual_map.count("help") || virtual_map.count("h"))
  {
    std::cout << des_cmd << std::endl;
    return 0;
  }
  else if (virtual_map.count("address") && virtual_map.count("set_port"))
  {
    std::string address = virtual_map["address"].as<std::string>();
    std::string set_port = virtual_map["set_port"].as<std::string>();

    // 判斷是不是默認(rèn)參數(shù)
    if (address == "127.0.0.1" || set_port == "none")
    {
      std::cout << des_cmd << std::endl;
    }
    else
    {
      // 執(zhí)行掃描流程
      std::vector<int> scan_port_list;

      bool scan_ref = CalculationPort(set_port, scan_port_list);
      if (scan_ref == true)
      {
        boost::thread_group group;
        // 循環(huán)取出需要掃描的端口對目標(biāo)進(jìn)行掃描
        for (int x = 0; x < scan_port_list.size(); x++)
        {
          group.create_thread(boost::bind(MyThread, address, scan_port_list[x]));
        }
        group.join_all();
      }
    }
  }
  else
  {
    std::cout << "參數(shù)錯(cuò)誤" << std::endl;
  }
  return 0;

  std::system("pause");
  return 0;
}

運(yùn)行效果如下圖所示,通過使用多線程可提高程序的掃描效率。

完整掃描器代碼

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/date_time/posix_time/posix_time_types.hpp>

#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include <boost/program_options.hpp>

#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/function.hpp>
#include <boost/thread/thread_guard.hpp>

using namespace std;
using namespace boost;
using boost::asio::ip::tcp;
namespace opt = boost::program_options;

boost::mutex io_mutex;

void ShowOpt()
{
  fprintf(stderr,
    "#                       #                          #       \n"
    "#                       #                          #       \n"
    "#     #    #    #####   ######    ######   # ###   #   ##  \n"
    "#     #    #   #        #     #  #     #   ##      #  #    \n"
    "#     #    #    ####    #     #  #     #   #       ###     \n"
    "#      #####        #   #     #  #    ##   #       #  #    \n"
    "#####      #   #####    #     #   #### #   #       #   ##  \n\n"
    );
}

// 異步連接地址與端口
class AsyncConnect
{
public:
  AsyncConnect(boost::asio::io_service& ios, tcp::socket &s)
    :io_service_(ios), timer_(ios), socket_(s) {}

  // 異步連接
  bool aysnc_connect(const tcp::endpoint &ep, int million_seconds)
  {
    bool connect_success = false;

    // 異步連接,當(dāng)連接成功后將觸發(fā) connect_handle 函數(shù)
    socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success)));

    // 設(shè)置一個(gè)定時(shí)器  million_seconds 
    timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds));
    bool timeout = false;

    // 異步等待 如果超時(shí)則執(zhí)行 timer_handle
    timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout)));
    do
    {
      // 等待異步操作完成
      io_service_.run_one();
      // 判斷如果timeout沒超時(shí),或者是連接建立了,則不再等待
    } while (!timeout && !connect_success);
    timer_.cancel();
    return connect_success;
  }

private:
  // 如果連接成功了,則 connect_success = true
  void connect_handle(boost::system::error_code ec, bool &connect_success)
  {
    if (!ec)
    {
      connect_success = true;
    }
  }

  // 定時(shí)器超時(shí)timeout = true
  void timer_handle(boost::system::error_code ec, bool &timeout)
  {
    if (!ec)
    {
      socket_.close();
      timeout = true;
    }
  }
  boost::asio::io_service &io_service_;
  boost::asio::deadline_timer timer_;
  tcp::socket &socket_;
};

// 封裝端口掃描函數(shù)
bool PortScan(std::string address, int port, int timeout)
{
  try
  {
    boost::asio::io_service io;
    tcp::socket socket(io);
    AsyncConnect acHandler(io, socket);
    tcp::endpoint ep(boost::asio::ip::address::from_string(address), port);

    // 傳遞掃描ep地址結(jié)構(gòu),以及超時(shí)時(shí)間
    if (acHandler.aysnc_connect(ep, timeout))
    {
      io.run();
      return true;
    }
    else
    {
      return false;
    }

  }
  catch (...)
  {
    return false;
  }
}

// 傳遞IP地址范圍,自動生成IP地址表
bool CalculationAddress(std::string address, std::vector<std::string> &ref)
{
  std::vector<std::string> vect;
  try
  {
    // 以/,兩個(gè)下劃線作為切割符號,切割后放入vect容器中
    boost::split(vect, address, boost::is_any_of("/") || boost::is_any_of("."), boost::token_compress_on);

    // 將開始和結(jié)束地址取出來
    int start_count = lexical_cast<int>(vect[3]);
    int end_count = lexical_cast<int>(vect[4]);

    // IP地址中的C段必須小于255
    if (end_count <= 255)
    {
      for (int x = start_count; x <= end_count; x++)
      {
        std::string this_address = boost::str(boost::format("%s.%s.%s.%s") % vect[0] % vect[1] % vect[2] % x);
        ref.push_back(this_address);
      }
    }
    else
    {
      return false;
    }
  }
  catch (...)
  {
    return false;
  }
  return true;
}

// 傳遞端口字符串,解析為vector容器
bool CalculationPort(std::string port_string, std::vector<int> &ref)
{
  std::vector<std::string> vect;
  try
  {
    boost::split(vect, port_string, boost::is_any_of(","), boost::token_compress_on);

    for (int x = 0; x < vect.size(); x++)
    {
      ref.push_back(lexical_cast<int>(vect[x]));
    }
    return true;
  }
  catch (...)
  {
    return false;
  }
  return true;
}

// 實(shí)現(xiàn)多線程掃描
void MyThread(std::string address, int port)
{
  bool is_open = PortScan(address, port, 1000);
  // boost::mutex::scoped_lock lock(io_mutex);

  boost::lock_guard<boost::mutex> global_mutex(io_mutex);
  if (is_open == true)
  {
    std::cout << "掃描地址: " << address << " 掃描端口: " << port << " 掃描狀態(tài): 開放" << std::endl;
  }
  else
  {
    std::cout << "掃描地址: " << address << " 掃描端口: " << port << " 掃描狀態(tài): 關(guān)閉" << std::endl;
  }
}

// 實(shí)現(xiàn)全端口線程掃描
void MyThreadB(std::string address, int port)
{
  bool is_open = PortScan(address, port, 1000);
  // boost::mutex::scoped_lock lock(io_mutex);

  boost::lock_guard<boost::mutex> global_mutex(io_mutex);
  if (is_open == true)
  {
    std::cout << "掃描地址: " << address << " 掃描端口: " << port << " 掃描狀態(tài): 開放" << std::endl;
  }
}

int main(int argc, char * argv[])
{
  opt::options_description des_cmd("\n Usage: LyShark 端口掃描器 Ver:1.1 \n\n Options");
  des_cmd.add_options()
    ("address,a", opt::value<std::string>(), "指定掃描地址 192.168.1.1")
    ("c_address,c", opt::value<std::string>(), "設(shè)置掃描C地址段 192.168.1.1/24")
    ("set_port,s", opt::value<std::string>(), "設(shè)置掃描端口 80,443,135,139")
    ("type,t", opt::value<std::string>(), "對特定主機(jī) 掃描 1-65535 全端口")
    ("help,h", "幫助菜單");

  opt::variables_map virtual_map;
  try
  {
    opt::store(opt::parse_command_line(argc, argv, des_cmd), virtual_map);
  }
  catch (...){ return 0; }

  // 定義消息
  opt::notify(virtual_map);

  // 無參數(shù)直接返回
  if (virtual_map.empty())
  {
    ShowOpt();
    std::cout << des_cmd << std::endl;
    return 0;
  }
  else if (virtual_map.count("help") || virtual_map.count("h"))
  {
    ShowOpt();
    std::cout << des_cmd << std::endl;
    return 0;
  }
  // 掃描全端口
  else if (virtual_map.count("address") && virtual_map.count("type"))
  {
    std::string address = virtual_map["address"].as<std::string>();
    std::string type = virtual_map["type"].as<std::string>();

    if (address.length() != 0 && type == "all")
    {
      // 執(zhí)行全端口掃描
      boost::thread_group group;
      for (int x = 0; x < 65534; x++)
      {
        group.create_thread(boost::bind(MyThreadB, address, x));
        _sleep(50);
      }
      group.join_all();
    }
  }

  // 掃描特定端口
  else if (virtual_map.count("address") && virtual_map.count("set_port"))
  {
    std::string address = virtual_map["address"].as<std::string>();
    std::string set_port = virtual_map["set_port"].as<std::string>();

    // 執(zhí)行特定端口掃描
    std::vector<int> scan_port_list;

    bool scan_ref = CalculationPort(set_port, scan_port_list);
    if (scan_ref == true)
    {
      boost::thread_group group;
      // 循環(huán)取出需要掃描的端口對目標(biāo)進(jìn)行掃描
      for (int x = 0; x < scan_port_list.size(); x++)
      {
        group.create_thread(boost::bind(MyThread, address, scan_port_list[x]));
      }
      group.join_all();
    }
  }

  // 掃描特定地址段中的特定端口
  else if (virtual_map.count("c_address") && virtual_map.count("set_port"))
  {
    std::string c_address = virtual_map["c_address"].as < std::string >();
    std::string set_port = virtual_map["set_port"].as<std::string>();

    // 計(jì)算出需要掃描的端口
    std::vector<int> scan_port_list;
    bool scan_port_ref = CalculationPort(set_port, scan_port_list);

    // 計(jì)算出需要掃描的地址段
    std::vector < std::string > scan_address_list;

    bool scan_address_ref = CalculationAddress(c_address, scan_address_list);

    if (scan_port_ref == true && scan_address_ref == true)
    {
      // 分別取出每一個(gè)IP地址
      for (int x = 0; x < scan_address_list.size(); x++)
      {
        boost::thread_group group;
        // 對每一個(gè)IP地址中的端口段進(jìn)行掃描
        for (int y = 0; y < scan_port_list.size(); y++)
        {
          group.create_thread(boost::bind(MyThreadB, scan_address_list[x], scan_port_list[y]));
        }
        group.join_all();
      }
    }
  }
  else
  {
    std::cout << "參數(shù)錯(cuò)誤" << std::endl;
  }
  return 0;
}

至此,一個(gè)基于ASIO異步模型的,多線程端口掃描器就這么完成了,總結(jié)幫助手冊。

  • 掃描全端口: lyscanner.exe --address 192.168.1.1 --type all
  • 掃描整個(gè)C段: lyscanner.exe --c_address 192.168.1.1/10 --set_port 22,25
  • 特定端口掃描: lyscanner.exe --address 192.168.1.1 --set_port 22,25,135,139

以上就是C++ Boost實(shí)現(xiàn)異步端口掃描器詳解的詳細(xì)內(nèi)容,更多關(guān)于C++ Boost端口掃描器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言移除元素的三種思路講解

    C語言移除元素的三種思路講解

    這篇文章主要介紹了C語言移除元素的三種思路,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路
    2022-10-10
  • 淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換

    淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換

    這篇文章主要介紹了淺談C++的語句語法與強(qiáng)制數(shù)據(jù)類型轉(zhuǎn)換,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++?BoostAsyncSocket實(shí)現(xiàn)異步反彈通信的案例詳解

    C++?BoostAsyncSocket實(shí)現(xiàn)異步反彈通信的案例詳解

    這篇文章主要為大家詳細(xì)介紹了C++?BoostAsyncSocket如何實(shí)現(xiàn)異步反彈通信,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-03-03
  • boost.asio框架系列之socket編程

    boost.asio框架系列之socket編程

    這篇文章介紹了boost.asio框架系列之socket編程,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 最新評論